/*************************************************************************
* Copyright 2009-2016 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.euare.persist;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import com.eucalyptus.auth.Accounts;
import com.eucalyptus.auth.AuthException;
import com.eucalyptus.auth.Debugging;
import com.eucalyptus.auth.InvalidAccessKeyAuthException;
import com.eucalyptus.auth.euare.persist.entities.AccessKeyEntity_;
import com.eucalyptus.auth.euare.persist.entities.AccountEntity_;
import com.eucalyptus.auth.euare.persist.entities.CertificateEntity_;
import com.eucalyptus.auth.euare.persist.entities.GroupEntity_;
import com.eucalyptus.auth.euare.persist.entities.InstanceProfileEntity;
import com.eucalyptus.auth.euare.persist.entities.InstanceProfileEntity_;
import com.eucalyptus.auth.euare.persist.entities.ManagedPolicyEntity;
import com.eucalyptus.auth.euare.persist.entities.ManagedPolicyEntity_;
import com.eucalyptus.auth.euare.persist.entities.ManagedPolicyVersionEntity;
import com.eucalyptus.auth.euare.persist.entities.ManagedPolicyVersionEntity_;
import com.eucalyptus.auth.euare.persist.entities.OpenIdProviderEntity;
import com.eucalyptus.auth.euare.persist.entities.OpenIdProviderEntity_;
import com.eucalyptus.auth.euare.persist.entities.PolicyEntity;
import com.eucalyptus.auth.euare.persist.entities.PolicyEntity_;
import com.eucalyptus.auth.euare.persist.entities.RoleEntity_;
import com.eucalyptus.auth.euare.persist.entities.ServerCertificateEntity;
import com.eucalyptus.auth.euare.persist.entities.ServerCertificateEntity_;
import com.eucalyptus.auth.euare.persist.entities.UserEntity_;
import com.eucalyptus.auth.euare.principal.EuareAccount;
import com.eucalyptus.auth.euare.principal.EuareRole;
import com.eucalyptus.auth.euare.principal.EuareUser;
import com.eucalyptus.auth.principal.AccountIdentifiers;
import com.eucalyptus.auth.principal.AccountIdentifiersImpl;
import com.eucalyptus.entities.Entities;
import org.apache.log4j.Logger;
import org.hibernate.FetchMode;
import org.hibernate.criterion.Restrictions;
import com.eucalyptus.auth.euare.AccountProvider;
import com.eucalyptus.auth.euare.checker.InvalidValueException;
import com.eucalyptus.auth.euare.checker.ValueChecker;
import com.eucalyptus.auth.euare.checker.ValueCheckerFactory;
import com.eucalyptus.auth.euare.persist.entities.AccessKeyEntity;
import com.eucalyptus.auth.euare.persist.entities.AccountEntity;
import com.eucalyptus.auth.euare.persist.entities.CertificateEntity;
import com.eucalyptus.auth.euare.persist.entities.GroupEntity;
import com.eucalyptus.auth.euare.persist.entities.RoleEntity;
import com.eucalyptus.auth.euare.persist.entities.UserEntity;
import com.eucalyptus.auth.principal.AccessKey;
import com.eucalyptus.auth.principal.Certificate;
import com.eucalyptus.entities.EntityRestriction;
import com.eucalyptus.entities.TransactionResource;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import org.hibernate.persister.collection.CollectionPropertyNames;
import javax.annotation.Nullable;
/**
* The authorization provider based on database storage. This class includes all the APIs to
* create/delete/query Eucalyptus authorization entities.
*/
public class DatabaseAuthProvider implements AccountProvider {
private static Logger LOG = Logger.getLogger( DatabaseAuthProvider.class );
private static final ValueChecker ACCOUNT_NAME_CHECKER = ValueCheckerFactory.createAccountNameChecker( );
public DatabaseAuthProvider( ) {
}
@Override
public EuareUser lookupUserById( final String userId ) throws AuthException {
if ( userId == null ) {
throw new AuthException( AuthException.EMPTY_USER_ID );
}
try ( final TransactionResource db = Entities.transactionFor( UserEntity.class ) ) {
UserEntity user = DatabaseAuthUtils.getUnique( UserEntity.class, UserEntity_.userId, userId );
db.commit( );
return new DatabaseUserProxy( user );
} catch ( NoSuchElementException e ) {
throw new AuthException( AuthException.NO_SUCH_USER, e );
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to find user by ID " + userId );
throw new AuthException( AuthException.NO_SUCH_USER, e );
}
}
@Override
public EuareRole lookupRoleById( final String roleId ) throws AuthException {
if ( roleId == null ) {
throw new AuthException( AuthException.EMPTY_ROLE_ID );
}
try ( final TransactionResource db = Entities.transactionFor( RoleEntity.class ) ) {
final RoleEntity role = DatabaseAuthUtils.getUnique( RoleEntity.class, RoleEntity_.roleId, roleId );
return new DatabaseRoleProxy( role );
} catch ( NoSuchElementException e ) {
throw new AuthException( AuthException.NO_SUCH_ROLE, e );
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to find role by ID " + roleId );
throw new AuthException( AuthException.NO_SUCH_ROLE, e );
}
}
/**
* Add account admin user separately.
*/
@Override
public EuareAccount addAccount( @Nullable String accountName ) throws AuthException {
if ( accountName != null ) {
try {
ACCOUNT_NAME_CHECKER.check( accountName );
} catch ( InvalidValueException e ) {
Debugging.logError( LOG, e, "Invalid account name " + accountName );
throw new AuthException( AuthException.INVALID_NAME, e );
}
if ( DatabaseAuthUtils.checkAccountExists( accountName ) ) {
throw new AuthException( AuthException.ACCOUNT_ALREADY_EXISTS );
}
}
return doAddAccount( accountName );
}
/**
*
*/
@Override
public EuareAccount addSystemAccount( String accountName ) throws AuthException {
if ( accountName.startsWith( AccountIdentifiers.SYSTEM_ACCOUNT_PREFIX ) ) {
try {
ACCOUNT_NAME_CHECKER.check( accountName.substring( EuareAccount.SYSTEM_ACCOUNT_PREFIX.length( ) ) );
} catch ( InvalidValueException e ) {
Debugging.logError( LOG, e, "Invalid account name " + accountName );
throw new AuthException( AuthException.INVALID_NAME, e );
}
} else if ( !AccountIdentifiers.SYSTEM_ACCOUNT.equals( accountName ) ) {
throw new AuthException( AuthException.INVALID_NAME );
}
EuareAccount account = null;
try {
account = lookupAccountByName( accountName );
} catch ( AuthException e ) {
// create it
}
if ( account == null ) {
account = doAddAccount( accountName );
}
return account;
}
/**
*
*/
private EuareAccount doAddAccount( @Nullable String accountName ) throws AuthException {
AccountEntity account = new AccountEntity( accountName );
try ( final TransactionResource db = Entities.transactionFor( AccountEntity.class ) ) {
Entities.persist( account );
db.commit( );
return new DatabaseAccountProxy( account );
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to add account " + accountName );
throw new AuthException( AuthException.ACCOUNT_CREATE_FAILURE, e );
}
}
@Override
@SuppressWarnings( "unchecked" )
public void deleteAccount( final String accountName, boolean forceDeleteSystem, boolean recursive ) throws AuthException {
if ( accountName == null ) {
throw new AuthException( AuthException.EMPTY_ACCOUNT_NAME );
}
if ( !forceDeleteSystem && Accounts.isSystemAccount( accountName ) ) {
throw new AuthException( AuthException.DELETE_SYSTEM_ACCOUNT );
}
if ( !(recursive || DatabaseAuthUtils.isAccountEmpty( accountName ) ) ) {
throw new AuthException( AuthException.ACCOUNT_DELETE_CONFLICT );
}
try ( final TransactionResource db = Entities.transactionFor( AccountEntity.class ) ) {
final Optional<AccountEntity> account = Entities.criteriaQuery( AccountEntity.class )
.whereEqual( AccountEntity_.name, accountName )
.uniqueResultOption( );
if ( !account.isPresent( ) ) {
throw new NoSuchElementException( "Can not find account " + accountName );
}
if ( recursive ) {
Entities.delete( PolicyEntity.class )
.whereIn( PolicyEntity_.id, PolicyEntity.class, PolicyEntity_.id, subquery -> subquery
.join( PolicyEntity_.group )
.join( GroupEntity_.account ).whereEqual( AccountEntity_.name, accountName ) ).delete( );
Entities.delete( PolicyEntity.class )
.whereIn( PolicyEntity_.id, PolicyEntity.class, PolicyEntity_.id, subquery -> subquery
.join( PolicyEntity_.role )
.join( RoleEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
Entities.delete( AccessKeyEntity.class )
.whereIn( AccessKeyEntity_.id, AccessKeyEntity.class, AccessKeyEntity_.id, subquery -> subquery
.join( AccessKeyEntity_.user )
.join( UserEntity_.groups ).whereEqual( GroupEntity_.userGroup, Boolean.TRUE )
.join( GroupEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
Entities.delete( CertificateEntity.class )
.whereIn( CertificateEntity_.id, CertificateEntity.class, CertificateEntity_.id, subquery -> subquery
.join( CertificateEntity_.user )
.join( UserEntity_.groups ).whereEqual( GroupEntity_.userGroup, Boolean.TRUE )
.join( GroupEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
// This deletes the entries from the user/group join table first, meaning that no users
// are then deleted as users can no longer be joined. We then delete all users that are
// not in any group as any valid user is in at least the special user group (GroupEntity#userGroup)
Entities.delete( UserEntity.class )
.whereIn( UserEntity_.uniqueName, UserEntity.class, UserEntity_.uniqueName, subquery -> subquery
.join( UserEntity_.groups ).whereEqual( GroupEntity_.userGroup, Boolean.TRUE )
.join( GroupEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
Entities.delete( UserEntity.class )
.whereIn( UserEntity_.uniqueName, UserEntity.class, UserEntity_.uniqueName, subquery -> subquery
.joinLeft( UserEntity_.groups ).where( Entities.restriction( GroupEntity.class ).isNull( GroupEntity_.id ) ) )
.delete( );
Entities.delete( ServerCertificateEntity.class )
.whereEqual( ServerCertificateEntity_.ownerAccountNumber, account.get( ).getAccountNumber( ) )
.delete( );
Entities.delete( InstanceProfileEntity.class )
.whereIn( InstanceProfileEntity_.id, InstanceProfileEntity.class, InstanceProfileEntity_.id, subquery -> subquery
.join( InstanceProfileEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
Entities.delete( OpenIdProviderEntity.class )
.whereIn( OpenIdProviderEntity_.id, OpenIdProviderEntity.class, OpenIdProviderEntity_.id, subquery -> subquery
.join( OpenIdProviderEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
// Delete roles and the assume role policies that they referenced
Entities.delete( RoleEntity.class )
.whereIn( RoleEntity_.id, RoleEntity.class, RoleEntity_.id, subquery -> subquery
.join( RoleEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
Entities.delete( PolicyEntity.class )
.whereIn( PolicyEntity_.id, PolicyEntity.class, PolicyEntity_.id, subquery -> subquery
.where( Entities.restriction( PolicyEntity.class )
.isNull( PolicyEntity_.role )
.isNull( PolicyEntity_.group )
)
.joinLeft( PolicyEntity_.assumeRole ).where( Entities.restriction( RoleEntity.class ).isNull( RoleEntity_.id ) ) )
.delete( );
Entities.delete( GroupEntity.class )
.whereIn( GroupEntity_.id, GroupEntity.class, GroupEntity_.id, subquery -> subquery
.join( GroupEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
// Delete non-default policy versions, others deleted on cascade from managed policy entity
Entities.delete( ManagedPolicyVersionEntity.class )
.whereIn( ManagedPolicyVersionEntity_.id, ManagedPolicyVersionEntity.class, ManagedPolicyVersionEntity_.id, subquery -> subquery
.whereEqual( ManagedPolicyVersionEntity_.defaultPolicy, false )
.join( ManagedPolicyVersionEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
Entities.delete( ManagedPolicyEntity.class )
.whereIn( ManagedPolicyEntity_.id, ManagedPolicyEntity.class, ManagedPolicyEntity_.id, subquery -> subquery
.join( ManagedPolicyEntity_.account ).whereEqual( AccountEntity_.name, accountName ) )
.delete( );
}
Entities.delete( account.get( ) );
db.commit( );
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to delete account " + accountName );
throw new AuthException( AuthException.NO_SUCH_ACCOUNT, e );
}
}
@Override
public List<AccountIdentifiers> resolveAccountNumbersForName( final String accountNameLike ) throws AuthException {
final List<AccountIdentifiers> results = Lists.newArrayList( );
final EntityRestriction<AccountEntity> accountNameLikeRestriction =
Entities.restriction( AccountEntity.class ).like( AccountEntity_.name, accountNameLike ).build( );
try ( final TransactionResource db = Entities.transactionFor( AccountEntity.class ) ) {
for ( final AccountEntity account : Entities.criteriaQuery( accountNameLikeRestriction ).list( ) ) {
results.add( new AccountIdentifiersImpl(
account.getAccountNumber( ),
account.getName( ),
account.getCanonicalId( )
) );
}
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to resolve account numbers" );
throw new AuthException( "Failed to resolve account numbers", e );
}
return results;
}
@Override
public List<EuareUser> listAllUsers( ) throws AuthException {
List<EuareUser> results = Lists.newArrayList( );
try ( final TransactionResource db = Entities.transactionFor( UserEntity.class ) ) {
List<UserEntity> users = Entities.criteriaQuery( UserEntity.class ).readonly( ).list( );
db.commit( );
for ( UserEntity u : users ) {
results.add( new DatabaseUserProxy( u ) );
}
return results;
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to get all users" );
throw new AuthException( "Failed to get all users", e );
}
}
@Override
public List<EuareAccount> listAllAccounts( ) throws AuthException {
List<EuareAccount> results = Lists.newArrayList( );
try ( final TransactionResource db = Entities.transactionFor( AccountEntity.class ) ) {
for ( AccountEntity account : Entities.criteriaQuery( AccountEntity.class ).readonly( ).list( ) ) {
results.add( new DatabaseAccountProxy( account ) );
}
return results;
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to get accounts" );
throw new AuthException( "Failed to accounts", e );
}
}
@Override
public Certificate lookupCertificateByHashId( String certificateId ) throws AuthException {
if ( certificateId == null ) {
throw new AuthException( "Certificate identifier required" );
}
try ( final TransactionResource db = Entities.transactionFor( CertificateEntity.class ) ) {
CertificateEntity certEntity = DatabaseAuthUtils.getUnique( CertificateEntity.class, CertificateEntity_.certificateHashId, certificateId );
db.commit( );
return new DatabaseCertificateProxy( certEntity );
} catch ( NoSuchElementException e ) {
throw new AuthException( AuthException.NO_SUCH_CERTIFICATE, e );
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to lookup cert " + certificateId );
throw new AuthException( AuthException.NO_SUCH_CERTIFICATE, e );
}
}
@Override
public Certificate lookupCertificateById( String certificateId ) throws AuthException {
if ( certificateId == null ) {
throw new AuthException( "Certificate identifier required" );
}
try ( final TransactionResource db = Entities.transactionFor( CertificateEntity.class ) ) {
CertificateEntity certEntity = DatabaseAuthUtils.getUnique( CertificateEntity.class, CertificateEntity_.certificateId, certificateId );
db.commit( );
return new DatabaseCertificateProxy( certEntity );
} catch ( NoSuchElementException e ) {
throw new AuthException( AuthException.NO_SUCH_CERTIFICATE, e );
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to lookup cert " + certificateId );
throw new AuthException( AuthException.NO_SUCH_CERTIFICATE, e );
}
}
@Override
public EuareAccount lookupAccountByName( String accountName ) throws AuthException {
if ( accountName == null ) {
throw new AuthException( AuthException.EMPTY_ACCOUNT_NAME );
}
try ( final TransactionResource db = Entities.transactionFor( CertificateEntity.class ) ) {
final Optional<AccountEntity> result = Entities.criteriaQuery( AccountEntity.class )
.whereEqual( AccountEntity_.name, accountName )
.readonly( )
.uniqueResultOption( );
if ( !result.isPresent( ) ) {
throw new AuthException( AuthException.NO_SUCH_ACCOUNT );
}
return new DatabaseAccountProxy( result.get( ) );
} catch ( AuthException e ) {
throw e;
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to find account " + accountName );
throw new AuthException( AuthException.NO_SUCH_ACCOUNT, e );
}
}
@Override
public EuareAccount lookupAccountById( final String accountId ) throws AuthException {
if ( accountId == null ) {
throw new AuthException( AuthException.EMPTY_ACCOUNT_ID );
}
try ( final TransactionResource db = Entities.transactionFor( AccountEntity.class ) ) {
AccountEntity account = DatabaseAuthUtils.getUnique( AccountEntity.class, AccountEntity_.accountNumber, accountId );
db.commit( );
return new DatabaseAccountProxy( account );
} catch ( NoSuchElementException e ) {
throw new AuthException( AuthException.NO_SUCH_ACCOUNT, e );
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to find account " + accountId );
throw new AuthException( AuthException.NO_SUCH_ACCOUNT, e );
}
}
@Override
public EuareAccount lookupAccountByCanonicalId( final String canonicalId ) throws AuthException {
if ( canonicalId == null || "".equals(canonicalId) ) {
throw new AuthException( AuthException.EMPTY_CANONICAL_ID );
}
try ( final TransactionResource db = Entities.transactionFor( AccountEntity.class ) ) {
final Optional<AccountEntity> result = Entities.criteriaQuery( AccountEntity.class )
.whereEqual( AccountEntity_.canonicalId, canonicalId )
.readonly( )
.uniqueResultOption( );
if ( result.isPresent( ) ) {
return new DatabaseAccountProxy( result.get( ) );
} else {
throw new AuthException( AuthException.NO_SUCH_USER );
}
} catch ( AuthException e ) {
throw e;
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Error occurred looking for account by canonical ID " + canonicalId );
throw new AuthException( AuthException.NO_SUCH_USER, e );
}
}
@Override
public AccessKey lookupAccessKeyById( final String keyId ) throws AuthException {
if ( keyId == null ) {
throw new AuthException( "Empty access key ID" );
}
try ( final TransactionResource db = Entities.transactionFor( AccessKeyEntity.class ) ) {
AccessKeyEntity keyEntity = DatabaseAuthUtils.getUnique( AccessKeyEntity.class, AccessKeyEntity_.accessKey, keyId );
db.commit( );
return new DatabaseAccessKeyProxy( keyEntity );
} catch ( NoSuchElementException e ) {
throw new InvalidAccessKeyAuthException( "Failed to find access key", e );
} catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to find access key with ID " + keyId );
throw new InvalidAccessKeyAuthException( "Failed to find access key", e );
}
}
public EuareUser lookupUserByEmailAddress( String email ) throws AuthException {
if (email == null || "".equals(email)) {
throw new AuthException("Empty email address to search");
}
try ( final TransactionResource tx = Entities.transactionFor( UserEntity.class ) ) {
final UserEntity match = (UserEntity) Entities.createCriteria(UserEntity.class)
.setCacheable(true)
.createAlias("info", "i") //TODO:STEVE: case insensitive compare
.add(Restrictions.eq("i." + CollectionPropertyNames.COLLECTION_ELEMENTS, email).ignoreCase())
.setFetchMode("info", FetchMode.JOIN)
.setReadOnly( true )
.uniqueResult();
if (match == null) {
throw new AuthException(AuthException.NO_SUCH_USER);
}
boolean emailMatched = false;
Map<String,String> info = match.getInfo();
if ( info != null ) {
for (Map.Entry<String,String> entry : info.entrySet()) {
if (entry.getKey() != null
&& EuareUser.EMAIL.equals( entry.getKey() )
&& entry.getValue() != null
&& email.equalsIgnoreCase(entry.getValue())) {
emailMatched = true;
break;
}
}
}
if (! emailMatched) {
throw new AuthException(AuthException.NO_SUCH_USER);
}
return new DatabaseUserProxy(match);
}
catch ( AuthException e ) {
throw e;
}
catch ( Exception e ) {
Debugging.logError( LOG, e, "Failed to find user by email address " + email );
throw new AuthException( AuthException.NO_SUCH_USER, e );
}
}
}