Package org.persvr.security

Source Code of org.persvr.security.CapabilityUser

/*
* User.java
*
* Created on July 5, 2005, 10:58 PM
*
* To change this basis, choose Tools | Options and locate the basis under
* the Source Creation and Management node. Right-click the basis and choose
* Open. You can then make changes to the basis in the Source Editor.
*/

package org.persvr.security;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.WeakHashMap;

import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.Base64;
import org.mozilla.javascript.BaseFunction;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.persvr.Persevere;
import org.persvr.data.DataSourceManager;
import org.persvr.data.GlobalData;
import org.persvr.data.JsonPath;
import org.persvr.data.ObjectId;
import org.persvr.data.Persistable;
import org.persvr.data.PersistableArray;
import org.persvr.data.PersistableList;
import org.persvr.data.PersistableObject;
import org.persvr.data.PersistableClass;
import org.persvr.data.Transaction;
import org.persvr.remote.Client;
/**
*
* There are three states of a user:
* 1. anonymous private - user is maintained across sessions through cookies and can be converted to a real user by establishing a username and password.  This is the default state.
* 2. shared public - multiple users are using this computer so a user is not maintained across sessions
* 3. authenticated - either one or two can convert to this, but if a user already exists, it must do a merge of data
*/
public class CapabilityUser extends PersistableObject implements User {
/*    public PermissionLevel getPermissionLevel(Persistable obj) {
      if (supervisorGroup.isMember(this)) // TODO: we need a faster way to do this
        return PermissionLevel.WRITE_LEVEL;
      Acl acl = obj.getAcl();
        Enumeration<Permission> permissions = acl.getPermissions(this);
        while (permissions.hasMoreElements()) {
          Permission perm = permissions.nextElement();
          if (perm instanceof PermissionLevel)
            return (PermissionLevel) perm;
        }
        return PermissionLevel.NONE_LEVEL;

  }


  public boolean hasPermission(Permission permision) {
    return getSupervisorGroup().isMember(this);
  }*/
  public static final String PASSWORD_FIELD = ":password";
  public static final String IN_GROUPS_FIELD = ":inGroups";
  public static final String USER_DATA_FIELD = "userData";
  public static final String PUBLIC_USER_NAME="_public_";
    //TODO: make this not public!
    public Map<Persistable,PermissionLevel> computedPermissions = new WeakHashMap();
    boolean isSharedPublic = false;
    private static CapabilityUser publicUserObject; 

    static java.security.acl.Group supervisorGroup;
    public static void resetSecurity() {
      /*
      UserSecurity.doPriviledgedAction(new PrivilegedAction() {

      public Object run() {
/*        Object securitySettingsObject = DataSourceManager.getRootObject().get("securitySettings");
        Object supervisorGroupObject = ScriptableObject.NOT_FOUND;
        if (securitySettingsObject instanceof Persistable) { 
            securitySettings = (Persistable) securitySettingsObject;
        }
        else {
          DataSourceManager.getRootObject().set("securitySettings",new NativeObject());
          securitySettingsObject = DataSourceManager.getRootObject().get("securitySettings");
            securitySettings = (Persistable) securitySettingsObject;
        }
          //publicUserObject = (Persistable) getSecuritySettings().get("anonymousUser");
          supervisorGroupObject = getSecuritySettings().get("supervisor");
        Persistable groups = ObjectId.idForString("Group").getTarget();
        Object supervisorGroupObject = groups.get("supervisor");
          if (supervisorGroupObject==ScriptableObject.NOT_FOUND)
            supervisorGroup = new Anyone();
          else
            supervisorGroup = (java.security.acl.Group) supervisorGroupObject;
          return null;
      }
       
      });
      */
    }
    static boolean unrestrictedMode;
    public static CapabilityUser PUBLIC_USER;
    static {
/*      int numUsers = usersTable().size();
    if (numUsers == 0) { //first real user
      PUBLIC_USER = (CapabilityUser) Persevere.newObject("User");
      PUBLIC_USER.setUsername("public");
      unrestrictedMode = true;
    }
    else {
      if (numUsers == 1)
        unrestrictedMode = true;
      PUBLIC_USER = (CapabilityUser) usersTable().get(0);
    }*/
    }
/*
      // must set this temporarily while we are starting so that there is a supervisor group
      supervisorGroup = new java.security.acl.Group() {
        public boolean addMember(Principal user) {
          return false;
        }
        public boolean isMember(Principal member) {
          return false;
        }
        public Enumeration<? extends Principal> members() {
          return null;
        }
        public boolean removeMember(Principal user) {
          return false;
        }
        public String getName() {
          return "No one";
        }
      };
      resetSecurity();
    }*/
    long id;
  public void onCreation() {
    super.onCreation();
    if (unrestrictedMode) { //first real user
      Object writeable = noCheckGet("full");
      if (!(writeable instanceof PersistableArray)) {
        writeable = Persevere.newArray();
        set("full",writeable);
      }
      ((PersistableArray) writeable).add(DataSourceManager.getRootObject());
    }
    unrestrictedMode = false;
//    setupNewUser(true);
  }

/*    public AclUser(final String username, final String password) {
        //id = getNewId();
      //findUser("" + id);
      UserSecurity.doPriviledgedAction(new PrivilegedAction() {

      public Object run() {
        validateUsername(username);
        setupNewUser(true);
        setUsername(username);
        setPassword(password);
        Transaction.currentTransaction().commit();
        return null;
      }
      });
    }*/

