diff --git a/projects/cadcAccessControl/build.xml b/projects/cadcAccessControl/build.xml new file mode 100644 index 0000000000000000000000000000000000000000..25762598f1a728a912d6fe99a1a6c27352a4e9cf --- /dev/null +++ b/projects/cadcAccessControl/build.xml @@ -0,0 +1,123 @@ +<!-- +************************************************************************ +******************* CANADIAN ASTRONOMY DATA CENTRE ******************* +************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** +* +* (c) 2009. (c) 2009. +* Government of Canada Gouvernement du Canada +* National Research Council Conseil national de recherches +* Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 +* All rights reserved Tous droits réservés +* +* NRC disclaims any warranties, Le CNRC dénie toute garantie +* expressed, implied, or énoncée, implicite ou légale, +* statutory, of any kind with de quelque nature que ce +* respect to the software, soit, concernant le logiciel, +* including without limitation y compris sans restriction +* any warranty of merchantability toute garantie de valeur +* or fitness for a particular marchande ou de pertinence +* purpose. NRC shall not be pour un usage particulier. +* liable in any event for any Le CNRC ne pourra en aucun cas +* damages, whether direct or être tenu responsable de tout +* indirect, special or general, dommage, direct ou indirect, +* consequential or incidental, particulier ou général, +* arising from the use of the accessoire ou fortuit, résultant +* software. Neither the name de l'utilisation du logiciel. Ni +* of the National Research le nom du Conseil National de +* Council of Canada nor the Recherches du Canada ni les noms +* names of its contributors may de ses participants ne peuvent +* be used to endorse or promote être utilisés pour approuver ou +* products derived from this promouvoir les produits dérivés +* software without specific prior de ce logiciel sans autorisation +* written permission. préalable et particulière +* par écrit. +* +* This file is part of the Ce fichier fait partie du projet +* OpenCADC project. OpenCADC. +* +* OpenCADC is free software: OpenCADC est un logiciel libre ; +* you can redistribute it and/or vous pouvez le redistribuer ou le +* modify it under the terms of modifier suivant les termes de +* the GNU Affero General Public la “GNU Affero General Public +* License as published by the License” telle que publiée +* Free Software Foundation, par la Free Software Foundation +* either version 3 of the : soit la version 3 de cette +* License, or (at your option) licence, soit (à votre gré) +* any later version. toute version ultérieure. +* +* OpenCADC is distributed in the OpenCADC est distribué +* hope that it will be useful, dans l’espoir qu’il vous +* but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE +* without even the implied GARANTIE : sans même la garantie +* warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ +* or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF +* PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence +* General Public License for Générale Publique GNU Affero +* more details. pour plus de détails. +* +* You should have received Vous devriez avoir reçu une +* a copy of the GNU Affero copie de la Licence Générale +* General Public License along Publique GNU Affero avec +* with OpenCADC. If not, see OpenCADC ; si ce n’est +* <http://www.gnu.org/licenses/>. pas le cas, consultez : +* <http://www.gnu.org/licenses/>. +* +* $Revision: 4 $ +* +************************************************************************ +--> + + +<!DOCTYPE project> +<project default="build" basedir="."> + <property environment="env"/> + <property file="local.build.properties" /> + + <!-- site-specific build properties or overrides of values in opencadc.properties --> + <property file="${env.CADC_PREFIX}/etc/local.properties" /> + + <!-- site-specific targets, e.g. install, cannot duplicate those in opencadc.targets.xml --> + <import file="${env.CADC_PREFIX}/etc/local.targets.xml" optional="true" /> + + <!-- default properties and targets --> + <property file="${env.CADC_PREFIX}/etc/opencadc.properties" /> + <import file="${env.CADC_PREFIX}/etc/opencadc.targets.xml"/> + + <!-- developer convenience: place for extra targets and properties --> + <import file="extras.xml" optional="true" /> + + <property name="project" value="cadcAccessControl" /> + + <property name="cadcUtil" value="${lib}/cadcUtil.jar" /> + + <property name="jars" value="${cadcUtil}:${ext.lib}/log4j.jar" /> + + <target name="build" depends="compile"> + <jar jarfile="${build}/lib/${project}.jar" + basedir="${build}/class" + update="no"> + <include name="ca/nrc/cadc/**" /> + </jar> + </target> + + <!-- JAR files needed to run the test suite --> + <property name="testingJars" value="${build}/class:${jars}:${ext.lib}/junit.jar:${ext.lib}/xerces.jar:${ext.dev}/easymock.jar:${ext.dev}/cglib.jar:${ext.dev}/objenesis.jar:${ext.dev}/asm.jar" /> + + <target name="test" depends="compile-test"> + <echo message="Running test" /> + + <!-- Run the junit test suite --> + <echo message="Running test suite..." /> + <junit printsummary="yes" haltonfailure="yes" fork="yes"> + <classpath> + <pathelement path="${build}/class"/> + <pathelement path="${build}/test/class"/> + <pathelement path="${testingJars}"/> + </classpath> + <test name="ca.nrc.cadc.ac.UserTest" /> + <test name="ca.nrc.cadc.ac.GroupTest" /> + <formatter type="plain" usefile="false" /> + </junit> + </target> + +</project> diff --git a/projects/cadcAccessControl/doc/AccessControl.png b/projects/cadcAccessControl/doc/AccessControl.png new file mode 100644 index 0000000000000000000000000000000000000000..52bcea3a9f84a12817a27af6e2e3f7623e5b6b6f Binary files /dev/null and b/projects/cadcAccessControl/doc/AccessControl.png differ diff --git a/projects/cadcAccessControl/doc/auth.html b/projects/cadcAccessControl/doc/auth.html new file mode 100644 index 0000000000000000000000000000000000000000..8608f3dde4f3f9b468e08ac6e1e5d5cd144b02b9 --- /dev/null +++ b/projects/cadcAccessControl/doc/auth.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<title> + CADC User Authorization Model +</title> +</head> + +<body> + +<div class="main"> + +<h1>CADC User Authorization Model</h1> + +<p>The CADC User Authorization Model is a model for representing CADC users and groups. The model is used primarily in the GMS and Users Web services. +</p> + +<a href="uml/UserAuth.png"> <img src="uml/UserAuth.png" alt="CADC User Authorization Model"></a> + +<h2>User Class Features </h2> +In the system, a user is uniquely identified by one Principal (in CADC's case that is of type NumericPrincipal) but can have a number of other identities for different contexts: +<ul> + <li>HttpPrincipal: Web user identity associated with Simple HHTP User Password access.</li> + <li>X500Principal: X509 certificate identity. </li> + <li>NumericPrincipal: An numeric identity associated with a user. Typically, used internally within a system.</li> + <li>OpenIdPrincipal: An OpenID identity. </li> +</ul> + +<h2>Group Class Features</h2> +Groups represet associations of users. Members of groups can be groups of users or simple users. groupWrite and groupRead represent the groups that have read and read-and-write permissions to the current group. + +</body> +</html> diff --git a/projects/cadcAccessControl/doc/auth.zargo b/projects/cadcAccessControl/doc/auth.zargo new file mode 100644 index 0000000000000000000000000000000000000000..57aa2846f75e01db9d2e032775009c297468d492 Binary files /dev/null and b/projects/cadcAccessControl/doc/auth.zargo differ diff --git a/projects/cadcAccessControl/doc/uml/UserAuth.png b/projects/cadcAccessControl/doc/uml/UserAuth.png new file mode 100644 index 0000000000000000000000000000000000000000..64354ac504dff79d1f26a7e0e17100cb82bac64a Binary files /dev/null and b/projects/cadcAccessControl/doc/uml/UserAuth.png differ diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/Group.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/Group.java new file mode 100644 index 0000000000000000000000000000000000000000..e89798147a80a826b7c03c819ed51ac35f48748a --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/Group.java @@ -0,0 +1,193 @@ +/* + ************************************************************************ + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + * + * (c) 2014. (c) 2014. + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits reserves + * + * NRC disclaims any warranties Le CNRC denie toute garantie + * expressed, implied, or statu- enoncee, implicite ou legale, + * tory, of any kind with respect de quelque nature que se soit, + * to the software, including concernant le logiciel, y com- + * without limitation any war- pris sans restriction toute + * ranty of merchantability or garantie de valeur marchande + * fitness for a particular pur- ou de pertinence pour un usage + * pose. NRC shall not be liable particulier. Le CNRC ne + * in any event for any damages, pourra en aucun cas etre tenu + * whether direct or indirect, responsable de tout dommage, + * special or general, consequen- direct ou indirect, particul- + * tial or incidental, arising ier ou general, accessoire ou + * from the use of the software. fortuit, resultant de l'utili- + * sation du logiciel. + * + * + * @author adriand + * + * @version $Revision: $ + * + * + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + ************************************************************************ + */ + +package ca.nrc.cadc.ac; + +import java.security.Principal; +import java.util.HashSet; +import java.util.Set; + +public class Group +{ + private String groupID; + + private User<? extends Principal> owner; + + // group's properties + protected Set<GroupProperty> properties = new HashSet<GroupProperty>(); + + // group's user members + private Set<User<? extends Principal>> userMembers = + new HashSet<User<? extends Principal>>(); + // group's group members + private Set<Group> groupMembers = new HashSet<Group>(); + + public String description; + + // Access Control properties + /** + * group that can read details of this group + * Note: this class does not enforce any access control rules + */ + public Group groupRead; + /** + * group that can read and write details of this group + * Note: this class does not enforce any access control rules + */ + public Group groupWrite; + /** + * flag that show whether the details of this group are publicly readable + * Note: this class does not enforce any access control rules + */ + public boolean publicRead = false; + + /** + * Ctor. + * + * @param groupID + * Unique ID for the group. Must be a valid URI fragment component, + * so it's restricted to alphanumeric and "-", ".","_","~" characters. + * @param owner + * Owner/Creator of the group. + */ + public Group(final String groupID, + final User<? extends Principal> owner) + { + if(groupID == null) + { + throw new IllegalArgumentException("Null groupID"); + } + + // check for invalid path characters in groupID + if(!groupID.matches("^[a-zA-Z0-9\\-\\.~_]*$")) + throw new IllegalArgumentException("Invalid group ID " + groupID + + ": may not contain space ( ), slash (/), escape (\\), or percent (%)"); + + this.groupID = groupID; + if(owner == null) + { + throw new IllegalArgumentException("Null owner"); + } + this.owner = owner; + } + + /** + * Obtain this Group's unique id. + * + * @return String group ID. + */ + public String getID() + { + return groupID; + } + + /** + * Obtain this group's owner + * @return owner of the group + */ + public User<? extends Principal> getOwner() + { + return owner; + } + + /** + * + * @return a set of properties associated with a group + */ + public Set<GroupProperty> getProperties() + { + return properties; + } + + /** + * + * @return individual user members of this group + */ + public Set<User<? extends Principal>> getUserMembers() + { + return userMembers; + } + + /** + * + * @return group members of this group + */ + public Set<Group> getGroupMembers() + { + return groupMembers; + } + + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + return 31 + groupID.hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (!(obj instanceof Group)) + { + return false; + } + Group other = (Group) obj; + if (!groupID.equals(other.groupID)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + groupID + "]"; + } + +} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupProperty.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupProperty.java new file mode 100644 index 0000000000000000000000000000000000000000..5ddfa8016e0e75077bf34bac7b7b02b32291d4bc --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupProperty.java @@ -0,0 +1,174 @@ +/* +************************************************************************ +******************* CANADIAN ASTRONOMY DATA CENTRE ******************* +************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** +* +* (c) 2009. (c) 2009. +* Government of Canada Gouvernement du Canada +* National Research Council Conseil national de recherches +* Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 +* All rights reserved Tous droits réservés +* +* NRC disclaims any warranties, Le CNRC dénie toute garantie +* expressed, implied, or énoncée, implicite ou légale, +* statutory, of any kind with de quelque nature que ce +* respect to the software, soit, concernant le logiciel, +* including without limitation y compris sans restriction +* any warranty of merchantability toute garantie de valeur +* or fitness for a particular marchande ou de pertinence +* purpose. NRC shall not be pour un usage particulier. +* liable in any event for any Le CNRC ne pourra en aucun cas +* damages, whether direct or être tenu responsable de tout +* indirect, special or general, dommage, direct ou indirect, +* consequential or incidental, particulier ou général, +* arising from the use of the accessoire ou fortuit, résultant +* software. Neither the name de l'utilisation du logiciel. Ni +* of the National Research le nom du Conseil National de +* Council of Canada nor the Recherches du Canada ni les noms +* names of its contributors may de ses participants ne peuvent +* be used to endorse or promote être utilisés pour approuver ou +* products derived from this promouvoir les produits dérivés +* software without specific prior de ce logiciel sans autorisation +* written permission. préalable et particulière +* par écrit. +* +* This file is part of the Ce fichier fait partie du projet +* OpenCADC project. OpenCADC. +* +* OpenCADC is free software: OpenCADC est un logiciel libre ; +* you can redistribute it and/or vous pouvez le redistribuer ou le +* modify it under the terms of modifier suivant les termes de +* the GNU Affero General Public la “GNU Affero General Public +* License as published by the License” telle que publiée +* Free Software Foundation, par la Free Software Foundation +* either version 3 of the : soit la version 3 de cette +* License, or (at your option) licence, soit (à votre gré) +* any later version. toute version ultérieure. +* +* OpenCADC is distributed in the OpenCADC est distribué +* hope that it will be useful, dans l’espoir qu’il vous +* but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE +* without even the implied GARANTIE : sans même la garantie +* warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ +* or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF +* PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence +* General Public License for Générale Publique GNU Affero +* more details. pour plus de détails. +* +* You should have received Vous devriez avoir reçu une +* a copy of the GNU Affero copie de la Licence Générale +* General Public License along Publique GNU Affero avec +* with OpenCADC. If not, see OpenCADC ; si ce n’est +* <http://www.gnu.org/licenses/>. pas le cas, consultez : +* <http://www.gnu.org/licenses/>. +* +* +************************************************************************ +*/ + +package ca.nrc.cadc.ac; + +/** + * A property representing metadata for a group. + * + */ +public class GroupProperty +{ + // The property identifier + private String key; + + // The value of the property + private Object value; + + // true if the property cannot be modified. + private boolean readOnly; + + + /** + * GroupProperty constructor. + * + * @param key The property key. Cannot be null. + * @param value The property value. + */ + public GroupProperty(String key, Object value, boolean readOnly) + { + if(key == null) + { + throw new IllegalArgumentException("Null key"); + } + if(value == null) + { + throw new IllegalArgumentException("Null value"); + } + this.key = key; + this.value = value; + this.readOnly = readOnly; + } + + /** + * @return property key + */ + public String getKey() + { + return key; + } + + /** + * @return value + */ + public Object getValue() + { + return value; + } + + /** + * @return read only + */ + public boolean isReadOnly() + { + return readOnly; + } + + + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (!(obj instanceof GroupProperty)) + { + return false; + } + GroupProperty other = (GroupProperty) obj; + return key.equals(other.key); + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + key + ": " + value + "]"; + } + +} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/PersonalDetails.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/PersonalDetails.java new file mode 100644 index 0000000000000000000000000000000000000000..a5ca2405f39ea169147858ebeba054c9963e08eb --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/PersonalDetails.java @@ -0,0 +1,203 @@ +/* + ************************************************************************ + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + * + * (c) 2014. (c) 2014. + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits reserves + * + * NRC disclaims any warranties Le CNRC denie toute garantie + * expressed, implied, or statu- enoncee, implicite ou legale, + * tory, of any kind with respect de quelque nature que se soit, + * to the software, including concernant le logiciel, y com- + * without limitation any war- pris sans restriction toute + * ranty of merchantability or garantie de valeur marchande + * fitness for a particular pur- ou de pertinence pour un usage + * pose. NRC shall not be liable particulier. Le CNRC ne + * in any event for any damages, pourra en aucun cas etre tenu + * whether direct or indirect, responsable de tout dommage, + * special or general, consequen- direct ou indirect, particul- + * tial or incidental, arising ier ou general, accessoire ou + * from the use of the software. fortuit, resultant de l'utili- + * sation du logiciel. + * + * + * @author adriand + * + * @version $Revision: $ + * + * + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + ************************************************************************ + */ + +package ca.nrc.cadc.ac; + +public class PersonalDetails implements UserDetails +{ + private String firstName; + private String lastName; + private String email; + private String address; + private String institute; + private String city; + private String country; + + public PersonalDetails(String firstName, String lastName, String email, + String address, String institute, String city, String country) + { + if (firstName == null) + { + throw new IllegalArgumentException("null firstName"); + } + if (lastName == null) + { + throw new IllegalArgumentException("null lastName"); + } + if (email == null) + { + throw new IllegalArgumentException("null email"); + } + + if (address == null) + { + throw new IllegalArgumentException("null address"); + } + if (institute == null) + { + throw new IllegalArgumentException("null institute"); + } + if (city == null) + { + throw new IllegalArgumentException("null city"); + } + if (country == null) + { + throw new IllegalArgumentException("null country"); + } + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + this.address = address; + this.institute = institute; + this.city = city; + this.country = country; + } + + public String getFirstName() + { + return firstName; + } + + public String getLastName() + { + return lastName; + } + + public String getEmail() + { + return email; + } + + public String getAddress() + { + return address; + } + + public String getInstitute() + { + return institute; + } + + public String getCity() + { + return city; + } + + public String getCountry() + { + return country; + } + + /* (non-Javadoc) + * @see ca.nrc.cadc.auth.model.UserDetails#hashCode() + */ + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + address.hashCode(); + result = prime * result + city.hashCode(); + result = prime * result + country.hashCode(); + result = prime * result + email.hashCode(); + result = prime * result + firstName.hashCode(); + result = prime * result + institute.hashCode(); + result = prime * result + lastName.hashCode(); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (!(obj instanceof PersonalDetails)) + { + return false; + } + PersonalDetails other = (PersonalDetails) obj; + if (!firstName.equals(other.firstName)) + { + return false; + } + if (!lastName.equals(other.lastName)) + { + return false; + } + if (!email.equals(other.email)) + { + return false; + } + if (!institute.equals(other.institute)) + { + return false; + } + if (!address.equals(other.address)) + { + return false; + } + if (!city.equals(other.city)) + { + return false; + } + if (!country.equals(other.country)) + { + return false; + } + return true; + } + + /* (non-Javadoc) + * @see ca.nrc.cadc.auth.model.UserDetails#toString() + */ + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + firstName + ", " + + lastName + ", " + email + ", " + address + ", " + + institute + ", " + city + ", " + country + "]"; + } +} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/PosixDetails.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/PosixDetails.java new file mode 100644 index 0000000000000000000000000000000000000000..12d8dec1b4560d9d3b68a681dc36793d51c81247 --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/PosixDetails.java @@ -0,0 +1,152 @@ +/* + ************************************************************************ + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + * + * (c) 2014. (c) 2014. + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits reserves + * + * NRC disclaims any warranties Le CNRC denie toute garantie + * expressed, implied, or statu- enoncee, implicite ou legale, + * tory, of any kind with respect de quelque nature que se soit, + * to the software, including concernant le logiciel, y com- + * without limitation any war- pris sans restriction toute + * ranty of merchantability or garantie de valeur marchande + * fitness for a particular pur- ou de pertinence pour un usage + * pose. NRC shall not be liable particulier. Le CNRC ne + * in any event for any damages, pourra en aucun cas etre tenu + * whether direct or indirect, responsable de tout dommage, + * special or general, consequen- direct ou indirect, particul- + * tial or incidental, arising ier ou general, accessoire ou + * from the use of the software. fortuit, resultant de l'utili- + * sation du logiciel. + * + * + * @author adriand + * + * @version $Revision: $ + * + * + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + ************************************************************************ + */ + +package ca.nrc.cadc.ac; + +/** + * Represents the posix account details associated with a user account. + */ +public class PosixDetails implements UserDetails +{ + private long uid; + private long gid; + private String homeDirectory; + + /** + * user login shell + */ + public String loginShell; + + /** + * + * @param uid + * posix uid + * @param gid + * posix gid + * @param homeDirectory + * home directory + */ + public PosixDetails(long uid, long gid, String homeDirectory) + { + this.uid = uid; + this.gid = gid; + if (homeDirectory == null) + { + throw new IllegalArgumentException( + "null home directory in POSIX details"); + } + this.homeDirectory = homeDirectory; + } + + /** + * @return the uid + */ + public long getUid() + { + return uid; + } + + /** + * @return the gid + */ + public long getGid() + { + return gid; + } + + /** + * @return the homeDirectory + */ + public String getHomeDirectory() + { + return homeDirectory; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + (int) (gid ^ (gid >>> 32)); + result = prime * result + homeDirectory.hashCode(); + result = prime * result + (int) (uid ^ (uid >>> 32)); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (!(obj instanceof PosixDetails)) + { + return false; + } + PosixDetails other = (PosixDetails) obj; + if (gid != other.gid) + { + return false; + } + + if (!homeDirectory.equals(other.homeDirectory)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + uid + ", " + gid + ", " + + homeDirectory + "]"; + } + +} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/User.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/User.java new file mode 100644 index 0000000000000000000000000000000000000000..3174d0136d7d2fbbc5bdd0a4fa5e758118ae0ded --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/User.java @@ -0,0 +1,118 @@ +/* + ************************************************************************ + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + * + * (c) 2014. (c) 2014. + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits reserves + * + * NRC disclaims any warranties Le CNRC denie toute garantie + * expressed, implied, or statu- enoncee, implicite ou legale, + * tory, of any kind with respect de quelque nature que se soit, + * to the software, including concernant le logiciel, y com- + * without limitation any war- pris sans restriction toute + * ranty of merchantability or garantie de valeur marchande + * fitness for a particular pur- ou de pertinence pour un usage + * pose. NRC shall not be liable particulier. Le CNRC ne + * in any event for any damages, pourra en aucun cas etre tenu + * whether direct or indirect, responsable de tout dommage, + * special or general, consequen- direct ou indirect, particul- + * tial or incidental, arising ier ou general, accessoire ou + * from the use of the software. fortuit, resultant de l'utili- + * sation du logiciel. + * + * + * @author adriand + * + * @version $Revision: $ + * + * + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + ************************************************************************ + */ + + + +package ca.nrc.cadc.ac; + +import java.security.Principal; +import java.util.HashSet; +import java.util.Set; + +public class User<T extends Principal> +{ + private T userID; + + private Set<Principal> principals = new HashSet<Principal>(); + + public Set<UserDetails> details = new HashSet<UserDetails>(); + + + public User(final T userID) + { + if(userID == null) + { + throw new IllegalArgumentException("null userID"); + } + this.userID = userID; + } + + + public Set<Principal> getPrincipals() + { + return principals; + } + + public T getUserID() + { + return userID; + } + + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + userID.hashCode(); + return result; + } + + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + User<?> other = (User<?>) obj; + if (!userID.equals(other.userID)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + userID.getName() + "]"; + } + +} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserDetails.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserDetails.java new file mode 100644 index 0000000000000000000000000000000000000000..d03035c1be2377d4de5ebd9174729138006da364 --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserDetails.java @@ -0,0 +1,56 @@ +/* + ************************************************************************ + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + * + * (c) 2014. (c) 2014. + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits reserves + * + * NRC disclaims any warranties Le CNRC denie toute garantie + * expressed, implied, or statu- enoncee, implicite ou legale, + * tory, of any kind with respect de quelque nature que se soit, + * to the software, including concernant le logiciel, y com- + * without limitation any war- pris sans restriction toute + * ranty of merchantability or garantie de valeur marchande + * fitness for a particular pur- ou de pertinence pour un usage + * pose. NRC shall not be liable particulier. Le CNRC ne + * in any event for any damages, pourra en aucun cas etre tenu + * whether direct or indirect, responsable de tout dommage, + * special or general, consequen- direct ou indirect, particul- + * tial or incidental, arising ier ou general, accessoire ou + * from the use of the software. fortuit, resultant de l'utili- + * sation du logiciel. + * + * + * @author adriand + * + * @version $Revision: $ + * + * + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + ************************************************************************ + */ + +package ca.nrc.cadc.ac; + +public interface UserDetails +{ + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + public int hashCode(); + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj); + + public String toString(); + +} diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3e48c9a0c5cb5a5446d4645d7470db1951d7b37c --- /dev/null +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupTest.java @@ -0,0 +1,163 @@ +/* + ************************************************************************ + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + * + * (c) 2014. (c) 2014. + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits reserves + * + * NRC disclaims any warranties Le CNRC denie toute garantie + * expressed, implied, or statu- enoncee, implicite ou legale, + * tory, of any kind with respect de quelque nature que se soit, + * to the software, including concernant le logiciel, y com- + * without limitation any war- pris sans restriction toute + * ranty of merchantability or garantie de valeur marchande + * fitness for a particular pur- ou de pertinence pour un usage + * pose. NRC shall not be liable particulier. Le CNRC ne + * in any event for any damages, pourra en aucun cas etre tenu + * whether direct or indirect, responsable de tout dommage, + * special or general, consequen- direct ou indirect, particul- + * tial or incidental, arising ier ou general, accessoire ou + * from the use of the software. fortuit, resultant de l'utili- + * sation du logiciel. + * + * + * @author adriand + * + * @version $Revision: $ + * + * + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + ************************************************************************ + */ + + + +package ca.nrc.cadc.ac; + +import org.apache.log4j.Logger; +import org.junit.Test; +import static org.junit.Assert.*; + +import ca.nrc.cadc.auth.HttpPrincipal; + +public class GroupTest +{ + private static Logger log = Logger.getLogger(GroupTest.class); + + @Test + public void simpleGroupTest() throws Exception + { + + User<HttpPrincipal> owner = new User<HttpPrincipal>(new HttpPrincipal("owner")); + Group group1 = new Group("TestGroup", owner); + User<HttpPrincipal> user = new User<HttpPrincipal>(new HttpPrincipal("user")); + + group1.getUserMembers().add(user); + assertEquals(1, group1.getUserMembers().size()); + + Group group2 = group1; + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1, group2); + assertTrue(group1 == group2); + + group2 = new Group("TestGroup", owner); + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1,group2); + + group2.getUserMembers().add(user); + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1,group2); + + group1.getGroupMembers().add(group2); + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1,group2); + + group1.description = "Test group"; + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1,group2); + + // group read and write equality tests + group1.groupRead = group2; + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1,group2); + + // group write equality tests + group1.groupWrite = group2; + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1,group2); + + group1.publicRead = true; + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1,group2); + + group2 = new Group("NewTestGroup-._~.", owner); + assertFalse(group1.hashCode() == group2.hashCode()); + assertFalse(group1.equals(group2)); + + // test toString + System.out.println(group1); + } + + @Test + public void exceptionTests() + { + boolean thrown = false; + try + { + new Group(null, new User<HttpPrincipal>(new HttpPrincipal("owner"))); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + + thrown = false; + try + { + new Group("NewTestGroup", null); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + // invavlid group IDs + thrown = false; + try + { + new Group("New/Test/Group", new User<HttpPrincipal>(new HttpPrincipal("owner"))); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new Group("New%Test%Group", new User<HttpPrincipal>(new HttpPrincipal("owner"))); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new Group("New\\Test\\Group", new User<HttpPrincipal>(new HttpPrincipal("owner"))); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + } +} diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/UserTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/UserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0fce989ccfd154bcb79f29134780d0d486ec9a21 --- /dev/null +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/UserTest.java @@ -0,0 +1,233 @@ +/* + ************************************************************************ + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + * + * (c) 2014. (c) 2014. + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits reserves + * + * NRC disclaims any warranties Le CNRC denie toute garantie + * expressed, implied, or statu- enoncee, implicite ou legale, + * tory, of any kind with respect de quelque nature que se soit, + * to the software, including concernant le logiciel, y com- + * without limitation any war- pris sans restriction toute + * ranty of merchantability or garantie de valeur marchande + * fitness for a particular pur- ou de pertinence pour un usage + * pose. NRC shall not be liable particulier. Le CNRC ne + * in any event for any damages, pourra en aucun cas etre tenu + * whether direct or indirect, responsable de tout dommage, + * special or general, consequen- direct ou indirect, particul- + * tial or incidental, arising ier ou general, accessoire ou + * from the use of the software. fortuit, resultant de l'utili- + * sation du logiciel. + * + * + * @author adriand + * + * @version $Revision: $ + * + * + **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** + ************************************************************************ + */ + +package ca.nrc.cadc.ac; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import javax.security.auth.x500.X500Principal; + +import org.apache.log4j.Logger; +import org.junit.Test; + +import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.NumericPrincipal; +import ca.nrc.cadc.auth.OpenIdPrincipal; + +public class UserTest +{ + private static Logger log = Logger.getLogger(UserTest.class); + + @Test + public void simpleEqualityTests() throws Exception + { + + User<HttpPrincipal> user1 = new User<HttpPrincipal>( + new HttpPrincipal("user1")); + User<HttpPrincipal> user2 = user1; + assertEquals(user1, user2); + assertEquals(user1.hashCode(), user2.hashCode()); + + user2 = new User<HttpPrincipal>(new HttpPrincipal("user1")); + assertEquals(user1, user2); + assertEquals(user1.hashCode(), user2.hashCode()); + + user1.details.add(new PersonalDetails("Joe", "Raymond", + "jr@email.com", "123 Street", "CADC", "Victoria", "CA")); + assertEquals(user1, user2); + assertEquals(user1.hashCode(), user2.hashCode()); + + + User<X500Principal> user3 = new User<X500Principal>( + new X500Principal("cn=aaa,ou=ca")); + User<HttpPrincipal> user4 = new User<HttpPrincipal>( + new HttpPrincipal("cn=aaa,ou=ca")); + assertFalse(user3.equals(user4)); + assertFalse(user3.hashCode() == user4.hashCode()); + + user1.getPrincipals().add(new X500Principal("cn=aaa,ou=ca")); + assertEquals(user1, user2); + assertEquals(user1.hashCode(), user2.hashCode()); + + user1.details.add(new PosixDetails(12, 23, + "/home/myhome")); + assertEquals(user1, user2); + assertEquals(user1.hashCode(), user2.hashCode()); + + User<NumericPrincipal> user5 = new User<NumericPrincipal>( + new NumericPrincipal(32)); + assertFalse(user1.equals(user5)); + + // visual test of toString + System.out.println(user1); + System.out.println(new PersonalDetails("Joe", "Raymond", + "jr@email.com", "123 Street", "CADC", "Victoria", "CA")); + System.out.println(new PosixDetails(12, 23,"/home/myhome")); + + } + + @Test + public void exceptionTests() + { + boolean thrown = false; + try + { + new User<NumericPrincipal>(null); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new PersonalDetails(null, "Raymond", + "jr@email.com", "123 Street", "CADC", "Victoria", "CA"); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new PersonalDetails("Joe", null, + "jr@email.com", "123 Street", "CADC", "Victoria", "CA"); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new PersonalDetails("Joe", "Raymond", + null, "123 Street", "CADC", "Victoria", "CA"); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new PersonalDetails("Joe", "Raymond", + "jr@email.com", null, "CADC", "Victoria", "CA"); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new PersonalDetails("Joe", "Raymond", + "jr@email.com", "123 Street", null, "Victoria", "CA"); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new PersonalDetails("Joe", "Raymond", + "jr@email.com", "123 Street", "CADC", null, "CA"); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new PersonalDetails("Joe", "Raymond", + "jr@email.com", "123 Street", "CADC", "Victoria", null); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new PosixDetails(11, 22, null); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new HttpPrincipal(null); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + + thrown = false; + try + { + new OpenIdPrincipal(null); + } + catch(IllegalArgumentException e) + { + thrown = true; + } + assertTrue(thrown); + } +}