/*******************************************************************************
 * Copyright (c) 2001, 2008 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.useradmin;

import java.util.Enumeration;
import java.util.Vector;
import org.osgi.service.prefs.BackingStoreException;

/**
 * A named grouping of roles.
 * <p>
 * Whether or not a given authorization context implies a Group role
 * depends on the members of that role.
 * <p>
 * A Group role can have two kinds of member roles: <i>basic</i> and
 * <i>required</i>.
 * A Group role is implied by an authorization context if all of
 * its required member roles are implied
 * and at least one of its basic member roles is implied.
 * <p>
 * A Group role must contain at least one basic member role in order
 * to be implied. In other words, a Group without any basic member
 * roles is never implied by any authorization context.
 * <p>
 * A User role always implies itself.
 * <p>
 * No loop detection is performed when adding members to groups, which
 * means that it is possible to create circular implications. Loop
 * detection is instead done when roles are checked. The semantics is that
 * if a role depends on itself (i.e., there is an implication loop), the
 * role is not implied.
 * <p>
 * The rule that a group must have at least one basic member to be implied
 * is motivated by the following example:
 *
 * <pre>
 * group foo
 *   required members: marketing
 *   basic members: alice, bob
 * </pre>
 *
 * Privileged operations that require membership in "foo" can be performed
 * only by alice and bob, who are in marketing.
 * <p>
 * If alice and bob ever transfer to a different department, anybody in
 * marketing will be able to assume the "foo" role, which certainly must be
 * prevented.
 * Requiring that "foo" (or any Group role for that matter) must have at least
 * one basic member accomplishes that.
 * <p>
 * However, this would make it impossible for a group to be implied by just
 * its required members. An example where this implication might be useful
 * is the following declaration: "Any citizen who is an adult is allowed to
 * vote."
 * An intuitive configuration of "voter" would be:
 *
 * <pre>
 * group voter
 *   required members: citizen, adult
 *      basic members:
 * </pre>
 *
 * However, according to the above rule, the "voter" role could never be
 * assumed by anybody, since it lacks any basic members.
 * In order to address this deficiency a predefined role named
 * "user.anyone" can be specified, which is always implied.
 * The desired implication of the "voter" group can then be achieved by
 * specifying "user.anyone" as its basic member, as follows:
 *
 * <pre>
 * group voter
 *   required members: citizen, adult
 *      basic members: user.anyone
 * </pre>
 */

public class Group extends User implements org.osgi.service.useradmin.Group {

	protected Vector requiredMembers;
	protected Vector basicMembers;

	protected Group(String name, UserAdmin useradmin) {
		super(name, useradmin);
		this.useradmin = useradmin;
		basicMembers = new Vector();
		requiredMembers = new Vector();
	}

	/**
	 * Adds the specified role as a basic member to this Group.
	 *
	 * @param role The role to add as a basic member.
	 *
	 * @return <code>true</code> if the given role could be added as a basic
	 * member,
	 * and <code>false</code> if this Group already contains a role whose name
	 * matches that of the specified role.
	 *
	 * @throws SecurityException If a security manager exists and the caller
	 * does not have the <tt>UserAdminPermission</tt> with name <tt>admin</tt>.
	 */
	public boolean addMember(org.osgi.service.useradmin.Role role) {
		useradmin.checkAlive();
		useradmin.checkAdminPermission();
		//only need to check for null for the public methods
		if (role == null) {
			return (false);
		}
		synchronized (useradmin) {
			if (basicMembers.contains(role)) {
				return (false);
			}
			return (addMember(role, true));
		}
	}

	// When we are loading from storage this method is called directly.  We
	// do not want to write to storage when we are loading form storage.
	protected boolean addMember(org.osgi.service.useradmin.Role role, boolean store) {
		((org.eclipse.equinox.internal.useradmin.Role) role).addImpliedRole(this);
		if (store) {
			try {
				useradmin.userAdminStore.addMember(this, (org.eclipse.equinox.internal.useradmin.Role) role);
			} catch (BackingStoreException ex) {
				return (false);
			}
		}
		basicMembers.addElement(role);
		return (true);
	}

	/**
	 * Adds the specified role as a required member to this Group.
	 *
	 * @param role The role to add as a required member.
	 *
	 * @return <code>true</code> if the given role could be added as a required
	 * member, and <code>false</code> if this Group already contains a role
	 * whose name matches that of the specified role.
	 *
	 * @throws SecurityException If a security manager exists and the caller
	 * does not have the <tt>UserAdminPermission</tt> with name <tt>admin</tt>.
	 */
	public boolean addRequiredMember(org.osgi.service.useradmin.Role role) {
		useradmin.checkAlive();
		useradmin.checkAdminPermission();
		if (role == null) {
			return (false);
		}
		synchronized (useradmin) {
			if (requiredMembers.contains(role)) {
				return (false);
			}
			return (addRequiredMember(role, true));
		}
	}