    public CapabilityUser() {
    }
    private CapabilityUser(boolean isShared) {
      this.isSharedPublic = isShared;
    }

    public static java.security.acl.Group getSupervisorGroup() {
      return (java.security.acl.Group) supervisorGroup;
     
    }
    private CapabilityUser findUser(String id) {
        List correctUsers = (List) JsonPath.query(usersTable(),"[?(@.userid=$1)]",id);
          //PersistentList.filter(usersTable(),new SimpleStipulation(USER_Id_FIELD,"" + id));
        //System.err.println("correctUsers = " + correctUsers.isEmpty());
        if (correctUsers.isEmpty())
          return publicUserObject;
        else
          return (CapabilityUser) correctUsers.get(0);
    }
/*   private void setupNewUser(final boolean realUser) {
     
            //usersTable().add(AclUser.this);
            boolean registerAsNewUser = true;
//            userObject = (Persistable) usersTable().get(usersTable().size()-1);
          if (realUser) {
              //calculateMembership(userObject, usersTable());
            //  userObject.put(USER_Id_FIELD, id);
              //if (usersTable().get(GlobalData.PERMISSION_FIELD) instanceof DataSourceObject)
                 // userObject.put(GlobalData.PERMISSION_FIELD, usersTable().get(GlobalData.PERMISSION_FIELD));
            Persistable groups = ObjectId.idForString("Group").getTarget();
              if (Scriptable.NOT_FOUND== groups.get("supervisor")) {
                supervisorGroup = (Group) PersevereRuntime.newObject("Group");
//                ((Persistable) supervisorGroup).set(GlobalData.BASIS_FIELD, Templates.getBasisForClass(Group.class));
                groups.set("supervisor",supervisorGroup);
                getSupervisorGroup().addMember(CapabilityUser.this);
                registerAsNewUser = true;
               
                  //calculateMembership(User.this, getSupervisorGroup());
                //getSecuritySettings().delete("nextCreatedUserIsSupervisor");
              }
          }
           
            //PersevereRuntime.newObject(DataSourceManager.getSource("User"));
            Persistable userData = (Persistable) set(USER_DATA_FIELD, PersevereRuntime.newArray());
            List security =(List) userData.set(ACCESS_FIELD, PersevereRuntime.newArray());
            //((Persistable) security).set("name", getName() + "'s");
            //DataObjectList list = (DataObjectList) security.put(ROLE_PERMITS_FIELD, new TransientDataObjectList());
            Persistable rolePermit = PersevereRuntime.newObject();
            //TODO: Change this to get the permit by level number
//            Object writeLevel = ((List) JsonPath.query((Persistable) securitySettings.get("permissionLevelTypes"),"$[?(@.name='write')]")).get(0);
            rolePermit.set(PERMISSION_LEVEL_FIELD, "write");
           /* rolePermit.put(VERSION_FIELD, Boolean.TRUE);
            rolePermit.put(APPEND_FIELD, Boolean.TRUE);
            rolePermit.put(READ_FIELD, Boolean.TRUE);
            rolePermit.put(WRITE_FIELD, Boolean.TRUE);
            rolePermit.set(ROLE_FIELD, CapabilityUser.this);
            security.add(rolePermit);

    }*/

