package com.eucalyptus.auth;
import java.security.Principal;
import java.util.Enumeration;
import java.util.List;
import org.apache.log4j.Logger;
import com.eucalyptus.auth.principal.Authorization;
import com.eucalyptus.auth.principal.BaseAuthorization;
import com.eucalyptus.auth.principal.Group;
import com.eucalyptus.auth.principal.User;
import com.eucalyptus.entities.EntityWrapper;
import com.eucalyptus.records.EventClass;
import com.eucalyptus.records.EventRecord;
import com.eucalyptus.records.EventType;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.FinalReturn;
import com.eucalyptus.util.TransactionException;
import com.eucalyptus.util.Transactions;
import com.eucalyptus.util.Tx;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
public class DatabaseWrappedGroup implements Group {
private static Logger LOG = Logger.getLogger( DatabaseWrappedGroup.class );
public static Group newInstance( Group g ) {
if( Groups.NAME_ALL.equals( g.getName( ) ) ) {
return new AllGroup( g );
} else {
return new DatabaseWrappedGroup( g );
}
}
private GroupEntity searchGroup;
private Group group;
protected DatabaseWrappedGroup( Group group ) {
this.searchGroup = new GroupEntity( group.getName( ) );
this.group = group;
}
@Override
public boolean addMember( Principal principal ) {
EntityWrapper<UserEntity> db = Authentication.getEntityWrapper( );
try {
UserEntity user = db.getUnique( new UserEntity( principal.getName( ) ) );
GroupEntity g = db.recast( GroupEntity.class ).getUnique( this.searchGroup );
if ( !g.isMember( user ) ) {
g.addMember( user );
db.commit( );
EventRecord.here( Groups.class, EventClass.GROUP, EventType.GROUP_MEMBER_ADDED, this.getName( ), user.getName( ) ).info();
return true;
} else {
db.rollback( );
return false;
}
} catch ( EucalyptusCloudException e ) {
LOG.debug( e, e );
db.rollback( );
return false;
}
}
@Override
public boolean isMember( Principal member ) {
EntityWrapper<UserEntity> db = Authentication.getEntityWrapper( );
try {
boolean ret = this.group.isMember( db.getUnique( new UserEntity( member.getName( ) ) ) );
db.commit( );
return ret;
} catch ( EucalyptusCloudException e ) {
LOG.debug( e, e );
db.rollback( );
return false;
}
}
@Override
public Enumeration<? extends Principal> members( ) {
final List<User> userList = Lists.newArrayList( );
try {
Transactions.one( this.searchGroup, new Tx<GroupEntity>( ) {
@Override
public void fire( GroupEntity t ) throws Throwable {
for( User user : t.getMembers( ) ) {
try {
userList.add( Users.lookupUser( user.getName( ) ) );
} catch ( NoSuchUserException e ) {
LOG.debug( e, e );
}
}
}
} );
} catch ( TransactionException e1 ) {
LOG.debug( e1, e1 );
}
return Iterators.asEnumeration( userList.iterator( ) );
}
@Override
public boolean removeMember( Principal user ) {
EntityWrapper<UserEntity> db = Authentication.getEntityWrapper( );
try {
UserEntity userInfo = db.getUnique( new UserEntity( user.getName( ) ) );
GroupEntity g = db.recast( GroupEntity.class ).getUnique( this.searchGroup );
if ( g.isMember( userInfo ) ) {
g.removeMember( userInfo );
db.commit( );
EventRecord.here( Groups.class, EventClass.GROUP, EventType.GROUP_MEMBER_REMOVED, this.getName( ), userInfo.getName( ) ).info();
return true;
} else {
db.rollback( );
return false;
}
} catch ( EucalyptusCloudException e ) {
LOG.debug( e, e );
db.rollback( );
return false;
}
}
@Override
public String getName( ) {
return this.group.getName( );
}
@Override
public boolean equals( Object o ) {
if ( this == o ) return true;
if ( o instanceof GroupEntity ) {
GroupEntity that = ( GroupEntity ) o;
return this.group.equals( that );
} else if ( o instanceof DatabaseWrappedGroup ) {
DatabaseWrappedGroup that = ( DatabaseWrappedGroup ) o;
return this.group.equals( that.group );
} else {
return false;
}
}
@Override
public boolean addAuthorization( final Authorization authorization ) {
if ( authorization instanceof BaseAuthorization ) {
BaseAuthorization auth = ( BaseAuthorization ) authorization;
EntityWrapper<BaseAuthorization> db = EntityWrapper.get( BaseAuthorization.class );
boolean ret = false;
try {
db.add( auth );
GroupEntity g = db.recast( GroupEntity.class ).getUnique( searchGroup );
ret = g.addAuthorization( auth );
db.recast( GroupEntity.class ).merge( g );
this.group = g;
db.commit( );
EventRecord.here( Groups.class, EventClass.GROUP, EventType.GROUP_AUTH_GRANTED, this.getName( ), auth.getDisplayName( ), auth.getValue( ) ).info();
} catch ( Throwable e ) {
ret = false;
LOG.debug( e, e );
db.rollback( );
}
return ret;
} else {
throw new RuntimeException( "Authorizations must extend from BaseAuthorization, passed: " + authorization.getClass( ).getCanonicalName( ) );
}
}
@Override
public ImmutableList<Authorization> getAuthorizations( ) {
final List<Authorization> auths = Lists.newArrayList( );
try {
Transactions.one( this.searchGroup, new Tx<GroupEntity>( ) {
@Override
public void fire( GroupEntity t ) throws Throwable {
for( Authorization a : t.getAuthorizations( ) ) {
auths.add( a );
}
}
} );
} catch ( TransactionException e ) {
LOG.debug( e, e );
}
return ImmutableList.copyOf( auths );
}
@Override
public ImmutableList<User> getMembers( ) {
final List<User> users = Lists.newArrayList( );
try {
Transactions.one( this.searchGroup, new Tx<GroupEntity>( ) {
@Override
public void fire( GroupEntity t ) throws Throwable {
users.addAll( t.getMembers( ) );
}
} );
} catch ( TransactionException e ) {
LOG.debug( e, e );
}
return ImmutableList.copyOf( users );
}
@Override
public boolean removeAuthorization( final Authorization auth ) {
final FinalReturn<Boolean> ret = FinalReturn.newInstance( );
try {
Transactions.one( this.searchGroup, new Tx<GroupEntity>( ) {
@Override
public void fire( GroupEntity t ) throws Throwable {
ret.set( t.removeAuthorization( auth ) );
EventRecord.here( Groups.class, EventClass.GROUP, EventType.GROUP_AUTH_REVOKED, t.getName( ), auth.getDisplayName( ), auth.getValue( ) ).info();
}
} );
} catch ( TransactionException e ) {
LOG.debug( e, e );
}
return ret.get( );
}
}