Skip to content
GMSClient.java 42.5 KiB
Newer Older
        if (mySocketFactory != null)
            throw new IllegalStateException("Illegal use of GMSClient: "
                    + "cannot set SSLSocketFactory after using one created from Subject");
Jeff Burke's avatar
Jeff Burke committed
        this.sslSocketFactory = sslSocketFactory;
    private SSLSocketFactory getSSLSocketFactory()
    {
        AccessControlContext ac = AccessController.getContext();
        Subject s = Subject.getSubject(ac);
        
        // no real Subject: can only use the one from setSSLSocketFactory
        if (s == null || s.getPrincipals().isEmpty())
        {
            return sslSocketFactory;
        }
        
        // lazy init
        if (this.mySocketFactory == null)
        {
            log.debug("getSSLSocketFactory: " + s);
            this.mySocketFactory = SSLUtil.getSocketFactory(s);
            this.subjectHashCode = s.hashCode();
        }
        else
            int c = s.hashCode();
            if (c != subjectHashCode)
                throw new IllegalStateException("Illegal use of " 
                        + this.getClass().getSimpleName()
                        + ": subject change not supported for internal SSLSocketFactory");
    
    protected void clearCache()
    {
        AccessControlContext acContext = AccessController.getContext();
        Subject subject = Subject.getSubject(acContext);
        if (subject != null)
        {
            subject.getPrivateCredentials().remove(new GroupMemberships());
    protected GroupMemberships getGroupCache(Principal userID)
    {
        AccessControlContext acContext = AccessController.getContext();
        Subject subject = Subject.getSubject(acContext);
        
        // only consult cache if the userID is of the calling subject
        if (userIsSubject(userID, subject))
            Set<GroupMemberships> gset = subject.getPrivateCredentials(GroupMemberships.class);
            if (gset == null || gset.isEmpty())
                GroupMemberships mems = new GroupMemberships();
                subject.getPrivateCredentials().add(mems);
                return mems;
            GroupMemberships mems = gset.iterator().next();
            return mems;
        return null; // no cache
    }
    
    protected Group getCachedGroup(Principal userID, String groupID, Role role)
    {
        List<Group> groups = getCachedGroups(userID, role, false);
        if (groups == null)
            return null; // no cache
        for (Group g : groups)
        {
            if (g.getID().equals(groupID))
                return g;
        }
        return null;
    }
    protected List<Group> getCachedGroups(Principal userID, Role role, boolean complete)
    {
        GroupMemberships mems = getGroupCache(userID);
        if (mems == null)
            return null; // no cache

        Boolean cacheState = mems.complete.get(role);
        if (!complete || Boolean.TRUE.equals(cacheState))
            return mems.memberships.get(role);
        
        // caller wanted complete and we don't have that
    protected void addCachedGroup(Principal userID, Group group, Role role)
    {
        GroupMemberships mems = getGroupCache(userID);
        if (mems == null)
            return; // no cache
        
        List<Group> groups = mems.memberships.get(role);
        if (groups == null)
        {
            groups = new ArrayList<Group>();
            mems.complete.put(role, Boolean.FALSE);
            mems.memberships.put(role, groups);
        }
        if (!groups.contains(group))
            groups.add(group);
    }
    
    protected void setCachedGroups(Principal userID, List<Group> groups, Role role)
        GroupMemberships mems = getGroupCache(userID);
        if (mems == null)
            return; // no cache
        log.debug("Caching groups for " + userID + ", role " + role);
        List<Group> cur = mems.memberships.get(role);
        if (cur == null)
            cur = new ArrayList<Group>();
            mems.complete.put(role, Boolean.FALSE);
            mems.memberships.put(role, cur);
        }
        for (Group group : groups)
        {
            if (!cur.contains(group))
                cur.add(group);
            mems.complete.put(role, Boolean.TRUE);
        }
    }
    
    protected boolean userIsSubject(Principal userID, Subject subject)
    {
        if (userID == null || subject == null)
        {
            return false;
        }
        
Dustin Jenkins's avatar
Dustin Jenkins committed
        for (Principal subjectPrincipal : subject.getPrincipals())
            if (AuthenticationUtil.equals(subjectPrincipal, userID))
        return false;
Jeff Burke's avatar
Jeff Burke committed
    /**
     * Class used to hold list of groups in which a user is known to be a member.
Jeff Burke's avatar
Jeff Burke committed
     */
    protected class GroupMemberships implements Comparable
        Map<Role, List<Group>> memberships = new HashMap<Role, List<Group>>();
        Map<Role, Boolean> complete = new HashMap<Role, Boolean>();
        
        protected GroupMemberships()
        // only allow one in a set - makes clearCache simple too
        public boolean equals(Object rhs)
        {
            if (rhs != null && rhs instanceof GroupMemberships)
                return true;
            return false;
        }

        public int compareTo(Object t)
        {
            if (this.equals(t))
                return 0;
            return -1; // wonder if this is sketchy
        }