001package org.apache.archiva.redback.users.memory;
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.policy.UserSecurityPolicy;
023import org.apache.archiva.redback.users.AbstractUserManager;
024import org.apache.archiva.redback.users.PermanentUserException;
025import org.apache.archiva.redback.users.User;
026import org.apache.archiva.redback.users.UserExistsException;
027import org.apache.archiva.redback.users.UserManager;
028import org.apache.archiva.redback.users.UserManagerException;
029import org.apache.archiva.redback.users.UserNotFoundException;
030import org.apache.archiva.redback.users.UserQuery;
031import org.apache.archiva.redback.users.memory.util.UserSorter;
032import org.apache.commons.lang3.StringUtils;
033import org.springframework.stereotype.Service;
034
035import javax.annotation.Resource;
036import java.util.ArrayList;
037import java.util.Collections;
038import java.util.Date;
039import java.util.HashMap;
040import java.util.Iterator;
041import java.util.List;
042import java.util.Map;
043
044/**
045 *
046 */
047@Service("userManager#memory")
048public class MemoryUserManager
049    extends AbstractUserManager
050    implements UserManager
051{
052    @Resource
053    private UserSecurityPolicy userSecurityPolicy;
054
055    public String getId()
056    {
057        return "memory";
058    }
059    
060    public boolean isReadOnly()
061    {
062        return false;
063    }
064
065    public UserQuery createUserQuery()
066    {
067        return new SimpleUserQuery();
068    }
069
070    public List<User> findUsersByQuery( UserQuery query )
071    {
072        SimpleUserQuery uq = (SimpleUserQuery) query;
073
074        List<User> list = new ArrayList<User>();
075
076        for ( Iterator<User> i = users.values().iterator(); i.hasNext(); )
077        {
078            SimpleUser user = (SimpleUser) i.next();
079            boolean matches = uq.matches( user );
080            if ( matches )
081            {
082                list.add( user );
083            }
084        }
085
086        Collections.sort( list, uq.getComparator() );
087
088        List<User> cutList = new ArrayList<User>();
089
090        for ( long i = query.getFirstResult();
091              i < list.size() && ( query.getMaxResults() == -1 || i < query.getFirstResult() + uq.getMaxResults() );
092              i++ )
093        {
094            cutList.add( list.get( (int) i ) );
095        }
096        return cutList;
097    }
098
099    private Map<Object, User> users = new HashMap<Object, User>();
100
101    public User addUser(User user) throws UserManagerException {
102        return addUser( user, false );
103    }
104
105    private User addUser( User user, boolean checked ) throws UserManagerException
106    {
107        if (checked && userExists( user.getUsername() )) {
108            throw new UserExistsException( "User exists already " + user.getUsername( ) );
109        }
110        user.setAccountCreationDate( new Date( ) );
111        saveUser( user );
112        fireUserManagerUserAdded( user );
113
114        // If there exists no encoded password, then this is a new user setup 
115        if ( StringUtils.isEmpty( user.getEncodedPassword() ) )
116        {
117            userSecurityPolicy.extensionChangePassword( user );
118        }
119
120        return user;
121    }
122
123    private void saveUser( User user )
124    {
125        triggerInit();
126        users.put( user.getUsername(), user );
127    }
128
129    public User updateUser( User user )
130    {
131        return updateUser( user, false );
132    }
133
134    public User updateUser( User user, boolean passwordChangeRequired )
135    {
136        if ( StringUtils.isNotEmpty( user.getPassword() ) )
137        {
138            userSecurityPolicy.extensionChangePassword( user, passwordChangeRequired );
139        }
140
141        saveUser( user );
142
143        fireUserManagerUserUpdated( user );
144
145        return user;
146    }
147
148    public boolean userExists( String principal )
149    {
150        try
151        {
152            findUser( principal );
153            return true;
154        }
155        catch ( UserNotFoundException ne )
156        {
157            return false;
158        }
159    }
160
161
162    public User createUser( String username, String fullName, String emailAddress )
163    {
164        User user = new SimpleUser();
165        user.setUsername( username );
166        user.setFullName( fullName );
167        user.setEmail( emailAddress );
168
169        return user;
170    }
171
172    public void deleteUser( String username )
173        throws UserNotFoundException, UserManagerException
174    {
175        User user = findUser( username );
176
177        if ( user.isPermanent() )
178        {
179            throw new PermanentUserException( "Cannot delete permanent user." );
180        }
181
182        users.remove( user.getUsername() );
183
184        fireUserManagerUserRemoved( user );
185    }
186
187    public void addUserUnchecked( User user )
188    {
189        try
190        {
191            addUser( user, false );
192        }
193        catch ( UserManagerException e )
194        {
195            log.error( "User manager exception " + e.getMessage( ) );
196        }
197    }
198
199    public void eraseDatabase()
200    {
201        users.clear();
202    }
203
204    public User findUser( String username )
205        throws UserNotFoundException
206    {
207        triggerInit();
208        User user = null;
209
210        Iterator<User> it = users.values().iterator();
211        while ( it.hasNext() )
212        {
213            User u = it.next();
214            if ( u.getUsername().equals( username ) )
215            {
216                user = u;
217            }
218        }
219
220        if ( user == null )
221        {
222            throw new UserNotFoundException( "Unable to find user '" + username + "'" );
223        }
224
225        return user;
226    }
227
228    @Override
229    public User findUser( String username, boolean useCache )
230        throws UserNotFoundException, UserManagerException
231    {
232        return findUser( username );
233    }
234
235    public List<User> findUsersByUsernameKey( String usernameKey, boolean orderAscending )
236    {
237        triggerInit();
238
239        List<User> userList = new ArrayList<User>();
240
241        Iterator<User> it = users.values().iterator();
242        while ( it.hasNext() )
243        {
244            User u = it.next();
245            if ( u.getUsername().indexOf( usernameKey ) > -1 )
246            {
247                userList.add( u );
248            }
249        }
250
251        Collections.sort( userList, new UserSorter( orderAscending ) );
252
253        return userList;
254    }
255
256    public List<User> findUsersByFullNameKey( String fullNameKey, boolean orderAscending )
257    {
258        triggerInit();
259
260        List<User> userList = new ArrayList<User>();
261
262        Iterator<User> it = users.values().iterator();
263        while ( it.hasNext() )
264        {
265            User u = it.next();
266            if ( u.getFullName().indexOf( fullNameKey ) > -1 )
267            {
268                userList.add( u );
269            }
270        }
271
272        Collections.sort( userList, new UserSorter( orderAscending ) );
273
274        return userList;
275    }
276
277    public List<User> findUsersByEmailKey( String emailKey, boolean orderAscending )
278    {
279        triggerInit();
280
281        List<User> userList = new ArrayList<User>();
282
283        Iterator<User> it = users.values().iterator();
284        while ( it.hasNext() )
285        {
286            User u = it.next();
287            if ( u.getEmail().indexOf( emailKey ) > -1 )
288            {
289                userList.add( u );
290            }
291        }
292
293        Collections.sort( userList, new UserSorter( orderAscending ) );
294
295        return userList;
296    }
297
298    public List<User> getUsers()
299    {
300        triggerInit();
301        return new ArrayList<User>( users.values() );
302    }
303
304    public List<User> getUsers( boolean ascendingUsername )
305    {
306        return getUsers();
307    }
308
309    private boolean hasTriggeredInit = false;
310
311    public void triggerInit()
312    {
313        if ( !hasTriggeredInit )
314        {
315            fireUserManagerInit( users.isEmpty() );
316            hasTriggeredInit = true;
317        }
318    }
319
320    public String getDescriptionKey()
321    {
322        return "archiva.redback.usermanager.memory";
323    }
324}