Changing logic for /tickets API in CAS - cas

Reference: https://wiki.jasig.org/display/CASUM/RESTful+API
I would like to change the logic behind POST /cas/v1/tickets How would I go about doing that?
Basically, I need the logic to make an API call to a different software. Depending on the response to that call I decide whether or not the user authenticates correctly or not.
I see that in reslet-servlet.xml there is a TicketResource object associated to /tickets. Do I start there by inheriting it? Where do I start? Am I looking at the write file?
<bean id="root" class="org.restlet.ext.spring.SpringRouter">
<property name="attachments">
<map>
<entry key="/tickets">
<bean class="org.restlet.ext.spring.SpringFinder">
<lookup-method name="createResource" bean="ticketResource" />
</bean>
Thanks in advance.

Yes, it's a good way to start : inheriting from TicketResource and implementing your own logic in acceptRepresentation method...

Related

Reading method-level properties using JUnit + spring-test

What is the best way to use spring-test with JUnit to read property files specific to a test method?
The following bean illustrates the intent to search method-level, then class-level, then package-level, then root-level property files:
<bean name="properties" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer" >
<property name="locations">
<list>
<value>classpath:properties.xml</value>
<value>classpath:*/properties.xml</value>
<value>classpath:*/*/properties.xml</value>
<value>classpath:*/*/*.properties.xml</value>
</list>
</property>
</bean>
I've considered using/subclassing PropertySourcesPlaceholderConfigurer or SpringMethodRule, but so far, neither a viable nor elegant solution has occurred to me. spring-test offers a variety of promising class-level annotations, but the stumbling block is that I want to be able to find a method-specific file, e.g.:
classpath:myPackage/myClass/myMethod.properties.xml
If you are just looking for an algorithm that helps you to look up classpath resources based on the current method, you can take inspiration from the ServletTestExecutionListener in the Spring TestContext Framework, specifically the detectDefaultScript() method.
Regards,
Sam (author of the Spring TestContext Framework)

checkstyle - prohibit initializing object of type

suppose I have an external library with a class called Foo. I can't change Foo to have a private constructor, but I have a FooFactory class that I wrote.
So I have FooFactory.getAFoo() but I want checkstyle to catch any new Foo() in the rest of my code, to force using the factory.
I have this:
<module name="IllegalTokenText">
<property name="tokens" value="LITERAL_NEW"/>
<property name="format" value="Foo"/>
</module>
but this doesn't seem to detect a new Foo().
I could use a regex but this is much cleaner.
I had a similar problem with preventing extending a class:
<module name="IllegalTokenText">
<property name="tokens" value="EXTENDS_CLAUSE"/>
<property name="format" value="AndroidTestCase"/>
</module>
Neither of these checkstyle module seem to do anything at all.
What am I doing wrong?
IllegalTokenText checks for illegal text on the token itself, not on subsequent IDENT tokens or some such. So that is why it seems to do nothing in your case.
In your case, you may want to try using the SevNTU Checkstyle extension, which offers a check called ForbidInstantiation which might solve your problem. They have no documentation that I am aware of, so I am linking the source code with Javadoc. When you use SevNTU Checkstyle, be sure to use the right versions of regular Checkstyle and SevNTU Checkstyle, because not all combinations are compatible (overview).
If that does not help, you will have to roll your own.

CAS primaryAuthenticationHandler ldapAuthenticationHandler

I think I've exhausted searching and need to ask this seemingly very popular question about CAS configuration for Active Directory. I followed the steps on CAS docs to modify the deployerConfigContext.xml to include the ldapAuthenticationHandler bean.
But seems like CAS is continuing to use AcceptUsersAuthenticationHandler defined in the same file in the primaryAuthenticationHandler tag.
Question: So basically I need to replace AcceptUsersAuthenticationHandler with ldapAuthenticationHandler as the default authenticator. What is the correct syntax to do so in the following snippet?
<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
<property name="users">
<map>
<entry key="casuser" value="Mellon"/>
</map>
</property>
</bean>
This is what I have tried so far:
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.LdapAuthenticationHandler"></bean>
java.lang.NoSuchMethodException: org.jasig.cas.authentication.LdapAuthenticationHandler.<init>()
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.ldapAuthenticationHandler"></bean>
java.lang.ClassNotFoundException: org.jasig.cas.authentication.ldapAuthenticationHandler
<bean id="primaryAuthenticationHandler" class="ldapAuthenticationHandler"></bean>
java.lang.ClassNotFoundException: ldapAuthenticationHandler
Did you add the dependency in pom.xml?
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-support-ldap</artifactId>
<version>${cas.version}</version>
</dependency>
Indeed, LdapAuthenticationHandler doesn't implement a default constructor, you need to configure a org.ldaptive.auth.Authenticator on the attribute c:authenticator-ref:
<bean id="ldapAuthenticationHandler"
class="org.jasig.cas.authentication.LdapAuthenticationHandler"
p:principalIdAttribute="mail"
c:authenticator-ref="authenticator"/>
LDAP authentication is not as simple as the default hardcoded user/password authentication handler. In this link you can see an example on how to configure a connection to Active Directory: Active Directory Authentication
Following the example, you will find in "LDAP Properties Starter" some properties defined. You will need to copy them to the file cas.properties on the same folder as deployerConfigContext.xml. You have to adjust the properties to your usecase and be aware that some of the properties names don't correspond with the ones on the xml examples.

Logback: Multiple Property Sources

I want to do something like:
<insertFromJNDI env-entry-name="java:comp/env/conf/app-log-path" as="logPath" />
<if test='!isDefined("logPath") && isDefined("catalina.home")'>
<then>
<property name="logPath" value="${catalina.home}/logs/" />
</then>
</if>
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logPath:-logs/}myapp.log</file>
</appender>
that is, allow a JNDI property to be sent in to my logging configuration, and if that is not found then try using catalina.home, and if that is not found then use a default value. Is this possible? It seems to me that is should be, but the never seems to take effect, maybe properties can't be updated in this manner? The documentation (chapter 3 of the manual) makes the property substituton seem quite powerful, but I just can't seem to get it working properly.
I believe I got an old or incorrect demo. Immediately after posting this, I realized that the attribute is condition="" instead of test="".

Help with Castle Windsor XML configuration

I have the following three components defined in the Caste-Windsor XML configuration for my application:
<component id="StringFactory"
service="IStringFactory, MyApp"
type="DefaultStringFactory, MyApp"
lifestyle="singleton"
/>
<component id="TheString"
type="System.String"
factoryId="StringFactory"
factoryCreate="CreateString"
>
<parameters>
<name>SomeString</name>
</parameters>
</component>
<component id="TheTarget"
service="ITarget, MyApp"
type="TheTarget, MyApp"
lifestyle="transient"
>
<parameters>
<aString>${TheString}</aString>
</parameters>
</component>
And the following facility defined:
<facility id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"
/>
When I run the application and set a breakpoint in the constructor of the TheObject class, the value passed in as the aString parameter is "${TheString}" when I expect it to resolve to the value of the component with that name.
Also, I have a breakpoint in the StringFactory constructor and CreateString method, neither of which are hit. I know the configuration is being used as other components are resolving correctly.
What am I missing or doing wrong here?
UPDATE
In light of the huge tangient this topic has taken, I've refactored the code above to remove anything to do with connection strings. The original intent of this post was about injecting a property with the value returned from a method on another object. Somehow that point was lost in a discussion about why I'm using XML versus code-based configuration and if this is a good way to inject a connection string.
The above approach is far from an original idea and it was pulled from several other discussions on this topic and our requirements are what they are. I'd like help understanding why the configuration as it is in place (whether the right approach or not) isn't working as expected.
I did verify that the first two components are being instantiated correctly. When I call Container.Resolve("TheString"), I get the correct value back. For whatever reason, The parameter syntax is not working correctly.
Any ideas?
While not a definitive solution to what I need to do in my application, I believe I've figured out what is wrong with the code. Or at least I've found a way to make it work which hints at the original problem.
I replaced the String type for TheString with a custom class. That's it. Once I did that, everything worked fine.
My guess is that it has something to do with the fact that I was trying to use a ValueType (primitive) as a component. I guess Castle doesn't support it.
So, knowing that's the case, I can now move on to figuring out if this approach is really going to work or if we need to change direction.
UPDATE
For the sake of completeness, I thought I'd go ahead and explain what I did to solve my problem AND satisfy my requirements.
As before, I have access to my configuration settings through an IConfigurationService defined as:
<component id="ConfigurationService"
service="MyApp.IConfigurationService, MyApp"
type="MyApp.RuntimeConfigurationService, MyApp"
lifestyle="singleton"
/>
This is automatically injected into my (new) IConnectionFactory which is responsible for generating IDbConnection objects based on the connection strings defined in the application's configuration file. The factory is declared as:
<component id="ConnectionFactory"
service="MyApp.Factories.IConnectionFactory, MyApp"
type="MyApp.Factories.DefaultConnectionFactory, MyApp"
lifestyle="singleton"
/>
In order to resolve what connection is used by my repository, I declare each connection as a component using the ConnectionFactory to create each instance:
<component id="MyDbConnection"
type="System.Data.IDbConnection,
System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089"
factoryId="ConnectionFactory"
factoryCreate="CreateConnection"
lifestyle="transient"
>
<parameters>
<connectionStringName>MyDB</connectionStringName>
</parameters>
</component>
Notice the fully described reference to System.Data. I found this is necessary whenever referencing assemblies in the GAC.
Finally, my repository is defined as:
<component id="MyRepository"
service="MyApp.Repositories.IMyRepository, MyApp"
type="MyApp.Sql.SqlMyRepository, MyApp.Sql"
lifestyle="transient"
>
<parameters>
<connection>${MyDbConnection}</connection>
</parameters>
</component>
Now everything resolves correctly and I don't have ANY hard-coded strings compiled into my code. No connection string names, app setting keys or whatever. The app is completely reconfigurable from the XML files which is a requirement I must satisfy. Plus, other devs that will be working with the solution can manage the actual connection strings in the way they are used to. Win-win.
Hope this helps anyone else that runs into a similar scenario.
You don't really need XML registrations here, since you probably don't need to swap components or change the method used without recompiling. Writing a configurable app does not imply having to use XML registrations.
The problem with this particular XML registration you posted is that the connection string is a parameter, but it's treated like a service.
Doing this with code registrations is much easier, e.g.:
var container = new WindsorContainer();
container.Register(Component.For<IConfigurationService>().ImplementedBy<RuntimeConfigurationService>());
container.Register(Component.For<ITheRepository>().ImplementedBy<TheRepository>()
.LifeStyle.Transient
.DynamicParameters((k, d) => {
var cfg = k.Resolve<IConfigurationService>();
d["connectionString"] = cfg.GetConnectionString();
k.ReleaseComponent(cfg);
}));
Or if you don't want to depend on IConfigurationService, you could do something like:
container.Register(Component.For<ITheRepository>().ImplementedBy<TheRepository>()
.LifeStyle.Transient
.DependsOn(Property.ForKey("connectionString")
.Is(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["connName"]].ConnectionString))