    static long getNewId() {
        // TODO: we need to do something ensure that this does not return a value that had been used before, it is also more efficient if it is hex format
        return (new Random()).nextLong();
    }
    @Deprecated
    public static CapabilityUser publicUser() {
        return PUBLIC_USER;
    }
/*    DataObject getUserObject() {
        DataObjectList correctUsers = (DataObjectList) usersTable.get(new SimpleStipulation("userid","" + id));
        if (correctUsers.size() == 0) {
            throw new LoginException("operating on a user with no valid entry in the database");
        }
        return (DataObject) correctUsers.get(0);
    }*/
    /*User(Persistable userObject ) {
      addActiveUser();
        this.userObject = userObject;
        //id = Long.parseLong((String) userObject.get(USER_Id_FIELD));
        if (userObject.get("name") instanceof String)
            username = (String) userObject.get("name");
      //  else
        //    username = "" + id;
    }*/
    String currentTicket;
    public String getCurrentTicket() {
      return currentTicket;
    }
    public static CapabilityUser getUserByTicket(String id,String ipAddress) throws LoginException {
        if (PUBLIC_USER_NAME.equals(id))
            return publicUser();
      final String ticket = id + ipAddress;
      Object userObject = UserSecurity.doPriviledgedAction(new PrivilegedAction() {
        public Object run() {
          Object userTickets = DataSourceManager.getRootObject().get("userTickets");
          if (!(userTickets instanceof Persistable)) {
            userTickets = Persevere.newObject();
            DataSourceManager.getRootObject().set("userTickets",userTickets);
          }
             
        return ((Persistable) userTickets).get(ticket);
      }    
      });
     
      if (userObject instanceof CapabilityUser) {
        return (CapabilityUser) userObject;
      }
      else
        throw new LoginException("The user ticket is no longer valid");
    }
    @Deprecated
    public String getNewTicket(String ipAddress) {
      String ticket = ipAddress + new Date().getTime() + "" + new Random().nextInt();
      ((Persistable) DataSourceManager.getRootObject().get("userTickets")).set(ticket,this);
      return ticket;
    }
    static CapabilityUser getUserByUsername(String username) {
      if (username.equals(UserSecurity.getUserName()))
        return (CapabilityUser) UserSecurity.currentUser();
        List correctUsers = (List) JsonPath.query(usersTable(),"$[?(@.name=$1)]", username);
        if (correctUsers.size() == 0) {
            throw new RuntimeException("user " + username + " not found");
        }
      return (CapabilityUser) ((Persistable) correctUsers.get(0));
       
    }
    /* merge the data into our data */
    void mergeUserData(CapabilityUser user) {
        //TODO: Implement this
    //    userObject.putAll(user.userObject);
      //  userObject.put("name",username);
    }
    public static CapabilityUser authenticate(final String username,final String password) throws LoginException {
      Object result = UserSecurity.doPriviledgedAction(new PrivilegedAction() {
        public Object run() {
          List correctUsers = (List) JsonPath.query(usersTable(),"$[?(@.name=$1)]", username);
              if (correctUsers.size() == 0) {
                  return new LoginException("user " + username + " not found");
              }
              Persistable userObject = (Persistable) correctUsers.get(0);
              boolean alreadyHashed = false;
              boolean passwordMatch = password.equals(userObject.get(PASSWORD_FIELD));
              if (!passwordMatch) {
                  try {
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(((String) userObject.get(PASSWORD_FIELD)).getBytes());
            passwordMatch = password.equals(new String(new Base64().encode(md.digest())));
            } catch (NoSuchAlgorithmException e) {
              throw new RuntimeException(e);
            }
            alreadyHashed = true;         
              }
              if (passwordMatch) {
                  //Logger.getLogger(CapabilityUser.class.toString()).info("User " + username + " has been authenticated");
                  CapabilityUser user = (CapabilityUser) userObject;
                  try {
                    if (alreadyHashed)
                      user.currentTicket = password;
                    else {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(password.getBytes());
                user.currentTicket = new String(new Base64().encode(md.digest()));
                    }
            } catch (NoSuchAlgorithmException e) {
              throw new RuntimeException(e);
            }
                  return user;
              }
              else {
                  //Logger.getLogger(CapabilityUser.class.toString()).info("The password was incorrect for " + username);
                  return new LoginException("The password was incorrect for user " + username + ". ");
              }
         
        }
      });
      if (result instanceof LoginException)
        throw (LoginException) result;
      return (CapabilityUser) result;
    }
/*    public User reAuthenticate(String username,String password) throws LoginException{
        User user = authenticate(username,password);
        if (getName() == null)  // merge the current data only if he is not another named user
            user.mergeUserData(this);
        return user;
    }*/
    static boolean hostSpecificSecurity = false;
    protected static Persistable usersTable() {
      return (Persistable) ObjectId.idForString("User/").getTarget();
//      if (hostSpecificSecurity)
    }
    //private String username = null;
   // private Persistable userObject = null;
//    private String password = null;
/*    public Persistable getUserObject() {
      return userObject;
    }*/
    public void logout() {
      //  username = null;
    }
    public String getName() {
      Object nameObject = get("name");
      if (nameObject instanceof String)
        return (String) nameObject;
      return null;
    }
    public String getPassword() {
      return (String) get(PASSWORD_FIELD);
    }
    public static final Persistable PRIVILEDGED_USER_OBJECT = Persevere.newObject();
    public static final String EVERYONE = "everyone";
    public static final Object SUPER_ROLE = new Object();
    /*public boolean isUserInRole(final Object role) {
        // TODO: Put this in the same package as AbstractWrapper so we can go through to the inner data to do this check
/*        while (role instanceof DataObject && !(role instanceof DataSourceObject)) {
            role = ((AbstractWrapper) role).data();
        }
        //System.err.println("testisUserInRole " + role + " userObject " + userObject + " == " + (role == userObject));
        if (role == userObject)
            return true;
        if (role.equals(EVERYONE))
            return true;
        if (userObject == null)
            return false;
        if (role.equals("authenticated"))
            return true; // TODO: I would like to get rid of these two for optimization
        if (userObject.equals(PRIVILEDGED_USER_OBJECT))
          return true;
/*        if (username != null && username.equals(role)) // Your user name counts as a role
            return true;
        //Object userInfo = userObject.get(USER_INFO_FIELD);
        if (role instanceof Persistable) {
            // assuming it is a group now
          return Boolean.TRUE.equals(doPriviledgedAction(new PrivilegedAction<Boolean>() {

          public Boolean run() {

            List roleMatch = PersistentList.filter((List) userObject.get(IN_GROUPS_FIELD),new IsStipulation(role));
                  return !roleMatch.isEmpty();
          }
        }));
/*            Object users = ((DataObject) role).get(USERS_FIELD);
            if (users instanceof DataObjectList)
                return !((DataObjectList) users).get(new IsStipulation(userObject)).isEmpty();
            else
                System.err.println("specified role is not a group " + role); */
        //}
/*        if (userInfo instanceof DataObject)
            return (((DataObjectList) ((DataObject) userInfo).get("groups")).get(new SimpleStipulation("name", role)).size() > 0);
        return false;
    }*/
    public void setUsername(String username) {
      List correctUsers = (List) JsonPath.query(usersTable(),"$[?(@.name=$1)]", username);
      if (correctUsers.size() == 0) {
            set("name",username);
            //this.username = username;
        }
        else
            throw new RuntimeException("The username " + username + " is already taken");
    }
    /* login as a different user, must be in the su capable group */
    public CapabilityUser su(String username) {
        if (!getSupervisorGroup().isMember(this))
            throw new RuntimeException("You are not a part of the su capable group, so you can not su");
        List correctUsers = (List) JsonPath.query(usersTable(),"$[?(@.name=$1)]", username);
        if (correctUsers.size() == 0) {
            throw new RuntimeException("user " + username + " not found");
        }
        Persistable userObject = (Persistable) correctUsers.get(0);
        return (CapabilityUser) userObject;
    }
    public void setPassword(String password) {
        //Logger.getLogger(CapabilityUser.class.toString()).info("now changing the password for " + getName());
        set(PASSWORD_FIELD,password);
        setAttributes(PASSWORD_FIELD, ScriptableObject.DONTENUM);
    }
    static String encrypt(String plaintext)
    {
         MessageDigest d =null;
         try {
         d = MessageDigest.getInstance("SHA-1");
         //d.reset();
         d.update(plaintext.getBytes("UTF-8"));
         }
         catch(Exception e) {
             e.printStackTrace();
         }
         return new String(Base64.encodeBase64(d.digest()));
    }
    private static boolean oneWayCompare(Collection c1, Collection c2)
    {
      for (Object obj : c1)
        if (!c2.contains(obj))
          return false;
      return true;
    }
    private static boolean compare(Collection c1, Collection c2) {
      return oneWayCompare(c1, c2) && oneWayCompare(c2, c1);
    }
    public static Set<Persistable> calculateMembership(Persistable member, List groupToConsider) {
      //Logger.getLogger(CapabilityUser.class.toString()).info("calculating membership");
      Set newInGroups = new HashSet();
      Set<List>groupsToConsider = new HashSet();
      if (groupToConsider != null)
        groupsToConsider.add(groupToConsider);
      try {
        groupsToConsider.addAll((List) member.get(IN_GROUPS_FIELD));
      }
      catch (ClassCastException e) {
      }
      try {
        for (List group : groupsToConsider) {
          if (group.contains(member)) { // verify membership
            newInGroups.addAll(calculateMembership((Persistable) group,null));
          }
        }
      }
      catch (ClassCastException e) {
        e.printStackTrace();
      }
     
      Object oldInGroups = member.get(IN_GROUPS_FIELD);
      if (!(oldInGroups instanceof List) ||  !compare((List) oldInGroups,newInGroups)) {
        NativeArray newInGroupsObject = Persevere.newArray();
        //for (Object obj : newInGroups)
          //newInGroupsObject.add(obj);
        member.set(IN_GROUPS_FIELD, newInGroupsObject);
        for (Persistable subMember : (List<Persistable>) member)
          calculateMembership(subMember, (List) member);
      }
      newInGroups.add(member)// we return a list of all membership, so I should be included
      resetComputedPermissions();
      return newInGroups;
    }


    public int compareTo(Object o) {
        return new Integer(hashCode()).compareTo(new Integer(o.hashCode()));
    }
   
  private static PersistableObject getOrCreatePersistentObject(Persistable object, String name) {
    Object value = object.get(name);
    if (!(value instanceof PersistableObject)) {
      value = Persevere.newObject();
      object.put(name, object, value);
    }
    return (PersistableObject) value;
  }
  private static PersistableArray getOrCreatePersistentList(Persistable object, String name) {
    Object value = object.get(name);
    if (!(value instanceof PersistableArray)) {
      value = Persevere.newArray();
      object.put(name, object, value);
    }
    return (PersistableArray) value;
  }

  public static boolean isHostSpecificSecurity() {
    return hostSpecificSecurity;
  }

  public static void setHostSpecificSecurity(boolean websiteSpecificSecurity) {
    CapabilityUser.hostSpecificSecurity = websiteSpecificSecurity;
  }

}
TOP

Related Classes of org.persvr.security.CapabilityUser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.