001: /*
002: * Copyright 2007 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: */
013: package com.pentaho.security.ldap;
014:
015: import org.acegisecurity.GrantedAuthority;
016: import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper;
017: import org.apache.commons.logging.Log;
018: import org.apache.commons.logging.LogFactory;
019: import org.springframework.beans.factory.InitializingBean;
020:
021: import org.pentaho.messages.Messages;
022:
023: /**
024: * Extension of <code>LdapUserDetailsMapper</code> which extracts the value of
025: * the component named <code>tokenName</code> within any attribute in
026: * <code>roleAttributes</code>.
027: *
028: * <p>
029: * Example LDIF:
030: * </p>
031: *
032: * <pre>
033: * dn: uid=joe,ou=users,ou=system
034: * ...
035: * uniqueMember: cn=ceo,ou=roles
036: * </pre>
037: *
038: * Assume that you want the value of the <code>cn</code> component within the
039: * value of the <code>uniqueMember</code> attribute to be used as the role
040: * name.
041: *
042: * You would use <code>mapper.setTokenName("cn")</code> or the equivalent to
043: * this setter call in your Spring beans XML.
044: *
045: * @author mlowery
046: *
047: */
048: public class RolePreprocessingMapper extends LdapUserDetailsMapper
049: implements InitializingBean {
050:
051: private static final Log logger = LogFactory
052: .getLog(RolePreprocessingMapper.class);
053:
054: private String tokenName = "cn"; //$NON-NLS-1$
055:
056: public RolePreprocessingMapper() {
057: super ();
058: }
059:
060: public RolePreprocessingMapper(final String tokenName) {
061: super ();
062: this .tokenName = tokenName;
063: }
064:
065: protected GrantedAuthority createAuthority(final Object role) {
066: Object newRole = preprocessRole(role);
067: return super .createAuthority(newRole);
068: }
069:
070: protected Object preprocessRole(final Object role) {
071: final String COMPONENT_SEPARATOR = ","; //$NON-NLS-1$
072: final String NAME_VALUE_PAIR_SEPARATOR = "="; //$NON-NLS-1$
073: if (role instanceof String) {
074: String roleString = (String) role;
075: String[] tokens = roleString.split(COMPONENT_SEPARATOR);
076: for (int i = 0; i < tokens.length; i++) {
077: String rdnString = tokens[i];
078: String[] rdnTokens = rdnString
079: .split(NAME_VALUE_PAIR_SEPARATOR);
080: if (rdnTokens[0].trim().equals(tokenName)) {
081: return rdnTokens[1].trim();
082: }
083: }
084: if (logger.isWarnEnabled()) {
085: logger
086: .warn(Messages
087: .getString(
088: "RolePreprocessingMapper.WARN_TOKEN_NOT_FOUND", tokenName)); //$NON-NLS-1$
089: }
090: // return null so that superclass does not use the value of this
091: // attribute
092: return null;
093: } else {
094: // do not know what to do with this; return it unmodified
095: return role;
096: }
097: }
098:
099: public void setTokenName(final String tokenName) {
100: this .tokenName = tokenName;
101: }
102:
103: public String getTokenName() {
104: return tokenName;
105: }
106:
107: public void afterPropertiesSet() throws Exception {
108: }
109:
110: }
|