bacef7ae15ed62a2a99bdf19b8fd20368323c7af
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / common / provider / X509SubjectNameNameIdentifierMapping.java
1 package edu.internet2.middleware.shibboleth.common.provider;
2
3 import java.util.regex.Matcher;
4 import java.util.regex.Pattern;
5 import java.util.regex.PatternSyntaxException;
6
7 import org.apache.log4j.Logger;
8 import javax.xml.namespace.QName;
9 import org.opensaml.SAMLException;
10 import org.opensaml.SAMLNameIdentifier;
11 import org.w3c.dom.Element;
12
13 import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
14 import edu.internet2.middleware.shibboleth.common.IdentityProvider;
15 import edu.internet2.middleware.shibboleth.common.InvalidNameIdentifierException;
16 import edu.internet2.middleware.shibboleth.common.NameIdentifierMapping;
17 import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
18 import edu.internet2.middleware.shibboleth.common.ServiceProvider;
19
20 /**
21  * <code>HSNameIdentifierMapping</code> implementation that translates principal names to E-Auth compliant
22  * X509SubjectNames.
23  * 
24  * @author Walter Hoehn
25  */
26 public class X509SubjectNameNameIdentifierMapping extends BaseNameIdentifierMapping implements NameIdentifierMapping {
27
28         private static Logger log = Logger.getLogger(X509SubjectNameNameIdentifierMapping.class.getName());
29         private String regexTemplate = ".*uid=([^,/]+).*";
30         private Pattern regex;
31         private String qualifier;
32         private String internalNameContext;
33         private QName[] errorCodes = new QName[0];
34
35         public X509SubjectNameNameIdentifierMapping(Element config) throws NameIdentifierMappingException {
36
37                 super(config);
38
39                 String rawRegex = ((Element) config).getAttribute("regex");
40                 if (rawRegex != null && !rawRegex.equals("")) {
41                         try {
42                                 regex = Pattern.compile(rawRegex);
43                         } catch (PatternSyntaxException e) {
44                                 log.error("Supplied (regex) attribute is not a valid regular expressions.  Using default value.");
45                                 regex = Pattern.compile(regexTemplate);
46                         }
47                 } else {
48                         regex = Pattern.compile(regexTemplate);
49                 }
50
51                 qualifier = ((Element) config).getAttribute("qualifier");
52                 if (qualifier == null || qualifier.equals("")) {
53                         log.error("The X509SubjectName NameMapping requires a (qualifier) attribute.");
54                         throw new NameIdentifierMappingException(
55                                         "Invalid configuration.  Unable to initialize X509SubjectName Mapping.");
56                 }
57
58                 internalNameContext = ((Element) config).getAttribute("internalNameContext");
59                 if (internalNameContext == null || internalNameContext.equals("")) {
60                         log.error("The X509SubjectName NameMapping requires a (internalNameContext) attribute.");
61                         throw new NameIdentifierMappingException(
62                                         "Invalid configuration.  Unable to initialize X509SubjectName Mapping.");
63                 }
64         }
65
66         /*
67          * (non-Javadoc)
68          * 
69          * @see edu.internet2.middleware.shibboleth.common.NameIdentifierMapping#getPrincipal(org.opensaml.SAMLNameIdentifier,
70          *      edu.internet2.middleware.shibboleth.common.ServiceProvider,
71          *      edu.internet2.middleware.shibboleth.common.IdentityProvider)
72          */
73
74         public AuthNPrincipal getPrincipal(SAMLNameIdentifier nameId, ServiceProvider sProv, IdentityProvider idProv)
75                         throws NameIdentifierMappingException, InvalidNameIdentifierException {
76
77                 if (!nameId.getNameQualifier().equals(qualifier)) {
78                         log.error("The name qualifier (" + nameId.getNameQualifier()
79                                         + ") for the referenced subject is not valid for this identity provider.");
80                         throw new NameIdentifierMappingException("The name qualifier (" + nameId.getNameQualifier()
81                                         + ") for the referenced subject is not valid for this identity provider.");
82                 }
83
84                 Matcher matcher = regex.matcher(nameId.getName());
85                 matcher.find();
86                 String principal = matcher.group(1);
87                 if (principal == null) { throw new InvalidNameIdentifierException("Unable to map X509SubjectName ("
88                                 + nameId.getName() + ") to a local principal.", errorCodes); }
89                 return new AuthNPrincipal(principal);
90         }
91
92         /*
93          * (non-Javadoc)
94          * 
95          * @see edu.internet2.middleware.shibboleth.hs.HSNameIdentifierMapping#getNameIdentifierName(edu.internet2.middleware.shibboleth.common.AuthNPrincipal,
96          *      edu.internet2.middleware.shibboleth.common.ServiceProvider,
97          *      edu.internet2.middleware.shibboleth.common.IdentityProvider)
98          */
99         public SAMLNameIdentifier getNameIdentifierName(AuthNPrincipal principal, ServiceProvider sProv,
100                         IdentityProvider idProv) throws NameIdentifierMappingException {
101
102                 try {
103                         return new SAMLNameIdentifier(internalNameContext.replaceAll("%PRINCIPAL%", principal.getName()),
104                                         qualifier, getNameIdentifierFormat().toString());
105                 } catch (SAMLException e) {
106                         throw new NameIdentifierMappingException("Unable to generate X509 SubjectName: " + e);
107                 }
108
109         }
110
111 }