001package org.apache.turbine.services.security;
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
022
023import org.apache.fulcrum.security.acl.AccessControlList;
024import org.apache.fulcrum.security.entity.Group;
025import org.apache.fulcrum.security.entity.Permission;
026import org.apache.fulcrum.security.entity.Role;
027import org.apache.fulcrum.security.model.turbine.TurbineModelManager;
028import org.apache.fulcrum.security.util.DataBackendException;
029import org.apache.fulcrum.security.util.EntityExistsException;
030import org.apache.fulcrum.security.util.FulcrumSecurityException;
031import org.apache.fulcrum.security.util.GroupSet;
032import org.apache.fulcrum.security.util.PasswordMismatchException;
033import org.apache.fulcrum.security.util.PermissionSet;
034import org.apache.fulcrum.security.util.RoleSet;
035import org.apache.fulcrum.security.util.UnknownEntityException;
036import org.apache.turbine.om.security.User;
037import org.apache.turbine.services.TurbineServices;
038
039/**
040 * This is a Facade class for SecurityService.
041 *
042 * This class provides static methods that call related methods of the
043 * implementation of SecurityService used by the System, according to
044 * the settings in TurbineResources.
045 * <br>
046 *
047 * <a name="global">
048 * <p> Certain Roles that the Users may have in the system may are not related
049 * to any specific resource nor entity. They are assigned within a special group
050 * named 'global' that can be referenced in the code as
051 * {@link TurbineModelManager#GLOBAL_GROUP_NAME}.
052 *
053 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
054 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
055 * @version $Id: TurbineSecurity.java 1706239 2015-10-01 13:18:35Z tv $
056 */
057public abstract class TurbineSecurity
058{
059    /**
060     * Retrieves an implementation of SecurityService, base on the settings in
061     * TurbineResources.
062     *
063     * @return an implementation of SecurityService.
064     */
065    public static SecurityService getService()
066    {
067        return (SecurityService) TurbineServices.getInstance().
068                getService(SecurityService.SERVICE_NAME);
069    }
070
071    /*-----------------------------------------------------------------------
072      Management of User objects
073      -----------------------------------------------------------------------*/
074
075    /**
076     * Construct a blank User object.
077     *
078     * This method calls getUserClass, and then creates a new object using
079     * the default constructor.
080     *
081     * @return an object implementing User interface.
082     * @throws UnknownEntityException if the object could not be instantiated.
083     */
084    public static User getUserInstance()
085            throws UnknownEntityException
086    {
087        return getService().getUserInstance();
088    }
089
090    /**
091     * Returns the configured UserManager.
092     *
093     * @return An UserManager object
094     */
095    public static UserManager getUserManager()
096    {
097        return getService().getUserManager();
098    }
099
100    /**
101     * Check whether a specified user's account exists.
102     *
103     * The login name is used for looking up the account.
104     *
105     * @param user The user to be checked.
106     * @return true if the specified account exists
107     * @throws DataBackendException if there was an error accessing the data
108     *         backend.
109     */
110    public static boolean accountExists(User user)
111            throws DataBackendException
112    {
113        return getService().accountExists(user);
114    }
115
116    /**
117     * Check whether a specified user's account exists.
118     *
119     * The login name is used for looking up the account.
120     *
121     * @param userName The name of the user to be checked.
122     * @return true if the specified account exists
123     * @throws DataBackendException if there was an error accessing the data
124     *         backend.
125     */
126    public static boolean accountExists(String userName)
127            throws DataBackendException
128    {
129        return getService().accountExists(userName);
130    }
131
132    /**
133     * Authenticates an user, and constructs an User object to represent
134     * him/her.
135     *
136     * @param username The user name.
137     * @param password The user password.
138     * @return An authenticated Turbine User.
139     * @throws DataBackendException if there was an error accessing the data
140     *         backend.
141     * @throws UnknownEntityException if user account is not present.
142     * @throws PasswordMismatchException if the supplied password was incorrect.
143     */
144    public static User getAuthenticatedUser(String username, String password)
145            throws DataBackendException, UnknownEntityException,
146            PasswordMismatchException
147    {
148        return getService().getAuthenticatedUser(username, password);
149    }
150
151    /**
152     * Constructs an User object to represent a registered user of the
153     * application.
154     *
155     * @param username The user name.
156     * @return A Turbine User.
157     * @throws DataBackendException if there was an error accessing the data
158     *         backend.
159     * @throws UnknownEntityException if user account is not present.
160     */
161    public static User getUser(String username)
162            throws DataBackendException, UnknownEntityException
163    {
164        return getService().getUser(username);
165    }
166
167    /**
168     * Constructs an User object to represent an anonymous user of the
169     * application.
170     *
171     * @return An anonymous Turbine User.
172     * @throws UnknownEntityException if the anonymous User object couldn't be
173     *         constructed.
174     */
175    public static User getAnonymousUser()
176            throws UnknownEntityException
177    {
178        return getService().getAnonymousUser();
179    }
180
181    /**
182     * Checks whether a passed user object matches the anonymous user pattern
183     * according to the configured service
184     *
185     * @param user A user object
186     * @return True if this is an anonymous user
187     */
188    public static boolean isAnonymousUser(User user)
189    {
190        return getService().isAnonymousUser(user);
191    }
192
193    /**
194     * Saves User's data in the permanent storage. The user account is required
195     * to exist in the storage.
196     *
197     * @param user The User object to save.
198     * @throws UnknownEntityException if the user's account does not
199     *         exist in the database.
200     * @throws DataBackendException if there is a problem accessing the
201     *         storage.
202     */
203    public static void saveUser(User user)
204            throws UnknownEntityException, DataBackendException
205    {
206        getService().saveUser(user);
207    }
208
209    /**
210     * Saves User data when the session is unbound. The user account is required
211     * to exist in the storage.
212     *
213     * LastLogin, AccessCounter, persistent pull tools, and any data stored
214     * in the permData hashtable that is not mapped to a column will be saved.
215     *
216     * @param user the user in the session
217     *
218     * @exception UnknownEntityException if the user's account does not
219     *            exist in the database.
220     * @exception DataBackendException if there is a problem accessing the
221     *            storage.
222     */
223    public static void saveOnSessionUnbind(User user)
224            throws UnknownEntityException, DataBackendException
225    {
226        getService().saveOnSessionUnbind(user);
227    }
228
229    /**
230     * Change the password for an User.
231     *
232     * @param user an User to change password for.
233     * @param oldPassword the current password supplied by the user.
234     * @param newPassword the current password requested by the user.
235     * @throws PasswordMismatchException if the supplied password was
236     *         incorrect.
237     * @throws UnknownEntityException if the user's record does not
238     *         exist in the database.
239     * @throws DataBackendException if there is a problem accessing the
240     *         storage.
241     */
242    public static void changePassword(User user, String oldPassword,
243                                      String newPassword)
244            throws PasswordMismatchException, UnknownEntityException,
245            DataBackendException
246    {
247        getService().changePassword(user, oldPassword, newPassword);
248    }
249
250    /**
251     * Forcibly sets new password for an User.
252     *
253     * This is supposed by the administrator to change the forgotten or
254     * compromised passwords. Certain implementations of this feature
255     * would require administrative level access to the authenticating
256     * server / program.
257     *
258     * @param user an User to change password for.
259     * @param password the new password.
260     * @throws UnknownEntityException if the user's record does not
261     *         exist in the database.
262     * @throws DataBackendException if there is a problem accessing the
263     *         storage.
264     */
265    public static void forcePassword(User user, String password)
266            throws UnknownEntityException, DataBackendException
267    {
268        getService().forcePassword(user, password);
269    }
270
271    /*-----------------------------------------------------------------------
272      Creation of AccessControlLists
273      -----------------------------------------------------------------------*/
274
275    /**
276     * Constructs an AccessControlList for a specific user.
277     *
278     * @param user the user for whom the AccessControlList are to be retrieved
279     * @return The AccessControList object constructed from the user object.
280     * @throws DataBackendException if there was an error accessing the data
281     *         backend.
282     * @throws UnknownEntityException if user account is not present.
283     */
284    public static AccessControlList getACL(User user)
285            throws DataBackendException, UnknownEntityException
286    {
287        return getService().getACL(user);
288    }
289
290    /*-----------------------------------------------------------------------
291      Security management
292      -----------------------------------------------------------------------*/
293
294    /**
295     * Grant an User a Role in a Group.
296     *
297     * @param user the user.
298     * @param group the group.
299     * @param role the role.
300     * @throws DataBackendException if there was an error accessing the data
301     *         backend.
302     * @throws UnknownEntityException if user account, group or role is not
303     *         present.
304     */
305    public static void grant(User user, Group group, Role role)
306            throws DataBackendException, UnknownEntityException
307    {
308        getService().grant(user, group, role);
309    }
310
311    /**
312     * Revoke a Role in a Group from an User.
313     *
314     * @param user the user.
315     * @param group the group.
316     * @param role the role.
317     * @throws DataBackendException if there was an error accessing the data
318     *         backend.
319     * @throws UnknownEntityException if user account, group or role is not
320     *         present.
321     */
322    public static void revoke(User user, Group group, Role role)
323            throws DataBackendException, UnknownEntityException
324    {
325        getService().revoke(user, group, role);
326    }
327
328    /**
329     * Revokes all roles from an User.
330     *
331     * This method is used when deleting an account.
332     *
333     * @param user the User.
334     * @throws DataBackendException if there was an error accessing the data
335     *         backend.
336     * @throws UnknownEntityException if the account is not present.
337     */
338    public static void revokeAll(User user)
339            throws DataBackendException, UnknownEntityException
340    {
341        getService().revokeAll(user);
342    }
343
344    /**
345     * Grants a Role a Permission
346     *
347     * @param role the Role.
348     * @param permission the Permission.
349     * @throws DataBackendException if there was an error accessing the data
350     *         backend.
351     * @throws UnknownEntityException if role or permission is not present.
352     */
353    public static void grant(Role role, Permission permission)
354            throws DataBackendException, UnknownEntityException
355    {
356        getService().grant(role, permission);
357    }
358
359    /**
360     * Revokes a Permission from a Role.
361     *
362     * @param role the Role.
363     * @param permission the Permission.
364     * @throws DataBackendException if there was an error accessing the data
365     *         backend.
366     * @throws UnknownEntityException if role or permission is not present.
367     */
368    public static void revoke(Role role, Permission permission)
369            throws DataBackendException, UnknownEntityException
370    {
371        getService().revoke(role, permission);
372    }
373
374    /**
375     * Revokes all permissions from a Role.
376     *
377     * This method is user when deleting a Role.
378     *
379     * @param role the Role
380     * @throws DataBackendException if there was an error accessing the data
381     *         backend.
382     * @throws  UnknownEntityException if the Role is not present.
383     */
384    public static void revokeAll(Role role)
385            throws DataBackendException, UnknownEntityException
386    {
387        getService().revokeAll(role);
388    }
389
390    /*-----------------------------------------------------------------------
391      Account management
392      -----------------------------------------------------------------------*/
393
394    /**
395     * Creates new user account with specified attributes.
396     *
397     * <strong>TODO</strong> throw more specific exception<br>
398     *
399     * @param user the object describing account to be created.
400     * @param password password for the new user
401     * @throws DataBackendException if there was an error accessing the data
402     *         backend.
403     * @throws EntityExistsException if the user account already exists.
404     */
405    public static void addUser(User user, String password)
406            throws DataBackendException, EntityExistsException
407    {
408        getService().addUser(user, password);
409    }
410
411    /**
412     * Removes an user account from the system.
413     *
414     * <strong>TODO</strong> throw more specific exception<br>
415     *
416     * @param user the object describing the account to be removed.
417     * @throws DataBackendException if there was an error accessing the data
418     *         backend.
419     * @throws UnknownEntityException if the user account is not present.
420     */
421    public static void removeUser(User user)
422            throws DataBackendException, UnknownEntityException
423    {
424        getService().removeUser(user);
425    }
426
427    /*-----------------------------------------------------------------------
428      Group/Role/Permission management
429      -----------------------------------------------------------------------*/
430    /**
431     * Provides a reference to the Group object that represents the
432     * <a name="global">global group</a>.
433     *
434     * @return a Group object that represents the global group.
435     */
436    public static Group getGlobalGroup()
437    {
438        return getService().getGlobalGroup();
439    }
440
441    /**
442     * Creates a new Group in the system. This is a convenience
443     * method.
444     *
445     * @param name The name of the new Group.
446     * @return An object representing the new Group.
447     * @throws FulcrumSecurityException if the Group could not be created.
448     */
449    public static Group createGroup(String name)
450            throws FulcrumSecurityException
451    {
452        return getService().addGroup(getGroupInstance(name));
453    }
454
455    /**
456     * Creates a new Permission in the system. This is a convenience
457     * method.
458     *
459     * @param name The name of the new Permission.
460     * @return An object representing the new Permission.
461     * @throws FulcrumSecurityException if the Permission could not be created.
462     */
463    public static Permission createPermission(String name)
464            throws FulcrumSecurityException
465    {
466        return getService().addPermission(getPermissionInstance(name));
467    }
468
469    /**
470     * Creates a new Role in the system. This is a convenience
471     * method.
472     *
473     * @param name The name of the Role.
474     *
475     * @return An object representing the new Role.
476     *
477     * @throws FulcrumSecurityException if the Role could not be created.
478     */
479    public static Role createRole(String name)
480        throws FulcrumSecurityException
481    {
482        return getService().addRole(getRoleInstance(name));
483    }
484
485    /**
486     * Retrieve a Group object with specified name.
487     *
488     * @param groupName The name of the Group to be retrieved.
489     * @return an object representing the Group with specified name.
490     * @throws DataBackendException if there was an error accessing the data
491     *         backend.
492     * @throws UnknownEntityException if the Group is not present.
493     */
494    public static Group getGroupByName(String groupName)
495            throws DataBackendException, UnknownEntityException
496    {
497        return getService().getGroupByName(groupName);
498    }
499
500    /**
501     * Retrieve a Group object with specified Id.
502     *
503     * @param groupId the id of the Group.
504     *
505     * @return an object representing the Group with specified name.
506     *
507     * @exception UnknownEntityException if the permission does not
508     *            exist in the database.
509     * @exception DataBackendException if there is a problem accessing the
510     *            storage.
511     */
512    public static Group getGroupById(int groupId)
513            throws DataBackendException,
514                   UnknownEntityException
515    {
516        return getService().getGroupById(groupId);
517    }
518
519    /**
520     * Construct a blank Group object.
521     *
522     * This method calls getGroupClass, and then creates a new object using
523     * the default constructor.
524     *
525     * @param groupName The name of the Group
526     *
527     * @return an object implementing Group interface.
528     *
529     * @throws UnknownEntityException if the object could not be instantiated.
530     */
531    public static Group getGroupInstance(String groupName)
532            throws UnknownEntityException
533    {
534        return getService().getGroupInstance(groupName);
535    }
536
537    /**
538     * Construct a blank Role object.
539     *
540     * This method calls getRoleClass, and then creates a new object using
541     * the default constructor.
542     *
543     * @param roleName The name of the role.
544     *
545     * @return an object implementing Role interface.
546     *
547     * @throws UnknownEntityException if the object could not be instantiated.
548     */
549    public static Role getRoleInstance(String roleName)
550            throws UnknownEntityException
551    {
552        return getService().getRoleInstance(roleName);
553    }
554
555    /**
556     * Construct a blank Permission object.
557     *
558     * This method calls getPermissionClass, and then creates a new object using
559     * the default constructor.
560     *
561     * @param permName The name of the permission.
562     *
563     * @return an object implementing Permission interface.
564     * @throws UnknownEntityException if the object could not be instantiated.
565     */
566    public static Permission getPermissionInstance(String permName)
567            throws UnknownEntityException
568    {
569        return getService().getPermissionInstance(permName);
570    }
571
572    /**
573     * Retrieve a Role object with specified name.
574     *
575     * @param roleName The name of the Role to be retrieved.
576     * @return an object representing the Role with specified name.
577     * @throws DataBackendException if there was an error accessing the data
578     *         backend.
579     * @throws UnknownEntityException if the Role is not present.
580     */
581    public static Role getRoleByName(String roleName)
582            throws DataBackendException, UnknownEntityException
583    {
584        return getService().getRoleByName(roleName);
585    }
586
587    /**
588     * Retrieve a Role object with specified Id.
589     *
590     * @param roleId the id of the Role.
591     *
592     * @return an object representing the Role with specified name.
593     *
594     * @exception UnknownEntityException if the permission does not
595     *            exist in the database.
596     * @exception DataBackendException if there is a problem accessing the
597     *            storage.
598     */
599    public static Role getRoleById(int roleId)
600            throws DataBackendException,
601                   UnknownEntityException
602    {
603        return getService().getRoleById(roleId);
604    }
605
606    /**
607     * Retrieve a Permission object with specified name.
608     *
609     * @param permissionName The name of the Permission to be retrieved.
610     * @return an object representing the Permission with specified name.
611     * @throws DataBackendException if there was an error accessing the data
612     *         backend.
613     * @throws UnknownEntityException if the Permission is not present.
614     */
615    public static Permission getPermissionByName(String permissionName)
616            throws DataBackendException, UnknownEntityException
617    {
618        return getService().getPermissionByName(permissionName);
619    }
620
621    /**
622     * Retrieve a Permission object with specified Id.
623     *
624     * @param permissionId the id of the Permission.
625     *
626     * @return an object representing the Permission with specified name.
627     *
628     * @exception UnknownEntityException if the permission does not
629     *            exist in the database.
630     * @exception DataBackendException if there is a problem accessing the
631     *            storage.
632     */
633    public static Permission getPermissionById(int permissionId)
634            throws DataBackendException,
635                   UnknownEntityException
636    {
637        return getService().getPermissionById(permissionId);
638    }
639
640    /**
641     * Retrieves all groups defined in the system.
642     *
643     * @return the names of all groups defined in the system.
644     * @throws DataBackendException if there was an error accessing the data
645     *         backend.
646     */
647    public static GroupSet getAllGroups()
648            throws DataBackendException
649    {
650        return getService().getAllGroups();
651    }
652
653    /**
654     * Retrieves all roles defined in the system.
655     *
656     * @return the names of all roles defined in the system.
657     * @throws DataBackendException if there was an error accessing the data
658     *         backend.
659     */
660    public static RoleSet getAllRoles()
661            throws DataBackendException
662    {
663        return getService().getAllRoles();
664    }
665
666    /**
667     * Retrieves all permissions defined in the system.
668     *
669     * @return the names of all roles defined in the system.
670     * @throws DataBackendException if there was an error accessing the data
671     *         backend.
672     */
673    public static PermissionSet getAllPermissions()
674            throws DataBackendException
675    {
676        return getService().getAllPermissions();
677    }
678
679    /**
680     * Retrieves all permissions associated with a role.
681     *
682     * @param role the role name, for which the permissions are to be retrieved.
683     * @return the Permissions for the specified role
684     * @throws DataBackendException if there was an error accessing the data
685     *         backend.
686     * @throws UnknownEntityException if the role is not present.
687     */
688    public static PermissionSet getPermissions(Role role)
689            throws DataBackendException, UnknownEntityException
690    {
691        return getService().getPermissions(role);
692    }
693
694    /**
695     * Creates a new group with specified attributes.
696     *
697     * @param group the object describing the group to be created.
698     * @throws DataBackendException if there was an error accessing the data
699     *         backend.
700     * @throws EntityExistsException if the group already exists.
701     */
702    public static void addGroup(Group group)
703            throws DataBackendException, EntityExistsException
704    {
705        getService().addGroup(group);
706    }
707
708    /**
709     * Creates a new role with specified attributes.
710     *
711     * @param role the objects describing the role to be created.
712     * @throws DataBackendException if there was an error accessing the data
713     *         backend.
714     * @throws EntityExistsException if the role already exists.
715     */
716    public static void addRole(Role role)
717            throws DataBackendException, EntityExistsException
718    {
719        getService().addRole(role);
720    }
721
722    /**
723     * Creates a new permission with specified attributes.
724     *
725     * @param permission the objects describing the permission to be created.
726     * @throws DataBackendException if there was an error accessing the data
727     *         backend.
728     * @throws EntityExistsException if the permission already exists.
729     */
730    public static void addPermission(Permission permission)
731            throws DataBackendException, EntityExistsException
732    {
733        getService().addPermission(permission);
734    }
735
736    /**
737     * Removes a Group from the system.
738     *
739     * @param group the object describing group to be removed.
740     * @throws DataBackendException if there was an error accessing the data
741     *         backend.
742     * @throws UnknownEntityException if the group does not exist.
743     */
744    public static void removeGroup(Group group)
745            throws DataBackendException, UnknownEntityException
746    {
747        getService().removeGroup(group);
748    }
749
750    /**
751     * Removes a Role from the system.
752     *
753     * @param role The object describing the role to be removed.
754     * @throws DataBackendException if there was an error accessing the data backend.
755     * @throws UnknownEntityException if the role does not exist.
756     */
757    public static void removeRole(Role role)
758            throws DataBackendException, UnknownEntityException
759    {
760        getService().removeRole(role);
761    }
762
763    /**
764     * Removes a Permission from the system.
765     *
766     * @param permission The object describing the permission to be removed.
767     * @throws DataBackendException if there was an error accessing the data
768     *         backend.
769     * @throws UnknownEntityException if the permission does not exist.
770     */
771    public static void removePermission(Permission permission)
772            throws DataBackendException, UnknownEntityException
773    {
774        getService().removePermission(permission);
775    }
776
777    /**
778     * Renames an existing Group.
779     *
780     * @param group The object describing the group to be renamed.
781     * @param name the new name for the group.
782     * @throws DataBackendException if there was an error accessing the data
783     *         backend.
784     * @throws UnknownEntityException if the group does not exist.
785     */
786    public static void renameGroup(Group group, String name)
787            throws DataBackendException, UnknownEntityException
788    {
789        getService().renameGroup(group, name);
790    }
791
792    /**
793     * Renames an existing Role.
794     *
795     * @param role The object describing the role to be renamed.
796     * @param name the new name for the role.
797     * @throws DataBackendException if there was an error accessing the data
798     *         backend.
799     * @throws UnknownEntityException if the role does not exist.
800     */
801    public static void renameRole(Role role, String name)
802            throws DataBackendException, UnknownEntityException
803    {
804        getService().renameRole(role, name);
805    }
806
807    /**
808     * Renames an existing Permission.
809     *
810     * @param permission The object describing the permission to be renamed.
811     * @param name the new name for the permission.
812     * @throws DataBackendException if there was an error accessing the data
813     *         backend.
814     * @throws UnknownEntityException if the permission does not exist.
815     */
816    public static void renamePermission(Permission permission, String name)
817            throws DataBackendException, UnknownEntityException
818    {
819        getService().renamePermission(permission, name);
820    }
821}