	protected boolean addRequiredMember(org.osgi.service.useradmin.Role role, boolean store) {
		((org.eclipse.equinox.internal.useradmin.Role) role).addImpliedRole(this);
		if (store) {
			try {
				useradmin.userAdminStore.addRequiredMember(this, (org.eclipse.equinox.internal.useradmin.Role) role);
			} catch (BackingStoreException ex) {
				return (false);
			}
		}
		requiredMembers.addElement(role);
		return (true);
	}

	/**
	 * Removes the specified role from this Group.
	 *
	 * @param role The role to remove from this Group.
	 *
	 * @return <code>true</code> if the role could be removed,
	 * otherwise <code>false</code>.
	 *
	 * @throws SecurityException If a security manager exists and the caller
	 * does not have the <tt>UserAdminPermission</tt> with name <tt>admin</tt>.
	 */
	public boolean removeMember(org.osgi.service.useradmin.Role role) {
		useradmin.checkAlive();
		useradmin.checkAdminPermission();
		if (role == null) {
			return (false);
		}
		synchronized (useradmin) {
			try {
				useradmin.userAdminStore.removeMember(this, (org.eclipse.equinox.internal.useradmin.Role) role);
			} catch (BackingStoreException ex) {
				return (false);
			}
			//The role keeps track of which groups it is a member of so it can remove itself from
			//the group if it is deleted.  In this case, this group is being removed from the role's
			//list.
			((org.eclipse.equinox.internal.useradmin.Role) role).removeImpliedRole(this);

			// We don't know if the Role to be removed is a basic orrequired member, or both.  We
			// simply try to remove it from both.
			boolean removeRequired = requiredMembers.removeElement(role);
			boolean removeBasic = basicMembers.removeElement(role);
			return (removeRequired || removeBasic);
		}
	}

	/**
	 * Gets the basic members of this Group.
	 *
	 * @return The basic members of this Group, or <code>null</code> if this
	 * Group does not contain any basic members.
	 */
	public org.osgi.service.useradmin.Role[] getMembers() {
		useradmin.checkAlive();
		synchronized (useradmin) {
			if (basicMembers.isEmpty()) {
				return (null);
			}
			Role[] roles = new Role[basicMembers.size()];
			basicMembers.copyInto(roles);
			return (roles);
		}
	}

	/**
	 * Gets the required members of this Group.
	 *
	 * @return The required members of this Group, or <code>null</code> if this
	 * Group does not contain any required members.
	 */
	public org.osgi.service.useradmin.Role[] getRequiredMembers() {
		useradmin.checkAlive();
		synchronized (useradmin) {
			if (requiredMembers.isEmpty()) {
				return (null);
			}
			Role[] roles = new Role[requiredMembers.size()];
			requiredMembers.copyInto(roles);
			return (roles);
		}
	}

	/**
	 * Returns the type of this role.
	 *
	 * @return The role's type.
	 */
	public int getType() {
		useradmin.checkAlive();
		return (org.osgi.service.useradmin.Role.GROUP);
	}

	protected boolean isImpliedBy(Role role, Vector checkLoop) {
		if (checkLoop.contains(name)) {
			//we have a circular dependency
			return (false);
		}
		if (name.equals(role.getName())) //A User always implies itself.  A Group is a User.
		{
			return (true);
		}
		checkLoop.addElement(name);
		Vector requiredCheckLoop = (Vector) checkLoop.clone();
		Vector basicCheckLoop = (Vector) checkLoop.clone();
		Enumeration e = requiredMembers.elements();

		//check to see if we imply all of the 0 or more required roles
		Role requiredRole;
		while (e.hasMoreElements()) {
			requiredRole = (Role) e.nextElement();
			if (!requiredRole.isImpliedBy(role, requiredCheckLoop)) {
				return (false);
			}
		}
		//check to see if we imply any of the basic roles (there must be at least one)
		e = basicMembers.elements();
		Role basicRole;
		while (e.hasMoreElements()) {
			basicRole = (Role) e.nextElement();
			if (basicRole.isImpliedBy(role, basicCheckLoop)) {
				return (true);
			}
		}
		return (false);
	}

}
