001package org.apache.turbine.services.security;
002
003
004/*
005 * Licensed to the Apache Software Foundation (ASF) under one
006 * or more contributor license agreements.  See the NOTICE file
007 * distributed with this work for additional information
008 * regarding copyright ownership.  The ASF licenses this file
009 * to you under the Apache License, Version 2.0 (the
010 * "License"); you may not use this file except in compliance
011 * with the License.  You may obtain a copy of the License at
012 *
013 *   http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing,
016 * software distributed under the License is distributed on an
017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018 * KIND, either express or implied.  See the License for the
019 * specific language governing permissions and limitations
020 * under the License.
021 */
022
023
024import org.apache.fulcrum.security.acl.AccessControlList;
025import org.apache.fulcrum.security.entity.Group;
026import org.apache.fulcrum.security.entity.Permission;
027import org.apache.fulcrum.security.entity.Role;
028import org.apache.fulcrum.security.util.DataBackendException;
029import org.apache.fulcrum.security.util.EntityExistsException;
030import org.apache.fulcrum.security.util.GroupSet;
031import org.apache.fulcrum.security.util.PasswordMismatchException;
032import org.apache.fulcrum.security.util.PermissionSet;
033import org.apache.fulcrum.security.util.RoleSet;
034import org.apache.fulcrum.security.util.UnknownEntityException;
035import org.apache.turbine.om.security.DefaultUserImpl;
036import org.apache.turbine.om.security.User;
037import org.apache.turbine.services.Service;
038import org.apache.turbine.services.security.passive.PassiveUserManager;
039
040/**
041 * The Security Service manages Users, Groups Roles and Permissions in the
042 * system.
043 *
044 * The task performed by the security service include creation and removal of
045 * accounts, groups, roles, and permissions; assigning users roles in groups;
046 * assigning roles specific permissions and construction of objects
047 * representing these logical entities.
048 *
049 * <p> Because of pluggable nature of the Services, it is possible to create
050 * multiple implementations of SecurityService, for example employing database
051 * and directory server as the data backend.<br>
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 * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
056 * @version $Id: SecurityService.java 1821872 2018-01-22 14:35:04Z gk $
057 */
058public interface SecurityService
059        extends Service
060{
061    /** The name of the service */
062    String SERVICE_NAME = "SecurityService";
063
064    /**
065     * the key within services's properties for user manager implementation
066     * classname (user.manager)
067     */
068    String USER_MANAGER_KEY = "user.manager";
069
070    /**
071     * the default implementation of UserManager interface
072     * (org.apache.turbine.services.security.passive.PassiveUserManager)
073     */
074    String USER_MANAGER_DEFAULT
075            = PassiveUserManager.class.getName();
076
077    /**
078     * the key within services's properties for user implementation
079     * classname (wrapper.class)
080     */
081    String USER_WRAPPER_KEY = "wrapper.class";
082
083    /**
084     * the default implementation of {@link User} interface
085     * (org.apache.turbine.om.security.DefaultUserImpl)
086     */
087    String USER_WRAPPER_DEFAULT
088            = DefaultUserImpl.class.getName();
089
090
091    /*-----------------------------------------------------------------------
092      Management of User objects
093      -----------------------------------------------------------------------*/
094
095    /**
096     * Construct a blank User object.
097     *
098     * @return an object implementing User interface.
099     * @throws UnknownEntityException if the object could not be instantiated.
100     */
101    <U extends User> U getUserInstance()
102            throws UnknownEntityException;
103
104    /**
105     * Construct a blank User object.
106     *
107     * @param userName The name of the user.
108     *
109     * @return an object implementing User interface.
110     * @throws UnknownEntityException if the object could not be instantiated.
111     */
112    <U extends User> U getUserInstance(String userName)
113            throws UnknownEntityException;
114
115    /**
116     * Construct a blank Group object.
117     *
118     * @return an object implementing Group interface.
119     * @throws UnknownEntityException if the object could not be instantiated.
120     */
121    <G extends Group> G getGroupInstance()
122            throws UnknownEntityException;
123
124    /**
125     * Construct a blank Group object.
126     *
127     * @param groupName The name of the Group
128     *
129     * @return an object implementing Group interface.
130     * @throws UnknownEntityException if the object could not be instantiated.
131     */
132    <G extends Group> G getGroupInstance(String groupName)
133            throws UnknownEntityException;
134
135    /**
136     * Construct a blank Permission object.
137     *
138     * @return an object implementing Permission interface.
139     * @throws UnknownEntityException if the object could not be instantiated.
140     */
141    <P extends Permission> P getPermissionInstance()
142            throws UnknownEntityException;
143
144    /**
145     * Construct a blank Permission object.
146     *
147     * @param permName The name of the Permission
148     *
149     * @return an object implementing Permission interface.
150     * @throws UnknownEntityException if the object could not be instantiated.
151     */
152    <P extends Permission> P getPermissionInstance(String permName)
153            throws UnknownEntityException;
154
155    /**
156     * Construct a blank Role object.
157     *
158     * @return an object implementing Role interface.
159     * @throws UnknownEntityException if the object could not be instantiated.
160     */
161    <R extends Role> R getRoleInstance()
162            throws UnknownEntityException;
163
164    /**
165     * Construct a blank Role object.
166     *
167     * @param roleName The name of the Role
168     *
169     * @return an object implementing Role interface.
170     * @throws UnknownEntityException if the object could not be instantiated.
171     */
172    <R extends Role> R getRoleInstance(String roleName)
173            throws UnknownEntityException;
174
175    /**
176     * Returns the configured UserManager.
177     *
178     * @return An UserManager object
179     */
180    UserManager getUserManager();
181
182    /**
183     * Check whether a specified user's account exists.
184     *
185     * The login name is used for looking up the account.
186     *
187     * @param userName The user to be checked.
188     * @return true if the specified account exists
189     * @throws DataBackendException if there was an error accessing the data
190     *         backend.
191     */
192    boolean accountExists(String userName)
193            throws DataBackendException;
194
195    /**
196     * Check whether a specified user's account exists.
197     * An User object is used for looking up the account.
198     *
199     * @param user The user object to be checked.
200     * @return true if the specified account exists
201     * @throws DataBackendException if there was an error accessing the data
202     *         backend.
203     */
204    boolean accountExists(User user)
205            throws DataBackendException;
206
207    /**
208     * Authenticates an user, and constructs an User object to represent
209     * him/her.
210     *
211     * @param username The user name.
212     * @param password The user password.
213     * @return An authenticated Turbine User.
214     * @throws DataBackendException if there was an error accessing the data
215     *         backend.
216     * @throws UnknownEntityException if user account is not present.
217     * @throws PasswordMismatchException if the supplied password was incorrect.
218     */
219    <U extends User> U getAuthenticatedUser(String username, String password)
220            throws DataBackendException, UnknownEntityException,
221            PasswordMismatchException;
222
223    /**
224     * Constructs an User object to represent a registered user of the
225     * application.
226     *
227     * @param username The user name.
228     * @return A Turbine User.
229     * @throws DataBackendException if there was an error accessing the data
230     *         backend.
231     * @throws UnknownEntityException if user account is not present.
232     */
233    <U extends User> U getUser(String username)
234            throws DataBackendException, UnknownEntityException;
235
236    /**
237     * Constructs an User object to represent an anonymous user of the
238     * application.
239     *
240     * @return An anonymous Turbine User.
241     * @throws UnknownEntityException if the anonymous User object couldn't be
242     *         constructed.
243     */
244    <U extends User> U getAnonymousUser()
245            throws UnknownEntityException;
246
247    /**
248     * Checks whether a passed user object matches the anonymous user pattern
249     * according to the configured user manager
250     *
251     * @param u a user object
252     *
253     * @return True if this is an anonymous user
254     *
255     */
256    boolean isAnonymousUser(User u);
257
258    /**
259     * Saves User's data in the permanent storage. The user account is required
260     * to exist in the storage.
261     *
262     * @param user the user object to save
263     * @throws UnknownEntityException if the user's account does not
264     *         exist in the database.
265     * @throws DataBackendException if there is a problem accessing the storage.
266     */
267    void saveUser(User user)
268            throws UnknownEntityException, DataBackendException;
269
270    /**
271     * Saves User data when the session is unbound. The user account is required
272     * to exist in the storage.
273     *
274     * LastLogin, AccessCounter, persistent pull tools, and any data stored
275     * in the permData hashtable that is not mapped to a column will be saved.
276     *
277     * @param user the user object
278     *
279     * @throws UnknownEntityException if the user's account does not
280     *            exist in the database.
281     * @throws DataBackendException if there is a problem accessing the
282     *            storage.
283     */
284    void saveOnSessionUnbind(User user)
285            throws UnknownEntityException, DataBackendException;
286
287    /*-----------------------------------------------------------------------
288      Account management
289      -----------------------------------------------------------------------*/
290
291    /**
292     * Creates new user account with specified attributes.
293     *
294     * @param user the object describing account to be created.
295     * @param password The password to use.
296     * @throws DataBackendException if there was an error accessing the data
297     *         backend.
298     * @throws EntityExistsException if the user account already exists.
299     * @throws UnknownEntityException  if the provided user does not exist (is null)
300     */
301    void addUser(User user, String password)
302            throws DataBackendException, EntityExistsException, UnknownEntityException;
303
304    /**
305     * Removes an user account from the system.
306     *
307     * @param user the object describing the account to be removed.
308     * @throws DataBackendException if there was an error accessing the data
309     *         backend.
310     * @throws UnknownEntityException if the user account is not present.
311     */
312    void removeUser(User user)
313            throws DataBackendException, UnknownEntityException;
314
315    /*-----------------------------------------------------------------------
316      Management of passwords
317      -----------------------------------------------------------------------*/
318
319    /**
320     * Change the password for an User.
321     *
322     * @param user an User to change password for.
323     * @param oldPassword the current password supplied by the user.
324     * @param newPassword the current password requested by the user.
325     * @throws PasswordMismatchException if the supplied password was
326     *            incorrect.
327     * @throws UnknownEntityException if the user's record does not
328     *            exist in the database.
329     * @throws DataBackendException if there is a problem accessing the
330     *            storage.
331     */
332    void changePassword(User user, String oldPassword,
333                        String newPassword)
334            throws PasswordMismatchException, UnknownEntityException,
335            DataBackendException;
336
337    /**
338     * Forcibly sets new password for an User.
339     *
340     * This is supposed by the administrator to change the forgotten or
341     * compromised passwords. Certain implementatations of this feature
342     * would require administrative level access to the authenticating
343     * server / program.
344     *
345     * @param user an User to change password for.
346     * @param password the new password.
347     * @throws UnknownEntityException if the user's record does not
348     *            exist in the database.
349     * @throws DataBackendException if there is a problem accessing the
350     *            storage.
351     */
352    void forcePassword(User user, String password)
353            throws UnknownEntityException, DataBackendException;
354
355    /*-----------------------------------------------------------------------
356      Retrieval of security information
357      -----------------------------------------------------------------------*/
358
359    /**
360     * Constructs an AccessControlList for a specific user.
361     *
362     * @param user the user for whom the AccessControlList are to be retrieved
363     * @return A new AccessControlList object.
364     * @throws DataBackendException if there was an error accessing the data backend.
365     * @throws UnknownEntityException if user account is not present.
366     */
367    <A extends AccessControlList> A getACL(User user)
368            throws DataBackendException, UnknownEntityException;
369
370    /**
371     * Retrieves all permissions associated with a role.
372     *
373     * @param role the role name, for which the permissions are to be retrieved.
374     * @return the permissions associated with the role
375     * @throws DataBackendException if there was an error accessing the data
376     *         backend.
377     * @throws UnknownEntityException if the role is not present.
378     */
379    PermissionSet getPermissions(Role role)
380            throws DataBackendException, UnknownEntityException;
381
382    /*-----------------------------------------------------------------------
383      Manipulation of security information
384      -----------------------------------------------------------------------*/
385
386    /**
387     * Grant an User a Role in a Group.
388     *
389     * @param user the user.
390     * @param group the group.
391     * @param role the role.
392     * @throws DataBackendException if there was an error accessing the data
393     *         backend.
394     * @throws UnknownEntityException if user account, group or role is not
395     *         present.
396     */
397    void grant(User user, Group group, Role role)
398            throws DataBackendException, UnknownEntityException;
399
400    /**
401     * Revoke a Role in a Group from an User.
402     *
403     * @param user the user.
404     * @param group the group.
405     * @param role the role.
406     * @throws DataBackendException if there was an error accessing the data
407     *         backend.
408     * @throws UnknownEntityException if user account, group or role is not
409     *         present.
410     */
411    void revoke(User user, Group group, Role role)
412            throws DataBackendException, UnknownEntityException;
413
414    /**
415     * Revokes all roles from an User.
416     *
417     * This method is used when deleting an account.
418     *
419     * @param user the User.
420     * @throws DataBackendException if there was an error accessing the data
421     *         backend.
422     * @throws UnknownEntityException if the account is not present.
423     */
424    void revokeAll(User user)
425            throws DataBackendException, UnknownEntityException;
426
427    /**
428     * Grants a Role a Permission
429     *
430     * @param role the Role.
431     * @param permission the Permission.
432     * @throws DataBackendException if there was an error accessing the data
433     *         backend.
434     * @throws UnknownEntityException if role or permission is not present.
435     */
436    void grant(Role role, Permission permission)
437            throws DataBackendException, UnknownEntityException;
438
439    /**
440     * Revokes a Permission from a Role.
441     *
442     * @param role the Role.
443     * @param permission the Permission.
444     * @throws DataBackendException if there was an error accessing the data
445     *         backend.
446     * @throws UnknownEntityException if role or permission is not present.
447     */
448    void revoke(Role role, Permission permission)
449            throws DataBackendException, UnknownEntityException;
450
451    /**
452     * Revokes all permissions from a Role.
453     *
454     * This method is user when deleting a Role.
455     *
456     * @param role the Role
457     * @throws DataBackendException if there was an error accessing the data
458     *         backend.
459     * @throws  UnknownEntityException if the Role is not present.
460     */
461    void revokeAll(Role role)
462            throws DataBackendException, UnknownEntityException;
463    
464    /**
465     * Revokes by default all permissions from a Role and if flag is set
466     * all groups and users for this role
467     * 
468     * This method is used when deleting a Role.
469     * 
470     * @param role
471     *            the Role
472     * @param cascadeDelete
473     *             if <code>true </code> removes all groups and user for this role.
474     * @throws DataBackendException
475     *             if there was an error accessing the data backend.
476     * @throws UnknownEntityException
477     *             if the Role is not present.
478     */
479    void revokeAll( Role role, boolean cascadeDelete )
480                    throws DataBackendException, UnknownEntityException;
481
482    /*-----------------------------------------------------------------------
483      Retrieval & storage of SecurityObjects
484      -----------------------------------------------------------------------*/
485
486    /**
487     * Provides a reference to the Group object that represents the
488     * <a href="#global">global group</a>.
489     *
490     * @return A Group object that represents the global group.
491     */
492    <G extends Group> G getGlobalGroup();
493
494    /**
495     * Retrieve a Group object with specified name.
496     *
497     * @param name the name of the Group.
498     * @return an object representing the Group with specified name.
499     * @throws DataBackendException if there was an error accessing the data
500     *         backend.
501     * @throws UnknownEntityException if the group does not exist.
502     */
503    <G extends Group> G getGroupByName(String name)
504            throws DataBackendException, UnknownEntityException;
505
506    /**
507     * Retrieve a Group object with specified Id.
508     *
509     * @param id the id of the Group.
510     *
511     * @return an object representing the Group with specified name.
512     *
513     * @throws UnknownEntityException if the permission does not
514     *            exist in the database.
515     * @throws DataBackendException if there is a problem accessing the
516     *            storage.
517     */
518    <G extends Group> G getGroupById(int id)
519            throws DataBackendException,
520                   UnknownEntityException;
521
522    /**
523     * Retrieve a Role object with specified name.
524     *
525     * @param name the name of the Role.
526     * @return an object representing the Role with specified name.
527     * @throws DataBackendException if there was an error accessing the data
528     *         backend.
529     * @throws UnknownEntityException if the role does not exist.
530     */
531    <R extends Role> R getRoleByName(String name)
532            throws DataBackendException, UnknownEntityException;
533
534    /**
535     * Retrieve a Role object with specified Id.
536     *
537     * @param id the id of the Role.
538     *
539     * @return an object representing the Role with specified name.
540     *
541     * @throws UnknownEntityException if the permission does not
542     *            exist in the database.
543     * @throws DataBackendException if there is a problem accessing the
544     *            storage.
545     */
546    <R extends Role> R getRoleById(int id)
547            throws DataBackendException,
548                   UnknownEntityException;
549
550    /**
551     * Retrieve a Permission object with specified name.
552     *
553     * @param name the name of the Permission.
554     * @return an object representing the Permission with specified name.
555     * @throws DataBackendException if there was an error accessing the data
556     *         backend.
557     * @throws UnknownEntityException if the permission does not exist.
558     */
559    <P extends Permission> P getPermissionByName(String name)
560            throws DataBackendException, UnknownEntityException;
561
562    /**
563     * Retrieve a Permission object with specified Id.
564     *
565     * @param id the id of the Permission.
566     *
567     * @return an object representing the Permission with specified name.
568     *
569     * @throws UnknownEntityException if the permission does not
570     *            exist in the database.
571     * @throws DataBackendException if there is a problem accessing the
572     *            storage.
573     */
574    <P extends Permission> P getPermissionById(int id)
575            throws DataBackendException,
576                   UnknownEntityException;
577
578    /**
579     * Retrieves all groups defined in the system.
580     *
581     * @return the names of all groups defined in the system.
582     * @throws DataBackendException if there was an error accessing the data
583     *         backend.
584     */
585    GroupSet getAllGroups()
586            throws DataBackendException;
587
588    /**
589     * Retrieves all roles defined in the system.
590     *
591     * @return the names of all roles defined in the system.
592     * @throws DataBackendException if there was an error accessing the data
593     *         backend.
594     */
595    RoleSet getAllRoles()
596            throws DataBackendException;
597
598    /**
599     * Retrieves all permissions defined in the system.
600     *
601     * @return the names of all roles defined in the system.
602     * @throws DataBackendException if there was an error accessing the data
603     *         backend.
604     */
605    PermissionSet getAllPermissions()
606            throws DataBackendException;
607
608    /*-----------------------------------------------------------------------
609      Group/Role/Permission management
610      -----------------------------------------------------------------------*/
611
612    /**
613     * Creates a new group with specified attributes.
614     *
615     * @param group the object describing the group to be created.
616     * @return the new Group object.
617     * @throws DataBackendException if there was an error accessing the data
618     *         backend.
619     * @throws EntityExistsException if the group already exists.
620     */
621    <G extends Group> G addGroup(G group)
622            throws DataBackendException, EntityExistsException;
623
624    /**
625     * Creates a new role with specified attributes.
626     *
627     * @param role The object describing the role to be created.
628     * @return the new Role object.
629     * @throws DataBackendException if there was an error accessing the data
630     *         backend.
631     * @throws EntityExistsException if the role already exists.
632     */
633    <R extends Role> R addRole(R role)
634            throws DataBackendException, EntityExistsException;
635
636    /**
637     * Creates a new permission with specified attributes.
638     *
639     * @param permission The object describing the permission to be created.
640     * @return the new Permission object.
641     * @throws DataBackendException if there was an error accessing the data
642     *         backend.
643     * @throws EntityExistsException if the permission already exists.
644     */
645    <P extends Permission> P addPermission(P permission)
646            throws DataBackendException, EntityExistsException;
647
648    /**
649     * Removes a Group from the system.
650     *
651     * @param group The object describing the group to be removed.
652     * @throws DataBackendException if there was an error accessing the data
653     *         backend.
654     * @throws UnknownEntityException if the group does not exist.
655     */
656    void removeGroup(Group group)
657            throws DataBackendException, UnknownEntityException;
658
659    /**
660     * Removes a Role from the system.
661     *
662     * @param role The object describing the role to be removed.
663     * @throws DataBackendException if there was an error accessing the data
664     *         backend.
665     * @throws UnknownEntityException if the role does not exist.
666     */
667    void removeRole(Role role)
668            throws DataBackendException, UnknownEntityException;
669
670    /**
671     * Removes a Permission from the system.
672     *
673     * @param permission The object describing the permission to be removed.
674     * @throws DataBackendException if there was an error accessing the data
675     *         backend.
676     * @throws UnknownEntityException if the permission does not exist.
677     */
678    void removePermission(Permission permission)
679            throws DataBackendException, UnknownEntityException;
680
681    /**
682     * Renames an existing Group.
683     *
684     * @param group The object describing the group to be renamed.
685     * @param name the new name for the group.
686     * @throws DataBackendException if there was an error accessing the data
687     *         backend.
688     * @throws UnknownEntityException if the group does not exist.
689     */
690    void renameGroup(Group group, String name)
691            throws DataBackendException, UnknownEntityException;
692
693    /**
694     * Renames an existing Role.
695     *
696     * @param role The object describing the role to be renamed.
697     * @param name the new name for the role.
698     * @throws DataBackendException if there was an error accessing the data
699     *         backend.
700     * @throws UnknownEntityException if the role does not exist.
701     */
702    void renameRole(Role role, String name)
703            throws DataBackendException, UnknownEntityException;
704
705    /**
706     * Renames an existing Permission.
707     *
708     * @param permission The object describing the permission to be renamed.
709     * @param name the new name for the permission.
710     * @throws DataBackendException if there was an error accessing the data
711     *         backend.
712     * @throws UnknownEntityException if the permission does not exist.
713     */
714    void renamePermission(Permission permission, String name)
715            throws DataBackendException, UnknownEntityException;
716    /**
717     * Replaces transactionally the first given role with the second role for the given user. 
718     * 
719     * @param user the user.
720     * @param role the old role
721     * @param newRole the new role
722     * 
723     * @throws DataBackendException
724     * @throws UnknownEntityException
725     */
726    void replaceRole( User user, Role role, Role newRole )
727        throws DataBackendException, UnknownEntityException;
728
729}