From c073c9171b5c4b2b45756770c373a792960895bf Mon Sep 17 00:00:00 2001 From: Adrian Damian <Adrian.Damian@nrc.ca> Date: Wed, 25 Jun 2014 09:22:35 -0700 Subject: [PATCH] Added the core authorization classes --- projects/cadcUtil/doc/auth.html | 36 +++ projects/cadcUtil/doc/uml/UserAuth.png | Bin 0 -> 18102 bytes .../src/ca/nrc/cadc/auth/model/Group.java | 263 ++++++++++++++++ .../ca/nrc/cadc/auth/model/GroupProperty.java | 199 ++++++++++++ .../ca/nrc/cadc/auth/model/PosixDetails.java | 167 ++++++++++ .../src/ca/nrc/cadc/auth/model/User.java | 146 +++++++++ .../ca/nrc/cadc/auth/model/UserDetails.java | 287 ++++++++++++++++++ .../src/ca/nrc/cadc/auth/model/GroupTest.java | 122 ++++++++ .../src/ca/nrc/cadc/auth/model/UserTest.java | 110 +++++++ 9 files changed, 1330 insertions(+) create mode 100644 projects/cadcUtil/doc/auth.html create mode 100644 projects/cadcUtil/doc/uml/UserAuth.png create mode 100644 projects/cadcUtil/src/ca/nrc/cadc/auth/model/Group.java create mode 100644 projects/cadcUtil/src/ca/nrc/cadc/auth/model/GroupProperty.java create mode 100644 projects/cadcUtil/src/ca/nrc/cadc/auth/model/PosixDetails.java create mode 100644 projects/cadcUtil/src/ca/nrc/cadc/auth/model/User.java create mode 100644 projects/cadcUtil/src/ca/nrc/cadc/auth/model/UserDetails.java create mode 100644 projects/cadcUtil/test/src/ca/nrc/cadc/auth/model/GroupTest.java create mode 100644 projects/cadcUtil/test/src/ca/nrc/cadc/auth/model/UserTest.java diff --git a/projects/cadcUtil/doc/auth.html b/projects/cadcUtil/doc/auth.html new file mode 100644 index 00000000..461ef1b2 --- /dev/null +++ b/projects/cadcUtil/doc/auth.html @@ -0,0 +1,36 @@ +<!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 a Principal (in CADC's case that is the CadcPrincipal) 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>SShPubKeyPrincipal: An ssh key identity. </li> + <li>CadcPrincipal: An identity used internally at the CADC. </li> + <li>CookiePrincipal: Cookie based identity. </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/cadcUtil/doc/uml/UserAuth.png b/projects/cadcUtil/doc/uml/UserAuth.png new file mode 100644 index 0000000000000000000000000000000000000000..ae0738a6cc4438945b20bac98a823a9b2f326086 GIT binary patch literal 18102 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 literal 0 HcmV?d00001 diff --git a/projects/cadcUtil/src/ca/nrc/cadc/auth/model/Group.java b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/Group.java new file mode 100644 index 00000000..41e2b98d --- /dev/null +++ b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/Group.java @@ -0,0 +1,263 @@ +/* + ************************************************************************ + **** 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.auth.model; + +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 + * @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"); + } + 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 (description == null) + { + if (other.description != null) + { + return false; + } + } + else if (!description.equals(other.description)) + { + return false; + } + if (groupRead == null) + { + if (other.groupRead != null) + { + return false; + } + } + else if (!groupRead.equals(other.groupRead)) + { + return false; + } + if (groupWrite == null) + { + if (other.groupWrite != null) + { + return false; + } + } + else if (!groupWrite.equals(other.groupWrite)) + { + return false; + } + if (groupID == null) + { + if (other.groupID != null) + { + return false; + } + } + else if (!groupID.equals(other.groupID)) + { + return false; + } + if (groupMembers == null) + { + if (other.groupMembers != null) + { + return false; + } + } + else if (!groupMembers.equals(other.groupMembers)) + { + return false; + } + if (!owner.equals(other.owner)) + { + return false; + } + if (properties == null) + { + if (other.properties != null) + { + return false; + } + } + else if (!properties.equals(other.properties)) + { + return false; + } + if (userMembers == null) + { + if (other.userMembers != null) + { + return false; + } + } + else if (!userMembers.equals(other.userMembers)) + { + return false; + } + return (publicRead == other.publicRead); + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + groupID + "]"; + } + +} diff --git a/projects/cadcUtil/src/ca/nrc/cadc/auth/model/GroupProperty.java b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/GroupProperty.java new file mode 100644 index 00000000..af96c28a --- /dev/null +++ b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/GroupProperty.java @@ -0,0 +1,199 @@ +/* +************************************************************************ +******************* 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.auth.model; + +/** + * 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"); + } + 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()); + result = prime * result + (readOnly ? 1231 : 1237); + result = prime * result + + ((value == null) ? 0 : value.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; + if (key == null) + { + if (other.key != null) + { + return false; + } + } + else if (!key.equals(other.key)) + { + return false; + } + if (readOnly != other.readOnly) + { + return false; + } + if (value == null) + { + if (other.value != null) + { + return false; + } + } + else if (!value.equals(other.value)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + key + ": " + value + "]"; + } + +} diff --git a/projects/cadcUtil/src/ca/nrc/cadc/auth/model/PosixDetails.java b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/PosixDetails.java new file mode 100644 index 00000000..dd8ea444 --- /dev/null +++ b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/PosixDetails.java @@ -0,0 +1,167 @@ +/* + ************************************************************************ + **** 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.auth.model; + +/** + * Represents the posix account details associated with a user account. + */ +public class PosixDetails +{ + 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; + } + if (loginShell == null) + { + if (other.loginShell != null) + { + return false; + } + } + else if (!loginShell.equals(other.loginShell)) + { + return false; + } + if (uid != other.uid) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + uid + ", " + gid + ", " + + homeDirectory + "]"; + } + +} diff --git a/projects/cadcUtil/src/ca/nrc/cadc/auth/model/User.java b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/User.java new file mode 100644 index 00000000..9a120094 --- /dev/null +++ b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/User.java @@ -0,0 +1,146 @@ +/* + ************************************************************************ + **** 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.auth.model; + +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 UserDetails userDetails; + public PosixDetails posixDetails; + + + public User(final T 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 == null) ? 0 : 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 == null) + { + if (other.userID != null) + { + return false; + } + } + else if (!userID.equals(other.userID)) + { + return false; + } + if (userDetails == null) + { + if (other.userDetails != null) + { + return false; + } + } + else if (!userDetails.equals(other.userDetails)) + { + return false; + } + if (posixDetails == null) + { + if (other.posixDetails != null) + { + return false; + } + } + else if (!posixDetails.equals(other.posixDetails)) + { + return false; + } + return this.getPrincipals().equals(other.getPrincipals()); + + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + userID.getName() + "]"; + } + +} diff --git a/projects/cadcUtil/src/ca/nrc/cadc/auth/model/UserDetails.java b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/UserDetails.java new file mode 100644 index 00000000..2b1101e8 --- /dev/null +++ b/projects/cadcUtil/src/ca/nrc/cadc/auth/model/UserDetails.java @@ -0,0 +1,287 @@ +/* + ************************************************************************ + **** 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.auth.model; + +public class UserDetails +{ + private String firstName; + private String lastName; + private String email; + private String address; + private String institute; + private String city; + private String country; + + public PersonalTitle title; + public String telephone; + public String fax; + public String province; + public String postalCode; + + public UserDetails(String firstName, String lastName, String email, + String address, String institute, String city, String 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; + } + + public String getFax() + { + return fax; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + + ((address == null) ? 0 : address.hashCode()); + result = prime * result + ((city == null) ? 0 : city.hashCode()); + result = prime * result + + ((country == null) ? 0 : country.hashCode()); + result = prime * result + + ((email == null) ? 0 : email.hashCode()); + result = prime * result + + ((firstName == null) ? 0 : firstName.hashCode()); + result = prime * result + + ((institute == null) ? 0 : institute.hashCode()); + result = prime * result + + ((lastName == null) ? 0 : 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 UserDetails)) + { + return false; + } + UserDetails other = (UserDetails) obj; + if (address == null) + { + if (other.address != null) + { + return false; + } + } + else if (!address.equals(other.address)) + { + return false; + } + if (city == null) + { + if (other.city != null) + { + return false; + } + } + else if (!city.equals(other.city)) + { + return false; + } + if (country == null) + { + if (other.country != null) + { + return false; + } + } + else if (!country.equals(other.country)) + { + return false; + } + if (email == null) + { + if (other.email != null) + { + return false; + } + } + else if (!email.equals(other.email)) + { + return false; + } + if (fax == null) + { + if (other.fax != null) + { + return false; + } + } + else if (!fax.equals(other.fax)) + { + return false; + } + if (firstName == null) + { + if (other.firstName != null) + { + return false; + } + } + else if (!firstName.equals(other.firstName)) + { + return false; + } + if (institute == null) + { + if (other.institute != null) + { + return false; + } + } + else if (!institute.equals(other.institute)) + { + return false; + } + if (lastName == null) + { + if (other.lastName != null) + { + return false; + } + } + else if (!lastName.equals(other.lastName)) + { + return false; + } + if (postalCode == null) + { + if (other.postalCode != null) + { + return false; + } + } + else if (!postalCode.equals(other.postalCode)) + { + return false; + } + if (province == null) + { + if (other.province != null) + { + return false; + } + } + else if (!province.equals(other.province)) + { + return false; + } + if (telephone == null) + { + if (other.telephone != null) + { + return false; + } + } + else if (!telephone.equals(other.telephone)) + { + return false; + } + if (title != other.title) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + "[" + firstName + ", " + + lastName + ", " + email + ", " + address + ", " + + institute + ", " + city + ", " + country + "]"; + } +} diff --git a/projects/cadcUtil/test/src/ca/nrc/cadc/auth/model/GroupTest.java b/projects/cadcUtil/test/src/ca/nrc/cadc/auth/model/GroupTest.java new file mode 100644 index 00000000..2fb6f9ce --- /dev/null +++ b/projects/cadcUtil/test/src/ca/nrc/cadc/auth/model/GroupTest.java @@ -0,0 +1,122 @@ +/* + ************************************************************************ + **** 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.auth.model; + +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()); + assertFalse(group1.equals(group2)); + + group2.getUserMembers().add(user); + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1, group2); + + group1.getGroupMembers().add(group2); + assertEquals(group1.hashCode(), group2.hashCode()); + assertFalse(group1.equals(group2)); + + group2.getGroupMembers().add(group2); + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1, group2); + + group1.description = "Test group"; + assertEquals(group1.hashCode(), group2.hashCode()); + assertFalse(group1.equals(group2)); + + group2.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()); + assertFalse(group1.equals(group2)); + + group2.groupRead = group2; + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1, group2); + + // group write equality tests + group1.groupWrite = group2; + assertEquals(group1.hashCode(), group2.hashCode()); + assertFalse(group1.equals(group2)); + + group2.groupWrite = group2; + assertEquals(group1.hashCode(), group2.hashCode()); + assertEquals(group1, group2); + + group1.publicRead = true; + assertEquals(group1.hashCode(), group2.hashCode()); + assertFalse(group1.equals(group2)); + + group2.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); + } +} diff --git a/projects/cadcUtil/test/src/ca/nrc/cadc/auth/model/UserTest.java b/projects/cadcUtil/test/src/ca/nrc/cadc/auth/model/UserTest.java new file mode 100644 index 00000000..c87163ed --- /dev/null +++ b/projects/cadcUtil/test/src/ca/nrc/cadc/auth/model/UserTest.java @@ -0,0 +1,110 @@ +/* + ************************************************************************ + **** 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.auth.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; + +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; + +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.userDetails = new UserDetails("Joe", "Raymond", + "jr@email.com", "123 Street", "CADC", "Victoria", "CA"); + assertFalse(user1.equals(user2)); + assertEquals(user1.hashCode(), user2.hashCode()); + + user2.userDetails = user1.userDetails; + 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")); + assertFalse(user1.equals(user2)); + assertEquals(user1.hashCode(), user2.hashCode()); + + user2.getPrincipals().add(new X500Principal("cn=aaa,ou=ca")); + assertEquals(user1, user1); + assertEquals(user1.hashCode(), user2.hashCode()); + + user1.posixDetails = new PosixDetails(12, 23, + "/home/myhome"); + assertFalse(user1.equals(user2)); + assertEquals(user1.hashCode(), user2.hashCode()); + + user2.getPrincipals().add(new X500Principal("cn=aaa,ou=ca")); + assertEquals(user1, user1); + 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(user1.userDetails); + System.out.println(user1.posixDetails); + + } +} -- GitLab