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