package edu.gatech.oad.rocket.findmythings.server.db.model; import com.google.appengine.api.datastore.PhoneNumber; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Index; import edu.gatech.oad.rocket.findmythings.server.model.AppMutableMember; import edu.gatech.oad.rocket.findmythings.server.security.DatabaseRealm; import edu.gatech.oad.rocket.findmythings.server.util.HashHelper; import org.apache.shiro.SecurityUtils; import org.apache.shiro.mgt.RealmSecurityManager; import org.apache.shiro.realm.Realm; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; /** * CS 2340 - FindMyStuff Android App * This abstract class specifies features of a DBMember * * @author TeamRocket * */ @Cache @Entity public class DBMember implements AppMutableMember { private static final long serialVersionUID = -9162883247171299555L; protected static final Logger LOGGER = Logger.getLogger(DBMember.class.getName()); @Id private String email; private String hashedPassword; /** The salt, used to make sure that a dictionary attack is harder given a list of all the * hashed passwords, as each salt will be different. */ private byte[] salt; private Set<String> roles; private Set<String> permissions; @Index private Date dateRegistered; private String name; private String address; private PhoneNumber phone; private boolean isLocked; /** Constructors **/ /** For objectify to create instances on retrieval */ protected DBMember() { this.roles = new HashSet<>(); this.permissions = new HashSet<>(); } DBMember(String email) { this(email, null, new HashSet<String>(), new HashSet<String>()); } public DBMember(String email, String password) { this(email, password, new HashSet<String>(), new HashSet<String>()); } public DBMember(String email, Set<String> roles, Set<String> permissions) { this(email, null, roles, permissions); } public DBMember(String email, String password, Set<String> roles, Set<String> permissions) { this(email, password, roles, permissions, false); } public DBMember(String email, String password, Set<String> roles, Set<String> permissions, boolean isRegistered) { Preconditions.checkNotNull(email, "DBMember email can't be null"); this.email = email; setPassword(password); if (roles == null) { this.roles = new HashSet<>(); } else { this.roles = new HashSet<>(roles); } if (permissions == null) { this.permissions = new HashSet<>(); } else { this.permissions = new HashSet<>(permissions); } this.dateRegistered = isRegistered ? new Date() : null; } /** Global utilities **/ /** Object overrides **/ @Override public int hashCode() { return Objects.hashCode(name, hashedPassword); } @Override public boolean equals(Object o) { if (o instanceof DBMember) { DBMember u = (DBMember)o; return Objects.equal(getName().trim(), u.getName().trim()) && Objects.equal(getHashedPassword(), u.getHashedPassword()); } else { return false; } } @Override public String toString() { return email; } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#getEmail() */ @Override public String getEmail() { return email; } /** * @return the salt */ public byte[] getSalt() { return salt; } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#getRoles() */ @Override public Collection<String> getRoles() { return roles; } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#getPermissions() */ @Override public Collection<String> getStringPermissions() { return permissions; } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#isRegistered() */ @Override public boolean isRegistered() { return getDateRegistered() != null; } @Override public boolean isEditable() { return true; } /** * @return the hashedPassword */ public String getHashedPassword() { return hashedPassword; } /** * @param password the password to set */ public void setPassword(String password) { Preconditions.checkNotNull(password); this.salt = HashHelper.getSaltedBytes(); this.hashedPassword = HashHelper.getHashString(password, getSalt()); } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#getName() */ public String getName() { return name; } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#setName(java.lang.String) */ public void setName(String s) { name = s.trim(); } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#getDateRegistered() */ public Date getDateRegistered() { return dateRegistered == null ? null : new Date(dateRegistered.getTime()); } public void register() { dateRegistered = new Date(); } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#getPhoneNumber() */ public PhoneNumber getPhone() { return phone; } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#setPhone(com.google.appengine.api.datastore.PhoneNumber) */ public void setPhone(PhoneNumber p) { phone = p; } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#getAddress() */ public String getAddress(){ return address; } /* (non-Javadoc) * @see edu.gatech.oad.rocket.findmythings.server.db.model.AppMember#setAddress(java.lang.String) */ public void setAddress(String s) { address = s.trim(); } @Override public void setLocked(boolean locked) { this.isLocked = locked; } @Override public void setAdmin(boolean admin) { permissions.clear(); roles.clear(); if (admin) { roles.add("admin"); permissions.add("*"); } else { roles.add("user"); permissions.add("submit"); permissions.add("browse"); } RealmSecurityManager manager = (RealmSecurityManager)SecurityUtils.getSecurityManager(); for (Realm realm : manager.getRealms()) { // really really bad design if (realm instanceof DatabaseRealm) { ((DatabaseRealm) realm).clearCachedAuthorizationInfo(getEmail()); } } } @Override public boolean isAdmin() { return roles.contains("admin"); } @Override public boolean isLocked() { return isLocked; } }