package org.deegree.security.drm;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.deegree.security.GeneralSecurityException;
import org.deegree.security.UnauthorizedException;
import org.deegree.security.drm.model.Group;
import org.deegree.security.drm.model.Privilege;
import org.deegree.security.drm.model.Right;
import org.deegree.security.drm.model.RightSet;
import org.deegree.security.drm.model.RightType;
import org.deegree.security.drm.model.Role;
import org.deegree.security.drm.model.SecurableObject;
import org.deegree.security.drm.model.SecuredObject;
import org.deegree.security.drm.model.User;
/**
*
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class SecurityTransaction extends SecurityAccess {
private Role adminRole;
private long timestamp;
SecurityTransaction(User user, SecurityRegistry registry, Role adminRole) {
super(user, registry);
this.adminRole = adminRole;
this.timestamp = System.currentTimeMillis();
}
/**
* Returns the conjunction of an array of roles plus a single role.
*
* @param roles
* @param role
*/
public Role[] addRoles(Role[] roles, Role role) {
HashSet roleSet = new HashSet(roles.length + 1);
roleSet.add(role);
for (int i = 0; i < roles.length; i++) {
roleSet.add(roles[i]);
}
return (Role[]) roleSet.toArray(new Role[roleSet.size()]);
}
/**
* Deletes all data from the underlying <code>Registry</code> and sets the
* default objects (SEC_ADMIN user, role and group) and standard rights and
* privileges.
*
* @throws GeneralSecurityException
*/
public void clean() throws GeneralSecurityException {
SecurityAccessManager.getInstance().verify(this);
registry.clean(this);
}
/**
* Removes a <code>Group</code> from the <code>Registry</code>.
*
* This means:
* <ul>
* <li>owner role ($G:GROUPNAME) is removed
* <li>group is removed
* </ul>
*
* NOTE: Only performed if the acting user has the 'delete'-right on the
* group object.
*
* @param group
* @throws GeneralSecurityException
*/
public void deregisterGroup(Group group) throws GeneralSecurityException,
UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.DELETE, group);
try {
Role ownerRole = registry.getRoleByName(this, "$G:"
+ group.getName());
registry.deregisterRole(this, ownerRole);
} catch (UnknownException e) {
}
registry.deregisterGroup(this, group);
}
/**
* Removes a <code>Role</code> from the <code>Registry</code>.
*
* This means:
* <ul>
* <li>owner role ($R:ROLENAME) is removed
* <li>role is removed
* </ul>
*
* NOTE: Only performed if acting user has the 'delete'-right on the role
* object.
*
* @param lock
* @param role
* @throws GeneralSecurityException
*/
public void deregisterRole(Role role) throws GeneralSecurityException,
UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.DELETE, role);
try {
Role ownerRole = registry.getRoleByName(this, "$R:"
+ role.getName());
registry.deregisterRole(this, ownerRole);
} catch (UnknownException e) {
}
registry.deregisterRole(this, role);
}
/**
* Removes a <code>SecuredObject</code> from the <code>Registry</code>.
*
* This means:
* <ul>
* <li>owner role ($O:OBJECTNAME) is removed
* <li>object is removed
* </ul>
*
* NOTE: Only performed if acting user has the 'delete'-right on the secured
* object.
*
* @param object
* @throws GeneralSecurityException
*/
public void deregisterSecuredObject(SecuredObject object)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.DELETE, object);
try {
Role ownerRole = registry.getRoleByName(this, "$O:"
+ object.getName());
registry.deregisterRole(this, ownerRole);
} catch (UnknownException e) {
}
registry.deregisterSecuredObject(this, object);
}
/**
* Removes a <code>User</code> from the <code>Registry</code>.
*
* This means:
* <ul>
* <li>owner role ($U:USERNAME) is removed
* <li>user is removed
* </ul>
*
* NOTE: Only performed if acting user has the 'delete'-right on the user
* object.
*
* @param user
* @throws GeneralSecurityException
*/
public void deregisterUser(User user) throws GeneralSecurityException,
UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.DELETE, user);
try {
Role ownerRole = registry.getRoleByName(this, "$U:"
+ user.getName());
registry.deregisterRole(this, ownerRole);
} catch (UnknownException e) {
e.printStackTrace();
}
registry.deregisterUser(this, user);
}
/**
*
* @uml.property name="timestamp"
*/
public long getTimestamp() {
return timestamp;
}
/**
* Registers a new <code>Group</code> to the <code>Registry</code>.
*
* This means:
* <ul>
* <li>a group is created in the registry
* <li>a corresponding owner role is created: $G:GROUPNAME
* <li>rights for the owner role are set up; creator has delete, update and
* grant rights on the group, administrator role gets these right, too
* </ul>
*
* NOTE: Only performed if acting user has the 'addgroup'-privilege.
*
* @param name
* @param title
* @throws GeneralSecurityException
*/
public Group registerGroup(String name, String title)
throws GeneralSecurityException {
SecurityAccessManager.getInstance().verify(this);
checkForPrivilege(Privilege.ADDGROUP);
if (name.startsWith("$")) {
throw new GeneralSecurityException("Groupname '" + name
+ "' is invalid. The '$'-character is for "
+ "internal use only.");
}
Group group = registry.registerGroup(this, name, title);
// only add owner role if lock holder is not the administrator
if (this.user.getID() != User.ID_SEC_ADMIN) {
Role ownerRole = registry.registerRole(this, "$G:" + name);
registry.setRolesForUser(this, user, addRoles(registry
.getRolesForUser(this, user), ownerRole));
registry.setRights(this, group, ownerRole, new Right[] {
new Right(group, RightType.DELETE),
new Right(group, RightType.UPDATE),
new Right(group, RightType.GRANT) });
}
registry.setRights(this, group, adminRole, new Right[] {
new Right(group, RightType.DELETE),
new Right(group, RightType.UPDATE),
new Right(group, RightType.GRANT) });
return group;
}
/**
* Registers a new <code>Role</code> to the <code>Registry</code>.
*
* This means:
* <ul>
* <li>a role is created in the registry
* <li>a corresponding owner role is created: $R:ROLENAME
* <li>rights for the owner role are set up; creator has delete, update and
* grant rights on the role, administrator role gets these right, too
* </ul>
*
* NOTE: Only performed if acting user has the 'addrole'-privilege.
*
* @param name
* @throws GeneralSecurityException
*/
public Role registerRole(String name) throws GeneralSecurityException {
SecurityAccessManager.getInstance().verify(this);
checkForPrivilege(Privilege.ADDROLE);
if (name.startsWith("$")) {
throw new GeneralSecurityException("Rolename '" + name
+ "' is invalid. The '$'-character is for "
+ "internal use only.");
}
Role role = registry.registerRole(this, name);
if (this.user.getID() != User.ID_SEC_ADMIN) {
Role ownerRole = registry.registerRole(this, "$R:" + name);
registry.setRolesForUser(this, user, addRoles(registry
.getRolesForUser(this, user), ownerRole));
registry.setRights(this, role, ownerRole, new Right[] {
new Right(role, RightType.DELETE),
new Right(role, RightType.UPDATE),
new Right(role, RightType.GRANT) });
}
registry.setRights(this, role, adminRole, new Right[] {
new Right(role, RightType.DELETE),
new Right(role, RightType.UPDATE),
new Right(role, RightType.GRANT) });
return role;
}
/**
* Registers a new <code>SecuredObject</code> to the <code>Registry</code>.
*
* This means:
* <ul>
* <li>a secured object is created in the registry
* <li>a corresponding owner role is created: $O:OBJECTNAME
* <li>rights for the owner role are set up; creator has delete, update and
* grant rights on the object, administrator role gets these right, too
* </ul>
*
* @param lock
* @param type
* @param name
* @param title
* @throws GeneralSecurityException
*/
public SecuredObject registerSecuredObject(String type, String name,
String title) throws GeneralSecurityException {
SecurityAccessManager.getInstance().verify(this);
checkForPrivilege(Privilege.ADDOBJECT);
if (name.startsWith("$")) {
throw new GeneralSecurityException("Objectname '" + name
+ "' is invalid. The '$'-character is for "
+ "internal use only.");
}
SecuredObject object = registry.registerSecuredObject(this, type, name,
title);
if (this.user.getID() != User.ID_SEC_ADMIN) {
Role ownerRole = registry.registerRole(this, "$O:" + name);
registry.setRolesForUser(this, user, addRoles(registry
.getRolesForUser(this, user), ownerRole));
registry.setRights(this, object, ownerRole, new Right[] {
new Right(object, RightType.DELETE),
new Right(object, RightType.UPDATE),
new Right(object, RightType.GRANT) });
}
registry.setRights(this, object, adminRole, new Right[] {
new Right(object, RightType.DELETE),
new Right(object, RightType.UPDATE),
new Right(object, RightType.GRANT) });
return object;
}
/**
* Registers a new <code>User</code> to the <code>Registry</code>.
*
* This means:
* <ul>
* <li>a user is created in the registry
* <li>a corresponding owner role is created: $U:USERNAME
* <li>rights for the owner role are set up; creator has delete, update and
* grant rights on the user, administrator role gets these right, too
* </ul>
*
* NOTE: Only performed if acting user has the 'adduser'-privilege.
*
* @param name
* @param password
* null means that password checking is disabled
* @param lastName
* @param firstName
* @param mailAddress
* @throws GeneralSecurityException
*/
public User registerUser(String name, String password, String lastName,
String firstName, String mailAddress)
throws GeneralSecurityException {
SecurityAccessManager.getInstance().verify(this);
checkForPrivilege(Privilege.ADDUSER);
if (name.startsWith("$")) {
throw new GeneralSecurityException("Username '" + name
+ "' is invalid. The '$'-character is for "
+ "internal use only.");
}
User user = registry.registerUser(this, name, password, lastName,
firstName, mailAddress);
// only add owner role if lock holder is not the administrator
if (this.user.getID() != User.ID_SEC_ADMIN) {
Role ownerRole = registry.registerRole(this, "$U:" + name);
registry.setRolesForUser(this, user, addRoles(registry
.getRolesForUser(this, user), ownerRole));
registry.setRights(this, user, ownerRole, new Right[] {
new Right(user, RightType.DELETE),
new Right(user, RightType.UPDATE),
new Right(user, RightType.GRANT) });
}
registry.setRights(this, user, adminRole, new Right[] {
new Right(user, RightType.DELETE),
new Right(user, RightType.UPDATE),
new Right(user, RightType.GRANT) });
return user;
}
/**
* Updates the data of an existing <code>User</code> in the
* <code>Registry</code>.
*
* NOTE: Only performed if acting user has the 'update'-right on the user.
*
* @throws GeneralSecurityException
*/
public void updateUser(User user) throws GeneralSecurityException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.UPDATE, user);
registry.updateUser(this, user);
}
/**
* Sets the <code>Group</code> s that a given <code>Group</code> is a
* DIRECT member of.
*
* NOTE: Only performed if the acting user has the 'grant'-right for all the
* groups that are requested to be added / removed.
*
* @param group
* @param newGroups
* @throws GeneralSecurityException
*/
public void setGroupsForGroup(Group group, Group[] newGroups)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
Group[] oldGroups = group.getGroups(this);
// build set for old groups
HashSet oldGroupSet = new HashSet(oldGroups.length);
for (int i = 0; i < oldGroups.length; i++) {
oldGroupSet.add(oldGroups[i]);
}
// build set for new groups
HashSet newGroupSet = new HashSet(oldGroups.length);
for (int i = 0; i < newGroups.length; i++) {
newGroupSet.add(newGroups[i]);
}
// check grant right for all groups requested to be removed
Iterator it = oldGroupSet.iterator();
while (it.hasNext()) {
Group currGroup = (Group) it.next();
if (!newGroupSet.contains(currGroup)) {
checkForRight(RightType.GRANT, group);
}
}
// check grant right for all groups requested to be added
it = newGroupSet.iterator();
while (it.hasNext()) {
Group currGroup = (Group) it.next();
if (!oldGroupSet.contains(currGroup)) {
checkForRight(RightType.GRANT, group);
}
}
registry.setGroupsForGroup(this, group, newGroups);
}
/**
* Sets the <code>Groups</code> that a given <code>User</code> is a
* DIRECT member of.
*
* NOTE: Only performed if the acting user has the 'grant'-right for all the
* groups that are requested to be added / removed.
*
* @param user
* @param newGroups
* @throws GeneralSecurityException
*/
public void setGroupsForUser(User user, Group[] newGroups)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
Group[] oldGroups = user.getGroups(this);
// build set for old groups
HashSet oldGroupSet = new HashSet(oldGroups.length);
for (int i = 0; i < oldGroups.length; i++) {
oldGroupSet.add(oldGroups[i]);
}
// build set for new groups
HashSet newGroupSet = new HashSet(oldGroups.length);
for (int i = 0; i < newGroups.length; i++) {
newGroupSet.add(newGroups[i]);
}
// check grant right for all groups requested to be removed
Iterator it = oldGroupSet.iterator();
while (it.hasNext()) {
Group group = (Group) it.next();
if (!newGroupSet.contains(group)) {
checkForRight(RightType.GRANT, group);
}
}
// check grant right for all groups requested to be added
it = newGroupSet.iterator();
while (it.hasNext()) {
Group group = (Group) it.next();
if (!oldGroupSet.contains(group)) {
checkForRight(RightType.GRANT, group);
}
}
registry.setGroupsForUser(this, user, newGroups);
}
/**
* Sets the members (groups) for a group.
*
* NOTE: Only performed if the acting user has the 'grant'-right on the
* group.
*
* @param group
* @param groups
* @throws GeneralSecurityException
*/
public void setGroupsInGroup(Group group, Group[] groups)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.GRANT, group);
registry.setGroupsInGroup(this, group, groups);
}
/**
* Sets the groups to be associated with the given role.
*
* NOTE: Only performed if the acting user has the 'grant'-right on the
* role.
*
* @param role
* @param groups
* @throws GeneralSecurityException
* if not permitted
*/
public void setGroupsWithRole(Role role, Group[] groups)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.GRANT, role);
registry.setGroupsWithRole(this, role, groups);
}
/**
* Sets the privileges for a certain role.
*
* NOTE: Only performed if the acting user has all the privileges he is
* trying to grant.
*
* FIXME: Shouldn't that be "... to grant / withdraw"?
*
* @param role
* @param privileges
* @throws GeneralSecurityException
* if not permitted
*/
public void setPrivilegesForRole(Role role, Privilege[] privileges)
throws GeneralSecurityException {
SecurityAccessManager.getInstance().verify(this);
Privilege[] holderPrivileges = user.getPrivileges(this);
HashSet holderSet = new HashSet(holderPrivileges.length);
for (int i = 0; i < holderPrivileges.length; i++) {
holderSet.add(holderPrivileges[i]);
}
for (int i = 0; i < privileges.length; i++) {
if (!holderSet.contains(privileges[i])) {
throw new GeneralSecurityException(
"The requested operation requires the privilege '"
+ privileges[i].getName() + "'.");
}
}
registry.setPrivilegesForRole(this, role, privileges);
}
/**
* Sets the <code>Rights</code> that a certain role has on a given object.
*
* NOTE: Only performed if the acting user has the 'update'-right on the
* role and the 'grant'-right on the securable object.
*
* @param object
* @param role
* @param rights
* @throws GeneralSecurityException
* if not permitted
*/
public void setRights(SecurableObject object, Role role, Right[] rights)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.UPDATE, role);
checkForRight(RightType.GRANT, object);
registry.setRights(this, object, role, rights);
}
/**
* Sets one certain right that a certain role has on the given objects.
*
* NOTE: Only performed if the acting user has the 'update'-right on the
* role and the 'grant'-right on the securable objects.
*
* @param objects
* @param role
* @param right
* @throws GeneralSecurityException
* if not permitted
*/
public void setRights(SecurableObject[] objects, Role role, Right right)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.UPDATE, role);
for (int i = 0; i < objects.length; i++) {
checkForRight(RightType.GRANT, objects[i]);
}
registry.setRights(this, objects, role, right);
}
/**
* Adds the specified <code>Rights</code> on the passed object to the passed role.
* If they are already present, nothing happens.
*
* @param object
* @param role
* @param additionalRights
* @throws GeneralSecurityException
* @throws UnauthorizedException
*/
public void addRights(SecurableObject object, Role role,
Right[] additionalRights) throws GeneralSecurityException,
UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.UPDATE, role);
checkForRight(RightType.GRANT, object);
RightSet presentRights = new RightSet( registry.getRights(this, object, role) );
RightSet newRights = presentRights.merge( new RightSet( additionalRights ) );
//RightSet newRights = new RightSet( additionalRights );
registry.setRights(this, object, role, newRights.toArray( object ) );
}
/**
* Removes all rights of the specified types that the role may have on the
* given <code>SecurableObject</code>.
*
* @param object
* @param role
* @param rights
* @throws GeneralSecurityException
* @throws UnauthorizedException
*/
public void removeRights (SecurableObject object, Role role, RightType[] types)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.UPDATE, role);
checkForRight(RightType.GRANT, object);
Right[] rights = registry.getRights(this, object, role);
List newRightList = new ArrayList (20);
for (int i = 0; i < rights.length; i++) {
RightType type = rights [i].getType();
boolean remove = true;
for (int j = 0; j < types.length; j++) {
if (type.equals (types [j])) {
remove = true;
}
}
if (!remove) {
newRightList.add (rights [i]);
}
}
Right [] newRights = (Right[]) newRightList.toArray(new Right[newRightList.size()]);
registry.setRights(this, object, role, newRights);
}
/**
* Sets the members (users) in a group.
*
* NOTE: Only performed if the acting user has the 'grant'-right on the
* group.
*
* @param group
* @param users
* @throws GeneralSecurityException
*/
public void setUsersInGroup(Group group, User[] users)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.GRANT, group);
registry.setUsersInGroup(this, group, users);
}
/**
* Sets the users to be associated with the given role (DIRECTLY, i.e. not
* via group memberships).
*
* NOTE: Only performed if the user has the 'grant'-right on the role.
*
* @param role
* @param users
* @throws GeneralSecurityException
* if not permitted
*/
public void setUsersWithRole(Role role, User[] users)
throws GeneralSecurityException, UnauthorizedException {
SecurityAccessManager.getInstance().verify(this);
checkForRight(RightType.GRANT, role);
registry.setUsersWithRole(this, role, users);
}
public String toString() {
StringBuffer sb = new StringBuffer();
try {
User[] users = getAllUsers();
sb.append("\n\nSecurityAccess @ " + System.currentTimeMillis());
sb.append("\n\n").append(users.length).append(
" registered users:\n");
for (int i = 0; i < users.length; i++) {
sb.append(users[i].toString(this)).append("\n");
}
Group[] groups = getAllGroups();
sb.append("\n").append(groups.length).append(
" registered groups:\n");
for (int i = 0; i < groups.length; i++) {
sb.append(groups[i].toString(this)).append("\n");
}
Role[] roles = getAllRoles();
sb.append("\n").append(roles.length).append(" registered roles:\n");
for (int i = 0; i < roles.length; i++) {
sb.append(roles[i].toString(this)).append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
void renew() {
this.timestamp = System.currentTimeMillis();
}
}/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: SecurityTransaction.java,v $
Revision 1.6 2006/07/12 14:46:18 poth
comment footer added
********************************************************************** */