/**
* Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016
*
* Licensed 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.glite.security.voms.admin.service;
import java.rmi.RemoteException;
import org.apache.commons.lang.StringUtils;
import org.glite.security.voms.VOMSException;
import org.glite.security.voms.admin.core.VOMSServiceConstants;
import org.glite.security.voms.admin.error.NullArgumentException;
import org.glite.security.voms.admin.operations.VOMSPermission;
import org.glite.security.voms.admin.operations.acls.DeleteACLEntryOperation;
import org.glite.security.voms.admin.operations.acls.LoadACLOperation;
import org.glite.security.voms.admin.operations.acls.SaveACLEntryOperation;
import org.glite.security.voms.admin.operations.acls.SetACLOperation;
import org.glite.security.voms.admin.operations.groups.FindGroupOperation;
import org.glite.security.voms.admin.persistence.HibernateFactory;
import org.glite.security.voms.admin.persistence.dao.ACLDAO;
import org.glite.security.voms.admin.persistence.dao.VOMSAdminDAO;
import org.glite.security.voms.admin.persistence.dao.VOMSGroupDAO;
import org.glite.security.voms.admin.persistence.dao.VOMSRoleDAO;
import org.glite.security.voms.admin.persistence.error.NoSuchACLException;
import org.glite.security.voms.admin.persistence.error.NoSuchAdminException;
import org.glite.security.voms.admin.persistence.error.NoSuchGroupException;
import org.glite.security.voms.admin.persistence.error.NoSuchRoleException;
import org.glite.security.voms.admin.persistence.model.ACL;
import org.glite.security.voms.admin.persistence.model.VOMSAdmin;
import org.glite.security.voms.admin.persistence.model.VOMSGroup;
import org.glite.security.voms.admin.persistence.model.VOMSRole;
import org.glite.security.voms.admin.util.PathNamingScheme;
import org.glite.security.voms.service.acl.ACLEntry;
import org.glite.security.voms.service.acl.VOMSACL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class VOMSACLService implements VOMSACL {
private static final Logger log = LoggerFactory
.getLogger(VOMSACLService.class);
public void addACLEntry(String container, ACLEntry entry,
boolean propagateToChildrenContexts) throws RemoteException, VOMSException {
log.info("addACLEntry('container=" + container + "', entry='" + entry
+ "');");
if (container == null)
throw new NullArgumentException("Container cannot be null!");
if (entry == null)
throw new NullArgumentException("Container cannot be null!");
try {
ACL theACL = (ACL) LoadACLOperation.instance(container).execute();
VOMSAdmin theAdmin = getAdminFromEntry(entry);
if (theAdmin == null)
throw new NoSuchAdminException("Unknown or illegal admin! '"
+ entry.getAdminSubject() + "," + entry.getAdminIssuer() + "'");
VOMSPermission perms = VOMSPermission.fromBits(entry
.getVomsPermissionBits());
ServiceUtils.limitUnauthenticatedClientPermissions(theAdmin, perms);
SaveACLEntryOperation.instance(theACL, theAdmin, perms,
propagateToChildrenContexts).execute();
HibernateFactory.commitTransaction();
} catch (RuntimeException e) {
ServiceExceptionHelper.handleServiceException(log, e);
throw e;
}
}
public void addDefaultACLEntry(String group, ACLEntry entry)
throws RemoteException, VOMSException {
log.info("addDefaultACLEntry("
+ StringUtils.join(new Object[] { group, entry }, ',') + ");");
if (group == null)
throw new NullArgumentException("group cannot be null!");
if (entry == null)
throw new NullArgumentException("entry cannot be null!");
VOMSGroup g = null;
try {
g = (VOMSGroup) FindGroupOperation.instance(group).execute();
if (g == null)
throw new NoSuchGroupException("Group '" + g
+ "' not found in database!");
ACL acl = g.getDefaultACL();
if (acl == null)
acl = ACLDAO.instance().create(g, true);
VOMSAdmin theAdmin = getAdminFromEntry(entry);
VOMSPermission perms = VOMSPermission.fromBits(entry
.getVomsPermissionBits());
ServiceUtils.limitUnauthenticatedClientPermissions(theAdmin, perms);
SaveACLEntryOperation.instance(acl, theAdmin, perms).execute();
// Commit hibernate transaction
HibernateFactory.commitTransaction();
} catch (RuntimeException e) {
// Clean up the just created ACL, if that's the case
if (g != null)
if (g.getDefaultACL() != null
&& g.getDefaultACL().getPermissions().isEmpty())
ACLDAO.instance().delete(g.getDefaultACL());
ServiceExceptionHelper.handleServiceException(log, e);
}
}
protected ACLEntry[] getACLImpl(String container, boolean defaultACL)
throws VOMSException {
ACL acl = (ACL) LoadACLOperation.instance(container, defaultACL).execute();
return ServiceUtils.toACLEntryArray(acl);
}
public ACLEntry[] getACL(String container) throws RemoteException,
VOMSException {
log.info("getACL(" + container + ");");
if (container == null)
throw new NullArgumentException("container cannot be null!");
try {
ACLEntry[] retVal = getACLImpl(container, false);
HibernateFactory.commitTransaction();
return retVal;
} catch (RuntimeException e) {
log.error(e.toString());
if (log.isDebugEnabled()) {
log.error(e.getMessage(), e);
}
throw e;
}
}
public ACLEntry[] getDefaultACL(String container) throws RemoteException,
VOMSException {
log.info("getDefaultACL(" + container + ");");
if (container == null)
throw new NullArgumentException("container cannot be null!");
try {
ACLEntry[] retVal = getACLImpl(container, true);
HibernateFactory.commitTransaction();
return retVal;
} catch (RuntimeException e) {
log.error(e.toString());
if (log.isDebugEnabled()) {
log.error(e.getMessage(), e);
}
throw e;
}
}
public void removeACLEntry(String container, ACLEntry entry,
boolean removeFromChildrenContexts) throws RemoteException, VOMSException {
log.info("removeACLEntry("
+ StringUtils.join(new Object[] { container, entry,
removeFromChildrenContexts }, ',') + ");");
if (container == null)
throw new NullArgumentException("container cannot be null!");
if (entry == null)
throw new NullArgumentException("entry cannot be null!");
try {
ACL theACL = (ACL) LoadACLOperation.instance(container).execute();
VOMSAdmin admin = getAdminFromEntry(entry);
DeleteACLEntryOperation.instance(theACL, admin,
removeFromChildrenContexts).execute();
// Commit hibernate transaction
HibernateFactory.commitTransaction();
} catch (RuntimeException e) {
ServiceExceptionHelper.handleServiceException(log, e);
}
}
public void removeDefaultACLEntry(String group, ACLEntry entry)
throws RemoteException, VOMSException {
log.info("removeDefaultACLEntry("
+ StringUtils.join(new Object[] { group, entry }, ',') + ");");
if (group == null)
throw new NullArgumentException("group cannot be null!");
if (entry == null)
throw new NullArgumentException("entry cannot be null!");
try {
ACL theACL = (ACL) LoadACLOperation.instance(group, true).execute();
if (theACL == null)
throw new NoSuchACLException("Default ACL is not defined for group "
+ group);
VOMSAdmin admin = getAdminFromEntry(entry);
DeleteACLEntryOperation.instance(theACL, admin).execute();
// Commit hibernate transaction
HibernateFactory.commitTransaction();
} catch (RuntimeException e) {
ServiceExceptionHelper.handleServiceException(log, e);
}
}
protected void setACLImpl(String container, boolean defaultACL,
ACLEntry[] entries) throws VOMSException {
if (container == null)
throw new NullArgumentException("container cannot be null!");
if (entries == null)
throw new NullArgumentException("entries cannot be null!");
VOMSGroup g = null;
try {
ACL theACL = (ACL) LoadACLOperation.instance(container, defaultACL)
.execute();
if (theACL == null && defaultACL) {
g = VOMSGroupDAO.instance().findByName(container);
theACL = ACLDAO.instance().create(g, true);
}
SetACLOperation.instance(theACL, ServiceUtils.toPermissionMap(entries))
.execute();
// Commit hibernate transaction
HibernateFactory.commitTransaction();
} catch (RuntimeException e) {
// Clean up the just created ACL, if that's the case
if (g != null)
if (g.getDefaultACL() != null
&& g.getDefaultACL().getPermissions().isEmpty())
ACLDAO.instance().delete(g.getDefaultACL());
ServiceExceptionHelper.handleServiceException(log, e);
}
}
public void setACL(String container, ACLEntry[] entries)
throws RemoteException, VOMSException {
log.info("setACL("
+ StringUtils.join(new Object[] { container, entries }, ',') + ");");
setACLImpl(container, false, entries);
}
public void setDefaultACL(String group, ACLEntry[] entries)
throws RemoteException, VOMSException {
log.info("setDefaultACL("
+ StringUtils.join(new Object[] { group, entries }, ',') + ");");
setACLImpl(group, true, entries);
}
protected VOMSAdmin getAdminFromEntry(ACLEntry entry) {
if (entry.getAdminSubject() == null)
throw new NullArgumentException("entry.adminSubject cannot be null!");
if (entry.getAdminIssuer() == null)
throw new NullArgumentException("entry.adminIssuer cannot be null!");
String subject = entry.getAdminSubject();
String issuer = entry.getAdminIssuer();
VOMSAdmin admin = VOMSAdminDAO.instance().findBySubjectAndIssuer(subject, issuer);
if (admin == null) {
// Admin not found, check if internal admin is requested
if (issuer.equals(VOMSServiceConstants.VIRTUAL_CA)) {
// ANYUSER admin
return VOMSAdminDAO.instance().getAnyAuthenticatedUserAdmin();
} else if (issuer.equals(VOMSServiceConstants.GROUP_CA)) {
VOMSGroup g = VOMSGroupDAO.instance().findByName(subject);
if (g == null)
throw new NoSuchGroupException("Group '" + subject
+ "' is not defined in database!");
return VOMSAdminDAO.instance().createFromFqan(subject);
} else if (issuer.equals(VOMSServiceConstants.ROLE_CA)) {
String groupName = PathNamingScheme.getGroupName(subject);
String roleName = PathNamingScheme.getRoleName(subject);
VOMSGroup g = VOMSGroupDAO.instance().findByName(groupName);
VOMSRole r = VOMSRoleDAO.instance().findByName(roleName);
if (g == null)
throw new NoSuchGroupException("Group '" + groupName
+ "' is not defined in database!");
if (r == null)
throw new NoSuchRoleException("Role '" + roleName
+ "' is not defined in database!");
return VOMSAdminDAO.instance().createFromFqan(subject);
}
// Another type of admin
return VOMSAdminDAO.instance().createFromSubjectAndIssuer(subject, issuer);
}
return admin;
}
}