/*
* Copyright 2003-2010 Tufts University Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
/*
* VueAuthorizationManager.java
*
* Created on December 15, 2003, 11:02 AM
*/
package tufts.oki.authorization;
import java.util.*;
import osid.shared.*;
/**
* The authorization manager maintains three lists of object related to authorizating
* operations in the VUE system. These objects are VueAuthorization, VueFunction, and
* VueQualifier. As stated by the OKI OSID documentation on authorization, these objects
* can be viewed as the subject, verb, and direct object. The VueAuthorization indictes
* who has this authorization, the VueFunction defines what operation is allowed, and the
* VueQualifier places restrictions (if any) on the operation.
* <p>
* The AuthZMgr queries take two forms: Explicit
* and Implicit. The documentation indicates that explicit authorizations may be modified.
* It is assumed that explicit authorization have a function Id and
* qualifier id physically present in the Authorization instance (which allows them to be
* modified). This is opposed to authorizations which are valid due to inheritied qualifiers
* (ancestors of the instance), which is the implicit form of authorization.
* <p>
* This implementation of the AuthorizationManager does not include persistance of any kind.
* This means that all authorizations, functions, and qualifiers must be defined at run time
* by an application which uses it. Note also, that funtion types and qualifier types are
* not defined either.
*
* @author Mark Norton
*/
public class AuthorizationManager extends tufts.oki.OsidManager implements osid.authorization.AuthorizationManager {
private Vector auths = null; // The list of authorizations.
private Vector functions = null; // The list of known functions.
private Vector qualifiers = null; // The list of known qualifiers.
private Vector rootQualifiers = null; // The list of qualifier hierarchies.
private osid.shared.Agent user = null; // The default user of this authorization manager.
static public osid.shared.SharedManager sharedMgr = null; // SharedManager is cached.
/**
* Creates a new instance of VueAuthorizationManager. The OsidOwner provides a context
* which can be shared between OSID managers. The user-agent should be an authenticated
* agent who is (presumably) the user of this application session. SharedManager is cached
* due to the need of resolving agent instances versus their Id's.
*/
public AuthorizationManager() {
super();
this.auths = new Vector(100);
this.functions = new Vector(100);
this.qualifiers = new Vector(100);
this.rootQualifiers = new Vector(100);
}
/**
* Creates a new instance of VueAuthorizationManager. The OsidOwner provides a context
* which can be shared between OSID managers. The user-agent should be an authenticated
* agent who is (presumably) the user of this application session. SharedManager is cached
* due to the need of resolving agent instances versus their Id's.
*/
public AuthorizationManager(osid.OsidOwner owner, osid.shared.Agent user, osid.shared.SharedManager sharedMgr) {
super(owner);
this.user = user;
this.auths = new Vector(100);
this.functions = new Vector(100);
this.qualifiers = new Vector(100);
this.rootQualifiers = new Vector(100);
this.sharedMgr = sharedMgr;
}
/**
* Initialize the authorization manager. This should be called if the Authorization
* Manager is loaded by OsidLoader. It causes the default user to be initialized and
* the Shared Manager to be cached locally.
*
* @author Mark Norton
*/
public void initManager (osid.shared.Agent user, osid.shared.SharedManager sharedMgr) {
this.user = user;
this.sharedMgr = sharedMgr;
}
/**
* The documentation indicates that this check doesn't determine if the agent is
* referenced by the AZMgr, or is present in the shared manager. The MIT implementation
* checks for an agent of the Id in a database table. It returns true if the agent
* is "known" to the authorization manager. This implementation returns true if
* an agent of the Id given is present in the list of authorizations.
*
* @author Mark Norton
*/
public boolean agentExists(osid.shared.Id agentId) {
for (int i = 0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
try {
if (agentId.isEqual(az.getAgent().getId()))
return true;
}
catch (osid.shared.SharedException ex) {
return false;
}
catch (osid.authorization.AuthorizationException ex2) {
return false;
}
}
return false;
}
/**
* Return a new authorization given an agent, function, and qualifier. Use this version
* if the authorization doesn't have date bounds. Creates explicit authorizations.
*
* @author Mark Norton
*/
public osid.authorization.Authorization createAuthorization(osid.shared.Id agentId, osid.shared.Id functionId, osid.shared.Id qualifierId) {
return createDatedAuthorization (agentId, functionId, qualifierId, null, null);
}
/**
* Return a new authorization given an agent, function, and qualifier. Use this version if
* the authorization has date bounds. Creates explicit authorizations.
*
* @author Mark Norton
*/
public osid.authorization.Authorization createDatedAuthorization(osid.shared.Id agentId, osid.shared.Id functionId, osid.shared.Id qualifierId, java.util.Calendar effectiveDate, java.util.Calendar expirationDate) {
//System.out.println ("createDatedAuthorization - functionID: "+functionId);
osid.shared.Id authId = null;
try {
authId = sharedMgr.createId();
}
catch (osid.shared.SharedException ex) {}
osid.authorization.Function ftn = getFunction (functionId);
osid.authorization.Qualifier qual = getQualifier (qualifierId);
VueAuthorization az = new VueAuthorization (authId, agentId, ftn, qual, effectiveDate, expirationDate, true);
auths.add (az);
return (osid.authorization.Authorization) az;
}
/**
* Create a new function given a functionId, display name, description, function type, and hierarchy id.
*
* @author Mark Norton
*/
public osid.authorization.Function createFunction(osid.shared.Id functionId, String displayName, String description, osid.shared.Type functionType, osid.shared.Id qualifierHierarchyId) {
VueFunction ftn = new VueFunction (displayName, description, functionType, functionId, qualifierHierarchyId);
functions.add (ftn);
return (osid.authorization.Function) ftn;
}
/**
* Create a new qualifier given a Id, dislay name, description, qualifier type, and parent.
* The parent may be null, if there is no inheritance relationships.
*
* @author Mark Norton
*/
public osid.authorization.Qualifier createQualifier(osid.shared.Id qualifierId, String displayName, String description, osid.shared.Type qualifierType, osid.shared.Id parentId) {
VueQualifier parent = (VueQualifier) this.getQualifier(parentId);
VueQualifier qual = new VueQualifier (displayName, description, qualifierId, qualifierType, this, parent);
qualifiers.add (qual);
return qual;
}
/**
* Create a qualifier node and enter it as the root of a qualifier hierarchy. Since osid.hierarchy is not being
* used in this implementation, the qualifier node created is added to the list of root nodes. The qualifier
* hierarchy Id is not used and may be passed as null. Qualifier roots do not have parents.
*
* @author Mark Norton
*/
public osid.authorization.Qualifier createRootQualifier(osid.shared.Id qualifierId, String displayName, String description, osid.shared.Type qualifierType, osid.shared.Id qualifierHierarchyId) {
VueQualifier qual = new VueQualifier (displayName, description, qualifierId, qualifierType, null);
qualifiers.add (qual);
rootQualifiers.add (qual);
return qual;
}
/**
* Delete the authorization given by the identifier passed.
*
* @author Mark Norton
*/
public void deleteAuthorization(osid.shared.Id authorizationId) {
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
try {
if (authorizationId.isEqual(az.getId())) {
auths.remove(i);
}
}
catch (osid.shared.SharedException ex) {}
}
}
/**
* Delete the function given by its identifier. All authorizations based on this
* function are also deleted.
*
* @author Mark Norton
*/
public void deleteFunction(osid.shared.Id functionId) {
// Search for all authorizations based on this function and delete them.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
VueFunction ftn = (VueFunction) az.getFunction();
try {
if (functionId.isEqual (ftn.getId()))
auths.remove (i);
}
catch (osid.shared.SharedException ex) {}
}
// Search for the function and remove it from the list of known functions.
for (int j=0; j < functions.size(); j++) {
VueFunction ftn = (VueFunction) functions.elementAt(j);
try {
if (functionId.isEqual(ftn.getId()))
functions.remove(j);
}
catch (osid.shared.SharedException ex2) {}
}
}
/**
* Since deleting qualifiers has a serious impact on the trees that they are included
* in, deletion is not supported in this implementation.
*
* @author Mark Norton
*/
public void deleteQualifier(osid.shared.Id qualifierId) throws osid.authorization.AuthorizationException {
// Trees need to be repaired if qualifiers are deleted.
throw new osid.authorization.AuthorizationException (osid.authorization.AuthorizationException.UNIMPLEMENTED);
}
/**
* Returns all authorizations with the agent id, function id and qualifier id given.
* If the active flag is true, the authorizations must be within the activation dates.
*
* @author Mark Norton
*/
// agent-id, funtion-id, qualifier-id, active
public osid.authorization.AuthorizationIterator getAllAZs(osid.shared.Id agentId, osid.shared.Id functionId, osid.shared.Id qualifierId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the agent, function and qualifier, and is active, then add it to our final list.
if (az.hasAgent(agentId) && az.hasFunction(functionId) && az.hasQualifierOrAncestor(qualifierId)) {
if (isActiveNow && az.isActiveNow()) {
VueAuthorization azCopy = (VueAuthorization) az.clone();
authz.add (azCopy);
}
else if (isActiveNow == false) {
VueAuthorization azCopy = (VueAuthorization) az.clone();
authz.add (az);
}
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Returns all authorizations with the agent id, function type and qualifier id given.
* If the active flag is true, the authorizations must be within the activation dates.
*
* @author Mark Norton
*/
// agent-id, function-type, qualifier-id, active
public osid.authorization.AuthorizationIterator getAllAZsByFuncType(osid.shared.Id agentId, osid.shared.Type functionType, osid.shared.Id qualifierId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the agent, function and qualifier, and is active, then add it to our final list.
if (az.hasAgent(agentId) && az.hasFunctionType(functionType) && az.hasQualifierOrAncestor(qualifierId)) {
if (isActiveNow && az.isActiveNow()) {
VueAuthorization azCopy = (VueAuthorization) az.clone();
authz.add (azCopy);
}
else if (isActiveNow == false) {
VueAuthorization azCopy = (VueAuthorization) az.clone();
authz.add (az);
}
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Returns all authorizations with the function id and qualifier id given.
* If the active flag is true, the authorizations must be within the activation dates.
*
* @author Mark Norton
*/
// function-id, qualifier-id, active
public osid.authorization.AuthorizationIterator getAllUserAZs(osid.shared.Id functionId, osid.shared.Id qualifierId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the function and qualifier, and is active, then add it to our final list.
if (az.hasFunction(functionId) && az.hasQualifierOrAncestor(qualifierId)) {
if (isActiveNow && az.isActiveNow()) {
VueAuthorization azCopy = (VueAuthorization) az.clone();
authz.add (azCopy);
}
else if (isActiveNow == false) {
VueAuthorization azCopy = (VueAuthorization) az.clone();
authz.add (az);
}
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Returns all authorizations with the function type and qualifier id given.
* If the active flag is true, the authorizations must be within the activation dates.
*
* @author Mark Norton
*/
// agent-id, funtion-type, qualifier-id, active
public osid.authorization.AuthorizationIterator getAllUserAZsByFuncType(osid.shared.Type functionType, osid.shared.Id qualifierId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the function and qualifier, and is active, then add it to our final list.
if (az.hasFunctionType(functionType) && az.hasQualifierOrAncestor(qualifierId)) {
if (isActiveNow && az.isActiveNow()) {
VueAuthorization azCopy = (VueAuthorization) az.clone();
authz.add (azCopy);
}
else if (isActiveNow == false) {
VueAuthorization azCopy = (VueAuthorization) az.clone();
authz.add (az);
}
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Returns all explicit authorizations with the agent id, function id and qualifier id given.
* If the active flag is true, the authorizations must be within the activation dates.
*
* @author Mark Norton
*/
// agent-id, function-id, qualifier-id, active
public osid.authorization.AuthorizationIterator getExplicitAZs(osid.shared.Id agentId, osid.shared.Id functionId, osid.shared.Id qualifierId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the agent, function and qualifier, and is active, then add it to our final list.
if (az.hasAgent(agentId) && az.hasFunction(functionId) && az.hasQualifier(qualifierId)) {
if (isActiveNow && az.isActiveNow())
authz.add (az);
else if (isActiveNow == false)
authz.add (az);
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Returns all explicit authorizations with the agent id, function type and qualifier id given.
* If the active flag is true, the authorizations must be within the activation dates.
*
* @author Mark Norton
*/
// agent-id, function-type, qualifier-id, active
public osid.authorization.AuthorizationIterator getExplicitAZsByFuncType(osid.shared.Id agentId, osid.shared.Type functionType, osid.shared.Id qualifierId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the agent, function and qualifier, and is active, then add it to our final list.
if (az.hasAgent(agentId) && az.hasFunctionType(functionType) && az.hasQualifier(qualifierId)) {
if (isActiveNow && az.isActiveNow())
authz.add (az);
else if (isActiveNow == false)
authz.add (az);
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Returns all explicit authorizations with the function id and qualifier id given.
* If the active flag is true, the authorizations must be within the activation dates.
*
* @author Mark Norton
*/
// funtion-id, qualifier-id, active
public osid.authorization.AuthorizationIterator getExplicitUserAZs(osid.shared.Id functionId, osid.shared.Id qualifierId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the function and qualifier, and is active, then add it to our final list.
if (az.hasFunction(functionId) && az.hasQualifier(qualifierId)) {
if (isActiveNow && az.isActiveNow())
authz.add (az);
else if (isActiveNow == false)
authz.add (az);
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Returns all explicit authorizations with the function type and qualifier id given.
* If the active flag is true, the authorizations must be within the activation dates.
*
* @author Mark Norton
*/
// function-type, qualifier-id, active
public osid.authorization.AuthorizationIterator getExplicitUserAZsByFuncType(osid.shared.Type functionType, osid.shared.Id qualifierId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the function and qualifier, and is active, then add it to our final list.
if (az.hasFunctionType(functionType) && az.hasQualifier(qualifierId)) {
if (isActiveNow && az.isActiveNow())
authz.add (az);
else if (isActiveNow == false)
authz.add (az);
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Get all the authorizations for a specified user agent.
* <p>
* Note that this method is an extension to osid.authorization.
*
* @author Mark Norton
*/
public osid.authorization.AuthorizationIterator getAllExplicitAZs(osid.shared.Id agentId, boolean isActiveNow) {
Vector authz = new Vector(100);
// Iterate over all known authorizations.
System.out.println ("getAllExplicitAZs: Authorization count: " + auths.size());
for (int i=0; i < auths.size(); i++) {
VueAuthorization az = (VueAuthorization) auths.elementAt(i);
// If the authorization has the agent and is active, then add it to our final list.
if (az.hasAgent(agentId)) {
if (isActiveNow && az.isActiveNow())
authz.add (az);
else if (isActiveNow == false)
authz.add (az);
}
}
return (osid.authorization.AuthorizationIterator) new VueAuthorizationIterator (authz);
}
/**
* Return the Function given an function Id.
*
* @author Mark Norton
*/
public osid.authorization.Function getFunction(osid.shared.Id functionId) {
osid.authorization.Function foundFtn = null;
VueFunctionIterator it = new VueFunctionIterator (functions);
while (it.hasNext()) {
osid.authorization.Function ftn = it.next();
osid.shared.Id id = ((VueFunction)ftn).getId();
try {
if (id.isEqual(functionId)) {
foundFtn = ftn;
break;
}
}
catch (osid.shared.SharedException ex) {}
}
return foundFtn;
}
/**
* Return an iterator which lists the known function types.
*
* @author Mark Norton
*/
public osid.shared.TypeIterator getFunctionTypes() {
return new tufts.oki.shared.TypeIterator (tufts.oki.authorization.VueFunctionType.functionTypes);
}
/**
* Return an iterator which lists the currently defined functions.
*
* @author Mark Norton
*/
public osid.authorization.FunctionIterator getFunctions(osid.shared.Type functionType) {
return new VueFunctionIterator (functions);
}
/**
* Return the qualifier who's id is given.
*
* @author Mark Norton
*/
public osid.authorization.Qualifier getQualifier(osid.shared.Id qualifierId) {
osid.authorization.Qualifier foundQual = null;
VueQualifierIterator it = new VueQualifierIterator (qualifiers);
while (it.hasNext()) {
osid.authorization.Qualifier qual = it.next();
osid.shared.Id id = ((VueQualifier)qual).getId();
try {
if (id.isEqual(qualifierId)) {
foundQual = qual;
break;
}
}
catch (osid.shared.SharedException ex) {}
}
return foundQual;
}
/**
* Return an interator for the children of the qualfier given by it's Id.
*
* @author Mark Norton
*/
public osid.authorization.QualifierIterator getQualifierChildren(osid.shared.Id qualifierId) {
Vector children = new Vector(10);
for (int i = 0; i < this.qualifiers.size(); i++) {
VueQualifier qual = (VueQualifier) qualifiers.elementAt(i);
if (qual.isChildOf (qualifierId)) {
children.add (qual);
}
}
return (osid.authorization.QualifierIterator) new VueQualifierIterator (children);
}
/**
* Return an iterator for all descendants of the qualfier given by it's Id.
*
* @author Mark Norton
*/
public osid.authorization.QualifierIterator getQualifierDescendants(osid.shared.Id qualifierId) {
Vector children = new Vector(10);
for (int i = 0; i < this.qualifiers.size(); i++) {
VueQualifier qual = (VueQualifier) qualifiers.elementAt(i);
if (qual.isDescendantOf (qualifierId)) {
children.add (qual);
}
}
return (osid.authorization.QualifierIterator) new VueQualifierIterator (children);
}
/**
* Return an iterator for the list of root qualifier hierarchy Ids.
*
* @author Mark Norton
*/
public osid.shared.IdIterator getQualifierHierarchies() {
Vector roots = new Vector (rootQualifiers.size());
for (int i=0; i < rootQualifiers.size(); i++) {
VueQualifier rt = (VueQualifier) rootQualifiers.elementAt(i);
roots.add (rt.getId());
}
return new tufts.oki.shared.IdIterator (roots);
}
/**
* Return an iterator for the list of known qualifier types.
*
* @author Mark Norton
*/
public osid.shared.TypeIterator getQualifierTypes() {
return new tufts.oki.shared.TypeIterator (tufts.oki.authorization.VueQualifierType.qualifierTypes);
}
/**
* This method is intended to return the roots associated with a particular hiearchy. Since
* this implementation doesn't use osid.hierarchy, it returns an iterator for the known
* qualifier roots. The qualifierHierarchyId is ignored and may be passed as null.
*
* @author Mark Norton
*/
public osid.authorization.QualifierIterator getRootQualifiers(osid.shared.Id qualifierHierarchyId) {
return (osid.authorization.QualifierIterator) new VueQualifierIterator (this.rootQualifiers);
}
/**
* Return an iterator which lists all agents who are authorized to perform the function on the qualifier
* given. The isActive flag is used to determine if all authorizations or only those which are active
* should be included.
*
* @author Mark Norton
*/
public osid.shared.AgentIterator getWhoCanDo(osid.shared.Id functionId, osid.shared.Id qualifierId, boolean isActiveNow) throws osid.authorization.AuthorizationException {
// Get all authorizations for this function, and qualifier.
VueAuthorizationIterator it = (VueAuthorizationIterator) this.getAllUserAZs (functionId, qualifierId, isActiveNow);
// Iterate over those authorizations and extract a unique list of agents.
Vector agents = new Vector(100);
while (it.hasNext()) {
VueAuthorization az = (VueAuthorization) it.next();
osid.shared.Agent ag = az.getAgent();
if (agents.indexOf (ag) == -1)
agents.add(ag);
}
return new tufts.oki.shared.AgentIterator(agents);
}
/**
* Return true if the agent provided is currently authorized to perform the function on
* the qualifer provided.
*
* @author Mark Norton
*/
public boolean isAuthorized(osid.shared.Id agentId, osid.shared.Id functionId, osid.shared.Id qualifierId) {
// Get all authorizations for this agent, function, and qualifier currently active.
VueAuthorizationIterator it = (VueAuthorizationIterator) this.getAllAZs(agentId, functionId, qualifierId, true);
// If there is one or more, then the agent is authorized.
if (it.hasNext())
return true;
else
return false;
}
/**
* Return true if the default user is currently authorized to perform the function on
* the qualifer provided.
*
* @author Mark Norton
*/
public boolean isUserAuthorized(osid.shared.Id functionId, osid.shared.Id qualifierId) throws osid.authorization.AuthorizationException {
osid.shared.Id userId = null;
// Check to see that there is a valid default user agent.
if (this.user == null)
throw new osid.authorization.AuthorizationException ("Unknown default user.");
// If so, use it to see if that agent is authorized to perform the function on the qualifier.
else {
try {
userId = this.user.getId();
}
catch (osid.shared.SharedException ex) {}
return isAuthorized (userId, functionId, qualifierId);
}
}
}