001package org.apache.archiva.redback.common.ldap.user;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.redback.common.ldap.LdapUtils;
023import org.apache.archiva.redback.common.ldap.MappingException;
024import org.apache.archiva.redback.configuration.UserConfiguration;
025import org.apache.archiva.redback.configuration.UserConfigurationKeys;
026import org.apache.archiva.redback.users.User;
027import org.apache.commons.lang3.StringUtils;
028import org.springframework.stereotype.Service;
029
030import javax.annotation.PostConstruct;
031import javax.inject.Inject;
032import javax.inject.Named;
033import javax.naming.directory.Attributes;
034import javax.naming.directory.BasicAttributes;
035import java.util.Date;
036
037/**
038 * @TODO: Try to retrieve createTimestamp and modifyTimestamp attributes for setting the corresponding user properties
039 * @author Jesse
040 */
041@Service( "userMapper#ldap" )
042public class LdapUserMapper
043    implements UserMapper
044{
045    String emailAttribute = "mail";
046
047    String fullNameAttribute = "givenName";
048
049    String passwordAttribute = "userPassword";
050
051    String userIdAttribute = "cn";
052
053    String distinguishedNameAttribute = "distinguishedName";
054
055    String userBaseDn;
056
057    String userObjectClass = "inetOrgPerson";
058
059    String userFilter;
060
061    int maxResultCount = 0;
062
063    @Inject
064    @Named( value = "userConfiguration#default" )
065    private UserConfiguration userConf;
066
067    @PostConstruct
068    public void initialize()
069    {
070        emailAttribute = userConf.getString( UserConfigurationKeys.LDAP_MAPPER_USER_ATTRIBUTE_EMAIL, emailAttribute );
071        fullNameAttribute =
072            userConf.getString( UserConfigurationKeys.LDAP_MAPPER_USER_ATTRIBUTE_FULLNAME, fullNameAttribute );
073        passwordAttribute =
074            userConf.getString( UserConfigurationKeys.LDAP_MAPPER_USER_ATTRIBUTE_PASSWORD, passwordAttribute );
075        userIdAttribute = userConf.getString( UserConfigurationKeys.LDAP_MAPPER_USER_ATTRIBUTE_ID, userIdAttribute );
076        userBaseDn = userConf.getConcatenatedList( "ldap.config.mapper.attribute.user.base.dn",
077                                                   userConf.getConcatenatedList( "ldap.config.base.dn", userBaseDn ) );
078        userObjectClass =
079            userConf.getString( UserConfigurationKeys.LDAP_MAPPER_USER_ATTRIBUTE_OBJECT_CLASS, userObjectClass );
080        userFilter =
081            userConf.getConcatenatedList( UserConfigurationKeys.LDAP_MAPPER_USER_ATTRIBUTE_FILTER, userFilter );
082        maxResultCount = userConf.getInt( UserConfigurationKeys.LDAP_MAX_RESULT_COUNT, maxResultCount );
083
084        distinguishedNameAttribute =
085            userConf.getString( UserConfigurationKeys.LDAP_DN_ATTRIBUTE, distinguishedNameAttribute );
086    }
087
088    public Attributes getCreationAttributes( User user, boolean encodePasswordIfChanged )
089        throws MappingException
090    {
091        Attributes userAttrs = new BasicAttributes();
092
093        boolean passwordSet = false;
094
095        if ( !passwordSet && ( user.getEncodedPassword() != null ) )
096        {
097            userAttrs.put( getPasswordAttribute(), user.getEncodedPassword() );
098        }
099
100        if ( !StringUtils.isEmpty( user.getFullName() ) )
101        {
102            userAttrs.put( getUserFullNameAttribute(), user.getFullName() );
103        }
104
105        if ( !StringUtils.isEmpty( user.getEmail() ) )
106        {
107            userAttrs.put( getEmailAddressAttribute(), user.getEmail() );
108        }
109
110        return userAttrs;
111    }
112
113    public String getEmailAddressAttribute()
114    {
115        return emailAttribute;
116    }
117
118    public String getUserFullNameAttribute()
119    {
120        return fullNameAttribute;
121    }
122
123    public String getPasswordAttribute()
124    {
125        return passwordAttribute;
126    }
127
128    public String getDistinguishedNameAttribute()
129    {
130        return distinguishedNameAttribute;
131    }
132
133    public void setDistinguishedNameAttribute( String distinguishedNameAttribute )
134    {
135        this.distinguishedNameAttribute = distinguishedNameAttribute;
136    }
137
138    public String[] getUserAttributeNames()
139    {
140        return new String[]{ emailAttribute, fullNameAttribute, passwordAttribute, userIdAttribute,
141            distinguishedNameAttribute };
142    }
143
144    public int getMaxResultCount()
145    {
146        return maxResultCount;
147    }
148
149    public UserUpdate getUpdate( LdapUser user )
150        throws MappingException
151    {
152
153        Attributes addAttrs = new BasicAttributes();
154
155        Attributes modAttrs = new BasicAttributes();
156
157        if ( !StringUtils.isEmpty( user.getFullName() ) )
158        {
159            if ( user.getFullName() == null )
160            {
161                addAttrs.put( getUserFullNameAttribute(), user.getFullName() );
162            }
163            else if ( !user.getFullName().equals( user.getFullName() ) )
164            {
165                modAttrs.put( getUserFullNameAttribute(), user.getFullName() );
166            }
167        }
168
169        if ( !StringUtils.isEmpty( user.getEmail() ) )
170        {
171            if ( user.getEmail() == null )
172            {
173                addAttrs.put( getEmailAddressAttribute(), user.getEmail() );
174            }
175            else if ( !user.getEmail().equals( user.getEmail() ) )
176            {
177                modAttrs.put( getEmailAddressAttribute(), user.getEmail() );
178            }
179        }
180
181        return null;
182    }
183
184    public LdapUser getUser( String dn, Attributes attributes )
185        throws MappingException
186    {
187        String userIdAttribute = getUserIdAttribute();
188        String emailAddressAttribute = getEmailAddressAttribute();
189        String nameAttribute = getUserFullNameAttribute();
190        String passwordAttribute = getPasswordAttribute();
191
192        String userId = LdapUtils.getAttributeValue( attributes, userIdAttribute, "username" );
193
194        LdapUser user = new LdapUser( userId );
195        user.setDn( dn );
196        user.setOriginalAttributes( attributes );
197
198        user.setEmail( LdapUtils.getAttributeValue( attributes, emailAddressAttribute, "email address" ) );
199        user.setFullName( LdapUtils.getAttributeValue( attributes, nameAttribute, "name" ) );
200
201        String encodedPassword = LdapUtils.getAttributeValueFromByteArray( attributes, passwordAttribute, "password" );
202
203        // it seems to be a common convention for the password to come back prepended with the encoding type..
204        // however we deal with that via configuration right now so just smoke it.
205        if ( encodedPassword != null && encodedPassword.startsWith( "{" ) )
206        {
207            encodedPassword = encodedPassword.substring( encodedPassword.indexOf( '}' ) + 1 );
208        }
209
210        user.setEncodedPassword( encodedPassword );
211
212        // REDBACK-215: skip NPE
213        user.setLastPasswordChange( new Date() );
214
215        return user;
216    }
217
218    public String getUserIdAttribute()
219    {
220        return userIdAttribute;
221    }
222
223    public String getEmailAttribute()
224    {
225        return emailAttribute;
226    }
227
228    public void setEmailAttribute( String emailAttribute )
229    {
230        this.emailAttribute = emailAttribute;
231    }
232
233    public String getFullNameAttribute()
234    {
235        return fullNameAttribute;
236    }
237
238    public void setFullNameAttribute( String fullNameAttribute )
239    {
240        this.fullNameAttribute = fullNameAttribute;
241    }
242
243    public void setMaxResultCount( int maxResultCount )
244    {
245        this.maxResultCount = maxResultCount;
246    }
247
248    public String getUserBaseDn()
249    {
250        return userBaseDn;
251    }
252
253    public void setUserBaseDn( String userBaseDn )
254    {
255        this.userBaseDn = userBaseDn;
256    }
257
258    public String getUserObjectClass()
259    {
260        return userObjectClass;
261    }
262
263    public String getUserFilter()
264    {
265        return userFilter;
266    }
267
268    public void setUserFilter( String userFilter )
269    {
270        this.userFilter = userFilter;
271    }
272
273    public void setUserObjectClass( String userObjectClass )
274    {
275        this.userObjectClass = userObjectClass;
276    }
277
278    public void setPasswordAttribute( String passwordAttribute )
279    {
280        this.passwordAttribute = passwordAttribute;
281    }
282
283    public void setUserIdAttribute( String userIdAttribute )
284    {
285        this.userIdAttribute = userIdAttribute;
286    }
287
288    public LdapUser newUserInstance( String username, String fullName, String email )
289    {
290        return new LdapUser( username, fullName, email );
291    }
292
293    public LdapUser newTemplateUserInstance()
294    {
295        return new LdapUser();
296    }
297
298    public String[] getReturningAttributes()
299    {
300        return new String[]{ getUserIdAttribute(), getEmailAttribute(), getFullNameAttribute(), getPasswordAttribute(),
301            getDistinguishedNameAttribute() };
302    }
303
304    public UserConfiguration getUserConf()
305    {
306        return userConf;
307    }
308
309    public void setUserConf( UserConfiguration userConf )
310    {
311        this.userConf = userConf;
312    }
313}