Java tutorial
/************************************************************************* * Copyright 2009-2012 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. * * This file may incorporate work covered under the following copyright * and permission notice: * * Software License Agreement (BSD License) * * Copyright (c) 2008, Regents of the University of California * All rights reserved. * * Redistribution and use of this software in source and binary forms, * with or without modification, are permitted provided that the * following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE * THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL, * COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE, * AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, * SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, * WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, * REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO * IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT * NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS. ************************************************************************/ package com.eucalyptus.auth; import java.io.IOException; import java.io.ObjectInputStream; import java.security.cert.X509Certificate; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.hibernate.criterion.Restrictions; import com.eucalyptus.auth.checker.InvalidValueException; import com.eucalyptus.auth.checker.ValueChecker; import com.eucalyptus.auth.checker.ValueCheckerFactory; import com.eucalyptus.auth.entities.AccessKeyEntity; import com.eucalyptus.auth.entities.AccountEntity; import com.eucalyptus.auth.entities.AuthorizationEntity; import com.eucalyptus.auth.entities.CertificateEntity; import com.eucalyptus.auth.entities.ConditionEntity; import com.eucalyptus.auth.entities.GroupEntity; import com.eucalyptus.auth.entities.PolicyEntity; import com.eucalyptus.auth.entities.StatementEntity; import com.eucalyptus.auth.entities.UserEntity; import com.eucalyptus.auth.policy.PolicyParser; import com.eucalyptus.auth.principal.AccessKey; import com.eucalyptus.auth.principal.Account; import com.eucalyptus.auth.principal.Authorization; import com.eucalyptus.auth.principal.Certificate; import com.eucalyptus.auth.principal.Group; import com.eucalyptus.auth.principal.Policy; import com.eucalyptus.auth.principal.User; import com.eucalyptus.auth.principal.Authorization.EffectType; import com.eucalyptus.auth.util.X509CertHelper; import com.eucalyptus.crypto.Crypto; import com.eucalyptus.entities.Entities; import com.eucalyptus.entities.EntityWrapper; import java.util.concurrent.ExecutionException; import com.eucalyptus.util.Exceptions; import com.eucalyptus.util.Tx; import com.google.common.base.Strings; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class DatabaseUserProxy implements User { private static final long serialVersionUID = 1L; private static Logger LOG = Logger.getLogger(DatabaseUserProxy.class); private static final ValueChecker NAME_CHECKER = ValueCheckerFactory.createUserAndGroupNameChecker(); private static final ValueChecker PATH_CHECKER = ValueCheckerFactory.createPathChecker(); private static final ValueChecker POLICY_NAME_CHECKER = ValueCheckerFactory.createPolicyNameChecker(); private UserEntity delegate; private transient Supplier<String> accountNumberSupplier = DatabaseAuthUtils.getAccountNumberSupplier(this); private transient Supplier<Map<String, String>> userInfoSupplier = getUserInfoSupplier(); public DatabaseUserProxy(UserEntity delegate) { this.delegate = delegate; } public DatabaseUserProxy(UserEntity delegate, String accountNumber) { this.delegate = delegate; accountNumberSupplier = Suppliers.ofInstance(accountNumber); } public DatabaseUserProxy(UserEntity delegate, String accountNumber, Map<String, String> info) { this.delegate = delegate; accountNumberSupplier = Suppliers.ofInstance(accountNumber); userInfoSupplier = Suppliers.ofInstance(info); } @Override public String toString() { final StringBuilder sb = new StringBuilder(); try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { sb.append(t.toString()); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to toString for " + this.delegate); } return sb.toString(); } @Override public String getName() { return this.delegate.getName(); } @Override public String getUserId() { return this.delegate.getUserId(); } @Override public void setName(String name) throws AuthException { try { NAME_CHECKER.check(name); } catch (InvalidValueException e) { Debugging.logError(LOG, e, "Invalid user name " + name); throw new AuthException(AuthException.INVALID_NAME, e); } try { // try looking up the user with same name this.getAccount().lookupUserByName(name); } catch (AuthException e) { // not found EntityWrapper<UserEntity> db = EntityWrapper.get(UserEntity.class); try { UserEntity user = DatabaseAuthUtils.getUnique(db, UserEntity.class, "userId", this.delegate.getUserId()); user.setName(name); for (GroupEntity g : user.getGroups()) { if (g.isUserGroup()) { g.setName(DatabaseAuthUtils.getUserGroupName(name)); break; } } db.commit(); } catch (Exception t) { Debugging.logError(LOG, t, "Failed to setName for " + this.delegate); db.rollback(); throw new AuthException(t); } return; } // found throw new AuthException(AuthException.USER_ALREADY_EXISTS); } @Override public String getPath() { return this.delegate.getPath(); } @Override public void setPath(final String path) throws AuthException { try { PATH_CHECKER.check(path); } catch (InvalidValueException e) { Debugging.logError(LOG, e, "Invalid path " + path); throw new AuthException(AuthException.INVALID_PATH, e); } try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.setPath(path); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setPath for " + this.delegate); throw new AuthException(e); } } @Override public RegistrationStatus getRegistrationStatus() { return this.delegate.getRegistrationStatus(); } @Override public void setRegistrationStatus(final RegistrationStatus stat) throws AuthException { try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.setRegistrationStatus(stat); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setRegistrationStatus for " + this.delegate); throw new AuthException(e); } } @Override public Boolean isEnabled() { return this.delegate.isEnabled(); } @Override public void setEnabled(final Boolean enabled) throws AuthException { try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.setEnabled(enabled); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setEnabled for " + this.delegate); throw new AuthException(e); } } @Override public String getToken() { return this.delegate.getToken(); } @Override public void setToken(final String token) throws AuthException { try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.setToken(token); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setToken for " + this.delegate); throw new AuthException(e); } } @Override public String resetToken() throws AuthException { String original = this.delegate.getToken(); this.setToken(Crypto.generateSessionToken()); return original; } @Override public String getConfirmationCode() { return this.delegate.getConfirmationCode(); } @Override public void setConfirmationCode(final String code) throws AuthException { try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.setConfirmationCode(code); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setConfirmationCode for " + this.delegate); throw new AuthException(e); } } @Override public void createConfirmationCode() throws AuthException { this.setConfirmationCode(Crypto.generateSessionToken()); } @Override public String getPassword() { return this.delegate.getPassword(); } @Override public void setPassword(final String password) throws AuthException { try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.setPassword(password); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setPassword for " + this.delegate); throw new AuthException(e); } } @Override public void createPassword() throws AuthException { this.setPassword(Crypto.generateEncryptedPassword(this.delegate.getName())); } @Override public Long getPasswordExpires() { return this.delegate.getPasswordExpires(); } @Override public void setPasswordExpires(final Long time) throws AuthException { try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.setPasswordExpires(time); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setPasswordExpires for " + this.delegate); throw new AuthException(e); } } @Override public String getInfo(final String key) throws AuthException { return DatabaseAuthUtils.extract(userInfoSupplier).get(key.toLowerCase()); } @Override public Map<String, String> getInfo() throws AuthException { return DatabaseAuthUtils.extract(userInfoSupplier); } @Override public void setInfo(final String key, final String value) throws AuthException { if (Strings.isNullOrEmpty(key)) { throw new AuthException("Empty key"); } try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.getInfo().put(key.toLowerCase(), value); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setInfo for " + this.delegate); throw new AuthException(e); } } @Override public void removeInfo(final String key) throws AuthException { if (Strings.isNullOrEmpty(key)) { throw new AuthException("Empty key"); } try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.getInfo().remove(key.toLowerCase()); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to removeInfo for " + this.delegate); throw new AuthException(e); } } @Override public void setInfo(final Map<String, String> newInfo) throws AuthException { if (newInfo == null) { throw new AuthException("Empty user info map"); } try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { t.getInfo().clear(); for (Map.Entry<String, String> entry : newInfo.entrySet()) { t.getInfo().put(entry.getKey().toLowerCase(), entry.getValue()); } } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to setInfo for " + this.delegate); throw new AuthException(e); } } @Override public List<AccessKey> getKeys() throws AuthException { final List<AccessKey> results = Lists.newArrayList(); try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { for (AccessKeyEntity k : t.getKeys()) { results.add(new DatabaseAccessKeyProxy(k)); } } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to getKeys for " + this.delegate); throw new AuthException(e); } return results; } @Override public AccessKey getKey(final String keyId) throws AuthException { EntityWrapper<AccessKeyEntity> db = EntityWrapper.get(AccessKeyEntity.class); try { AccessKeyEntity key = DatabaseAuthUtils.getUnique(db, AccessKeyEntity.class, "accessKey", keyId); db.commit(); return new DatabaseAccessKeyProxy(key); } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to get access key " + keyId); throw new AuthException(AuthException.NO_SUCH_KEY); } } @Override public void removeKey(final String keyId) throws AuthException { if (Strings.isNullOrEmpty(keyId)) { throw new AuthException(AuthException.EMPTY_KEY_ID); } EntityWrapper<UserEntity> db = EntityWrapper.get(UserEntity.class); try { UserEntity user = DatabaseAuthUtils.getUnique(db, UserEntity.class, "userId", this.delegate.getUserId()); AccessKeyEntity keyEntity = DatabaseAuthUtils.getUnique(db.recast(AccessKeyEntity.class), AccessKeyEntity.class, "accessKey", keyId); user.getKeys().remove(keyEntity); db.recast(AccessKeyEntity.class).delete(keyEntity); db.commit(); } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to get delete key " + keyId); throw new AuthException(e); } } @Override public AccessKey createKey() throws AuthException { EntityWrapper<UserEntity> db = EntityWrapper.get(UserEntity.class); try { UserEntity user = DatabaseAuthUtils.getUnique(db, UserEntity.class, "userId", this.delegate.getUserId()); AccessKeyEntity keyEntity = new AccessKeyEntity(user); keyEntity.setActive(true); db.recast(AccessKeyEntity.class).add(keyEntity); user.getKeys().add(keyEntity); db.commit(); return new DatabaseAccessKeyProxy(keyEntity); } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to get create new access key: " + e.getMessage()); throw new AuthException(e); } } @Override public List<Certificate> getCertificates() throws AuthException { final List<Certificate> results = Lists.newArrayList(); try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { for (CertificateEntity c : t.getCertificates()) { results.add(new DatabaseCertificateProxy(c)); } } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to getCertificates for " + this.delegate); throw new AuthException(e); } return results; } @Override public Certificate getCertificate(final String certificateId) throws AuthException { EntityWrapper<CertificateEntity> db = EntityWrapper.get(CertificateEntity.class); try { CertificateEntity cert = DatabaseAuthUtils.getUnique(db, CertificateEntity.class, "certificateId", certificateId); db.commit(); return new DatabaseCertificateProxy(cert); } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to get signing certificate " + certificateId); throw new AuthException(AuthException.NO_SUCH_CERTIFICATE); } } @Override public Certificate addCertificate(X509Certificate cert) throws AuthException { EntityWrapper<UserEntity> db = EntityWrapper.get(UserEntity.class); try { UserEntity user = DatabaseAuthUtils.getUnique(db, UserEntity.class, "userId", this.delegate.getUserId()); CertificateEntity certEntity = new CertificateEntity(X509CertHelper.fromCertificate(cert)); certEntity.setActive(true); certEntity.setRevoked(false); db.recast(CertificateEntity.class).add(certEntity); certEntity.setUser(user); user.getCertificates().add(certEntity); db.commit(); return new DatabaseCertificateProxy(certEntity); } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to get add certificate " + cert); throw new AuthException(e); } } @Override public void removeCertificate(final String certificateId) throws AuthException { if (Strings.isNullOrEmpty(certificateId)) { throw new AuthException(AuthException.EMPTY_CERT_ID); } EntityWrapper<CertificateEntity> db = EntityWrapper.get(CertificateEntity.class); try { CertificateEntity certificateEntity = DatabaseAuthUtils.getUnique(db, CertificateEntity.class, "certificateId", certificateId); certificateEntity.setRevoked(true); db.commit(); } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to get delete certificate " + certificateId); throw new AuthException(e); } } @Override public List<Group> getGroups() throws AuthException { final List<Group> results = Lists.newArrayList(); try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { for (GroupEntity g : t.getGroups()) { results.add(new DatabaseGroupProxy(g)); } } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to getGroups for " + this.delegate); throw new AuthException(e); } return results; } @Override public String getAccountNumber() throws AuthException { return DatabaseAuthUtils.extract(accountNumberSupplier); } @Override public Account getAccount() throws AuthException { final List<Account> results = Lists.newArrayList(); try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { if (t.getGroups().size() < 1) { throw new RuntimeException("Unexpected group number of the user"); } final AccountEntity account = t.getGroups().get(0).getAccount(); Entities.initialize(account); results.add(new DatabaseAccountProxy(account)); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to getAccount for " + this.delegate); throw new AuthException(e); } return results.get(0); } @Override public boolean isSystemAdmin() { try { return DatabaseAuthUtils.isSystemAccount(this.getAccount().getName()); } catch (AuthException e) { LOG.error(e, e); return false; } } @Override public boolean isSystemUser() { return isSystemAdmin(); } @Override public boolean isAccountAdmin() { return DatabaseAuthUtils.isAccountAdmin(this.getName()); } private GroupEntity getUserGroupEntity(UserEntity userEntity) { GroupEntity groupEntity = null; for (GroupEntity g : userEntity.getGroups()) { if (g.isUserGroup()) { groupEntity = g; break; } } return groupEntity; } @Override public List<Policy> getPolicies() throws AuthException { List<Policy> results = Lists.newArrayList(); EntityWrapper<UserEntity> db = EntityWrapper.get(UserEntity.class); try { UserEntity user = DatabaseAuthUtils.getUnique(db, UserEntity.class, "userId", this.delegate.getUserId()); GroupEntity group = getUserGroupEntity(user); if (group == null) { throw new RuntimeException("Can't find user group for user " + this.delegate.getName()); } for (PolicyEntity p : group.getPolicies()) { results.add(new DatabasePolicyProxy(p)); } db.commit(); return results; } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to get policies for " + this.delegate); throw new AuthException("Failed to get policies", e); } } @Override public Policy addPolicy(String name, String policy) throws AuthException, PolicyParseException { try { POLICY_NAME_CHECKER.check(name); } catch (InvalidValueException e) { Debugging.logError(LOG, e, "Invalid policy name " + name); throw new AuthException(AuthException.INVALID_NAME, e); } if (DatabaseAuthUtils.policyNameinList(name, this.getPolicies())) { Debugging.logError(LOG, null, "Policy name already used: " + name); throw new AuthException(AuthException.INVALID_NAME); } PolicyEntity parsedPolicy = PolicyParser.getInstance().parse(policy); if (this.isAccountAdmin() && parsedPolicy.containsAllowEffect()) { throw new PolicyParseException("Policy with Allow effect can not be assigned to account/account admin"); } parsedPolicy.setName(name); EntityWrapper<UserEntity> db = EntityWrapper.get(UserEntity.class); try { UserEntity userEntity = DatabaseAuthUtils.getUnique(db, UserEntity.class, "userId", this.delegate.getUserId()); GroupEntity groupEntity = getUserGroupEntity(userEntity); if (groupEntity == null) { throw new RuntimeException("Can't find user group for user " + this.delegate.getName()); } db.recast(PolicyEntity.class).add(parsedPolicy); parsedPolicy.setGroup(groupEntity); for (StatementEntity statement : parsedPolicy.getStatements()) { db.recast(StatementEntity.class).add(statement); statement.setPolicy(parsedPolicy); for (AuthorizationEntity auth : statement.getAuthorizations()) { db.recast(AuthorizationEntity.class).add(auth); auth.setStatement(statement); } for (ConditionEntity cond : statement.getConditions()) { db.recast(ConditionEntity.class).add(cond); cond.setStatement(statement); } } groupEntity.getPolicies().add(parsedPolicy); db.commit(); return new DatabasePolicyProxy(parsedPolicy); } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to attach policy for " + this.delegate.getName()); throw new AuthException("Failed to attach policy", e); } } @Override public void removePolicy(String name) throws AuthException { if (Strings.isNullOrEmpty(name)) { throw new AuthException(AuthException.EMPTY_POLICY_NAME); } EntityWrapper<UserEntity> db = EntityWrapper.get(UserEntity.class); try { UserEntity user = DatabaseAuthUtils.getUnique(db, UserEntity.class, "userId", this.delegate.getUserId()); GroupEntity group = getUserGroupEntity(user); if (group == null) { throw new RuntimeException("Can't find user group for user " + this.delegate.getName()); } PolicyEntity policy = DatabaseAuthUtils.removeGroupPolicy(group, name); if (policy != null) { db.recast(PolicyEntity.class).delete(policy); } db.commit(); } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to remove policy " + name + " in " + this.delegate); throw new AuthException("Failed to remove policy", e); } } @Override public List<Authorization> lookupAuthorizations(String resourceType) throws AuthException { String userId = this.delegate.getUserId(); if (resourceType == null) { throw new AuthException("Empty resource type"); } EntityWrapper<AuthorizationEntity> db = EntityWrapper.get(AuthorizationEntity.class); try { @SuppressWarnings("unchecked") List<AuthorizationEntity> authorizations = (List<AuthorizationEntity>) db .createCriteria(AuthorizationEntity.class).setCacheable(true) .add(Restrictions.and(Restrictions.eq("type", resourceType), Restrictions.or(Restrictions.eq("effect", EffectType.Allow), Restrictions.eq("effect", EffectType.Deny)))) .createCriteria("statement").setCacheable(true).createCriteria("policy").setCacheable(true) .createCriteria("group").setCacheable(true).createCriteria("users").setCacheable(true) .add(Restrictions.eq("userId", userId)).list(); db.commit(); List<Authorization> results = Lists.newArrayList(); for (AuthorizationEntity auth : authorizations) { results.add(new DatabaseAuthorizationProxy(auth)); } return results; } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to lookup authorization for user with ID " + userId + ", type=" + resourceType); throw new AuthException("Failed to lookup auth", e); } } @Override public List<Authorization> lookupQuotas(String resourceType) throws AuthException { String userId = this.delegate.getUserId(); EntityWrapper<AuthorizationEntity> db = EntityWrapper.get(AuthorizationEntity.class); try { @SuppressWarnings("unchecked") List<AuthorizationEntity> authorizations = (List<AuthorizationEntity>) db .createCriteria(AuthorizationEntity.class).setCacheable(true) .add(Restrictions.and(Restrictions.eq("type", resourceType), Restrictions.eq("effect", EffectType.Limit))) .createCriteria("statement").setCacheable(true).createCriteria("policy").setCacheable(true) .createCriteria("group").setCacheable(true).createCriteria("users") .add(Restrictions.eq("userId", userId)).list(); db.commit(); List<Authorization> results = Lists.newArrayList(); for (AuthorizationEntity auth : authorizations) { results.add(new DatabaseAuthorizationProxy(auth)); } return results; } catch (Exception e) { db.rollback(); Debugging.logError(LOG, e, "Failed to lookup quotas for user with ID " + userId + ", type=" + resourceType); throw new AuthException("Failed to lookup quota", e); } } private Supplier<Map<String, String>> getUserInfoSupplier() { return new Supplier<Map<String, String>>() { @Override public Map<String, String> get() { final Map<String, String> results = Maps.newHashMap(); try { DatabaseAuthUtils.invokeUnique(UserEntity.class, "userId", DatabaseUserProxy.this.delegate.getUserId(), new Tx<UserEntity>() { public void fire(UserEntity t) { results.putAll(t.getInfo()); } }); } catch (ExecutionException e) { Debugging.logError(LOG, e, "Failed to getInfo for " + DatabaseUserProxy.this.delegate); throw new RuntimeException(new AuthException(e).fillInStackTrace()); } return results; } }; } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.accountNumberSupplier = DatabaseAuthUtils.getAccountNumberSupplier(this); this.userInfoSupplier = getUserInfoSupplier(); } }