You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2015/10/21 22:36:28 UTC
[11/24] usergrid git commit: Refactor Realm to move principal related
logic into Principal class hierarchy, also fixed serialization of AuthC and
AuthZ info objects; tests still failing...
Refactor Realm to move principal related logic into Principal class hierarchy, also fixed serialization of AuthC and AuthZ info objects; tests still failing...
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/64876385
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/64876385
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/64876385
Branch: refs/heads/master
Commit: 648763854a50c7dd8bb0abe2440c89aee781de9f
Parents: 17ff2db
Author: Dave Johnson <sn...@apache.org>
Authored: Thu Sep 24 14:34:59 2015 -0400
Committer: Dave Johnson <sn...@apache.org>
Committed: Thu Sep 24 14:34:59 2015 -0400
----------------------------------------------------------------------
.../impl/ScopedCacheSerializationImpl.java | 19 +-
.../security/SecuredResourceFilterFactory.java | 1 +
.../rest/security/shiro/ShiroCache.java | 77 +++-
.../rest/security/shiro/ShiroCacheManager.java | 46 +-
.../collection/users/PermissionsResourceIT.java | 2 +-
.../rest/test/resource/ClientSetup.java | 3 -
stack/rest/src/test/resources/log4j.properties | 3 +-
.../apache/usergrid/management/UserInfo.java | 25 +-
.../apache/usergrid/security/shiro/Realm.java | 424 ++-----------------
.../shiro/UsergridAuthenticationInfo.java | 283 +++++++++++++
.../shiro/UsergridAuthorizationInfo.java | 103 +++++
.../AbstractAccessTokenCredentials.java | 9 +-
.../shiro/credentials/AdminUserAccessToken.java | 2 +
.../shiro/principals/AdminUserPrincipal.java | 143 ++++++-
.../principals/ApplicationGuestPrincipal.java | 65 ++-
.../shiro/principals/ApplicationPrincipal.java | 39 +-
.../principals/ApplicationUserPrincipal.java | 133 ++++++
.../shiro/principals/OrganizationPrincipal.java | 55 ++-
.../shiro/principals/PrincipalIdentifier.java | 85 ++++
.../shiro/principals/UserPrincipal.java | 6 +-
.../security/shiro/utils/SubjectUtils.java | 13 +-
.../usergrid/services/AbstractService.java | 4 +
.../services/guice/ServiceModuleImpl.java | 22 +-
.../usergrid/services/roles/RolesService.java | 8 +-
.../services/users/roles/RolesService.java | 10 +
25 files changed, 1128 insertions(+), 452 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/corepersistence/cache/src/main/java/org/apache/usergrid/persistence/cache/impl/ScopedCacheSerializationImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/cache/src/main/java/org/apache/usergrid/persistence/cache/impl/ScopedCacheSerializationImpl.java b/stack/corepersistence/cache/src/main/java/org/apache/usergrid/persistence/cache/impl/ScopedCacheSerializationImpl.java
index 3fc7332..bde6672 100644
--- a/stack/corepersistence/cache/src/main/java/org/apache/usergrid/persistence/cache/impl/ScopedCacheSerializationImpl.java
+++ b/stack/corepersistence/cache/src/main/java/org/apache/usergrid/persistence/cache/impl/ScopedCacheSerializationImpl.java
@@ -16,7 +16,8 @@
*/
package org.apache.usergrid.persistence.cache.impl;
-import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -25,14 +26,12 @@ import com.google.common.base.Preconditions;
import com.google.common.hash.Funnel;
import com.google.common.hash.PrimitiveSink;
import com.google.inject.Inject;
-import com.netflix.astyanax.ColumnListMutation;
import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.MutationBatch;
import com.netflix.astyanax.Serializer;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.connectionpool.exceptions.NotFoundException;
import com.netflix.astyanax.model.Column;
-import com.netflix.astyanax.model.ColumnList;
import com.netflix.astyanax.model.CompositeBuilder;
import com.netflix.astyanax.model.CompositeParser;
import com.netflix.astyanax.serializers.ObjectSerializer;
@@ -48,10 +47,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Iterator;
import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
/**
@@ -109,6 +105,10 @@ public class ScopedCacheSerializationImpl<K,V> implements ScopedCacheSerializati
@Inject
public ScopedCacheSerializationImpl( final Keyspace keyspace ) {
this.keyspace = keyspace;
+ //MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ MAPPER.enableDefaultTyping();
+ MAPPER.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
+ MAPPER.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
}
@@ -136,8 +136,8 @@ public class ScopedCacheSerializationImpl<K,V> implements ScopedCacheSerializati
//V value = MAPPER.readValue(result.getByteArrayValue(), new TypeReference<V>() {});
V value = MAPPER.readValue(result.getByteArrayValue(), typeRef);
- logger.info("Read cache item\n key/value types {}/{}\n key:value: {}:{}",
- new Object[] { key.getClass().getSimpleName(), value.getClass().getSimpleName(), key, value });
+ logger.debug("Read cache item\n key/value types {}/{}\n key:value: {}:{}",
+ new Object[]{key.getClass().getSimpleName(), value.getClass().getSimpleName(), key, value});
return value;
@@ -145,6 +145,7 @@ public class ScopedCacheSerializationImpl<K,V> implements ScopedCacheSerializati
logger.info("Value not found");
} catch (IOException ioe) {
+ logger.error("Unable to read cached value", ioe);
throw new RuntimeException("Unable to read cached value", ioe);
}
@@ -191,7 +192,7 @@ public class ScopedCacheSerializationImpl<K,V> implements ScopedCacheSerializati
executeBatch(batch);
- logger.info("Wrote cache item\n key/value types {}/{}\n key:value: {}:{}",
+ logger.debug("Wrote cache item\n key/value types {}/{}\n key:value: {}:{}",
new Object[]{key.getClass().getSimpleName(), value.getClass().getSimpleName(), key, value});
return value;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java b/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
index 3a290d9..04f0fc4 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/security/SecuredResourceFilterFactory.java
@@ -123,6 +123,7 @@ public class SecuredResourceFilterFactory implements DynamicFeature {
featureContext.register( ApplicationFilter.class );
}
else if ( am.isAnnotationPresent( RequireOrganizationAccess.class ) ) {
+
featureContext.register( OrganizationFilter.class );
}
else if ( am.isAnnotationPresent( RequireSystemAccess.class ) ) {
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCache.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCache.java b/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCache.java
index 03152b0..535a435 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCache.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCache.java
@@ -17,21 +17,24 @@
package org.apache.usergrid.rest.security.shiro;
import com.fasterxml.jackson.core.type.TypeReference;
-import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.usergrid.persistence.cache.CacheFactory;
import org.apache.usergrid.persistence.cache.CacheScope;
import org.apache.usergrid.persistence.cache.ScopedCache;
+import org.apache.usergrid.persistence.index.utils.UUIDUtils;
import org.apache.usergrid.persistence.model.entity.SimpleId;
+import org.apache.usergrid.persistence.model.util.UUIDGenerator;
+import org.apache.usergrid.security.shiro.UsergridAuthenticationInfo;
+import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
import org.apache.usergrid.security.shiro.principals.AdminUserPrincipal;
+import org.apache.usergrid.security.shiro.principals.UserPrincipal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
+import java.util.*;
/**
@@ -43,10 +46,11 @@ public class ShiroCache<K, V> implements Cache<K,V> {
CacheFactory<String, V> cacheFactory;
- TypeReference typeRef = new TypeReference<SimpleAuthorizationInfo>() {};
+ TypeReference typeRef = null;
- public ShiroCache( CacheFactory<String, V> cacheFactory ) {
+ public ShiroCache( TypeReference typeRef, CacheFactory<String, V> cacheFactory ) {
+ this.typeRef = typeRef;
this.cacheFactory = cacheFactory;
}
@@ -54,7 +58,21 @@ public class ShiroCache<K, V> implements Cache<K,V> {
public V get(K key) throws CacheException {
ScopedCache<String, V> scopedCache = getCacheScope(key);
if ( scopedCache != null ) {
- return scopedCache.get( getKeyString(key), typeRef);
+ V value = scopedCache.get(getKeyString(key), typeRef);
+
+ if ( value instanceof UsergridAuthorizationInfo ) {
+ UsergridAuthorizationInfo info = (UsergridAuthorizationInfo)value;
+ logger.debug("Got from AUTHZ cache {} for app {}", getKeyString(key), info.toString());
+
+ } else if ( value instanceof UsergridAuthenticationInfo ) {
+ UsergridAuthenticationInfo info = (UsergridAuthenticationInfo)value;
+ logger.debug("Got from AUTHC cache {} for app {}", getKeyString(key), info.toString());
+
+ } else if (value == null) {
+ logger.debug("Got NULL from cache app {} for key {}", getKeyString(key), key.toString() );
+ }
+
+ return value;
}
return null;
}
@@ -63,7 +81,18 @@ public class ShiroCache<K, V> implements Cache<K,V> {
public V put(K key, V value) throws CacheException {
ScopedCache<String, V> scopedCache = getCacheScope(key);
if ( scopedCache != null ) {
- return scopedCache.put( getKeyString(key) , value, 5000);
+ V ret = scopedCache.put(getKeyString(key), value, 5000);
+
+ if ( value instanceof UsergridAuthorizationInfo ) {
+ UsergridAuthorizationInfo info = (UsergridAuthorizationInfo)value;
+ logger.debug("Put to AUTHZ cache {} for app {}", getKeyString(key), info.toString());
+
+ } else if ( value instanceof UsergridAuthenticationInfo ) {
+ UsergridAuthenticationInfo info = (UsergridAuthenticationInfo)value;
+ logger.debug("Put to AUTHC cache {} for app {}", getKeyString(key), info.toString());
+ }
+
+ return ret;
}
return null;
}
@@ -101,30 +130,52 @@ public class ShiroCache<K, V> implements Cache<K,V> {
private ScopedCache<String, V> getCacheScope( K key ) {
if ( key instanceof SimplePrincipalCollection) {
+
SimplePrincipalCollection spc = (SimplePrincipalCollection)key;
if ( spc.getPrimaryPrincipal() instanceof AdminUserPrincipal ) {
+
AdminUserPrincipal p = (AdminUserPrincipal) spc.getPrimaryPrincipal();
CacheScope scope = new CacheScope(new SimpleId(p.getApplicationId(), "application"));
ScopedCache<String, V> scopedCache = cacheFactory.getScopedCache(scope);
return scopedCache;
+
+ } else {
+ throw new RuntimeException("Cannot determine application ID for cache scope");
}
+
+ } else if ( key instanceof AdminUserPrincipal ) {
+
+ AdminUserPrincipal p = (AdminUserPrincipal)key;
+ CacheScope scope = new CacheScope(new SimpleId(p.getApplicationId(), "application"));
+ ScopedCache<String, V> scopedCache = cacheFactory.getScopedCache(scope);
+ return scopedCache;
+
+ } else {
+ throw new RuntimeException("Cannot determine application ID for cache scope");
}
- return null;
}
- /** key is the application UUID in string form */
+ /** key is the user UUID in string form */
private String getKeyString( K key ) {
if ( key instanceof SimplePrincipalCollection) {
SimplePrincipalCollection spc = (SimplePrincipalCollection)key;
- if ( spc.getPrimaryPrincipal() instanceof AdminUserPrincipal ) {
+ if ( spc.getPrimaryPrincipal() instanceof UserPrincipal) {
AdminUserPrincipal p = (AdminUserPrincipal) spc.getPrimaryPrincipal();
- return p.getApplicationId().toString();
+ return p.getUser().getUuid().toString();
}
}
- return null;
+
+ return key.toString();
+ }
+
+ public void invalidate( UUID applicationId ) {
+ CacheScope scope = new CacheScope( new SimpleId(applicationId, "application") );
+ ScopedCache cache = cacheFactory.getScopedCache(scope);
+ cache.invalidate();
+
}
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCacheManager.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCacheManager.java b/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCacheManager.java
index 8ad9bd5..c4ffa83 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCacheManager.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/ShiroCacheManager.java
@@ -16,21 +16,24 @@
*/
package org.apache.usergrid.rest.security.shiro;
+import com.fasterxml.jackson.core.type.TypeReference;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
-import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
-import org.apache.shiro.subject.SimplePrincipalCollection;
-import org.apache.usergrid.corepersistence.GuiceFactory;
import org.apache.usergrid.persistence.cache.CacheFactory;
+import org.apache.usergrid.security.shiro.UsergridAuthenticationInfo;
+import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
/**
@@ -43,13 +46,44 @@ public class ShiroCacheManager implements CacheManager {
@Autowired
protected Injector injector;
+ Map<String, ShiroCache> caches = new HashMap<>();
+
public ShiroCacheManager() {
}
@Override
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
- return new ShiroCache( injector.getInstance(
- Key.get(new TypeLiteral<CacheFactory<String, SimpleAuthorizationInfo>>() {}))
- );
+ ShiroCache shiroCache = caches.get(name);
+
+ if ( shiroCache == null ) {
+
+ if ( "realm.authorizationCache".equals(name) ) {
+
+ shiroCache = new ShiroCache(
+ new TypeReference<UsergridAuthorizationInfo>(){},
+ injector.getInstance(
+ Key.get(new TypeLiteral<CacheFactory<String, UsergridAuthorizationInfo>>() { })));
+
+ } else if ( "realm.authenticationCache".equals(name)) {
+
+ shiroCache = new ShiroCache(
+ new TypeReference<UsergridAuthenticationInfo>(){},
+ injector.getInstance(
+ Key.get(new TypeLiteral<CacheFactory<String, UsergridAuthenticationInfo>>() { })));
+
+ } else {
+ throw new RuntimeException("Unknown Shiro cache name");
+ }
+
+ caches.put( name, shiroCache );
+ }
+ return shiroCache;
+ }
+
+ public void invalidateApplicationCaches( UUID applicationId ) {
+ for ( String key : caches.keySet() ) {
+ ShiroCache shiroCache = caches.get( key );
+ shiroCache.invalidate(applicationId);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
index f5cb60c..5bc2d46 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
@@ -51,7 +51,7 @@ public class PermissionsResourceIT extends AbstractRestIT {
}
- /*hi
+ /**
* Creates a user in the default org/app combo for use by all of the tests
*/
@Before
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/ClientSetup.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/ClientSetup.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/ClientSetup.java
index 853945d..fb597e2 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/ClientSetup.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/ClientSetup.java
@@ -1,6 +1,3 @@
-/**
- * Created by ApigeeCorporation on 12/4/14.
- */
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/rest/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/resources/log4j.properties b/stack/rest/src/test/resources/log4j.properties
index 3c532ae..33a25c4 100644
--- a/stack/rest/src/test/resources/log4j.properties
+++ b/stack/rest/src/test/resources/log4j.properties
@@ -34,8 +34,9 @@ log4j.logger.org.apache.shiro=DEBUG
#log4j.logger.org.apache.usergrid.persistence.cassandra=DEBUG
log4j.category.org.apache=ERROR
log4j.category.org.apache.usergrid=WARN
-log4j.category.org.apache.usergrid.rest=INFO
+log4j.category.org.apache.usergrid.rest=DEBUG
log4j.category.org.apache.usergrid.rest.security.shiro=DEBUG
+#log4j.category.org.apache.usergrid.persistence.cache=DEBUG
log4j.logger.org.apache.usergrid.persistence.cassandra.CounterUtils=ERROR
log4j.logger.org.apache.usergrid.persistence.cassandra.DB=WARN
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/management/UserInfo.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/management/UserInfo.java b/stack/services/src/main/java/org/apache/usergrid/management/UserInfo.java
index a6b9b73..c1d4d7e 100644
--- a/stack/services/src/main/java/org/apache/usergrid/management/UserInfo.java
+++ b/stack/services/src/main/java/org/apache/usergrid/management/UserInfo.java
@@ -39,17 +39,18 @@ import static org.apache.usergrid.utils.ConversionUtils.uuid;
@XmlRootElement
public class UserInfo {
- private final UUID applicationId;
- private final UUID id;
- private final String username;
- private final String name;
- private final String email;
- private final boolean activated;
- private final boolean confirmed;
- private final boolean disabled;
- private final Map<String, Object> properties;
- private final boolean admin;
-
+ private UUID applicationId;
+ private UUID id;
+ private String username;
+ private String name;
+ private String email;
+ private boolean activated;
+ private boolean confirmed;
+ private boolean disabled;
+ private Map<String, Object> properties;
+ private boolean admin;
+
+ public UserInfo() {}
public UserInfo( UUID applicationId, UUID id, String username, String name, String email, boolean confirmed,
boolean activated, boolean disabled, Map<String, Object> properties, boolean admin ) {
@@ -150,4 +151,6 @@ public class UserInfo {
public boolean isConfirmed() {
return confirmed;
}
+
+
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/Realm.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/Realm.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/Realm.java
index 013fd70..dabca6d 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/shiro/Realm.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/Realm.java
@@ -17,72 +17,29 @@
package org.apache.usergrid.security.shiro;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.apache.usergrid.management.AccountCreationProps;
-import org.apache.usergrid.management.ApplicationInfo;
-import org.apache.usergrid.management.ManagementService;
-import org.apache.usergrid.management.OrganizationInfo;
-import org.apache.usergrid.management.UserInfo;
-import org.apache.usergrid.persistence.Entity;
-import org.apache.usergrid.persistence.EntityManager;
-import org.apache.usergrid.persistence.EntityManagerFactory;
-import org.apache.usergrid.persistence.Results;
-import org.apache.usergrid.persistence.SimpleEntityRef;
-import org.apache.usergrid.persistence.entities.Group;
-import org.apache.usergrid.persistence.entities.Role;
-import org.apache.usergrid.persistence.entities.User;
-import org.apache.usergrid.security.shiro.credentials.AccessTokenCredentials;
-import org.apache.usergrid.security.shiro.credentials.AdminUserAccessToken;
-import org.apache.usergrid.security.shiro.credentials.AdminUserPassword;
-import org.apache.usergrid.security.shiro.credentials.ApplicationAccessToken;
-import org.apache.usergrid.security.shiro.credentials.ApplicationUserAccessToken;
-import org.apache.usergrid.security.shiro.credentials.ClientCredentials;
-import org.apache.usergrid.security.shiro.credentials.OrganizationAccessToken;
-import org.apache.usergrid.security.shiro.credentials.PrincipalCredentials;
-import org.apache.usergrid.security.shiro.principals.AdminUserPrincipal;
-import org.apache.usergrid.security.shiro.principals.ApplicationGuestPrincipal;
-import org.apache.usergrid.security.shiro.principals.ApplicationPrincipal;
-import org.apache.usergrid.security.shiro.principals.ApplicationUserPrincipal;
-import org.apache.usergrid.security.shiro.principals.OrganizationPrincipal;
-import org.apache.usergrid.security.shiro.principals.PrincipalIdentifier;
-import org.apache.usergrid.security.tokens.TokenInfo;
-import org.apache.usergrid.security.tokens.TokenService;
-
-import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authc.AuthenticationException;
-import org.apache.shiro.authc.AuthenticationInfo;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.authc.CredentialsException;
-import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
-import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.permission.PermissionResolver;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
+import org.apache.usergrid.management.AccountCreationProps;
+import org.apache.usergrid.management.ManagementService;
+import org.apache.usergrid.persistence.EntityManagerFactory;
+import org.apache.usergrid.security.shiro.credentials.*;
+import org.apache.usergrid.security.shiro.principals.*;
+import org.apache.usergrid.security.tokens.TokenService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
-import com.google.common.collect.HashBiMap;
-
-import static org.apache.commons.lang.StringUtils.isBlank;
-import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_SYSADMIN_LOGIN_ALLOWED;
-import org.apache.usergrid.persistence.Query.Level;
-import static org.apache.usergrid.security.shiro.utils.SubjectUtils.getPermissionFromPath;
-import static org.apache.usergrid.utils.StringUtils.stringOrSubstringAfterFirst;
-import static org.apache.usergrid.utils.StringUtils.stringOrSubstringBeforeFirst;
public class Realm extends AuthorizingRealm {
@@ -106,8 +63,8 @@ public class Realm extends AuthorizingRealm {
public Realm() {
- setCredentialsMatcher( new AllowAllCredentialsMatcher() );
- setPermissionResolver( new CustomPermissionResolver() );
+ setCredentialsMatcher(new AllowAllCredentialsMatcher());
+ setPermissionResolver(new CustomPermissionResolver());
}
@@ -127,7 +84,7 @@ public class Realm extends AuthorizingRealm {
public Realm( CacheManager cacheManager, CredentialsMatcher matcher ) {
- super( cacheManager, new AllowAllCredentialsMatcher() );
+ super(cacheManager, new AllowAllCredentialsMatcher());
setPermissionResolver( new CustomPermissionResolver() );
setCachingEnabled(true);
setAuthenticationCachingEnabled(true);
@@ -173,6 +130,25 @@ public class Realm extends AuthorizingRealm {
@Override
+ protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
+ UsergridAuthorizationInfo info = (UsergridAuthorizationInfo)super.getAuthorizationInfo(principals);
+
+ Subject currentUser = SecurityUtils.getSubject();
+ Session session = currentUser.getSession();
+ session.setAttribute( "applications", info.getApplicationSet());
+ session.setAttribute("organizations", info.getOrganizationSet());
+ if ( info.getOrganization() != null ) {
+ session.setAttribute( "organization", info.getOrganization() );
+ }
+ if ( info.getApplication() != null ) {
+ session.setAttribute( "application", info.getApplication() );
+ }
+
+ return info;
+ }
+
+
+ @Override
protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token ) throws AuthenticationException {
PrincipalCredentialsToken pcToken = ( PrincipalCredentialsToken ) token;
@@ -229,346 +205,16 @@ public class Realm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals ) {
- SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
-
- Map<UUID, String> organizationSet = HashBiMap.create();
- Map<UUID, String> applicationSet = HashBiMap.create();
- OrganizationInfo organization = null;
- ApplicationInfo application = null;
+ UsergridAuthorizationInfo info = new UsergridAuthorizationInfo();
for ( PrincipalIdentifier principal : principals.byType( PrincipalIdentifier.class ) ) {
-
- // TODO: refactor so that this whole instanceof mess can be replaced with this:
- // principle.addRolesAndPermissionsToInfo( info );
- // principle.addApplicationsToSet( applicationsSet );
- // principle.addOrganizationsToSet( applicationsSet );
- // organization = principle.getOrganization();
- // application = principle.getApplication();
-
- if ( principal instanceof OrganizationPrincipal ) {
-
- // OrganizationPricipals are usually only through OAuth
- // They have access to a single organization
-
- organization = ( ( OrganizationPrincipal ) principal ).getOrganization();
-
- role( info, principal, ROLE_ORGANIZATION_ADMIN );
- role( info, principal, ROLE_APPLICATION_ADMIN );
-
- grant( info, principal, "organizations:access:" + organization.getUuid() );
- organizationSet.put( organization.getUuid(), organization.getName() );
-
- Map<UUID, String> applications = null;
- try {
- applications = management.getApplicationsForOrganization( organization.getUuid() );
- }
- catch ( Exception e ) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- if ( ( applications != null ) && !applications.isEmpty() ) {
- grant( info, principal, "applications:admin,access,get,put,post,delete:" + StringUtils
- .join( applications.keySet(), ',' ) );
-
- applicationSet.putAll( applications );
- }
- }
- else if ( principal instanceof ApplicationPrincipal ) {
- // ApplicationPrincipal are usually only through OAuth
- // They have access to a single application
-
- role( info, principal, ROLE_APPLICATION_ADMIN );
-
- application = ( ( ApplicationPrincipal ) principal ).getApplication();
- grant( info, principal, "applications:admin,access,get,put,post,delete:" + application.getId() );
- applicationSet.put( application.getId(), application.getName().toLowerCase() );
- }
- else if ( principal instanceof AdminUserPrincipal ) {
- // AdminUserPrincipals are through basic auth and sessions
- // They have access to organizations and organization
- // applications
-
- UserInfo user = principal.getUser();
-
- if ( superUserEnabled && ( superUser != null ) && superUser.equals( user.getUsername() ) ) {
- // The system user has access to everything
-
- role( info, principal, ROLE_SERVICE_ADMIN );
- role( info, principal, ROLE_ORGANIZATION_ADMIN );
- role( info, principal, ROLE_APPLICATION_ADMIN );
- role( info, principal, ROLE_ADMIN_USER );
-
- grant( info, principal, "system:access" );
-
- grant( info, principal, "organizations:admin,access,get,put,post,delete:*" );
- grant( info, principal, "applications:admin,access,get,put,post,delete:*" );
- grant( info, principal, "organizations:admin,access,get,put,post,delete:*:/**" );
- grant( info, principal, "applications:admin,access,get,put,post,delete:*:/**" );
- grant( info, principal, "users:access:*" );
-
- grant( info, principal, getPermissionFromPath( emf.getManagementAppId(), "access" ) );
-
- grant( info, principal,
- getPermissionFromPath( emf.getManagementAppId(), "get,put,post,delete", "/**" ) );
-
- // get all organizations
- try {
-
- Map<UUID, String> allOrganizations = management.getOrganizations();
-
- if ( allOrganizations != null ) {
- for ( UUID id : allOrganizations.keySet() ) {
- grant( info, principal, "organizations:admin,access,get,put,post,delete:" + id );
- }
- organizationSet.putAll(allOrganizations);
-
- Map<UUID, String> allApplications =
- management.getApplicationsForOrganizations( allOrganizations.keySet() );
- if ( ( allApplications != null ) && !allApplications.isEmpty() ) {
- grant( info, principal, "applications:admin,access,get,put,post,delete:" + StringUtils
- .join( allApplications.keySet(), ',' ) );
- applicationSet.putAll( allApplications );
- }
- }
- }
- catch ( Exception e ) {
- logger.error( "Unable to construct superuser permissions", e );
- }
- }
- else {
-
- // For regular service users, we find what organizations
- // they're associated with
- // An service user can be associated with multiple
- // organizations
-
- grant( info, principal, getPermissionFromPath( emf.getManagementAppId(), "access" ) );
-
- // admin users cannot access the management app directly
- // so open all permissions
- grant( info, principal,
- getPermissionFromPath( emf.getManagementAppId(), "get,put,post,delete", "/**" ) );
-
- role( info, principal, ROLE_ADMIN_USER );
-
- try {
-
- Map<UUID, String> userOrganizations = management.getOrganizationsForAdminUser( user.getUuid() );
-
- if ( userOrganizations != null ) {
- for ( UUID id : userOrganizations.keySet() ) {
- grant( info, principal, "organizations:admin,access,get,put,post,delete:" + id );
- }
- organizationSet.putAll( userOrganizations );
-
- Map<UUID, String> userApplications =
- management.getApplicationsForOrganizations( userOrganizations.keySet() );
- if ( ( userApplications != null ) && !userApplications.isEmpty() ) {
- grant( info, principal, "applications:admin,access,get,put,post,delete:" + StringUtils
- .join( userApplications.keySet(), ',' ) );
- applicationSet.putAll( userApplications );
- }
-
- role( info, principal, ROLE_ORGANIZATION_ADMIN );
- role( info, principal, ROLE_APPLICATION_ADMIN );
- }
- }
- catch ( Exception e ) {
- logger.error( "Unable to construct admin user permissions", e );
- }
- }
- }
- else if ( principal instanceof ApplicationUserPrincipal ) {
-
- role( info, principal, ROLE_APPLICATION_USER );
-
- UUID applicationId = ( ( ApplicationUserPrincipal ) principal ).getApplicationId();
-
- AccessTokenCredentials tokenCredentials =
- principal.getAccessTokenCredentials();
- TokenInfo token = null;
- if ( tokenCredentials != null ) {
- try {
- token = tokens.getTokenInfo( tokenCredentials.getToken() );
- }
- catch ( Exception e ) {
- logger.error( "Unable to retrieve token info", e );
- }
- logger.debug( "Token: {}", token );
- }
-
- grant( info, principal, getPermissionFromPath( applicationId, "access" ) );
-
- /*
- * grant(info, principal, getPermissionFromPath(applicationId,
- * "get,put,post,delete", "/users/${user}",
- * "/users/${user}/feed", "/users/${user}/activities",
- * "/users/${user}/groups", "/users/${user}/following/*",
- * "/users/${user}/following/user/*"));
- */
-
- EntityManager em = emf.getEntityManager( applicationId );
- try {
- String appName = ( String ) em.getProperty( em.getApplicationRef(), "name" );
- applicationSet.put( applicationId, appName );
- application = new ApplicationInfo( applicationId, appName );
- }
- catch ( Exception e ) {
- }
-
- try {
- Set<String> permissions = em.getRolePermissions( "default" );
- grant( info, principal, applicationId, permissions );
- }
- catch ( Exception e ) {
- logger.error( "Unable to get user default role permissions", e );
- }
-
- UserInfo user = principal.getUser();
- try {
- Set<String> permissions = em.getUserPermissions( user.getUuid() );
- grant( info, principal, applicationId, permissions );
- }
- catch ( Exception e ) {
- logger.error( "Unable to get user permissions", e );
- }
-
- try {
- Set<String> rolenames = em.getUserRoles( user.getUuid() );
- grantAppRoles( info, em, applicationId, token, principal, rolenames );
- }
- catch ( Exception e ) {
- logger.error( "Unable to get user role permissions", e );
- }
-
- try {
- //TODO TN. This is woefully inefficient, but temporary. Introduce cassandra backed shiro
- // caching so this only ever happens once.
- //See USERGRID-779 for details
- Results r =
- em.getCollection( new SimpleEntityRef( User.ENTITY_TYPE, user.getUuid() ), "groups", null,
- 1000, Level.IDS, false );
- if ( r != null ) {
-
- Set<String> rolenames = new HashSet<String>();
-
- for ( UUID groupId : r.getIds() ) {
-
- Results roleResults =
- em.getCollection( new SimpleEntityRef( Group.ENTITY_TYPE, groupId ), "roles", null,
- 1000, Level.CORE_PROPERTIES, false );
-
- for ( Entity entity : roleResults.getEntities() ) {
- rolenames.add( entity.getName() );
- }
- }
-
-
- grantAppRoles( info, em, applicationId, token, principal, rolenames );
- }
- }
- catch ( Exception e ) {
- logger.error( "Unable to get user group role permissions", e );
- }
- }
- else if ( principal instanceof ApplicationGuestPrincipal ) {
- role( info, principal, ROLE_APPLICATION_USER );
-
- UUID applicationId = ( ( ApplicationGuestPrincipal ) principal ).getApplicationId();
-
- EntityManager em = emf.getEntityManager( applicationId );
- try {
- String appName = ( String ) em.getProperty( em.getApplicationRef(), "name" );
- applicationSet.put( applicationId, appName );
- application = new ApplicationInfo( applicationId, appName );
- }
- catch ( Exception e ) {
- }
-
- grant( info, principal, getPermissionFromPath( applicationId, "access" ) );
-
- try {
- Set<String> permissions = em.getRolePermissions( "guest" );
- grant( info, principal, applicationId, permissions );
- }
- catch ( Exception e ) {
- logger.error( "Unable to get user default role permissions", e );
- }
- }
- }
-
- // Store additional information in the request session to speed up
- // looking up organization info
-
- Subject currentUser = SecurityUtils.getSubject();
- Session session = currentUser.getSession();
- session.setAttribute( "applications", applicationSet );
- session.setAttribute("organizations", organizationSet);
- if ( organization != null ) {
- session.setAttribute( "organization", organization );
- }
- if ( application != null ) {
- session.setAttribute( "application", application );
+ principal.grant( info, emf, management, tokens );
}
return info;
}
- /** Grant all permissions for the role names on this application */
- private void grantAppRoles( SimpleAuthorizationInfo info, EntityManager em, UUID applicationId, TokenInfo token,
- PrincipalIdentifier principal, Set<String> rolenames ) throws Exception {
- Map<String, Role> app_roles = em.getRolesWithTitles( rolenames );
-
- for ( String rolename : rolenames ) {
- if ( ( app_roles != null ) && ( token != null ) ) {
- Role role = app_roles.get( rolename );
- if ( ( role != null ) && ( role.getInactivity() > 0 ) && ( token.getInactive() > role
- .getInactivity() ) ) {
- continue;
- }
- }
- Set<String> permissions = em.getRolePermissions( rolename );
- grant( info, principal, applicationId, permissions );
- role( info, principal,
- "application-role:".concat( applicationId.toString() ).concat( ":" ).concat( rolename ) );
- }
- }
-
-
- public static void grant( SimpleAuthorizationInfo info, PrincipalIdentifier principal, String permission ) {
- logger.debug( "Principal {} granted permission: {}", principal, permission );
- info.addStringPermission( permission );
- }
-
-
- public static void role( SimpleAuthorizationInfo info, PrincipalIdentifier principal, String role ) {
- logger.debug( "Principal {} added to role: {}", principal, role );
- info.addRole(role);
- }
-
-
- private static void grant( SimpleAuthorizationInfo info, PrincipalIdentifier principal, UUID applicationId,
- Set<String> permissions ) {
- if ( permissions != null ) {
- for ( String permission : permissions ) {
- if ( isNotBlank( permission ) ) {
- String operations = "*";
- if ( permission.indexOf( ':' ) != -1 ) {
- operations = stringOrSubstringBeforeFirst( permission, ':' );
- }
- if ( isBlank( operations ) ) {
- operations = "*";
- }
- permission = stringOrSubstringAfterFirst( permission, ':' );
- permission = "applications:" + operations + ":" + applicationId + ":" + permission;
- grant( info, principal, permission );
- }
- }
- }
- }
-
-
@Override
public boolean isAuthorizationCachingEnabled() {
return getCacheManager() != null;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/UsergridAuthenticationInfo.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/UsergridAuthenticationInfo.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/UsergridAuthenticationInfo.java
new file mode 100644
index 0000000..6f28cca
--- /dev/null
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/UsergridAuthenticationInfo.java
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.usergrid.security.shiro;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.MergableAuthenticationInfo;
+import org.apache.shiro.authc.SaltedAuthenticationInfo;
+import org.apache.shiro.subject.MutablePrincipalCollection;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.subject.SimplePrincipalCollection;
+import org.apache.shiro.util.ByteSource;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+
+/**
+ * Extend so we can control how JSON de-serialization works
+ */
+//@JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY, use= JsonTypeInfo.Id.NAME, property="class" )
+public class UsergridAuthenticationInfo implements MergableAuthenticationInfo, SaltedAuthenticationInfo {
+
+ /**
+ * The principals identifying the account associated with this AuthenticationInfo instance.
+ */
+ @JsonDeserialize(as=SimplePrincipalCollection.class)
+ protected PrincipalCollection principals;
+
+ /**
+ * The credentials verifying the account principals.
+ */
+ protected Object credentials;
+
+ /**
+ * Any salt used in hashing the credentials.
+ *
+ * @since 1.1
+ */
+ protected ByteSource credentialsSalt;
+
+ /**
+ * Default no-argument constructor.
+ */
+ public UsergridAuthenticationInfo() {
+ }
+
+ /**
+ * Constructor that takes in a single 'primary' principal of the account and its corresponding credentials,
+ * associated with the specified realm.
+ * <p/>
+ * This is a convenience constructor and will construct a {@link PrincipalCollection PrincipalCollection} based
+ * on the {@code principal} and {@code realmName} argument.
+ *
+ * @param principal the 'primary' principal associated with the specified realm.
+ * @param credentials the credentials that verify the given principal.
+ * @param realmName the realm from where the principal and credentials were acquired.
+ */
+ public UsergridAuthenticationInfo(Object principal, Object credentials, String realmName) {
+ this.principals = new SimplePrincipalCollection(principal, realmName);
+ this.credentials = credentials;
+ }
+
+ /**
+ * Constructor that takes in a single 'primary' principal of the account, its corresponding hashed credentials,
+ * the salt used to hash the credentials, and the name of the realm to associate with the principals.
+ * <p/>
+ * This is a convenience constructor and will construct a {@link PrincipalCollection PrincipalCollection} based
+ * on the <code>principal</code> and <code>realmName</code> argument.
+ *
+ * @param principal the 'primary' principal associated with the specified realm.
+ * @param hashedCredentials the hashed credentials that verify the given principal.
+ * @param credentialsSalt the salt used when hashing the given hashedCredentials
+ * @param realmName the realm from where the principal and credentials were acquired.
+ * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher
+ * @since 1.1
+ */
+ public UsergridAuthenticationInfo(Object principal, Object hashedCredentials, ByteSource credentialsSalt, String realmName) {
+ this.principals = new SimplePrincipalCollection(principal, realmName);
+ this.credentials = hashedCredentials;
+ this.credentialsSalt = credentialsSalt;
+ }
+
+ /**
+ * Constructor that takes in an account's identifying principal(s) and its corresponding credentials that verify
+ * the principals.
+ *
+ * @param principals a Realm's account's identifying principal(s)
+ * @param credentials the accounts corresponding principals that verify the principals.
+ */
+ public UsergridAuthenticationInfo(PrincipalCollection principals, Object credentials) {
+ this.principals = new SimplePrincipalCollection(principals);
+ this.credentials = credentials;
+ }
+
+ /**
+ * Constructor that takes in an account's identifying principal(s), hashed credentials used to verify the
+ * principals, and the salt used when hashing the credentials.
+ *
+ * @param principals a Realm's account's identifying principal(s)
+ * @param hashedCredentials the hashed credentials that verify the principals.
+ * @param credentialsSalt the salt used when hashing the hashedCredentials.
+ * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher
+ * @since 1.1
+ */
+ public UsergridAuthenticationInfo(PrincipalCollection principals, Object hashedCredentials, ByteSource credentialsSalt) {
+ this.principals = new SimplePrincipalCollection(principals);
+ this.credentials = hashedCredentials;
+ this.credentialsSalt = credentialsSalt;
+ }
+
+
+ public PrincipalCollection getPrincipals() {
+ return principals;
+ }
+
+ /**
+ * Sets the identifying principal(s) represented by this instance.
+ *
+ * @param principals the indentifying attributes of the corresponding Realm account.
+ */
+ public void setPrincipals(PrincipalCollection principals) {
+ this.principals = principals;
+ }
+
+ public Object getCredentials() {
+ return credentials;
+ }
+
+ /**
+ * Sets the credentials that verify the principals/identity of the associated Realm account.
+ *
+ * @param credentials attribute(s) that verify the account's identity/principals, such as a password or private key.
+ */
+ public void setCredentials(Object credentials) {
+ this.credentials = credentials;
+ }
+
+ /**
+ * Returns the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not
+ * hashed at all.
+ * <p/>
+ * Note that this attribute is <em>NOT</em> handled in the
+ * {@link #merge(AuthenticationInfo) merge} method - a hash salt is only useful within a single realm (as each
+ * realm will perform it's own Credentials Matching logic), and once finished in that realm, Shiro has no further
+ * use for salts. Therefore it doesn't make sense to 'merge' salts in a multi-realm scenario.
+ *
+ * @return the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not
+ * hashed at all.
+ * @since 1.1
+ */
+ public ByteSource getCredentialsSalt() {
+ return credentialsSalt;
+ }
+
+ /**
+ * Sets the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not
+ * hashed at all.
+ * <p/>
+ * Note that this attribute is <em>NOT</em> handled in the
+ * {@link #merge(AuthenticationInfo) merge} method - a hash salt is only useful within a single realm (as each
+ * realm will perform it's own Credentials Matching logic), and once finished in that realm, Shiro has no further
+ * use for salts. Therefore it doesn't make sense to 'merge' salts in a multi-realm scenario.
+ *
+ * @param salt the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not
+ * hashed at all.
+ * @since 1.1
+ */
+ public void setCredentialsSalt(ByteSource salt) {
+ this.credentialsSalt = salt;
+ }
+
+ /**
+ * Takes the specified <code>info</code> argument and adds its principals and credentials into this instance.
+ *
+ * @param info the <code>AuthenticationInfo</code> to add into this instance.
+ */
+ @SuppressWarnings("unchecked")
+ public void merge(AuthenticationInfo info) {
+ if (info == null || info.getPrincipals() == null || info.getPrincipals().isEmpty()) {
+ return;
+ }
+
+ if (this.principals == null) {
+ this.principals = info.getPrincipals();
+ } else {
+ if (!(this.principals instanceof MutablePrincipalCollection)) {
+ this.principals = new SimplePrincipalCollection(this.principals);
+ }
+ ((MutablePrincipalCollection) this.principals).addAll(info.getPrincipals());
+ }
+
+ //only mess with a salt value if we don't have one yet. It doesn't make sense
+ //to merge salt values from different realms because a salt is used only within
+ //the realm's credential matching process. But if the current instance's salt
+ //is null, then it can't hurt to pull in a non-null value if one exists.
+ //
+ //since 1.1:
+ if (this.credentialsSalt == null && info instanceof SaltedAuthenticationInfo) {
+ this.credentialsSalt = ((SaltedAuthenticationInfo) info).getCredentialsSalt();
+ }
+
+ Object thisCredentials = getCredentials();
+ Object otherCredentials = info.getCredentials();
+
+ if (otherCredentials == null) {
+ return;
+ }
+
+ if (thisCredentials == null) {
+ this.credentials = otherCredentials;
+ return;
+ }
+
+ if (!(thisCredentials instanceof Collection)) {
+ Set newSet = new HashSet();
+ newSet.add(thisCredentials);
+ setCredentials(newSet);
+ }
+
+ // At this point, the credentials should be a collection
+ Collection credentialCollection = (Collection) getCredentials();
+ if (otherCredentials instanceof Collection) {
+ credentialCollection.addAll((Collection) otherCredentials);
+ } else {
+ credentialCollection.add(otherCredentials);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the Object argument is an <code>instanceof SimpleAuthenticationInfo</code> and
+ * its {@link #getPrincipals() principals} are equal to this instance's principals, <code>false</code> otherwise.
+ *
+ * @param o the object to compare for equality.
+ * @return <code>true</code> if the Object argument is an <code>instanceof SimpleAuthenticationInfo</code> and
+ * its {@link #getPrincipals() principals} are equal to this instance's principals, <code>false</code> otherwise.
+ */
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof UsergridAuthenticationInfo)) return false;
+
+ UsergridAuthenticationInfo that = (UsergridAuthenticationInfo) o;
+
+ //noinspection RedundantIfStatement
+ if (principals != null ? !principals.equals(that.principals) : that.principals != null) return false;
+
+ return true;
+ }
+
+ /**
+ * Returns the hashcode of the internal {@link #getPrincipals() principals} instance.
+ *
+ * @return the hashcode of the internal {@link #getPrincipals() principals} instance.
+ */
+ public int hashCode() {
+ return (principals != null ? principals.hashCode() : 0);
+ }
+
+ /**
+ * Simple implementation that merely returns <code>{@link #getPrincipals() principals}.toString()</code>
+ *
+ * @return <code>{@link #getPrincipals() principals}.toString()</code>
+ */
+ public String toString() {
+ return principals.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/UsergridAuthorizationInfo.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/UsergridAuthorizationInfo.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/UsergridAuthorizationInfo.java
new file mode 100644
index 0000000..cad7d50
--- /dev/null
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/UsergridAuthorizationInfo.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.usergrid.security.shiro;
+
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.usergrid.management.ApplicationInfo;
+import org.apache.usergrid.management.OrganizationInfo;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+
+/**
+ * Extend so that we can add organizations and applications that user has access to.
+ */
+public class UsergridAuthorizationInfo extends SimpleAuthorizationInfo {
+
+ Map<UUID, String> organizationSet = new HashMap<>();
+ Map<UUID, String> applicationSet = new HashMap<>();
+ OrganizationInfo organization = null;
+ ApplicationInfo application = null;
+
+
+ /**
+ * Default no-argument constructor.
+ */
+ public UsergridAuthorizationInfo() { }
+
+
+ /**
+ * Creates a new instance with the specified roles and no permissions.
+ * @param roles the roles assigned to the realm account.
+ */
+ public UsergridAuthorizationInfo(Set<String> roles) {
+ this.roles = roles;
+ }
+
+ public Map<UUID, String> getOrganizationSet() {
+ return organizationSet;
+ }
+
+ public Map<UUID, String> getApplicationSet() {
+ return applicationSet;
+ }
+
+ public void setOrganization(OrganizationInfo organization) {
+ if ( organization != null ) {
+ this.organization = organization;
+ }
+ }
+
+ public OrganizationInfo getOrganization() {
+ return organization;
+ }
+
+ public void setApplication(ApplicationInfo application) {
+ if ( application != null ) {
+ this.application = application;
+ }
+ }
+
+ public ApplicationInfo getApplication() {
+ return application;
+ }
+
+ public void addApplicationSet(Map<UUID, String> applicationSet) {
+ this.applicationSet.putAll( applicationSet );
+ }
+
+ public void addOrganizationSet(Map<UUID, String> organizationSet) {
+ this.organizationSet.putAll( organizationSet );
+ }
+
+ @Override
+ public String toString() {
+ String orgName = null;
+ if ( organization != null ) {
+ orgName = organization.getName();
+ }
+ String appName = null;
+ if ( application != null ) {
+ orgName = application.getName();
+ }
+ return "{org: " + orgName + " app: " + appName + " orgs: " + organizationSet + " apps: " + applicationSet + "}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AbstractAccessTokenCredentials.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AbstractAccessTokenCredentials.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AbstractAccessTokenCredentials.java
index 290b044..ac35dcc 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AbstractAccessTokenCredentials.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AbstractAccessTokenCredentials.java
@@ -19,9 +19,11 @@ package org.apache.usergrid.security.shiro.credentials;
public abstract class AbstractAccessTokenCredentials implements AccessTokenCredentials {
- private final String token;
+ private String token;
+ public AbstractAccessTokenCredentials() {}
+
public AbstractAccessTokenCredentials( String token ) {
this.token = token;
}
@@ -31,4 +33,9 @@ public abstract class AbstractAccessTokenCredentials implements AccessTokenCrede
public String getToken() {
return token;
}
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AdminUserAccessToken.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AdminUserAccessToken.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AdminUserAccessToken.java
index 20b681f..a2f3743 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AdminUserAccessToken.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/credentials/AdminUserAccessToken.java
@@ -19,6 +19,8 @@ package org.apache.usergrid.security.shiro.credentials;
public class AdminUserAccessToken extends AbstractAccessTokenCredentials implements AdminUserCredentials {
+ public AdminUserAccessToken() {}
+
public AdminUserAccessToken( String token ) {
super( token );
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/AdminUserPrincipal.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/AdminUserPrincipal.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/AdminUserPrincipal.java
index 3a3c4d6..0e18f35 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/AdminUserPrincipal.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/AdminUserPrincipal.java
@@ -17,12 +17,153 @@
package org.apache.usergrid.security.shiro.principals;
+import com.google.common.collect.HashBiMap;
+import org.apache.commons.lang.StringUtils;
+import org.apache.usergrid.management.*;
+import org.apache.usergrid.persistence.EntityManagerFactory;
+import org.apache.usergrid.security.shiro.Realm;
+import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
+import org.apache.usergrid.security.shiro.utils.SubjectUtils;
+import org.apache.usergrid.security.tokens.TokenService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
import java.util.UUID;
-import org.apache.usergrid.management.UserInfo;
+
+import static org.apache.usergrid.security.shiro.utils.SubjectUtils.getPermissionFromPath;
+
public class AdminUserPrincipal extends UserPrincipal {
+ private static final Logger logger = LoggerFactory.getLogger(AdminUserPrincipal.class);
+
+ public AdminUserPrincipal() {
+ }
public AdminUserPrincipal( UUID managementAppId, UserInfo user ) {
super( managementAppId, user );
}
+
+ @Override
+ public void grant(
+ UsergridAuthorizationInfo info,
+ EntityManagerFactory emf,
+ ManagementService management,
+ TokenService tokens) {
+
+ // AdminUserPrincipals are through basic auth and sessions
+ // They have access to organizations and organization
+ // applications
+
+ UserInfo user = this.getUser();
+
+ Map<UUID, String> organizationSet = HashBiMap.create();
+ Map<UUID, String> applicationSet = HashBiMap.create();
+ OrganizationInfo organization = null;
+ ApplicationInfo application = null;
+
+ boolean superUserEnabled = false;
+ final String s = management.getProperties().getProperty(
+ AccountCreationProps.PROPERTIES_SYSADMIN_LOGIN_ALLOWED);
+ if ( s != null && "true".equalsIgnoreCase(s.trim())) {
+ superUserEnabled = true;
+ }
+
+ String superUser = management.getProperties().getProperty(
+ AccountCreationProps.PROPERTIES_SYSADMIN_LOGIN_NAME);
+
+ if ( superUserEnabled && ( superUser != null ) && superUser.equals( user.getUsername() ) ) {
+
+ // The system user has access to everything
+
+ role(info, Realm.ROLE_SERVICE_ADMIN);
+ role(info, Realm.ROLE_ORGANIZATION_ADMIN);
+ role(info, Realm.ROLE_APPLICATION_ADMIN);
+ role(info, Realm.ROLE_ADMIN_USER);
+
+ grant(info, "system:access");
+
+ grant(info, "organizations:admin,access,get,put,post,delete:*");
+ grant(info, "applications:admin,access,get,put,post,delete:*");
+ grant(info, "organizations:admin,access,get,put,post,delete:*:/**");
+ grant(info, "applications:admin,access,get,put,post,delete:*:/**");
+ grant(info, "users:access:*");
+
+ grant(info, SubjectUtils.getPermissionFromPath(emf.getManagementAppId(), "access"));
+
+ grant(info, SubjectUtils.getPermissionFromPath(emf.getManagementAppId(), "get,put,post,delete", "/**"));
+
+ // get all organizations
+ try {
+
+ Map<UUID, String> allOrganizations = management.getOrganizations();
+
+ if (allOrganizations != null) {
+
+ for (UUID id : allOrganizations.keySet()) {
+ grant(info, "organizations:admin,access,get,put,post,delete:" + id);
+ }
+ organizationSet.putAll(allOrganizations);
+
+ Map<UUID, String> allApplications =
+ management.getApplicationsForOrganizations(allOrganizations.keySet());
+
+ if ((allApplications != null) && ! allApplications.isEmpty()) {
+ grant(info, "applications:admin,access,get,put,post,delete:" + StringUtils
+ .join(allApplications.keySet(), ','));
+ applicationSet.putAll(allApplications);
+ }
+ }
+ } catch (Exception e) {
+ logger.error("Unable to construct superuser permissions", e);
+ }
+ }
+
+ else {
+
+ // For regular service users, we find what organizations
+ // they're associated with
+ // An service user can be associated with multiple
+ // organizations
+
+ grant( info, getPermissionFromPath( emf.getManagementAppId(), "access" ) );
+
+ // admin users cannot access the management app directly
+ // so open all permissions
+ grant( info, getPermissionFromPath(emf.getManagementAppId(), "get,put,post,delete", "/**") );
+
+ role(info, Realm.ROLE_ADMIN_USER);
+
+ try {
+
+ Map<UUID, String> userOrganizations = management.getOrganizationsForAdminUser(user.getUuid());
+
+ if ( userOrganizations != null ) {
+ for ( UUID id : userOrganizations.keySet() ) {
+ grant( info, "organizations:admin,access,get,put,post,delete:" + id );
+ }
+ organizationSet.putAll( userOrganizations );
+
+ Map<UUID, String> userApplications =
+ management.getApplicationsForOrganizations( userOrganizations.keySet() );
+ if ( ( userApplications != null ) && !userApplications.isEmpty() ) {
+ grant( info, "applications:admin,access,get,put,post,delete:" + StringUtils
+ .join(userApplications.keySet(), ',') );
+ applicationSet.putAll( userApplications );
+ }
+
+ role( info, Realm.ROLE_ORGANIZATION_ADMIN );
+ role( info, Realm.ROLE_APPLICATION_ADMIN );
+ }
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to construct admin user permissions", e );
+ }
+ }
+
+ info.setOrganization(organization);
+ info.addOrganizationSet(organizationSet);
+ info.setApplication(application);
+ info.addApplicationSet(applicationSet);
+ }
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationGuestPrincipal.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationGuestPrincipal.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationGuestPrincipal.java
index da93994..38da94d 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationGuestPrincipal.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationGuestPrincipal.java
@@ -17,16 +17,35 @@
package org.apache.usergrid.security.shiro.principals;
+import java.util.Map;
+import java.util.Set;
import java.util.UUID;
+import com.google.common.collect.HashBiMap;
import org.apache.usergrid.management.ApplicationInfo;
+import org.apache.usergrid.management.ManagementService;
+import org.apache.usergrid.management.OrganizationInfo;
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.EntityManagerFactory;
+import org.apache.usergrid.security.shiro.Realm;
+import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
+import org.apache.usergrid.security.tokens.TokenService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.usergrid.security.shiro.utils.SubjectUtils.getPermissionFromPath;
public class ApplicationGuestPrincipal extends PrincipalIdentifier {
- final ApplicationInfo application;
+ private static final Logger logger = LoggerFactory.getLogger(AdminUserPrincipal.class);
+
+
+ ApplicationInfo application;
+ public ApplicationGuestPrincipal( ) {}
+
public ApplicationGuestPrincipal( ApplicationInfo application ) {
this.application = application;
}
@@ -46,4 +65,48 @@ public class ApplicationGuestPrincipal extends PrincipalIdentifier {
public String toString() {
return application.toString();
}
+
+
+ @Override
+ public void grant(
+ UsergridAuthorizationInfo info,
+ EntityManagerFactory emf,
+ ManagementService management,
+ TokenService tokens) {
+
+ Map<UUID, String> organizationSet = HashBiMap.create();
+ Map<UUID, String> applicationSet = HashBiMap.create();
+ OrganizationInfo organization = null;
+ ApplicationInfo application = null;
+
+ role( info, Realm.ROLE_APPLICATION_USER );
+
+ UUID applicationId = getApplicationId();
+
+ EntityManager em = emf.getEntityManager( applicationId );
+ try {
+ String appName = ( String ) em.getProperty( em.getApplicationRef(), "name" );
+ applicationSet.put( applicationId, appName );
+ application = new ApplicationInfo( applicationId, appName );
+ }
+ catch ( Exception e ) {
+ }
+
+ grant( info, getPermissionFromPath( applicationId, "access" ) );
+
+ try {
+ Set<String> permissions = em.getRolePermissions( "guest" );
+ grant( info, applicationId, permissions );
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to get user default role permissions", e );
+ }
+
+
+ info.setOrganization(organization);
+ info.addOrganizationSet(organizationSet);
+ info.setApplication(application);
+ info.addApplicationSet(applicationSet);
+
+ }
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationPrincipal.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationPrincipal.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationPrincipal.java
index bdaa68e..5252052 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationPrincipal.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationPrincipal.java
@@ -17,16 +17,26 @@
package org.apache.usergrid.security.shiro.principals;
+import java.util.Map;
import java.util.UUID;
+import com.google.common.collect.HashBiMap;
import org.apache.usergrid.management.ApplicationInfo;
+import org.apache.usergrid.management.ManagementService;
+import org.apache.usergrid.management.OrganizationInfo;
+import org.apache.usergrid.persistence.EntityManagerFactory;
+import org.apache.usergrid.security.shiro.Realm;
+import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
+import org.apache.usergrid.security.tokens.TokenService;
public class ApplicationPrincipal extends PrincipalIdentifier {
- final ApplicationInfo application;
+ ApplicationInfo application;
+ public ApplicationPrincipal() {}
+
public ApplicationPrincipal( ApplicationInfo application ) {
this.application = application;
}
@@ -46,4 +56,31 @@ public class ApplicationPrincipal extends PrincipalIdentifier {
public String toString() {
return application.toString();
}
+
+ @Override
+ public void grant(
+ UsergridAuthorizationInfo info,
+ EntityManagerFactory emf,
+ ManagementService management,
+ TokenService tokens) {
+
+ // ApplicationPrincipal are usually only through OAuth
+ // They have access to a single application
+
+ Map<UUID, String> organizationSet = HashBiMap.create();
+ Map<UUID, String> applicationSet = HashBiMap.create();
+ OrganizationInfo organization = null;
+ ApplicationInfo application = null;
+
+ role( info, Realm.ROLE_APPLICATION_ADMIN );
+
+ application = getApplication();
+ grant( info, "applications:admin,access,get,put,post,delete:" + application.getId() );
+ applicationSet.put( application.getId(), application.getName().toLowerCase() );
+
+ info.setOrganization(organization);
+ info.addOrganizationSet(organizationSet);
+ info.setApplication(application);
+ info.addApplicationSet(applicationSet);
+ }
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
index 90630d8..38c5b2c 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/ApplicationUserPrincipal.java
@@ -17,13 +17,36 @@
package org.apache.usergrid.security.shiro.principals;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
import java.util.UUID;
+import com.google.common.collect.HashBiMap;
+import org.apache.usergrid.management.ApplicationInfo;
+import org.apache.usergrid.management.ManagementService;
+import org.apache.usergrid.management.OrganizationInfo;
import org.apache.usergrid.management.UserInfo;
+import org.apache.usergrid.persistence.*;
+import org.apache.usergrid.persistence.entities.Group;
+import org.apache.usergrid.persistence.entities.User;
+import org.apache.usergrid.security.shiro.Realm;
+import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
+import org.apache.usergrid.security.shiro.credentials.AccessTokenCredentials;
+import org.apache.usergrid.security.tokens.TokenInfo;
+import org.apache.usergrid.security.tokens.TokenService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.usergrid.security.shiro.utils.SubjectUtils.getPermissionFromPath;
public class ApplicationUserPrincipal extends UserPrincipal {
+ private static final Logger logger = LoggerFactory.getLogger(AdminUserPrincipal.class);
+
+ public ApplicationUserPrincipal() {}
+
public ApplicationUserPrincipal( UUID applicationId, UserInfo user ) {
super( applicationId, user );
}
@@ -33,4 +56,114 @@ public class ApplicationUserPrincipal extends UserPrincipal {
public String toString() {
return "user[" + user.getApplicationId() + "/" + user.getUuid() + "]";
}
+
+
+ @Override
+ public void grant(
+ UsergridAuthorizationInfo info,
+ EntityManagerFactory emf,
+ ManagementService management,
+ TokenService tokens) {
+
+ Map<UUID, String> organizationSet = HashBiMap.create();
+ Map<UUID, String> applicationSet = HashBiMap.create();
+ OrganizationInfo organization = null;
+ ApplicationInfo application = null;
+
+
+ role( info, Realm.ROLE_APPLICATION_USER );
+
+ UUID applicationId = getApplicationId();
+
+ AccessTokenCredentials tokenCredentials = getAccessTokenCredentials();
+ TokenInfo token = null;
+ if ( tokenCredentials != null ) {
+ try {
+ token = tokens.getTokenInfo( tokenCredentials.getToken() );
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to retrieve token info", e );
+ }
+ logger.debug( "Token: {}", token );
+ }
+
+ grant( info, getPermissionFromPath( applicationId, "access" ) );
+
+ /*
+ * grant(info, principal, getPermissionFromPath(applicationId,
+ * "get,put,post,delete", "/users/${user}",
+ * "/users/${user}/feed", "/users/${user}/activities",
+ * "/users/${user}/groups", "/users/${user}/following/*",
+ * "/users/${user}/following/user/*"));
+ */
+
+ EntityManager em = emf.getEntityManager( applicationId );
+ try {
+ String appName = ( String ) em.getProperty( em.getApplicationRef(), "name" );
+ applicationSet.put( applicationId, appName );
+ application = new ApplicationInfo( applicationId, appName );
+ }
+ catch ( Exception e ) {
+ }
+
+ try {
+ Set<String> permissions = em.getRolePermissions( "default" );
+ grant( info, applicationId, permissions );
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to get user default role permissions", e );
+ }
+
+ UserInfo user = getUser();
+ try {
+ Set<String> permissions = em.getUserPermissions( user.getUuid() );
+ grant( info, applicationId, permissions );
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to get user permissions", e );
+ }
+
+ try {
+ Set<String> rolenames = em.getUserRoles( user.getUuid() );
+ grantAppRoles( info, em, applicationId, token, rolenames );
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to get user role permissions", e );
+ }
+
+ try {
+
+ // this is woefully inefficient, thankfully we cache the info object now
+
+ Results r =
+ em.getCollection( new SimpleEntityRef( User.ENTITY_TYPE, user.getUuid() ), "groups", null,
+ 1000, Query.Level.IDS, false );
+ if ( r != null ) {
+
+ Set<String> rolenames = new HashSet<String>();
+
+ for ( UUID groupId : r.getIds() ) {
+
+ Results roleResults =
+ em.getCollection( new SimpleEntityRef( Group.ENTITY_TYPE, groupId ), "roles", null,
+ 1000, Query.Level.CORE_PROPERTIES, false );
+
+ for ( Entity entity : roleResults.getEntities() ) {
+ rolenames.add( entity.getName() );
+ }
+ }
+
+
+ grantAppRoles( info, em, applicationId, token, rolenames );
+ }
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to get user group role permissions", e );
+ }
+
+ info.setOrganization(organization);
+ info.addOrganizationSet(organizationSet);
+ info.setApplication(application);
+ info.addApplicationSet(applicationSet);
+ }
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/64876385/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/OrganizationPrincipal.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/OrganizationPrincipal.java b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/OrganizationPrincipal.java
index 6ea87cf..5c815f0 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/OrganizationPrincipal.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/shiro/principals/OrganizationPrincipal.java
@@ -17,14 +17,26 @@
package org.apache.usergrid.security.shiro.principals;
+import java.util.Map;
import java.util.UUID;
+import com.google.common.collect.HashBiMap;
+import org.apache.commons.lang.StringUtils;
+import org.apache.usergrid.management.ApplicationInfo;
+import org.apache.usergrid.management.ManagementService;
import org.apache.usergrid.management.OrganizationInfo;
+import org.apache.usergrid.persistence.EntityManagerFactory;
+import org.apache.usergrid.security.shiro.Realm;
+import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
+import org.apache.usergrid.security.tokens.TokenService;
public class OrganizationPrincipal extends PrincipalIdentifier {
- final OrganizationInfo organization;
+ OrganizationInfo organization;
+
+
+ public OrganizationPrincipal() {}
public OrganizationPrincipal( OrganizationInfo organization ) {
@@ -46,4 +58,45 @@ public class OrganizationPrincipal extends PrincipalIdentifier {
public String toString() {
return organization.toString();
}
+
+ @Override
+ public void grant(
+ UsergridAuthorizationInfo info,
+ EntityManagerFactory emf,
+ ManagementService management,
+ TokenService tokens) {
+
+ // OrganizationPricipals are usually only through OAuth
+ // They have access to a single organization
+
+ Map<UUID, String> organizationSet = HashBiMap.create();
+ Map<UUID, String> applicationSet = HashBiMap.create();
+ ApplicationInfo application = null;
+
+ role( info, Realm.ROLE_ORGANIZATION_ADMIN );
+ role( info, Realm.ROLE_APPLICATION_ADMIN );
+
+ grant( info, "organizations:access:" + organization.getUuid() );
+ organizationSet.put( organization.getUuid(), organization.getName() );
+
+ Map<UUID, String> applications = null;
+ try {
+ applications = management.getApplicationsForOrganization( organization.getUuid() );
+ }
+ catch ( Exception e ) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ if ( ( applications != null ) && !applications.isEmpty() ) {
+ grant( info, "applications:admin,access,get,put,post,delete:" + StringUtils
+ .join(applications.keySet(), ',') );
+
+ applicationSet.putAll( applications );
+ }
+
+ info.setOrganization(organization);
+ info.addOrganizationSet(organizationSet);
+ info.setApplication(application);
+ info.addApplicationSet(applicationSet);
+ }
}