/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.picketlink.http.internal;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import org.picketlink.config.SecurityConfigurationBuilder;
import org.picketlink.config.http.AuthenticationConfigurationBuilder;
import org.picketlink.config.http.AuthorizationConfigurationBuilder;
import org.picketlink.config.http.BasicAuthenticationConfigurationBuilder;
import org.picketlink.config.http.CORSConfigurationBuilder;
import org.picketlink.config.http.DigestAuthenticationConfigurationBuilder;
import org.picketlink.config.http.FormAuthenticationConfigurationBuilder;
import org.picketlink.config.http.HttpSecurityConfigurationChildBuilder;
import org.picketlink.config.http.PathConfigurationBuilder;
import org.picketlink.config.http.TokenAuthenticationConfigurationBuilder;
import org.picketlink.config.http.X509AuthenticationConfigurationBuilder;
import org.picketlink.config.http.annotations.AllPaths;
import org.picketlink.config.http.annotations.AllowAnyOrigin;
import org.picketlink.config.http.annotations.AllowedGroups;
import org.picketlink.config.http.annotations.AllowedOrigins;
import org.picketlink.config.http.annotations.AllowedRealms;
import org.picketlink.config.http.annotations.AllowedRoles;
import org.picketlink.config.http.annotations.Authc;
import org.picketlink.config.http.annotations.Authz;
import org.picketlink.config.http.annotations.Basic;
import org.picketlink.config.http.annotations.Cors;
import org.picketlink.config.http.annotations.Digest;
import org.picketlink.config.http.annotations.ExposedHeaders;
import org.picketlink.config.http.annotations.Expressions;
import org.picketlink.config.http.annotations.Form;
import org.picketlink.config.http.annotations.MaxAge;
import org.picketlink.config.http.annotations.Path;
import org.picketlink.config.http.annotations.PathGroup;
import org.picketlink.config.http.annotations.Restrictive;
import org.picketlink.config.http.annotations.SupportAnyHeader;
import org.picketlink.config.http.annotations.SupportedHeaders;
import org.picketlink.config.http.annotations.SupportedMethods;
import org.picketlink.config.http.annotations.SupportsCredentials;
import org.picketlink.config.http.annotations.Token;
import org.picketlink.config.http.annotations.X509;
/**
* @author Giriraj Sharma
*/
public class HttpSecurityAnnotationsParser {
private SecurityConfigurationBuilder builder = new SecurityConfigurationBuilder();
private HttpSecurityConfigurationChildBuilder httpSecurityBuilder = builder.http();
private PathConfigurationBuilder pathConfigurationBuilder;
private CORSConfigurationBuilder corsConfigurationBuilder;
private AuthenticationConfigurationBuilder authenticationConfigurationBuilder;
private FormAuthenticationConfigurationBuilder formAuthenticationConfigurationBuilder;
private BasicAuthenticationConfigurationBuilder basicAuthenticationConfigurationBuilder;
private DigestAuthenticationConfigurationBuilder digestAuthenticationConfigurationBuilder;
private TokenAuthenticationConfigurationBuilder tokenAuthenticationConfigurationBuilder;
private X509AuthenticationConfigurationBuilder x509AuthenticationConfigurationBuilder;
private AuthorizationConfigurationBuilder authorizationConfigurationBuilder;
public HttpSecurityConfigurationChildBuilder processAnnotatedType(Class<?> configurationClass) {
Class<?> clazz = configurationClass;
Class<? extends Annotation> previousAnnotation = null;
Class<? extends Annotation> newAnnotation = null;
for (Field enumm : clazz.getFields()) {
for (Annotation a : enumm.getAnnotations()) {
previousAnnotation = newAnnotation;
newAnnotation = a.annotationType();
if (a.annotationType() == Restrictive.class) {
this.httpSecurityBuilder = this.httpSecurityBuilder.restrictive();
} else if (a.annotationType() == AllPaths.class) {
this.pathConfigurationBuilder = this.httpSecurityBuilder.allPaths();
} else if (a.annotationType() == Path.class) {
Path path = (Path) a;
String pathName = path.pathName();
String pathGroup = path.pathGroup();
if (pathName != null && !pathName.isEmpty() && pathGroup != null && !pathGroup.isEmpty()) {
if (previousAnnotation == newAnnotation) {
this.pathConfigurationBuilder = this.pathConfigurationBuilder.forPath(pathName, pathGroup);
} else if (this.authorizationConfigurationBuilder != null) {
this.pathConfigurationBuilder = this.authorizationConfigurationBuilder.forPath(pathName, pathGroup);
} else if (previousAnnotation == Form.class || previousAnnotation == Basic.class
|| previousAnnotation == Digest.class || previousAnnotation == Token.class
|| previousAnnotation == X509.class) {
this.pathConfigurationBuilder = SetAuthenticationPathNameAndGroup(previousAnnotation, pathName,
pathGroup);
} else if (this.corsConfigurationBuilder != null) {
this.pathConfigurationBuilder = this.corsConfigurationBuilder.forPath(pathName, pathGroup);
} else {
this.pathConfigurationBuilder = this.httpSecurityBuilder.forPath(pathName, pathGroup);
}
} else if (pathName != null && !pathName.isEmpty()) {
if (previousAnnotation == newAnnotation) {
this.pathConfigurationBuilder = this.pathConfigurationBuilder.forPath(pathName);
} else if (this.authorizationConfigurationBuilder != null) {
this.pathConfigurationBuilder = this.authorizationConfigurationBuilder.forPath(pathName);
} else if (previousAnnotation == Form.class || previousAnnotation == Basic.class
|| previousAnnotation == Digest.class || previousAnnotation == Token.class
|| previousAnnotation == X509.class) {
this.pathConfigurationBuilder = SetAuthenticationPathName(previousAnnotation, pathName);
} else if (this.corsConfigurationBuilder != null) {
this.pathConfigurationBuilder = this.corsConfigurationBuilder.forPath(pathName, pathGroup);
} else {
this.pathConfigurationBuilder = this.httpSecurityBuilder.forPath(pathName);
}
}
} else if (a.annotationType() == PathGroup.class) {
PathGroup pathGroup = (PathGroup) a;
String groupName = pathGroup.pathGroupName();
if (groupName != null && !groupName.isEmpty()) {
this.pathConfigurationBuilder = this.httpSecurityBuilder.forGroup(groupName);
}
} else if (a.annotationType() == Cors.class) {
this.corsConfigurationBuilder = this.pathConfigurationBuilder.cors();
} else if (a.annotationType() == AllowedOrigins.class) {
AllowedOrigins allowedOrigins = (AllowedOrigins) a;
String[] origins = allowedOrigins.origins();
if (origins != null && origins.length > 0) {
this.corsConfigurationBuilder = this.corsConfigurationBuilder.allowOrigins(origins);
}
} else if (a.annotationType() == SupportedMethods.class) {
SupportedMethods supportedMethods = (SupportedMethods) a;
String[] methods = supportedMethods.methods();
if (methods != null && methods.length > 0) {
this.corsConfigurationBuilder = this.corsConfigurationBuilder.allowMethods(methods);
}
} else if (a.annotationType() == SupportedHeaders.class) {
SupportedHeaders supportedHeaders = (SupportedHeaders) a;
String[] headers = supportedHeaders.headers();
if (headers != null && headers.length > 0) {
this.corsConfigurationBuilder = this.corsConfigurationBuilder.allowHeaders(headers);
}
} else if (a.annotationType() == ExposedHeaders.class) {
ExposedHeaders exposedHeaders = (ExposedHeaders) a;
String[] headers = exposedHeaders.headers();
if (headers != null && headers.length > 0) {
this.corsConfigurationBuilder = this.corsConfigurationBuilder.exposedHeaders(headers);
}
} else if (a.annotationType() == SupportsCredentials.class) {
this.corsConfigurationBuilder = this.corsConfigurationBuilder.allowCredentials(true);
} else if (a.annotationType() == AllowAnyOrigin.class) {
this.corsConfigurationBuilder = this.corsConfigurationBuilder.allowAnyOrigin(true);
} else if (a.annotationType() == SupportAnyHeader.class) {
this.corsConfigurationBuilder = this.corsConfigurationBuilder.allowAnyHeader(true);
} else if (a.annotationType() == MaxAge.class) {
MaxAge maxAge = (MaxAge) a;
long age = maxAge.age();
this.corsConfigurationBuilder = this.corsConfigurationBuilder.maxAge(age);
} else if (a.annotationType() == Authc.class) {
if (this.corsConfigurationBuilder != null) {
this.authenticationConfigurationBuilder = this.corsConfigurationBuilder.authenticateWith();
} else {
this.authenticationConfigurationBuilder = this.pathConfigurationBuilder.authenticateWith();
}
} else if (a.annotationType() == Form.class) {
this.formAuthenticationConfigurationBuilder = this.authenticationConfigurationBuilder.form();
Form form = (Form) a;
String restoreOriginalRequest = form.restoreOriginalRequest();
String loginPage = form.loginPage();
String errorPage = form.errorPage();
if (loginPage != null && !loginPage.isEmpty()) {
this.formAuthenticationConfigurationBuilder = this.formAuthenticationConfigurationBuilder
.loginPage(loginPage);
}
if (errorPage != null && !errorPage.isEmpty()) {
this.formAuthenticationConfigurationBuilder = this.formAuthenticationConfigurationBuilder
.errorPage(errorPage);
}
if (restoreOriginalRequest != null && restoreOriginalRequest.equals("yes")) {
this.formAuthenticationConfigurationBuilder = this.formAuthenticationConfigurationBuilder
.restoreOriginalRequest();
}
} else if (a.annotationType() == Basic.class) {
this.basicAuthenticationConfigurationBuilder = this.authenticationConfigurationBuilder.basic();
Basic basic = (Basic) a;
String realmName = basic.realmName();
if (realmName != null && !realmName.isEmpty()) {
this.basicAuthenticationConfigurationBuilder = this.basicAuthenticationConfigurationBuilder
.realmName(realmName);
}
} else if (a.annotationType() == Digest.class) {
this.digestAuthenticationConfigurationBuilder = this.authenticationConfigurationBuilder.digest();
Digest digest = (Digest) a;
String realmName = digest.realmName();
if (realmName != null && !realmName.isEmpty()) {
this.digestAuthenticationConfigurationBuilder = this.digestAuthenticationConfigurationBuilder
.realmName(realmName);
}
} else if (a.annotationType() == X509.class) {
this.x509AuthenticationConfigurationBuilder = this.authenticationConfigurationBuilder.x509();
X509 x509 = (X509) a;
String subjectRegex = x509.subjectRegex();
if (subjectRegex != null && !subjectRegex.isEmpty()) {
this.x509AuthenticationConfigurationBuilder = this.x509AuthenticationConfigurationBuilder
.subjectRegex(subjectRegex);
}
} else if (a.annotationType() == Token.class) {
this.tokenAuthenticationConfigurationBuilder = this.authenticationConfigurationBuilder.token();
} else if (a.annotationType() == Authz.class) {
if (this.formAuthenticationConfigurationBuilder != null) {
this.authorizationConfigurationBuilder = this.formAuthenticationConfigurationBuilder.authorizeWith();
} else if (this.digestAuthenticationConfigurationBuilder != null) {
this.authorizationConfigurationBuilder = this.digestAuthenticationConfigurationBuilder.authorizeWith();
} else if (this.basicAuthenticationConfigurationBuilder != null) {
this.authorizationConfigurationBuilder = this.basicAuthenticationConfigurationBuilder.authorizeWith();
} else if (this.tokenAuthenticationConfigurationBuilder != null) {
this.authorizationConfigurationBuilder = this.tokenAuthenticationConfigurationBuilder.authorizeWith();
} else if (this.x509AuthenticationConfigurationBuilder != null) {
this.authorizationConfigurationBuilder = this.x509AuthenticationConfigurationBuilder.authorizeWith();
} else if (this.corsConfigurationBuilder != null) {
this.authorizationConfigurationBuilder = this.corsConfigurationBuilder.authorizeWith();
} else {
this.authorizationConfigurationBuilder = this.pathConfigurationBuilder.authorizeWith();
}
} else if (a.annotationType() == AllowedRoles.class) {
AllowedRoles role = (AllowedRoles) a;
String[] roles = role.roles();
if (roles != null && roles.length > 0) {
this.authorizationConfigurationBuilder = this.authorizationConfigurationBuilder.role(roles);
}
} else if (a.annotationType() == AllowedGroups.class) {
AllowedGroups group = (AllowedGroups) a;
String[] groups = group.groups();
if (groups != null && groups.length > 0) {
this.authorizationConfigurationBuilder = this.authorizationConfigurationBuilder.group(groups);
}
} else if (a.annotationType() == AllowedRealms.class) {
AllowedRealms realm = (AllowedRealms) a;
String[] realms = realm.realms();
if (realms != null && realms.length > 0) {
this.authorizationConfigurationBuilder = this.authorizationConfigurationBuilder.realm(realms);
}
} else if (a.annotationType() == Expressions.class) {
Expressions exp = (Expressions) a;
String[] expressions = exp.expressions();
if (expressions != null && expressions.length > 0) {
this.authorizationConfigurationBuilder = this.authorizationConfigurationBuilder.expression(expressions);
}
}
}
}
return this.httpSecurityBuilder;
}
private PathConfigurationBuilder SetAuthenticationPathName(Class<? extends Annotation> previousAnnotation, String pathName) {
if (previousAnnotation == Form.class) {
this.pathConfigurationBuilder = this.formAuthenticationConfigurationBuilder.forPath(pathName);
} else if (previousAnnotation == Digest.class) {
this.pathConfigurationBuilder = this.digestAuthenticationConfigurationBuilder.forPath(pathName);
} else if (previousAnnotation == Basic.class) {
this.pathConfigurationBuilder = this.basicAuthenticationConfigurationBuilder.forPath(pathName);
} else if (previousAnnotation == Token.class) {
this.pathConfigurationBuilder = this.tokenAuthenticationConfigurationBuilder.forPath(pathName);
} else if (previousAnnotation == X509.class) {
this.pathConfigurationBuilder = this.x509AuthenticationConfigurationBuilder.forPath(pathName);
}
return this.pathConfigurationBuilder;
}
private PathConfigurationBuilder SetAuthenticationPathNameAndGroup(Class<? extends Annotation> previousAnnotation,
String pathName, String pathGroup) {
if (previousAnnotation == Form.class) {
this.pathConfigurationBuilder = this.formAuthenticationConfigurationBuilder.forPath(pathName, pathGroup);
} else if (previousAnnotation == Digest.class) {
this.pathConfigurationBuilder = this.digestAuthenticationConfigurationBuilder.forPath(pathName, pathGroup);
} else if (previousAnnotation == Basic.class) {
this.pathConfigurationBuilder = this.basicAuthenticationConfigurationBuilder.forPath(pathName, pathGroup);
} else if (previousAnnotation == Token.class) {
this.pathConfigurationBuilder = this.tokenAuthenticationConfigurationBuilder.forPath(pathName, pathGroup);
} else if (previousAnnotation == X509.class) {
this.pathConfigurationBuilder = this.x509AuthenticationConfigurationBuilder.forPath(pathName, pathGroup);
}
return this.pathConfigurationBuilder;
}
}