Moving to root below branch label

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2005-12-08 07:13:07 +00:00
commit e1e6508fec
1095 changed files with 230566 additions and 0 deletions

View File

@@ -0,0 +1,230 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import org.alfresco.error.AlfrescoRuntimeException;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User;
/**
* This class abstract the support required to set up and query the Acegi
* context for security enforcement.
*
* There are some simple default method implementations to support simple
* authentication.
*
* @author Andy Hind
*/
public abstract class AbstractAuthenticationComponent implements AuthenticationComponent
{
// Name of the system user
private static final String SYSTEM_USER_NAME = "System";
public AbstractAuthenticationComponent()
{
super();
}
/**
* Explicitly set the current user to be authenticated.
*
* @param userName
* String
* @return Authentication
*/
public Authentication setCurrentUser(String userName)
{
try
{
UserDetails ud = null;
if (userName.equals(SYSTEM_USER_NAME))
{
GrantedAuthority[] gas = new GrantedAuthority[1];
gas[0] = new GrantedAuthorityImpl("ROLE_SYSTEM");
ud = new User(SYSTEM_USER_NAME, "", true, true, true, true, gas);
}
else
{
ud = getUserDetails(userName);
}
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(ud, "", ud
.getAuthorities());
auth.setDetails(ud);
auth.setAuthenticated(true);
return setCurrentAuthentication(auth);
}
catch (net.sf.acegisecurity.AuthenticationException ae)
{
throw new AuthenticationException(ae.getMessage(), ae);
}
}
/**
* Default implementation that makes an ACEGI object on the fly
*
* @param userName
* @return
*/
protected UserDetails getUserDetails(String userName)
{
GrantedAuthority[] gas = new GrantedAuthority[1];
gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED");
UserDetails ud = new User(userName, "", true, true, true, true, gas);
return ud;
}
/**
* Explicitly set the current authentication.
*
* @param authentication
* Authentication
*/
public Authentication setCurrentAuthentication(Authentication authentication)
{
Context context = ContextHolder.getContext();
SecureContext sc = null;
if ((context == null) || !(context instanceof SecureContext))
{
sc = new SecureContextImpl();
ContextHolder.setContext(sc);
}
else
{
sc = (SecureContext) context;
}
authentication.setAuthenticated(true);
sc.setAuthentication(authentication);
return authentication;
}
/**
* Get the current authentication context
*
* @return Authentication
* @throws AuthenticationException
*/
public Authentication getCurrentAuthentication() throws AuthenticationException
{
Context context = ContextHolder.getContext();
if ((context == null) || !(context instanceof SecureContext))
{
return null;
}
return ((SecureContext) context).getAuthentication();
}
/**
* Get the current user name.
*
* @return String
* @throws AuthenticationException
*/
public String getCurrentUserName() throws AuthenticationException
{
Context context = ContextHolder.getContext();
if ((context == null) || !(context instanceof SecureContext))
{
return null;
}
return getUserName(((SecureContext) context).getAuthentication());
}
/**
* Get the current user name
*
* @param authentication
* Authentication
* @return String
*/
private String getUserName(Authentication authentication)
{
String username = authentication.getPrincipal().toString();
if (authentication.getPrincipal() instanceof UserDetails)
{
username = ((UserDetails) authentication.getPrincipal()).getUsername();
}
return username;
}
/**
* Set the system user as the current user.
*
* @return Authentication
*/
public Authentication setSystemUserAsCurrentUser()
{
return setCurrentUser(SYSTEM_USER_NAME);
}
/**
* Get the name of the system user
*
* @return String
*/
public String getSystemUserName()
{
return SYSTEM_USER_NAME;
}
/**
* Remove the current security information
*/
public void clearCurrentSecurityContext()
{
ContextHolder.setContext(null);
}
/**
* The default is not to support Authentication token base authentication
*/
public Authentication authenticate(Authentication token) throws AuthenticationException
{
throw new AlfrescoRuntimeException("Authentication via token not supported");
}
/**
* The should only be supported if getNTLMMode() is NTLMMode.MD4_PROVIDER.
*/
public String getMD4HashedPassword(String userName)
{
throw new UnsupportedOperationException();
}
/**
* Get the NTML mode - none - supports MD4 hash to integrate - or it can
* asct as an NTLM authentication
*/
public NTLMMode getNTLMMode()
{
return NTLMMode.NONE;
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.AuthenticationException;
import net.sf.acegisecurity.providers.AuthenticationProvider;
public class AuthenticatedAuthenticationPassthroughProvider implements AuthenticationProvider
{
public AuthenticatedAuthenticationPassthroughProvider()
{
super();
}
public Authentication authenticate(Authentication authentication) throws AuthenticationException
{
if (!supports(authentication.getClass())) {
return null;
}
if(authentication.isAuthenticated())
{
return authentication;
}
else
{
return null;
}
}
public boolean supports(Class authentication)
{
return (Authentication.class.isAssignableFrom(authentication));
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import net.sf.acegisecurity.Authentication;
public interface AuthenticationComponent
{
/**
* Authenticate
*
* @param userName
* @param password
* @throws AuthenticationException
*/
public void authenticate(String userName, char[] password) throws AuthenticationException;
/**
* Authenticate using a token
*
* @param token Authentication
* @return Authentication
* @throws AuthenticationException
*/
public Authentication authenticate(Authentication token) throws AuthenticationException;
/**
* Explicitly set the current user to be authenticated.
*/
public Authentication setCurrentUser(String userName);
/**
* Remove the current security information
*
*/
public void clearCurrentSecurityContext();
/**
* Explicitly set the current suthentication.
*/
public Authentication setCurrentAuthentication(Authentication authentication);
/**
*
* @return
* @throws AuthenticationException
*/
public Authentication getCurrentAuthentication() throws AuthenticationException;
/**
* Set the system user as the current user.
*
* @return
*/
public Authentication setSystemUserAsCurrentUser();
/**
* Get the name of the system user
*
* @return
*/
public String getSystemUserName();
/**
* Get the current user name.
*
* @return
* @throws AuthenticationException
*/
public String getCurrentUserName() throws AuthenticationException;
/**
* Get the enum that describes NTLM integration
*
* @return
*/
public NTLMMode getNTLMMode();
/**
* Get the MD4 password hash, as required by NTLM based authentication methods.
*
* @param userName
* @return
*/
public String getMD4HashedPassword(String userName);
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import net.sf.acegisecurity.AuthenticationManager;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
{
private MutableAuthenticationDao authenticationDao;
AuthenticationManager authenticationManager;
public AuthenticationComponentImpl()
{
super();
}
/**
* IOC
*
* @param authenticationManager
*/
public void setAuthenticationManager(AuthenticationManager authenticationManager)
{
this.authenticationManager = authenticationManager;
}
/**
* IOC
*
* @param authenticationDao
*/
public void setAuthenticationDao(MutableAuthenticationDao authenticationDao)
{
this.authenticationDao = authenticationDao;
}
/**
* Authenticate
*/
public void authenticate(String userName, char[] password) throws AuthenticationException
{
try
{
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userName,
new String(password));
authenticationManager.authenticate(authentication);
setCurrentUser(userName);
}
catch (net.sf.acegisecurity.AuthenticationException ae)
{
throw new AuthenticationException(ae.getMessage(), ae);
}
}
/**
* We actually have an acegi object so override the default method.
*/
protected UserDetails getUserDetails(String userName)
{
return (UserDetails) authenticationDao.loadUserByUsername(userName);
}
/**
* Get the password hash from the DAO
*/
public String getMD4HashedPassword(String userName)
{
return authenticationDao.getMD4HashedPassword(userName);
}
/**
* This implementation supported MD4 password hashes.
*/
public NTLMMode getNTLMMode()
{
return NTLMMode.MD4_PROVIDER;
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* Alfresco Authentication Exception and wrapper
*
* @author andyh
*
*/
public class AuthenticationException extends AlfrescoRuntimeException
{
/**
*
*/
private static final long serialVersionUID = 3546647620128092466L;
public AuthenticationException(String msg)
{
super(msg);
}
public AuthenticationException(String msg, Throwable cause)
{
super(msg, cause);
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
import org.alfresco.service.cmr.security.AuthenticationService;
public class AuthenticationServiceImpl implements AuthenticationService
{
MutableAuthenticationDao authenticationDao;
AuthenticationComponent authenticationComponent;
TicketComponent ticketComponent;
PermissionServiceSPI permissionServiceSPI;
public AuthenticationServiceImpl()
{
super();
}
public void setAuthenticationDao(MutableAuthenticationDao authenticationDao)
{
this.authenticationDao = authenticationDao;
}
public void setTicketComponent(TicketComponent ticketComponent)
{
this.ticketComponent = ticketComponent;
}
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
{
this.authenticationComponent = authenticationComponent;
}
public void setPermissionServiceSPI(PermissionServiceSPI permissionServiceSPI)
{
this.permissionServiceSPI = permissionServiceSPI;
}
public void createAuthentication(String userName, char[] password) throws AuthenticationException
{
authenticationDao.createUser(userName, password);
}
public void updateAuthentication(String userName, char[] oldPassword, char[] newPassword)
throws AuthenticationException
{
authenticationDao.updateUser(userName, newPassword);
}
public void setAuthentication(String userName, char[] newPassword) throws AuthenticationException
{
authenticationDao.updateUser(userName, newPassword);
}
public void deleteAuthentication(String userName) throws AuthenticationException
{
authenticationDao.deleteUser(userName);
permissionServiceSPI.deletePermissions(authenticationDao.getUserNamesAreCaseSensitive() ? userName: userName.toLowerCase());
}
public boolean getAuthenticationEnabled(String userName) throws AuthenticationException
{
return authenticationDao.getEnabled(userName);
}
public void setAuthenticationEnabled(String userName, boolean enabled) throws AuthenticationException
{
authenticationDao.setEnabled(userName, enabled);
}
public void authenticate(String userName, char[] password) throws AuthenticationException
{
authenticationComponent.authenticate(userName, password);
}
public String getCurrentUserName() throws AuthenticationException
{
return authenticationComponent.getCurrentUserName();
}
public void invalidateUserSession(String userName) throws AuthenticationException
{
ticketComponent.invalidateTicketByUser(userName);
}
public void invalidateTicket(String ticket) throws AuthenticationException
{
ticketComponent.invalidateTicketById(ticket);
}
public void validate(String ticket) throws AuthenticationException
{
authenticationComponent.setCurrentUser(ticketComponent.validateTicket(ticket));
}
public String getCurrentTicket()
{
return ticketComponent.getTicket(getCurrentUserName());
}
public void clearCurrentSecurityContext()
{
authenticationComponent.clearCurrentSecurityContext();
}
public boolean isCurrentUserTheSystemUser()
{
String userName = getCurrentUserName();
if ((userName != null) && userName.equals(authenticationComponent.getSystemUserName()))
{
return true;
}
return false;
}
}

View File

@@ -0,0 +1,711 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.transaction.UserTransaction;
import junit.framework.TestCase;
import net.sf.acegisecurity.AccountExpiredException;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.AuthenticationManager;
import net.sf.acegisecurity.BadCredentialsException;
import net.sf.acegisecurity.CredentialsExpiredException;
import net.sf.acegisecurity.DisabledException;
import net.sf.acegisecurity.LockedException;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.SaltSource;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.DynamicNamespacePrefixResolver;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext;
public class AuthenticationTest extends TestCase
{
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private NodeService nodeService;
private SearchService searchService;
private NodeRef rootNodeRef;
private NodeRef systemNodeRef;
private NodeRef typesNodeRef;
private NodeRef personAndyNodeRef;
private DictionaryService dictionaryService;
private MD4PasswordEncoder passwordEncoder;
private MutableAuthenticationDao dao;
private AuthenticationManager authenticationManager;
private SaltSource saltSource;
private TicketComponent ticketComponent;
private AuthenticationService authenticationService;
private AuthenticationService pubAuthenticationService;
private AuthenticationComponent authenticationComponent;
private PermissionServiceSPI permissionServiceSPI;
private UserTransaction userTransaction;
public AuthenticationTest()
{
super();
}
public AuthenticationTest(String arg0)
{
super(arg0);
}
public void setUp() throws Exception
{
nodeService = (NodeService) ctx.getBean("nodeService");
searchService = (SearchService) ctx.getBean("searchService");
dictionaryService = (DictionaryService) ctx.getBean("dictionaryService");
passwordEncoder = (MD4PasswordEncoder) ctx.getBean("passwordEncoder");
ticketComponent = (TicketComponent) ctx.getBean("ticketComponent");
authenticationService = (AuthenticationService) ctx.getBean("authenticationService");
pubAuthenticationService = (AuthenticationService) ctx.getBean("AuthenticationService");
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
permissionServiceSPI = (PermissionServiceSPI) ctx.getBean("permissionService");
dao = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
saltSource = (SaltSource) ctx.getBean("saltSource");
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE
.getLocalName());
userTransaction = transactionService.getUserTransaction();
userTransaction.begin();
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef);
QName children = ContentModel.ASSOC_CHILDREN;
QName system = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "system");
QName container = ContentModel.TYPE_CONTAINER;
QName types = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "people");
systemNodeRef = nodeService.createNode(rootNodeRef, children, system, container).getChildRef();
typesNodeRef = nodeService.createNode(systemNodeRef, children, types, container).getChildRef();
Map<QName, Serializable> props = createPersonProperties("Andy");
personAndyNodeRef = nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props)
.getChildRef();
assertNotNull(personAndyNodeRef);
deleteAndy();
}
private void deleteAndy()
{
RepositoryAuthenticationDao dao = new RepositoryAuthenticationDao();
dao.setNodeService(nodeService);
dao.setSearchService(searchService);
dao.setDictionaryService(dictionaryService);
dao.setNamespaceService(getNamespacePrefixReolsver(""));
dao.setPasswordEncoder(passwordEncoder);
if(dao.getUserOrNull("andy") != null)
{
dao.deleteUser("andy");
}
}
@Override
protected void tearDown() throws Exception
{
userTransaction.rollback();
super.tearDown();
}
private Map<QName, Serializable> createPersonProperties(String userName)
{
HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME, "Andy");
return properties;
}
public void testCreateAndyUserAndOtherCRUD() throws NoSuchAlgorithmException, UnsupportedEncodingException
{
RepositoryAuthenticationDao dao = new RepositoryAuthenticationDao();
dao.setNodeService(nodeService);
dao.setSearchService(searchService);
dao.setDictionaryService(dictionaryService);
dao.setNamespaceService(getNamespacePrefixReolsver(""));
dao.setPasswordEncoder(passwordEncoder);
dao.createUser("Andy", "cabbage".toCharArray());
assertNotNull(dao.getUserOrNull("Andy"));
byte[] decodedHash = passwordEncoder.decodeHash(dao.getMD4HashedPassword("Andy"));
byte[] testHash = MessageDigest.getInstance("MD4").digest("cabbage".getBytes("UnicodeLittleUnmarked"));
assertEquals(new String(decodedHash), new String(testHash));
UserDetails AndyDetails = (UserDetails) dao.loadUserByUsername("Andy");
assertNotNull(AndyDetails);
assertEquals(dao.getUserNamesAreCaseSensitive() ? "Andy" : "andy", AndyDetails.getUsername());
// assertNotNull(dao.getSalt(AndyDetails));
assertTrue(AndyDetails.isAccountNonExpired());
assertTrue(AndyDetails.isAccountNonLocked());
assertTrue(AndyDetails.isCredentialsNonExpired());
assertTrue(AndyDetails.isEnabled());
assertNotSame("cabbage", AndyDetails.getPassword());
assertEquals(AndyDetails.getPassword(), passwordEncoder.encodePassword("cabbage", saltSource
.getSalt(AndyDetails)));
assertEquals(1, AndyDetails.getAuthorities().length);
// Object oldSalt = dao.getSalt(AndyDetails);
dao.updateUser("Andy", "carrot".toCharArray());
UserDetails newDetails = (UserDetails) dao.loadUserByUsername("Andy");
assertNotNull(newDetails);
assertEquals(dao.getUserNamesAreCaseSensitive() ? "Andy" : "andy", newDetails.getUsername());
// assertNotNull(dao.getSalt(newDetails));
assertTrue(newDetails.isAccountNonExpired());
assertTrue(newDetails.isAccountNonLocked());
assertTrue(newDetails.isCredentialsNonExpired());
assertTrue(newDetails.isEnabled());
assertNotSame("carrot", newDetails.getPassword());
assertEquals(1, newDetails.getAuthorities().length);
assertNotSame(AndyDetails.getPassword(), newDetails.getPassword());
// assertNotSame(oldSalt, dao.getSalt(newDetails));
dao.deleteUser("Andy");
assertNull(dao.getUserOrNull("Andy"));
MessageDigest digester;
try
{
digester = MessageDigest.getInstance("MD4");
System.out.println("Digester from " + digester.getProvider());
}
catch (NoSuchAlgorithmException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("No digester");
}
}
public void testAuthentication()
{
dao.createUser("GUEST", "".toCharArray());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("GUEST", "");
token.setAuthenticated(false);
Authentication result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.createUser("Andy", "squash".toCharArray());
token = new UsernamePasswordAuthenticationToken("Andy", "squash");
token.setAuthenticated(false);
result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.setEnabled("Andy", false);
try
{
result = authenticationManager.authenticate(token);
assertNotNull(result);
assertNotNull(null);
}
catch (DisabledException e)
{
// Expected
}
dao.setEnabled("Andy", true);
result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.setLocked("Andy", true);
try
{
result = authenticationManager.authenticate(token);
assertNotNull(result);
assertNotNull(null);
}
catch (LockedException e)
{
// Expected
}
dao.setLocked("Andy", false);
result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.setAccountExpires("Andy", true);
dao.setCredentialsExpire("Andy", true);
result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.setAccountExpiryDate("Andy", null);
dao.setCredentialsExpiryDate("Andy", null);
result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.setAccountExpiryDate("Andy", new Date(new Date().getTime() + 10000));
dao.setCredentialsExpiryDate("Andy", new Date(new Date().getTime() + 10000));
result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.setAccountExpiryDate("Andy", new Date(new Date().getTime() - 10000));
try
{
result = authenticationManager.authenticate(token);
assertNotNull(result);
assertNotNull(null);
}
catch (AccountExpiredException e)
{
// Expected
}
dao.setAccountExpiryDate("Andy", new Date(new Date().getTime() + 10000));
result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.setCredentialsExpiryDate("Andy", new Date(new Date().getTime() - 10000));
try
{
result = authenticationManager.authenticate(token);
assertNotNull(result);
assertNotNull(null);
}
catch (CredentialsExpiredException e)
{
// Expected
}
dao.setCredentialsExpiryDate("Andy", new Date(new Date().getTime() + 10000));
result = authenticationManager.authenticate(token);
assertNotNull(result);
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testAuthenticationFailure()
{
dao.createUser("Andy", "squash".toCharArray());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Andy", "turnip");
token.setAuthenticated(false);
try
{
Authentication result = authenticationManager.authenticate(token);
assertNotNull(result);
assertNotNull(null);
}
catch (BadCredentialsException e)
{
// Expected
}
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testTicket()
{
dao.createUser("Andy", "ticket".toCharArray());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Andy", "ticket");
token.setAuthenticated(false);
Authentication result = authenticationManager.authenticate(token);
result.setAuthenticated(true);
String ticket = ticketComponent.getTicket(getUserName(result));
String user = ticketComponent.validateTicket(ticket);
user = null;
try
{
user = ticketComponent.validateTicket("INVALID");
assertNotNull(null);
}
catch (AuthenticationException e)
{
assertNull(user);
}
ticketComponent.invalidateTicketById(ticket);
try
{
user = ticketComponent.validateTicket(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testTicketRepeat()
{
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
tc.setOneOff(false);
tc.setTicketsExpire(false);
tc.setValidDuration("P0D");
dao.createUser("Andy", "ticket".toCharArray());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Andy", "ticket");
token.setAuthenticated(false);
Authentication result = authenticationManager.authenticate(token);
result.setAuthenticated(true);
String ticket = tc.getTicket(getUserName(result));
tc.validateTicket(ticket);
tc.validateTicket(ticket);
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testTicketOneOff()
{
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
tc.setOneOff(true);
tc.setTicketsExpire(false);
tc.setValidDuration("P0D");
dao.createUser("Andy", "ticket".toCharArray());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Andy", "ticket");
token.setAuthenticated(false);
Authentication result = authenticationManager.authenticate(token);
result.setAuthenticated(true);
String ticket = tc.getTicket(getUserName(result));
tc.validateTicket(ticket);
try
{
tc.validateTicket(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testTicketExpires()
{
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
tc.setOneOff(false);
tc.setTicketsExpire(true);
tc.setValidDuration("P5S");
dao.createUser("Andy", "ticket".toCharArray());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Andy", "ticket");
token.setAuthenticated(false);
Authentication result = authenticationManager.authenticate(token);
result.setAuthenticated(true);
String ticket = tc.getTicket(getUserName(result));
tc.validateTicket(ticket);
tc.validateTicket(ticket);
tc.validateTicket(ticket);
synchronized (this)
{
try
{
wait(10000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
tc.validateTicket(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testTicketDoesNotExpire()
{
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
tc.setOneOff(false);
tc.setTicketsExpire(true);
tc.setValidDuration("P1D");
dao.createUser("Andy", "ticket".toCharArray());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Andy", "ticket");
token.setAuthenticated(false);
Authentication result = authenticationManager.authenticate(token);
result.setAuthenticated(true);
String ticket = tc.getTicket(getUserName(result));
tc.validateTicket(ticket);
tc.validateTicket(ticket);
tc.validateTicket(ticket);
synchronized (this)
{
try
{
wait(10000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
tc.validateTicket(ticket);
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testAuthenticationService()
{
authenticationService.createAuthentication("GUEST", "".toCharArray());
authenticationService.authenticate("GUEST", "".toCharArray());
// create an authentication object e.g. the user
authenticationService.createAuthentication("Andy", "auth1".toCharArray());
// authenticate with this user details
authenticationService.authenticate("Andy", "auth1".toCharArray());
// assert the user is authenticated
assertEquals(dao.getUserNamesAreCaseSensitive() ? "Andy" : "andy", authenticationService.getCurrentUserName());
// delete the user authentication object
authenticationService.clearCurrentSecurityContext();
authenticationService.deleteAuthentication("Andy");
// create a new authentication user object
authenticationService.createAuthentication("Andy", "auth2".toCharArray());
// change the password
authenticationService.setAuthentication("Andy", "auth3".toCharArray());
// authenticate again to assert password changed
authenticationService.authenticate("Andy", "auth3".toCharArray());
try
{
authenticationService.authenticate("Andy", "auth1".toCharArray());
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
try
{
authenticationService.authenticate("Andy", "auth2".toCharArray());
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
// get the ticket that represents the current user authentication
// instance
String ticket = authenticationService.getCurrentTicket();
// validate our ticket is still valid
authenticationService.validate(ticket);
// destroy the ticket instance
authenticationService.invalidateTicket(ticket);
try
{
authenticationService.validate(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
// clear any context and check we are no longer authenticated
authenticationService.clearCurrentSecurityContext();
assertNull(authenticationService.getCurrentUserName());
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testPubAuthenticationService()
{
pubAuthenticationService.createAuthentication("GUEST", "".toCharArray());
pubAuthenticationService.authenticate("GUEST", "".toCharArray());
// create an authentication object e.g. the user
pubAuthenticationService.createAuthentication("Andy", "auth1".toCharArray());
// authenticate with this user details
pubAuthenticationService.authenticate("Andy", "auth1".toCharArray());
// assert the user is authenticated
assertEquals(dao.getUserNamesAreCaseSensitive() ? "Andy" : "andy", authenticationService.getCurrentUserName());
// delete the user authentication object
pubAuthenticationService.clearCurrentSecurityContext();
pubAuthenticationService.deleteAuthentication("Andy");
// create a new authentication user object
pubAuthenticationService.createAuthentication("Andy", "auth2".toCharArray());
// change the password
pubAuthenticationService.setAuthentication("Andy", "auth3".toCharArray());
// authenticate again to assert password changed
pubAuthenticationService.authenticate("Andy", "auth3".toCharArray());
try
{
pubAuthenticationService.authenticate("Andy", "auth1".toCharArray());
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
try
{
pubAuthenticationService.authenticate("Andy", "auth2".toCharArray());
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
// get the ticket that represents the current user authentication
// instance
String ticket = pubAuthenticationService.getCurrentTicket();
// validate our ticket is still valid
pubAuthenticationService.validate(ticket);
// destroy the ticket instance
pubAuthenticationService.invalidateTicket(ticket);
try
{
pubAuthenticationService.validate(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
// clear any context and check we are no longer authenticated
pubAuthenticationService.clearCurrentSecurityContext();
assertNull(pubAuthenticationService.getCurrentUserName());
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testPassThroughLogin()
{
authenticationService.createAuthentication("Andy", "auth1".toCharArray());
authenticationComponent.setCurrentUser("Andy");
assertEquals(dao.getUserNamesAreCaseSensitive() ? "Andy" : "andy", authenticationService.getCurrentUserName());
//authenticationService.deleteAuthentication("andy");
}
private String getUserName(Authentication authentication)
{
String username = authentication.getPrincipal().toString();
if (authentication.getPrincipal() instanceof UserDetails)
{
username = ((UserDetails) authentication.getPrincipal()).getUsername();
}
return username;
}
private NamespacePrefixResolver getNamespacePrefixReolsver(String defaultURI)
{
DynamicNamespacePrefixResolver nspr = new DynamicNamespacePrefixResolver(null);
nspr.registerNamespace(NamespaceService.SYSTEM_MODEL_PREFIX, NamespaceService.SYSTEM_MODEL_1_0_URI);
nspr.registerNamespace(NamespaceService.CONTENT_MODEL_PREFIX, NamespaceService.CONTENT_MODEL_1_0_URI);
nspr.registerNamespace(ContentModel.USER_MODEL_PREFIX, ContentModel.USER_MODEL_URI);
nspr.registerNamespace("namespace", "namespace");
nspr.registerNamespace(NamespaceService.DEFAULT_PREFIX, defaultURI);
return nspr;
}
}

View File

@@ -0,0 +1,293 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import java.util.Date;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.StoreRef;
import org.springframework.dao.DataAccessException;
/**
* An authority DAO that has no implementation and should not be called.
*
* @author Andy Hind
*/
public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
{
/**
* Create a user with the given userName and password
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
*/
public void createUser(String userName, char[] rawPassword) throws AuthenticationException
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Update a user's password.
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
*/
public void updateUser(String userName, char[] rawPassword) throws AuthenticationException
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Delete a user.
*
* @param userName
* @throws AuthenticationException
*/
public void deleteUser(String userName) throws AuthenticationException
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Check is a user exists.
*
* @param userName
* @return
*/
public boolean userExists(String userName)
{
return true;
}
/**
* Get the store ref where user objects are persisted.
*
* @return
*/
public StoreRef getUserStoreRef()
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Enable/disable a user.
*
* @param userName
* @param enabled
*/
public void setEnabled(String userName, boolean enabled)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Getter for user enabled
*
* @param userName
* @return
*/
public boolean getEnabled(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Set if the account should expire
*
* @param userName
* @param expires
*/
public void setAccountExpires(String userName, boolean expires)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Does the account expire?
*
* @param userName
* @return
*/
public boolean getAccountExpires(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Has the account expired?
*
* @param userName
* @return
*/
public boolean getAccountHasExpired(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Set if the password expires.
*
* @param userName
* @param expires
*/
public void setCredentialsExpire(String userName, boolean expires)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Do the credentials for the user expire?
*
* @param userName
* @return
*/
public boolean getCredentialsExpire(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Have the credentials for the user expired?
*
* @param userName
* @return
*/
public boolean getCredentialsHaveExpired(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Set if the account is locked.
*
* @param userName
* @param locked
*/
public void setLocked(String userName, boolean locked)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Is the account locked?
*
* @param userName
* @return
*/
public boolean getAccountlocked(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Set the date on which the account expires
*
* @param userName
* @param exipryDate
*/
public void setAccountExpiryDate(String userName, Date exipryDate)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Get the date when this account expires.
*
* @param userName
* @return
*/
public Date getAccountExpiryDate(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Set the date when credentials expire.
*
* @param userName
* @param exipryDate
*/
public void setCredentialsExpiryDate(String userName, Date exipryDate)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Get the date when the credentials/password expire.
*
* @param userName
* @return
*/
public Date getCredentialsExpiryDate(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Get the MD4 password hash
*
* @param userName
* @return
*/
public String getMD4HashedPassword(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Are user names case sensitive?
*
* @return
*/
public boolean getUserNamesAreCaseSensitive()
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Return the user details for the specified user
*
* @param user String
* @return UserDetails
* @exception UsernameNotFoundException
* @exception DataAccessException
*/
public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException, DataAccessException
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* Return salt for user
*
* @param user UserDetails
* @return Object
*/
public Object getSalt(UserDetails user)
{
throw new AlfrescoRuntimeException("Not implemented");
}
}

View File

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.alfresco.service.cmr.repository.datatype.Duration;
import org.alfresco.util.GUID;
public class InMemoryTicketComponentImpl implements TicketComponent
{
public static final String GRANTED_AUTHORITY_TICKET_PREFIX = "TICKET_";
private boolean ticketsExpire;
private Duration validDuration;
private boolean oneOff;
private HashMap<String, Ticket> tickets = new HashMap<String, Ticket>();
public InMemoryTicketComponentImpl()
{
super();
}
public String getTicket(String userName) throws AuthenticationException
{
Date expiryDate = null;
if (ticketsExpire)
{
expiryDate = Duration.add(new Date(), validDuration);
}
Ticket ticket = new Ticket(ticketsExpire, expiryDate, userName);
tickets.put(ticket.getTicketId(), ticket);
return GRANTED_AUTHORITY_TICKET_PREFIX + ticket.getTicketId();
}
public String validateTicket(String ticketString) throws AuthenticationException
{
if (ticketString.length() < GRANTED_AUTHORITY_TICKET_PREFIX.length())
{
throw new AuthenticationException(ticketString + " is an invalid ticket format");
}
String key = ticketString.substring(GRANTED_AUTHORITY_TICKET_PREFIX.length());
Ticket ticket = tickets.get(key);
if (ticket == null)
{
throw new AuthenticationException("Missing ticket for " + ticketString);
}
if (ticket.hasExpired())
{
throw new TicketExpiredException("Ticket expired for " + ticketString);
}
// TODO: Recheck the user details here
// TODO: Strengthen ticket as GUID is predicatble
if(oneOff)
{
tickets.remove(key);
}
return ticket.getUserName();
}
public void invalidateTicketById(String ticketString)
{
String key = ticketString.substring(GRANTED_AUTHORITY_TICKET_PREFIX.length());
tickets.remove(key);
}
public void invalidateTicketByUser(String userName)
{
Set<String> toRemove = new HashSet<String>();
for(String key: tickets.keySet())
{
Ticket ticket = tickets.get(key);
if(ticket.getUserName().equals(userName))
{
toRemove.add(ticket.getTicketId());
}
}
for(String id: toRemove)
{
tickets.remove(id);
}
}
private static class Ticket
{
private boolean expires;
private Date expiryDate;
private String userName;
private String ticketId;
Ticket(boolean expires, Date expiryDate, String userName)
{
this.expires = expires;
this.expiryDate = expiryDate;
this.userName = userName;
this.ticketId = GUID.generate();
}
/**
* Has the tick expired
*
* @return
*/
boolean hasExpired()
{
if (expires && (expiryDate != null) && (expiryDate.compareTo(new Date()) < 0))
{
return true;
}
else
{
return false;
}
}
public boolean equals(Object o)
{
if (o == this)
{
return true;
}
if (!(o instanceof Ticket))
{
return false;
}
Ticket t = (Ticket) o;
return (this.expires == t.expires) && this.expiryDate.equals(t.expiryDate) && this.userName.equals(t.userName) && this.ticketId.equals(t.ticketId);
}
public int hashCode()
{
return ticketId.hashCode();
}
protected boolean getExpires()
{
return expires;
}
protected Date getExpiryDate()
{
return expiryDate;
}
protected String getTicketId()
{
return ticketId;
}
protected String getUserName()
{
return userName;
}
}
public void setOneOff(boolean oneOff)
{
this.oneOff = oneOff;
}
public void setTicketsExpire(boolean ticketsExpire)
{
this.ticketsExpire = ticketsExpire;
}
public void setValidDuration(String validDuration)
{
this.validDuration = new Duration(validDuration);
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import net.sf.acegisecurity.providers.encoding.PasswordEncoder;
public interface MD4PasswordEncoder extends PasswordEncoder
{
/**
* Get the MD4 byte array
*
* @param encodedHash
* @return
*/
public byte[] decodeHash(String encodedHash);
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import net.sf.acegisecurity.providers.encoding.BaseDigestPasswordEncoder;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import cryptix.jce.provider.CryptixCrypto;
/**
* <p>
* MD4 implementation of PasswordEncoder.
* </p>
*
* <p>
* If a <code>null</code> password is presented, it will be treated as an
* empty <code>String</code> ("") password.
* </p>
*
* <P>
* As MD4 is a one-way hash, the salt can contain any characters.
* </p>
*/
public class MD4PasswordEncoderImpl extends BaseDigestPasswordEncoder implements MD4PasswordEncoder
{
static
{
try
{
MessageDigest.getInstance("MD4");
}
catch (NoSuchAlgorithmException e)
{
Security.addProvider(new CryptixCrypto());
}
}
public MD4PasswordEncoderImpl()
{
super();
// TODO Auto-generated constructor stub
}
// ~ Methods
// ================================================================
public boolean isPasswordValid(String encPass, String rawPass, Object salt)
{
String pass1 = "" + encPass;
String pass2 = encodeInternal(mergePasswordAndSalt(rawPass, salt, false));
return pass1.equals(pass2);
}
public String encodePassword(String rawPass, Object salt)
{
return encodeInternal(mergePasswordAndSalt(rawPass, salt, false));
}
private String encodeInternal(String input)
{
if (!getEncodeHashAsBase64())
{
return new String(Hex.encodeHex(md4(input)));
}
byte[] encoded = Base64.encodeBase64(md4(input));
try
{
return new String(encoded, "UTF8");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException("UTF8 not supported!", e);
}
}
private byte[] md4(String input)
{
try
{
MessageDigest digester = MessageDigest.getInstance("MD4");
return digester.digest(input.getBytes("UnicodeLittleUnmarked"));
}
catch (NoSuchAlgorithmException e)
{
throw new RuntimeException(e.getMessage(), e);
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e.getMessage(), e);
}
}
public byte[] decodeHash(String encodedHash)
{
if (!getEncodeHashAsBase64())
{
try
{
return Hex.decodeHex(encodedHash.toCharArray());
}
catch (DecoderException e)
{
throw new RuntimeException("Unable to decode password hash");
}
}
else
{
return Base64.decodeBase64(encodedHash.getBytes());
}
}
}

View File

@@ -0,0 +1,205 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import java.util.Date;
import net.sf.acegisecurity.providers.dao.AuthenticationDao;
import net.sf.acegisecurity.providers.dao.SaltSource;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* A service provider interface to provide both acegi integration via AuthenticationDao and SaltSource
* and mutability support for user definitions.
*
* @author Andy Hind
*/
public interface MutableAuthenticationDao extends AuthenticationDao, SaltSource
{
/**
* Create a user with the given userName and password
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
*/
public void createUser(String userName, char[] rawPassword) throws AuthenticationException;
/**
* Update a user's password.
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
*/
public void updateUser(String userName, char[] rawPassword) throws AuthenticationException;
/**
* Delete a user.
*
* @param userName
* @throws AuthenticationException
*/
public void deleteUser(String userName) throws AuthenticationException;
/**
* CHeck is a user exists.
*
* @param userName
* @return
*/
public boolean userExists(String userName);
/**
* Get the store ref where user objects are persisted.
*
* @return
*/
public StoreRef getUserStoreRef();
/**
* Enable/disable a user.
*
* @param userName
* @param enabled
*/
public void setEnabled(String userName, boolean enabled);
/**
* Getter for user enabled
*
* @param userName
* @return
*/
public boolean getEnabled(String userName);
/**
* Set if the account should expire
*
* @param userName
* @param expires
*/
public void setAccountExpires(String userName, boolean expires);
/**
* Does the account expire?
*
* @param userName
* @return
*/
public boolean getAccountExpires(String userName);
/**
* Has the account expired?
*
* @param userName
* @return
*/
public boolean getAccountHasExpired(String userName);
/**
* Set if the password expires.
*
* @param userName
* @param expires
*/
public void setCredentialsExpire(String userName, boolean expires);
/**
* Do the credentials for the user expire?
*
* @param userName
* @return
*/
public boolean getCredentialsExpire(String userName);
/**
* Have the credentials for the user expired?
*
* @param userName
* @return
*/
public boolean getCredentialsHaveExpired(String userName);
/**
* Set if the account is locked.
*
* @param userName
* @param locked
*/
public void setLocked(String userName, boolean locked);
/**
* Is the account locked?
*
* @param userName
* @return
*/
public boolean getAccountlocked(String userName);
/**
* Set the date on which the account expires
*
* @param userName
* @param exipryDate
*/
public void setAccountExpiryDate(String userName, Date exipryDate);
/**
* Get the date when this account expires.
*
* @param userName
* @return
*/
public Date getAccountExpiryDate(String userName);
/**
* Set the date when credentials expire.
*
* @param userName
* @param exipryDate
*/
public void setCredentialsExpiryDate(String userName, Date exipryDate);
/**
* Get the date when the credentials/password expire.
*
* @param userName
* @return
*/
public Date getCredentialsExpiryDate(String userName);
/**
* Get the MD4 password hash
*
* @param userName
* @return
*/
public String getMD4HashedPassword(String userName);
/**
* Are user names case sensitive?
*
* @return
*/
public boolean getUserNamesAreCaseSensitive();
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
public enum NTLMMode
{
PASS_THROUGH, MD4_PROVIDER, NONE
}

View File

@@ -0,0 +1,510 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.dao.User;
import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
import net.sf.acegisecurity.providers.encoding.PasswordEncoder;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.search.QueryParameterDefImpl;
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.search.QueryParameterDefinition;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.springframework.dao.DataAccessException;
public class RepositoryAuthenticationDao implements MutableAuthenticationDao
{
private static final String SYSTEM_FOLDER = "/sys:system";
private static final String PEOPLE_FOLDER = SYSTEM_FOLDER + "/sys:people";
private NodeService nodeService;
private NamespacePrefixResolver namespacePrefixResolver;
private DictionaryService dictionaryService;
private SearchService searchService;
private PasswordEncoder passwordEncoder;
private StoreRef userStoreRef;
private boolean userNamesAreCaseSensitive;
public boolean getUserNamesAreCaseSensitive()
{
return userNamesAreCaseSensitive;
}
public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive)
{
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setNamespaceService(NamespacePrefixResolver namespacePrefixResolver)
{
this.namespacePrefixResolver = namespacePrefixResolver;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPasswordEncoder(PasswordEncoder passwordEncoder)
{
this.passwordEncoder = passwordEncoder;
}
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
public UserDetails loadUserByUsername(String caseSensitiveUserName) throws UsernameNotFoundException, DataAccessException
{
String userName = userNamesAreCaseSensitive ? caseSensitiveUserName: caseSensitiveUserName.toLowerCase();
NodeRef userRef = getUserOrNull(userNamesAreCaseSensitive ? userName: userName.toLowerCase());
if (userRef == null)
{
throw new UsernameNotFoundException("Could not find user by userName: " + caseSensitiveUserName);
}
Map<QName, Serializable> properties = nodeService.getProperties(userRef);
String password = DefaultTypeConverter.INSTANCE.convert(String.class, properties
.get(ContentModel.PROP_PASSWORD));
GrantedAuthority[] gas = new GrantedAuthority[1];
gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED");
UserDetails ud = new User(userName, password, getEnabled(userName), !getAccountHasExpired(userName),
!getCredentialsHaveExpired(userName), !getAccountlocked(userName), gas);
return ud;
}
public NodeRef getUserOrNull(String caseSensitiveUserName)
{
String userName = userNamesAreCaseSensitive ? caseSensitiveUserName: caseSensitiveUserName.toLowerCase();
NodeRef rootNode = nodeService.getRootNode(getUserStoreRef());
QueryParameterDefinition[] defs = new QueryParameterDefinition[1];
DataTypeDefinition text = dictionaryService.getDataType(DataTypeDefinition.TEXT);
defs[0] = new QueryParameterDefImpl(QName.createQName("usr", "var", namespacePrefixResolver), text, true,
userName);
List<NodeRef> results = searchService.selectNodes(rootNode, PEOPLE_FOLDER
+ "/usr:user[@usr:username = $usr:var ]", defs, namespacePrefixResolver, false);
if (results.size() != 1)
{
return null;
}
return results.get(0);
}
public void createUser(String caseSensitiveUserName, char[] rawPassword) throws AuthenticationException
{
String userName = userNamesAreCaseSensitive ? caseSensitiveUserName: caseSensitiveUserName.toLowerCase();
NodeRef userRef = getUserOrNull(userName);
if (userRef != null)
{
throw new AuthenticationException("User already exists: " + userName);
}
NodeRef typesNode = getOrCreateTypeLocation();
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USER_USERNAME, userName);
String salt = null; // GUID.generate();
properties.put(ContentModel.PROP_SALT, salt);
properties.put(ContentModel.PROP_PASSWORD, passwordEncoder.encodePassword(new String(rawPassword), salt));
properties.put(ContentModel.PROP_ACCOUNT_EXPIRES, Boolean.valueOf(false));
properties.put(ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(false));
properties.put(ContentModel.PROP_ENABLED, Boolean.valueOf(true));
properties.put(ContentModel.PROP_ACCOUNT_LOCKED, Boolean.valueOf(false));
nodeService.createNode(typesNode, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_USER, ContentModel.TYPE_USER,
properties);
}
private NodeRef getOrCreateTypeLocation()
{
NodeRef rootNode = nodeService.getRootNode(getUserStoreRef());
List<ChildAssociationRef> results = nodeService.getChildAssocs(
rootNode,
RegexQNamePattern.MATCH_ALL,
QName.createQName("sys", "system", namespacePrefixResolver));
NodeRef sysNode = null;
if (results.size() == 0)
{
sysNode = nodeService.createNode(rootNode, ContentModel.ASSOC_CHILDREN,
QName.createQName("sys", "system", namespacePrefixResolver), ContentModel.TYPE_CONTAINER)
.getChildRef();
}
else
{
sysNode = results.get(0).getChildRef();
}
results = nodeService.getChildAssocs(
sysNode,
RegexQNamePattern.MATCH_ALL,
QName.createQName("sys", "people", namespacePrefixResolver));
NodeRef typesNode = null;
if (results.size() == 0)
{
typesNode = nodeService.createNode(sysNode, ContentModel.ASSOC_CHILDREN,
QName.createQName("sys", "people", namespacePrefixResolver), ContentModel.TYPE_CONTAINER)
.getChildRef();
}
else
{
typesNode = results.get(0).getChildRef();
}
return typesNode;
}
public void updateUser(String userName, char[] rawPassword) throws AuthenticationException
{
NodeRef userRef = getUserOrNull(userName);
if (userRef == null)
{
throw new AuthenticationException("User does not exist: " + userName);
}
Map<QName, Serializable> properties = nodeService.getProperties(userRef);
String salt = null; // GUID.generate();
properties.remove(ContentModel.PROP_SALT);
properties.put(ContentModel.PROP_SALT, salt);
properties.remove(ContentModel.PROP_PASSWORD);
properties.put(ContentModel.PROP_PASSWORD, passwordEncoder.encodePassword(new String(rawPassword), salt));
nodeService.setProperties(userRef, properties);
}
public void deleteUser(String userName) throws AuthenticationException
{
NodeRef userRef = getUserOrNull(userName);
if (userRef == null)
{
throw new AuthenticationException("User does not exist: " + userName);
}
nodeService.deleteNode(userRef);
}
public synchronized StoreRef getUserStoreRef()
{
if (userStoreRef == null)
{
userStoreRef = new StoreRef("user", "alfrescoUserStore");
}
if (!nodeService.exists(userStoreRef))
{
nodeService.createStore(userStoreRef.getProtocol(), userStoreRef.getIdentifier());
}
return userStoreRef;
}
public Object getSalt(UserDetails userDetails)
{
// NodeRef userRef = getUserOrNull(userDetails.getUsername());
// if (userRef == null)
// {
// throw new UsernameNotFoundException("Could not find user by userName:
// " + userDetails.getUsername());
// }
//
// Map<QName, Serializable> properties =
// nodeService.getProperties(userRef);
//
// String salt = DefaultTypeConverter.INSTANCE.convert(String.class,
// properties.get(QName.createQName("usr", "salt",
// namespacePrefixResolver)));
//
// return salt;
return null;
}
public boolean userExists(String userName)
{
return (getUserOrNull(userName) != null);
}
public boolean getAccountExpires(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return false;
}
Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRES);
if (ser == null)
{
return false;
}
else
{
return DefaultTypeConverter.INSTANCE.booleanValue(ser);
}
}
public Date getAccountExpiryDate(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return null;
}
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode,
ContentModel.PROP_ACCOUNT_EXPIRES)))
{
return DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode,
ContentModel.PROP_ACCOUNT_EXPIRY_DATE));
}
else
{
return null;
}
}
public boolean getAccountHasExpired(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return false;
}
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode,
ContentModel.PROP_ACCOUNT_EXPIRES)))
{
Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode,
ContentModel.PROP_ACCOUNT_EXPIRY_DATE));
if (date == null)
{
return false;
}
else
{
return (date.compareTo(new Date()) < 1);
}
}
else
{
return false;
}
}
public boolean getAccountlocked(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return false;
}
Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_LOCKED);
if (ser == null)
{
return false;
}
else
{
return DefaultTypeConverter.INSTANCE.booleanValue(ser);
}
}
public boolean getCredentialsExpire(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return false;
}
Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE);
if (ser == null)
{
return false;
}
else
{
return DefaultTypeConverter.INSTANCE.booleanValue(ser);
}
}
public Date getCredentialsExpiryDate(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return null;
}
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode,
ContentModel.PROP_CREDENTIALS_EXPIRE)))
{
return DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode,
ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));
}
else
{
return null;
}
}
public boolean getCredentialsHaveExpired(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return false;
}
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode,
ContentModel.PROP_CREDENTIALS_EXPIRE)))
{
Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode,
ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));
if (date == null)
{
return false;
}
else
{
return (date.compareTo(new Date()) < 1);
}
}
else
{
return false;
}
}
public boolean getEnabled(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return false;
}
Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_ENABLED);
if (ser == null)
{
return true;
}
else
{
return DefaultTypeConverter.INSTANCE.booleanValue(ser);
}
}
public void setAccountExpires(String userName, boolean expires)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
throw new AuthenticationException("User not found: " + userName);
}
nodeService.setProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRES, Boolean.valueOf(expires));
}
public void setAccountExpiryDate(String userName, Date exipryDate)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
throw new AuthenticationException("User not found: " + userName);
}
nodeService.setProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRY_DATE, exipryDate);
}
public void setCredentialsExpire(String userName, boolean expires)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
throw new AuthenticationException("User not found: " + userName);
}
nodeService.setProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(expires));
}
public void setCredentialsExpiryDate(String userName, Date exipryDate)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
throw new AuthenticationException("User not found: " + userName);
}
nodeService.setProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE, exipryDate);
}
public void setEnabled(String userName, boolean enabled)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
throw new AuthenticationException("User not found: " + userName);
}
nodeService.setProperty(userNode, ContentModel.PROP_ENABLED, Boolean.valueOf(enabled));
}
public void setLocked(String userName, boolean locked)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
throw new AuthenticationException("User not found: " + userName);
}
nodeService.setProperty(userNode, ContentModel.PROP_ACCOUNT_LOCKED, Boolean.valueOf(locked));
}
public String getMD4HashedPassword(String userName)
{
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
return null;
}
else
{
String password = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(userNode,
ContentModel.PROP_PASSWORD));
return password;
}
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
/**
* Manage authentication tickets
*
* @author andyh
*
*/
public interface TicketComponent
{
/**
* Register a ticket
*
* @param authentication
* @return
* @throws AuthenticationException
*/
public String getTicket(String userName) throws AuthenticationException;
/**
* Check that a certificate is valid and can be used in place of a login.
*
* Tickets may be rejected because:
* <ol>
* <li> The certificate does not exists
* <li> The status of the user has changed
* <ol>
* <li> The user is locked
* <li> The account has expired
* <li> The credentials have expired
* <li> The account is disabled
* </ol>
* <li> The ticket may have expired
* <ol>
* <li> The ticked my be invalid by timed expiry
* <li> An attemp to reuse a once only ticket
* </ol>
* </ol>
*
* @param authentication
* @return
* @throws AuthenticationException
*/
public String validateTicket(String ticket) throws AuthenticationException;
public void invalidateTicketById(String ticket);
public void invalidateTicketByUser(String userName);
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authentication;
public class TicketExpiredException extends AuthenticationException
{
/**
*
*/
private static final long serialVersionUID = 3257572801815590969L;
public TicketExpiredException(String msg)
{
super(msg);
}
public TicketExpiredException(String msg, Throwable cause)
{
super(msg, cause);
}
}

View File

@@ -0,0 +1,90 @@
<model name="usr:usermodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<description>Alfresco User Model</description>
<author>Alfresco</author>
<published>2005-08-16</published>
<version>0.1</version>
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys"/>
</imports>
<namespaces>
<namespace uri="http://www.alfresco.org/model/user/1.0" prefix="usr"/>
</namespaces>
<types>
<type name="usr:authority">
<title>Alfreco Authority Abstract Type</title>
<parent>sys:base</parent>
</type>
<type name="usr:user">
<title>Alfresco User Type</title>
<parent>usr:authority</parent>
<properties>
<property name="usr:username">
<type>d:text</type>
</property>
<property name="usr:password">
<type>d:text</type>
</property>
<property name="usr:enabled">
<type>d:boolean</type>
</property>
<property name="usr:accountExpires">
<type>d:boolean</type>
</property>
<property name="usr:accountExpiryDate">
<type>d:datetime</type>
</property>
<property name="usr:credentialsExpire">
<type>d:boolean</type>
</property>
<property name="usr:credentialsExpiryDate">
<type>d:datetime</type>
</property>
<property name="usr:accountLocked">
<type>d:boolean</type>
</property>
<property name="usr:salt">
<type>d:text</type>
</property>
</properties>
</type>
<type name="usr:authorityContainer">
<title>Alfresco Authority Type</title>
<parent>usr:authority</parent>
<properties>
<property name="usr:authorityName">
<type>d:text</type>
</property>
<property name="usr:members">
<type>d:text</type>
<multiple>true</multiple>
</property>
</properties>
<associations>
<child-association name="usr:member">
<source>
<mandatory>false</mandatory>
<many>true</many>
</source>
<target>
<class>usr:authority</class>
<mandatory>false</mandatory>
<many>true</many>
</target>
<duplicate>false</duplicate>
</child-association>
</associations>
</type>
</types>
</model>

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authority;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
/**
* The default implementation of the authority service.
*
* @author Andy Hind
*/
public class SimpleAuthorityServiceImpl implements AuthorityService
{
private PersonService personService;
private NodeService nodeService;
private Set<String> adminSet = Collections.singleton(PermissionService.ADMINISTRATOR_AUTHORITY);
private Set<String> guestSet = Collections.singleton(PermissionService.GUEST);
private Set<String> allSet = Collections.singleton(PermissionService.ALL_AUTHORITIES);
private Set<String> adminUsers;
private AuthenticationComponent authenticationComponent;
public SimpleAuthorityServiceImpl()
{
super();
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
/**
* Currently the admin authority is granted only to the ALFRESCO_ADMIN_USER
* user.
*/
public boolean hasAdminAuthority()
{
String currentUserName = authenticationComponent.getCurrentUserName();
return ((currentUserName != null) && adminUsers.contains(currentUserName));
}
// IOC
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
{
this.authenticationComponent = authenticationComponent;
}
public void setAdminUsers(Set<String> adminUsers)
{
this.adminUsers = adminUsers;
}
public Set<String> getAuthorities()
{
Set<String> authorities = new HashSet<String>();
String currentUserName = authenticationComponent.getCurrentUserName();
if (adminUsers.contains(currentUserName))
{
authorities.addAll(adminSet);
}
authorities.addAll(allSet);
return authorities;
}
public Set<String> getAllAuthorities(AuthorityType type)
{
Set<String> authorities = new HashSet<String>();
switch (type)
{
case ADMIN:
authorities.addAll(adminSet);
break;
case EVERYONE:
authorities.addAll(allSet);
break;
case GUEST:
authorities.addAll(guestSet);
break;
case GROUP:
authorities.addAll(allSet);
break;
case OWNER:
break;
case ROLE:
break;
case USER:
for (NodeRef personRef : personService.getAllPeople())
{
authorities.add(DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(personRef,
ContentModel.PROP_USERNAME)));
}
break;
default:
break;
}
return authorities;
}
public void addAuthority(String parentName, String childName)
{
}
public String createAuthority(AuthorityType type, String parentName, String shortName)
{
return "";
}
public void deleteAuthority(String name)
{
}
public Set<String> getAllRootAuthorities(AuthorityType type)
{
return getAllAuthorities(type);
}
public Set<String> getContainedAuthorities(AuthorityType type, String name, boolean immediate)
{
return Collections.<String>emptySet();
}
public Set<String> getContainingAuthorities(AuthorityType type, String name, boolean immediate)
{
return Collections.<String>emptySet();
}
public String getName(AuthorityType type, String shortName)
{
if (type.isFixedString())
{
return type.getFixedString();
}
else if (type.isPrefixed())
{
return type.getPrefixString() + shortName;
}
else
{
return shortName;
}
}
public String getShortName(String name)
{
AuthorityType type = AuthorityType.getAuthorityType(name);
if (type.isFixedString())
{
return "";
}
else if (type.isPrefixed())
{
return name.substring(type.getPrefixString().length());
}
else
{
return name;
}
}
public void removeAuthority(String parentName, String childName)
{
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.authority;
import javax.transaction.UserTransaction;
import junit.framework.TestCase;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext;
public class SimpleAuthorityServiceTest extends TestCase
{
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private AuthenticationComponent authenticationComponent;
private AuthenticationService authenticationService;
private AuthorityService authorityService;
private AuthorityService pubAuthorityService;
private MutableAuthenticationDao authenticationDAO;
private PersonService personService;
private UserTransaction tx;
public SimpleAuthorityServiceTest()
{
super();
}
public void setUp() throws Exception
{
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
authenticationService = (AuthenticationService) ctx.getBean("authenticationService");
authorityService = (AuthorityService) ctx.getBean("authorityService");
pubAuthorityService = (AuthorityService) ctx.getBean("AuthorityService");
personService = (PersonService) ctx.getBean("personService");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
this.authenticationComponent.setSystemUserAsCurrentUser();
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE
.getLocalName());
tx = transactionService.getUserTransaction();
tx.begin();
if (!authenticationDAO.userExists("andy"))
{
authenticationService.createAuthentication("andy", "andy".toCharArray());
}
if (!authenticationDAO.userExists("admin"))
{
authenticationService.createAuthentication("admin", "admin".toCharArray());
}
if (!authenticationDAO.userExists("administrator"))
{
authenticationService.createAuthentication("administrator", "administrator".toCharArray());
}
}
@Override
protected void tearDown() throws Exception
{
authenticationService.clearCurrentSecurityContext();
tx.rollback();
super.tearDown();
}
public void testNonAdminUser()
{
authenticationComponent.setCurrentUser("andy");
assertFalse(authorityService.hasAdminAuthority());
assertFalse(pubAuthorityService.hasAdminAuthority());
assertEquals(1, authorityService.getAuthorities().size());
}
public void testAdminUser()
{
authenticationComponent.setCurrentUser("admin");
assertTrue(authorityService.hasAdminAuthority());
assertTrue(pubAuthorityService.hasAdminAuthority());
assertEquals(2, authorityService.getAuthorities().size());
authenticationComponent.setCurrentUser("administrator");
assertTrue(authorityService.hasAdminAuthority());
assertTrue(pubAuthorityService.hasAdminAuthority());
assertEquals(2, authorityService.getAuthorities().size());
}
public void testAuthorities()
{
assertEquals(1, pubAuthorityService.getAllAuthorities(AuthorityType.ADMIN).size());
assertTrue(pubAuthorityService.getAllAuthorities(AuthorityType.ADMIN).contains(
PermissionService.ADMINISTRATOR_AUTHORITY));
assertEquals(1, pubAuthorityService.getAllAuthorities(AuthorityType.EVERYONE).size());
assertTrue(pubAuthorityService.getAllAuthorities(AuthorityType.EVERYONE).contains(
PermissionService.ALL_AUTHORITIES));
assertEquals(1, pubAuthorityService.getAllAuthorities(AuthorityType.GROUP).size());
assertTrue(pubAuthorityService.getAllAuthorities(AuthorityType.GROUP).contains(
PermissionService.ALL_AUTHORITIES));
assertEquals(1, pubAuthorityService.getAllAuthorities(AuthorityType.GUEST).size());
assertTrue(pubAuthorityService.getAllAuthorities(AuthorityType.GUEST).contains(PermissionService.GUEST));
assertEquals(0, pubAuthorityService.getAllAuthorities(AuthorityType.OWNER).size());
assertEquals(0, pubAuthorityService.getAllAuthorities(AuthorityType.ROLE).size());
assertEquals(personService.getAllPeople().size(), pubAuthorityService.getAllAuthorities(AuthorityType.USER)
.size());
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* Runtime access denied exception that is exposed
*
* @author Andy Hind
*/
public class AccessDeniedException extends AlfrescoRuntimeException
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = -4451661115250681152L;
public AccessDeniedException(String msg)
{
super(msg);
}
public AccessDeniedException(String msg, Throwable cause)
{
super(msg, cause);
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions;
/**
* A simple reference to a string authority.
*
* @author Andy Hind
*/
public interface AuthorityReference
{
public String getAuthority();
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* The interface for a dynamic authority provider e.g. for the owner of a node
* or any other authority that is determined by the context rather than just a
* node.
*
* @author Andy Hind
*/
public interface DynamicAuthority
{
/**
* Is this authority granted to the given user for this node ref?
*
* @param nodeRef
* @param userName
* @return
*/
public boolean hasAuthority(NodeRef nodeRef, String userName);
/**
* If this authority is granted this method provides the string
* representation of the granted authority.
*
* @return
*/
public String getAuthority();
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions;
import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Encapsulate how permissions are globally inherited between nodes.
*
* @author andyh
*/
public interface NodePermissionEntry
{
/**
* Get the node ref.
*
* @return
*/
public NodeRef getNodeRef();
/**
* Does the node inherit permissions from its primary parent?
*
* @return
*/
public boolean inheritPermissions();
/**
* Get the permission entries set for this node.
*
* @return
*/
public Set<? extends PermissionEntry> getPermissionEntries();
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
/**
* A single permission entry defined against a node.
*
* @author andyh
*/
public interface PermissionEntry
{
/**
* Get the permission definition.
*
* This may be null. Null implies that the settings apply to all permissions
*
* @return
*/
public PermissionReference getPermissionReference();
/**
* Get the authority to which this entry applies This could be the string
* value of a username, group, role or any other authority assigned to the
* authorisation.
*
* If null then this applies to all.
*
* @return
*/
public String getAuthority();
/**
* Get the node ref for the node to which this permission applies.
*
* This can only be null for a global permission
*
* @return
*/
public NodeRef getNodeRef();
/**
* Is permissions denied?
*
*/
public boolean isDenied();
/**
* Is permission allowed?
*
*/
public boolean isAllowed();
/**
* Get the Access enum value
*
* @return
*/
public AccessStatus getAccessStatus();
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions;
import org.alfresco.service.namespace.QName;
/**
* A Permission is a named permission against a type or aspect which is defined
* by QName. So a permission string is scoped by type.
*
* @author Andy Hind
*/
public interface PermissionReference
{
/**
* Get the QName of the type or aspect against which the permission is
* defined.
*
* @return
*/
public QName getQName();
/**
* Get the name of the permission
*
* @return
*/
public String getName();
}

View File

@@ -0,0 +1,141 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions;
import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
/**
* The public API for a permission service
*
* The implementation may be changed in the application configuration
*
* @author Andy Hind
*/
public interface PermissionServiceSPI extends PermissionService
{
/**
* Get the All Permission
*
* @return the All permission
*/
public PermissionReference getAllPermissionReference();
/**
* Get the permissions that can be set for a given type
*
* @param nodeRef
* @return
*/
public Set<PermissionReference> getSettablePermissionReferences(QName type);
/**
* Get the permissions that can be set for a given type
*
* @param nodeRef
* @return
*/
public Set<PermissionReference> getSettablePermissionReferences(NodeRef nodeRef);
/**
* Get the permissions that have been set on the given node (it knows
* nothing of the parent permissions)
*
* @param nodeRef
* @return
*/
public NodePermissionEntry getSetPermissions(NodeRef nodeRef);
/**
* Check that the given authentication has a particular permission for the
* given node. (The default behaviour is to inherit permissions)
*
* @param nodeRef
* @param perm
* @return
*/
public AccessStatus hasPermission(NodeRef nodeRef, PermissionReference perm);
/**
* Where is the permission set that controls the behaviour for the given
* permission for the given authentication to access the specified name.
*
* @param nodeRef
* @param auth
* @param perm
* @return
*/
public NodePermissionEntry explainPermission(NodeRef nodeRef, PermissionReference perm);
/**
* Delete the permissions defined by the nodePermissionEntry
* @param nodePermissionEntry
*/
public void deletePermissions(NodePermissionEntry nodePermissionEntry);
/**
* Delete a single permission entry
* @param permissionEntry
*/
public void deletePermission(PermissionEntry permissionEntry);
/**
* Add or set a permission entry on a node.
*
* @param permissionEntry
*/
public void setPermission(PermissionEntry permissionEntry);
/**
* Set the permissions on a node.
*
* @param nodePermissionEntry
*/
public void setPermission(NodePermissionEntry nodePermissionEntry);
/**
* Get the permission reference for the given data type and permission name.
*
* @param qname - may be null if the permission name is unique
* @param permissionName
* @return
*/
public PermissionReference getPermissionReference(QName qname, String permissionName);
/**
* Get the permission reference by permission name.
*
* @param permissionName
* @return
*/
public PermissionReference getPermissionReference(String permissionName);
/**
* Get the string that can be used to identify the given permission reference.
*
* @param permissionReference
* @return
*/
public String getPermission(PermissionReference permissionReference);
public void deletePermissions(String recipient);
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.dynamic;
import org.alfresco.repo.security.permissions.DynamicAuthority;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.springframework.beans.factory.InitializingBean;
public class LockOwnerDynamicAuthority implements DynamicAuthority, InitializingBean
{
private LockService lockService;
public LockOwnerDynamicAuthority()
{
super();
}
public boolean hasAuthority(NodeRef nodeRef, String userName)
{
return lockService.getLockStatus(nodeRef) == LockStatus.LOCK_OWNER;
}
public String getAuthority()
{
return PermissionService.LOCK_OWNER_AUTHORITY;
}
public void afterPropertiesSet() throws Exception
{
if(lockService == null)
{
throw new IllegalStateException("A lock service must be set");
}
}
public void setLockService(LockService lockService)
{
this.lockService = lockService;
}
}

View File

@@ -0,0 +1,216 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.dynamic;
import javax.transaction.UserTransaction;
import junit.framework.TestCase;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext;
public class LockOwnerDynamicAuthorityTest extends TestCase
{
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private NodeService nodeService;
private AuthenticationService authenticationService;
private AuthenticationComponent authenticationComponent;
private MutableAuthenticationDao authenticationDAO;
private LockService lockService;
private NodeRef rootNodeRef;
private UserTransaction userTransaction;
private PermissionService permissionService;
private LockOwnerDynamicAuthority dynamicAuthority;
public LockOwnerDynamicAuthorityTest()
{
super();
}
public LockOwnerDynamicAuthorityTest(String arg0)
{
super(arg0);
}
public void setUp() throws Exception
{
nodeService = (NodeService) ctx.getBean("nodeService");
authenticationService = (AuthenticationService) ctx.getBean("authenticationService");
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
lockService = (LockService) ctx.getBean("lockService");
permissionService = (PermissionService) ctx.getBean("permissionService");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE
.getLocalName());
userTransaction = transactionService.getUserTransaction();
userTransaction.begin();
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef);
permissionService.setPermission(rootNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.ADD_CHILDREN,
true);
if (authenticationDAO.userExists("andy"))
{
authenticationService.deleteAuthentication("andy");
}
authenticationService.createAuthentication("andy", "andy".toCharArray());
if (authenticationDAO.userExists("lemur"))
{
authenticationService.deleteAuthentication("lemur");
}
authenticationService.createAuthentication("lemur", "lemur".toCharArray());
if (authenticationDAO.userExists("frog"))
{
authenticationService.deleteAuthentication("frog");
}
authenticationService.createAuthentication("frog", "frog".toCharArray());
dynamicAuthority = new LockOwnerDynamicAuthority();
dynamicAuthority.setLockService(lockService);
authenticationComponent.clearCurrentSecurityContext();
}
@Override
protected void tearDown() throws Exception
{
authenticationComponent.clearCurrentSecurityContext();
userTransaction.rollback();
super.tearDown();
}
public void testSetup()
{
assertNotNull(nodeService);
assertNotNull(authenticationService);
assertNotNull(lockService);
}
public void testUnSet()
{
permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true);
authenticationService.authenticate("andy", "andy".toCharArray());
assertEquals(LockStatus.NO_LOCK, lockService.getLockStatus(rootNodeRef));
authenticationService.clearCurrentSecurityContext();
}
public void testPermissionWithNoLockAspect()
{
authenticationService.authenticate("andy", "andy".toCharArray());
NodeRef testNode = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_PERSON,
ContentModel.TYPE_CMOBJECT, null).getChildRef();
assertNotNull(testNode);
permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true);
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rootNodeRef,
PermissionService.LOCK));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rootNodeRef,
PermissionService.UNLOCK));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rootNodeRef, PermissionService.CHECK_OUT));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rootNodeRef, PermissionService.CHECK_IN));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rootNodeRef, PermissionService.CANCEL_CHECK_OUT));
}
public void testPermissionWithLockAspect()
{
permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true);
permissionService.setPermission(rootNodeRef, "lemur", PermissionService.CHECK_OUT, true);
permissionService.setPermission(rootNodeRef, "lemur", PermissionService.WRITE, true);
permissionService.setPermission(rootNodeRef, "lemur", PermissionService.READ, true);
permissionService.setPermission(rootNodeRef, "frog", PermissionService.CHECK_OUT, true);
permissionService.setPermission(rootNodeRef, "frog", PermissionService.WRITE, true);
permissionService.setPermission(rootNodeRef, "frog", PermissionService.READ, true);
authenticationService.authenticate("andy", "andy".toCharArray());
NodeRef testNode = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_PERSON,
ContentModel.TYPE_CMOBJECT, null).getChildRef();
lockService.lock(testNode, LockType.READ_ONLY_LOCK);
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode,
PermissionService.LOCK));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode,
PermissionService.UNLOCK));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT));
authenticationService.authenticate("lemur", "lemur".toCharArray());
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode,
PermissionService.LOCK));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode,
PermissionService.UNLOCK));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT));
authenticationService.authenticate("andy", "andy".toCharArray());
lockService.unlock(testNode);
authenticationService.authenticate("lemur", "lemur".toCharArray());
lockService.lock(testNode, LockType.READ_ONLY_LOCK);
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode,
PermissionService.LOCK));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode,
PermissionService.UNLOCK));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT));
authenticationService.authenticate("frog", "frog".toCharArray());
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode,
PermissionService.LOCK));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode,
PermissionService.UNLOCK));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT));
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.dynamic;
import org.alfresco.repo.security.permissions.DynamicAuthority;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.util.EqualsHelper;
import org.springframework.beans.factory.InitializingBean;
public class OwnerDynamicAuthority implements DynamicAuthority, InitializingBean
{
private OwnableService ownableService;
public OwnerDynamicAuthority()
{
super();
}
public void setOwnableService(OwnableService ownableService)
{
this.ownableService = ownableService;
}
public void afterPropertiesSet() throws Exception
{
if (ownableService == null)
{
throw new IllegalArgumentException("There must be an ownable service");
}
}
public boolean hasAuthority(NodeRef nodeRef, String userName)
{
return EqualsHelper.nullSafeEquals(ownableService.getOwner(nodeRef), userName);
}
public String getAuthority()
{
return PermissionService.OWNER_AUTHORITY;
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.alfresco.repo.security.permissions.NodePermissionEntry;
/**
* This class provides common support for hash code and equality.
*
* @author andyh
*/
public abstract class AbstractNodePermissionEntry implements
NodePermissionEntry
{
public AbstractNodePermissionEntry()
{
super();
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof AbstractNodePermissionEntry))
{
return false;
}
AbstractNodePermissionEntry other = (AbstractNodePermissionEntry) o;
return this.getNodeRef().equals(other.getNodeRef())
&& (this.inheritPermissions() == other.inheritPermissions())
&& (this.getPermissionEntries().equals(other.getPermissionEntries()));
}
@Override
public int hashCode()
{
return getNodeRef().hashCode();
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.util.EqualsHelper;
/**
* This class provides common support for hash code and equality.
*
* @author andyh
*/
public abstract class AbstractPermissionEntry implements PermissionEntry
{
public AbstractPermissionEntry()
{
super();
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof AbstractPermissionEntry))
{
return false;
}
AbstractPermissionEntry other = (AbstractPermissionEntry) o;
return EqualsHelper.nullSafeEquals(this.getNodeRef(),
other.getNodeRef())
&& EqualsHelper.nullSafeEquals(this.getPermissionReference(),
other.getPermissionReference())
&& EqualsHelper.nullSafeEquals(this.getAuthority(), other.getAuthority())
&& EqualsHelper.nullSafeEquals(this.getAccessStatus(), other.getAccessStatus());
}
@Override
public int hashCode()
{
int hashCode = getNodeRef().hashCode();
if (getPermissionReference() != null)
{
hashCode = hashCode * 37 + getPermissionReference().hashCode();
}
if (getAuthority() != null)
{
hashCode = hashCode * 37 + getAuthority().hashCode();
}
if(getAccessStatus() != null)
{
hashCode = hashCode * 37 + getAccessStatus().hashCode();
}
return hashCode;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.alfresco.repo.security.permissions.PermissionReference;
/**
* This class provides common support for hash code and equality.
*
* @author andyh
*/
public abstract class AbstractPermissionReference implements PermissionReference
{
public AbstractPermissionReference()
{
super();
}
@Override
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if(!(o instanceof AbstractPermissionReference))
{
return false;
}
AbstractPermissionReference other = (AbstractPermissionReference)o;
return this.getName().equals(other.getName()) && this.getQName().equals(other.getQName());
}
@Override
public int hashCode()
{
return getQName().hashCode() * 37 + getName().hashCode();
}
@Override
public String toString()
{
return getQName()+ "." + getName();
}
}

View File

@@ -0,0 +1,166 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseSpringTest;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
public class AbstractPermissionTest extends BaseSpringTest
{
protected static final String ROLE_AUTHENTICATED = "ROLE_AUTHENTICATED";
protected NodeService nodeService;
protected DictionaryService dictionaryService;
protected PermissionServiceSPI permissionService;
protected AuthenticationService authenticationService;
private MutableAuthenticationDao authenticationDAO;
protected LocalSessionFactoryBean sessionFactory;
protected NodeRef rootNodeRef;
protected NamespacePrefixResolver namespacePrefixResolver;
protected ServiceRegistry serviceRegistry;
protected NodeRef systemNodeRef;
protected AuthenticationComponent authenticationComponent;
protected ModelDAO permissionModelDAO;
protected PersonService personService;
protected AuthorityService authorityService;
public AbstractPermissionTest()
{
super();
// TODO Auto-generated constructor stub
}
protected void onSetUpInTransaction() throws Exception
{
nodeService = (NodeService) applicationContext.getBean("nodeService");
dictionaryService = (DictionaryService) applicationContext.getBean(ServiceRegistry.DICTIONARY_SERVICE
.getLocalName());
permissionService = (PermissionServiceSPI) applicationContext.getBean("permissionService");
namespacePrefixResolver = (NamespacePrefixResolver) applicationContext
.getBean(ServiceRegistry.NAMESPACE_SERVICE.getLocalName());
authenticationService = (AuthenticationService) applicationContext.getBean("authenticationService");
authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
serviceRegistry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
permissionModelDAO = (ModelDAO) applicationContext.getBean("permissionsModelDAO");
personService = (PersonService) applicationContext.getBean("personService");
authorityService = (AuthorityService) applicationContext.getBean("authorityService");
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());
rootNodeRef = nodeService.getRootNode(storeRef);
QName children = ContentModel.ASSOC_CHILDREN;
QName system = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "system");
QName container = ContentModel.TYPE_CONTAINER;
QName types = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "people");
systemNodeRef = nodeService.createNode(rootNodeRef, children, system, container).getChildRef();
NodeRef typesNodeRef = nodeService.createNode(systemNodeRef, children, types, container).getChildRef();
Map<QName, Serializable> props = createPersonProperties("andy");
nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef();
props = createPersonProperties("lemur");
nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef();
// create an authentication object e.g. the user
if(authenticationDAO.userExists("andy"))
{
authenticationService.deleteAuthentication("andy");
}
authenticationService.createAuthentication("andy", "andy".toCharArray());
if(authenticationDAO.userExists("lemur"))
{
authenticationService.deleteAuthentication("lemur");
}
authenticationService.createAuthentication("lemur", "lemur".toCharArray());
if(authenticationDAO.userExists("admin"))
{
authenticationService.deleteAuthentication("admin");
}
authenticationService.createAuthentication("admin", "admin".toCharArray());
authenticationComponent.clearCurrentSecurityContext();
}
protected void onTearDownInTransaction()
{
flushAndClear();
super.onTearDownInTransaction();
}
protected void runAs(String userName)
{
authenticationService.authenticate(userName, userName.toCharArray());
assertNotNull(authenticationService.getCurrentUserName());
// for(GrantedAuthority authority : woof.getAuthorities())
// {
// System.out.println("Auth = "+authority.getAuthority());
// }
}
private Map<QName, Serializable> createPersonProperties(String userName)
{
HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME, userName);
return properties;
}
protected PermissionReference getPermission(String permission)
{
return permissionModelDAO.getPermissionReference(null, permission);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AlwaysProceedMethodInterceptor implements MethodInterceptor
{
public AlwaysProceedMethodInterceptor()
{
super();
}
public Object invoke(MethodInvocation mi) throws Throwable
{
return mi.proceed();
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import net.sf.acegisecurity.AccessDeniedException;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class ExceptionTranslatorMethodInterceptor implements MethodInterceptor
{
private static final String MSG_ACCESS_DENIED = "permissions.err_access_denied";
public ExceptionTranslatorMethodInterceptor()
{
super();
}
public Object invoke(MethodInvocation mi) throws Throwable
{
try
{
return mi.proceed();
}
catch(AccessDeniedException ade)
{
throw new org.alfresco.repo.security.permissions.AccessDeniedException(MSG_ACCESS_DENIED, ade);
}
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import java.util.Set;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* The API for the alfresco permission model.
*
* @author Andy Hind
*/
public interface ModelDAO
{
/**
* Get the permissions that can be set for the given type.
*
* @param type - the type in the data dictionary.
* @return
*/
public Set<PermissionReference> getAllPermissions(QName type);
/**
* Get the permissions that can be set for the given node.
* This is determined by the node type.
*
* @param nodeRef
* @return
*/
public Set<PermissionReference> getAllPermissions(NodeRef nodeRef);
/**
*Get the permissions that are exposed to be set for the given type.
*
* @param type - the type in the data dictionary.
* @return
*/
public Set<PermissionReference> getExposedPermissions(QName type);
/**
* Get the permissions that are exposed to be set for the given node.
* This is determined by the node type.
*
* @param nodeRef
* @return
*/
public Set<PermissionReference> getExposedPermissions(NodeRef nodeRef);
/**
* Get all the permissions that grant this permission.
*
* @param perm
* @return
*/
public Set<PermissionReference> getGrantingPermissions(PermissionReference perm);
/**
* Get the permissions that must also be present on the node for the required permission to apply.
*
* @param required
* @param qName
* @param aspectQNames
* @param on
* @return
*/
public Set<PermissionReference> getRequiredPermissions(PermissionReference required, QName qName, Set<QName> aspectQNames, RequiredPermission.On on);
/**
* Get the permissions which are granted by the supplied permission.
*
* @param permissionReference
* @return
*/
public Set<PermissionReference> getGranteePermissions(PermissionReference permissionReference);
/**
* Is this permission refernece to a permission and not a permissoinSet?
*
* @param required
* @return
*/
public boolean checkPermission(PermissionReference required);
/**
* Does the permission reference have a unique name?
*
* @param permissionReference
* @return
*/
public boolean isUnique(PermissionReference permissionReference);
/**
* Find a permission by name in the type context.
* If the context is null and the permission name is unique it will be found.
*
* @param qname
* @param permissionName
* @return
*/
public PermissionReference getPermissionReference(QName qname, String permissionName);
/**
* Get the global permissions for the model.
* Permissions that apply to all nodes and take precedence over node specific permissions.
*
* @return
*/
public Set<? extends PermissionEntry> getGlobalPermissionEntries();
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.alfresco.service.namespace.QName;
/**
* A simple permission reference (not persisted).
*
* A permission is identified by name for a given type, which is identified by its qualified name.
*
* @author andyh
*/
public class PermissionReferenceImpl extends AbstractPermissionReference
{
private QName qName;
private String name;
public PermissionReferenceImpl(QName qName, String name)
{
this.qName = qName;
this.name = name;
}
public String getName()
{
return name;
}
public QName getQName()
{
return qName;
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* The API for accessing persisted Alfresco permissions.
*
* @author andyh
*/
public interface PermissionsDAO
{
/**
* Get the permissions that have been set on a given node.
*
* @param nodeRef
* @return
*/
public NodePermissionEntry getPermissions(NodeRef nodeRef);
/**
* Delete all the permissions on a given node.
* The node permission and all the permission entries it contains will be deleted.
*
* @param nodeRef
*/
public void deletePermissions(NodeRef nodeRef);
/**
* Delete all the permissions on a given node.
* The node permission and all the permission entries it contains will be deleted.
*
* @param nodePermissionEntry
*/
public void deletePermissions(NodePermissionEntry nodePermissionEntry);
/**
* Delete as single permission entry.
* This deleted one permission on the node. It does not affect the persistence of any other permissions.
*
* @param permissionEntry
*/
public void deletePermissions(PermissionEntry permissionEntry);
/**
*
* Delete as single permission entry, if a match is found.
* This deleted one permission on the node. It does not affect the persistence of any other permissions.
*
* @param nodeRef
* @param authority
* @param perm
* @param allow
*/
public void deletePermissions(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow);
/**
* Set a permission on a node.
* If the node has no permissions set then a default node permission (allowing inheritance) will be created to
* contain the permission entry.
*
* @param nodeRef
* @param authority
* @param perm
* @param allow
*/
public void setPermission(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow);
/**
* Create a persisted permission entry given and other representation of a permission entry.
*
* @param permissionEntry
*/
public void setPermission(PermissionEntry permissionEntry);
/**
* Create a persisted node permission entry given a template object from which to copy.
*
* @param nodePermissionEntry
*/
public void setPermission(NodePermissionEntry nodePermissionEntry);
/**
* Set the inheritance behaviour for permissions on a given node.
*
* @param nodeRef
* @param inheritParentPermissions
*/
public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions);
/**
* Return the inheritance behaviour for permissions on a given node.
*
* @param nodeRef
* @return inheritParentPermissions
*/
public boolean getInheritParentPermissions(NodeRef nodeRef);
/**
* Clear all the permissions set for a given authentication
*
* @param nodeRef
* @param authority
*/
public void clearPermission(NodeRef nodeRef, String authority);
/**
* Remove all permissions for the specvified authority
* @param authority
*/
public void deleteAllPermissionsForAuthority(String authority);
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.alfresco.service.namespace.QName;
/**
* Store and read the definition of a required permission.
*
* @author andyh
*/
public class RequiredPermission extends PermissionReferenceImpl
{
public enum On {
PARENT, NODE, CHILDREN
};
private On on;
boolean implies;
public RequiredPermission(QName qName, String name, On on, boolean implies)
{
super(qName, name);
this.on = on;
this.implies = implies;
}
public boolean isImplies()
{
return implies;
}
public On getOn()
{
return on;
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import java.io.Serializable;
import java.util.Set;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* A simple object representation of a node permission entry
*
* @author andyh
*/
public class SimpleNodePermissionEntry extends AbstractNodePermissionEntry implements Serializable
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 8157870444595023347L;
/*
* The node
*/
private NodeRef nodeRef;
/*
* Are permissions inherited?
*/
private boolean inheritPermissions;
/*
* The set of permission entries.
*/
private Set<? extends PermissionEntry> permissionEntries;
public SimpleNodePermissionEntry(NodeRef nodeRef, boolean inheritPermissions, Set<? extends PermissionEntry> permissionEntries)
{
super();
this.nodeRef = nodeRef;
this.inheritPermissions = inheritPermissions;
this.permissionEntries = permissionEntries;
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public boolean inheritPermissions()
{
return inheritPermissions;
}
public Set<? extends PermissionEntry> getPermissionEntries()
{
return permissionEntries;
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
/**
* A simple object representation of a permission entry.
*
* @author andyh
*/
public class SimplePermissionEntry extends AbstractPermissionEntry
{
/*
* The node ref to which the permissoin applies
*/
private NodeRef nodeRef;
/*
* The permission reference - as a simple permission reference
*/
private PermissionReference permissionReference;
/*
* The authority to which the permission aplies
*/
private String authority;
/*
* The access mode for the permission
*/
private AccessStatus accessStatus;
public SimplePermissionEntry(NodeRef nodeRef, PermissionReference permissionReference, String authority, AccessStatus accessStatus)
{
super();
this.nodeRef = nodeRef;
this.permissionReference = permissionReference;
this.authority = authority;
this.accessStatus = accessStatus;
}
public PermissionReference getPermissionReference()
{
return permissionReference;
}
public String getAuthority()
{
return authority;
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public boolean isDenied()
{
return accessStatus == AccessStatus.DENIED;
}
public boolean isAllowed()
{
return accessStatus == AccessStatus.ALLOWED;
}
public AccessStatus getAccessStatus()
{
return accessStatus;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl;
import org.alfresco.service.namespace.QName;
/**
* A simple permission reference.
*
* @author andyh
*/
public class SimplePermissionReference extends AbstractPermissionReference
{
/*
* The type
*/
private QName qName;
/*
* The name of the permission
*/
private String name;
public SimplePermissionReference(QName qName, String name)
{
super();
this.qName = qName;
this.name = name;
}
public QName getQName()
{
return qName;
}
public String getName()
{
return name;
}
}

View File

@@ -0,0 +1,635 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.acegi;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.afterinvocation.AfterInvocationProvider;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider, InitializingBean
{
private static Log log = LogFactory.getLog(ACLEntryAfterInvocationProvider.class);
private static final String AFTER_ACL_NODE = "AFTER_ACL_NODE";
private static final String AFTER_ACL_PARENT = "AFTER_ACL_PARENT";
private PermissionService permissionService;
private NamespacePrefixResolver nspr;
private NodeService nodeService;
private AuthenticationService authenticationService;
public ACLEntryAfterInvocationProvider()
{
super();
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public PermissionService getPermissionService()
{
return permissionService;
}
public NamespacePrefixResolver getNamespacePrefixResolver()
{
return nspr;
}
public void setNamespacePrefixResolver(NamespacePrefixResolver nspr)
{
this.nspr = nspr;
}
public NodeService getNodeService()
{
return nodeService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public AuthenticationService getAuthenticationService()
{
return authenticationService;
}
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
public void afterPropertiesSet() throws Exception
{
if (permissionService == null)
{
throw new IllegalArgumentException("There must be a permission service");
}
if (nspr == null)
{
throw new IllegalArgumentException("There must be a namespace service");
}
if (nodeService == null)
{
throw new IllegalArgumentException("There must be a node service");
}
if (authenticationService == null)
{
throw new IllegalArgumentException("There must be an authentication service");
}
}
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Object returnedObject) throws AccessDeniedException
{
if (log.isDebugEnabled())
{
MethodInvocation mi = (MethodInvocation) object;
log.debug("Method: " + mi.getMethod().toString());
}
try
{
if (authenticationService.isCurrentUserTheSystemUser())
{
if (log.isDebugEnabled())
{
log.debug("Allowing system user access");
}
return returnedObject;
}
else if (returnedObject == null)
{
if (log.isDebugEnabled())
{
log.debug("Allowing null object access");
}
return null;
}
else if (StoreRef.class.isAssignableFrom(returnedObject.getClass()))
{
if (log.isDebugEnabled())
{
log.debug("Store access");
}
return decide(authentication, object, config, nodeService.getRootNode((StoreRef) returnedObject))
.getStoreRef();
}
else if (NodeRef.class.isAssignableFrom(returnedObject.getClass()))
{
if (log.isDebugEnabled())
{
log.debug("Node access");
}
return decide(authentication, object, config, (NodeRef) returnedObject);
}
else if (ChildAssociationRef.class.isAssignableFrom(returnedObject.getClass()))
{
if (log.isDebugEnabled())
{
log.debug("Child Association access");
}
return decide(authentication, object, config, (ChildAssociationRef) returnedObject);
}
else if (ResultSet.class.isAssignableFrom(returnedObject.getClass()))
{
if (log.isDebugEnabled())
{
log.debug("Result Set access");
}
return decide(authentication, object, config, (ResultSet) returnedObject);
}
else if (Collection.class.isAssignableFrom(returnedObject.getClass()))
{
if (log.isDebugEnabled())
{
log.debug("Collection Access");
}
return decide(authentication, object, config, (Collection) returnedObject);
}
else if (returnedObject.getClass().isArray())
{
if (log.isDebugEnabled())
{
log.debug("Array Access");
}
return decide(authentication, object, config, (Object[]) returnedObject);
}
else
{
if (log.isDebugEnabled())
{
log.debug("Uncontrolled object - access allowed for " + object.getClass().getName());
}
return returnedObject;
}
}
catch (AccessDeniedException ade)
{
if (log.isDebugEnabled())
{
log.debug("Access denied");
ade.printStackTrace();
}
throw ade;
}
catch (RuntimeException re)
{
if (log.isDebugEnabled())
{
log.debug("Access denied by runtime exception");
re.printStackTrace();
}
throw re;
}
}
public NodeRef decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
NodeRef returnedObject) throws AccessDeniedException
{
if (returnedObject == null)
{
return null;
}
List<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
if (supportedDefinitions.size() == 0)
{
return returnedObject;
}
for (ConfigAttributeDefintion cad : supportedDefinitions)
{
NodeRef testNodeRef = null;
if (cad.typeString.equals(AFTER_ACL_NODE))
{
testNodeRef = returnedObject;
}
else if (cad.typeString.equals(AFTER_ACL_PARENT))
{
testNodeRef = nodeService.getPrimaryParent(returnedObject).getParentRef();
}
if ((testNodeRef != null)
&& (permissionService.hasPermission(testNodeRef, cad.required.toString()) == AccessStatus.DENIED))
{
throw new AccessDeniedException("Access Denied");
}
}
return returnedObject;
}
private List<ConfigAttributeDefintion> extractSupportedDefinitions(ConfigAttributeDefinition config)
{
List<ConfigAttributeDefintion> definitions = new ArrayList<ConfigAttributeDefintion>();
Iterator iter = config.getConfigAttributes();
while (iter.hasNext())
{
ConfigAttribute attr = (ConfigAttribute) iter.next();
if (this.supports(attr))
{
definitions.add(new ConfigAttributeDefintion(attr));
}
}
return definitions;
}
public ChildAssociationRef decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
ChildAssociationRef returnedObject) throws AccessDeniedException
{
if (returnedObject == null)
{
return null;
}
List<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
if (supportedDefinitions.size() == 0)
{
return returnedObject;
}
for (ConfigAttributeDefintion cad : supportedDefinitions)
{
NodeRef testNodeRef = null;
if (cad.typeString.equals(AFTER_ACL_NODE))
{
testNodeRef = ((ChildAssociationRef) returnedObject).getChildRef();
}
else if (cad.typeString.equals(AFTER_ACL_PARENT))
{
testNodeRef = ((ChildAssociationRef) returnedObject).getParentRef();
}
if ((testNodeRef != null)
&& (permissionService.hasPermission(testNodeRef, cad.required.toString()) == AccessStatus.DENIED))
{
throw new AccessDeniedException("Access Denied");
}
}
return returnedObject;
}
public ResultSet decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
ResultSet returnedObject) throws AccessDeniedException
{
FilteringResultSet filteringResultSet = new FilteringResultSet((ResultSet) returnedObject);
if (returnedObject == null)
{
return null;
}
List<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
if (supportedDefinitions.size() == 0)
{
return returnedObject;
}
for (int i = 0; i < returnedObject.length(); i++)
{
for (ConfigAttributeDefintion cad : supportedDefinitions)
{
filteringResultSet.setIncluded(i, true);
NodeRef testNodeRef = null;
if (cad.typeString.equals(AFTER_ACL_NODE))
{
testNodeRef = returnedObject.getNodeRef(i);
}
else if (cad.typeString.equals(AFTER_ACL_PARENT))
{
testNodeRef = returnedObject.getChildAssocRef(i).getParentRef();
}
if (filteringResultSet.getIncluded(i)
&& (testNodeRef != null)
&& (permissionService.hasPermission(testNodeRef, cad.required.toString()) == AccessStatus.DENIED))
{
filteringResultSet.setIncluded(i, false);
}
}
}
return filteringResultSet;
}
public Collection decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Collection returnedObject) throws AccessDeniedException
{
if (returnedObject == null)
{
return null;
}
List<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
if (supportedDefinitions.size() == 0)
{
return returnedObject;
}
Set<Object> removed = new HashSet<Object>();
if (log.isDebugEnabled())
{
log.debug("Entries are " + supportedDefinitions);
}
for (Object nextObject : returnedObject)
{
boolean allowed = true;
for (ConfigAttributeDefintion cad : supportedDefinitions)
{
NodeRef testNodeRef = null;
if (cad.typeString.equals(AFTER_ACL_NODE))
{
if (StoreRef.class.isAssignableFrom(nextObject.getClass()))
{
testNodeRef = nodeService.getRootNode((StoreRef) nextObject);
if (log.isDebugEnabled())
{
log.debug("\tNode Test on store " + nodeService.getPath(testNodeRef));
}
}
else if (NodeRef.class.isAssignableFrom(nextObject.getClass()))
{
testNodeRef = (NodeRef) nextObject;
if (log.isDebugEnabled())
{
log.debug("\tNode Test on node " + nodeService.getPath(testNodeRef));
}
}
else if (ChildAssociationRef.class.isAssignableFrom(nextObject.getClass()))
{
testNodeRef = ((ChildAssociationRef) nextObject).getChildRef();
if (log.isDebugEnabled())
{
log.debug("\tNode Test on child association ref using " + nodeService.getPath(testNodeRef));
}
}
else
{
throw new ACLEntryVoterException(
"The specified parameter is not a collection of NodeRefs or ChildAssociationRefs");
}
}
else if (cad.typeString.equals(AFTER_ACL_PARENT))
{
if (StoreRef.class.isAssignableFrom(nextObject.getClass()))
{
// Will be allowed
testNodeRef = null;
if (log.isDebugEnabled())
{
log.debug("\tParent Test on store ");
}
}
else if (NodeRef.class.isAssignableFrom(nextObject.getClass()))
{
testNodeRef = nodeService.getPrimaryParent((NodeRef) nextObject).getParentRef();
if (log.isDebugEnabled())
{
log.debug("\tParent test on node " + nodeService.getPath(testNodeRef));
}
}
else if (ChildAssociationRef.class.isAssignableFrom(nextObject.getClass()))
{
testNodeRef = ((ChildAssociationRef) nextObject).getParentRef();
if (log.isDebugEnabled())
{
log.debug("\tParent Test on child association ref using "
+ nodeService.getPath(testNodeRef));
}
}
else
{
throw new ACLEntryVoterException(
"The specified parameter is not a collection of NodeRefs or ChildAssociationRefs");
}
}
if (allowed
&& (testNodeRef != null)
&& (permissionService.hasPermission(testNodeRef, cad.required.toString()) == AccessStatus.DENIED))
{
allowed = false;
}
}
if (!allowed)
{
removed.add(nextObject);
}
}
for (Object toRemove : removed)
{
while (returnedObject.remove(toRemove))
;
}
return returnedObject;
}
public Object[] decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Object[] returnedObject) throws AccessDeniedException
{
BitSet incudedSet = new BitSet(returnedObject.length);
if (returnedObject == null)
{
return null;
}
List<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
if (supportedDefinitions.size() == 0)
{
return returnedObject;
}
for (int i = 0, l = returnedObject.length; i < l; i++)
{
Object current = returnedObject[i];
for (ConfigAttributeDefintion cad : supportedDefinitions)
{
incudedSet.set(i, true);
NodeRef testNodeRef = null;
if (cad.typeString.equals(AFTER_ACL_NODE))
{
if (StoreRef.class.isAssignableFrom(current.getClass()))
{
testNodeRef = nodeService.getRootNode((StoreRef) current);
}
else if (NodeRef.class.isAssignableFrom(current.getClass()))
{
testNodeRef = (NodeRef) current;
}
else if (ChildAssociationRef.class.isAssignableFrom(current.getClass()))
{
testNodeRef = ((ChildAssociationRef) current).getChildRef();
}
else
{
throw new ACLEntryVoterException("The specified array is not of NodeRef or ChildAssociationRef");
}
}
else if (cad.typeString.equals(AFTER_ACL_PARENT))
{
if (StoreRef.class.isAssignableFrom(current.getClass()))
{
testNodeRef = null;
}
else if (NodeRef.class.isAssignableFrom(current.getClass()))
{
testNodeRef = nodeService.getPrimaryParent((NodeRef) current).getParentRef();
}
else if (ChildAssociationRef.class.isAssignableFrom(current.getClass()))
{
testNodeRef = ((ChildAssociationRef) current).getParentRef();
}
else
{
throw new ACLEntryVoterException("The specified array is not of NodeRef or ChildAssociationRef");
}
}
if (incudedSet.get(i)
&& (testNodeRef != null)
&& (permissionService.hasPermission(testNodeRef, cad.required.toString()) == AccessStatus.DENIED))
{
incudedSet.set(i, false);
}
}
}
if (incudedSet.cardinality() == returnedObject.length)
{
return returnedObject;
}
else
{
Object[] answer = new Object[incudedSet.cardinality()];
for (int i = incudedSet.nextSetBit(0), p = 0; i >= 0; i = incudedSet.nextSetBit(++i), p++)
{
answer[p] = returnedObject[i];
}
return answer;
}
}
public boolean supports(ConfigAttribute attribute)
{
if ((attribute.getAttribute() != null)
&& (attribute.getAttribute().startsWith(AFTER_ACL_NODE) || attribute.getAttribute().startsWith(
AFTER_ACL_PARENT)))
{
return true;
}
else
{
return false;
}
}
public boolean supports(Class clazz)
{
return (MethodInvocation.class.isAssignableFrom(clazz));
}
private class ConfigAttributeDefintion
{
String typeString;
SimplePermissionReference required;
ConfigAttributeDefintion(ConfigAttribute attr)
{
StringTokenizer st = new StringTokenizer(attr.getAttribute(), ".", false);
if (st.countTokens() != 3)
{
throw new ACLEntryVoterException("There must be three . separated tokens in each config attribute");
}
typeString = st.nextToken();
String qNameString = st.nextToken();
String permissionString = st.nextToken();
if (!(typeString.equals(AFTER_ACL_NODE) || typeString.equals(AFTER_ACL_PARENT)))
{
throw new ACLEntryVoterException("Invalid type: must be ACL_NODE or ACL_PARENT");
}
QName qName = QName.createQName(qNameString, nspr);
required = new SimplePermissionReference(qName, permissionString);
}
}
}

View File

@@ -0,0 +1,884 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.acegi;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.search.results.ChildAssocRefResultSet;
import org.alfresco.repo.security.permissions.impl.AbstractPermissionTest;
import org.alfresco.repo.security.permissions.impl.SimplePermissionEntry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.target.SingletonTargetSource;
public class ACLEntryAfterInvocationTest extends AbstractPermissionTest
{
public ACLEntryAfterInvocationTest()
{
super();
}
public void testBasicAllowNullNode() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoNodeRef", new Class[] { NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
Object answer = method.invoke(proxy, new Object[] { null });
assertNull(answer);
}
public void testBasicAllowNullStore() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoStoreRef", new Class[] { StoreRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
Object answer = method.invoke(proxy, new Object[] { null });
assertNull(answer);
}
public void testBasicAllowUnrecognisedObject() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoObject", new Class[] { Object.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
Object answer = method.invoke(proxy, new Object[] { "noodle" });
assertNotNull(answer);
}
public void testBasicDenyStore() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoStoreRef", new Class[] { StoreRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
Object answer = method.invoke(proxy, new Object[] { rootNodeRef.getStoreRef() });
assertNotNull(answer);
}
catch (InvocationTargetException e)
{
}
}
public void testBasicDenyNode() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoNodeRef", new Class[] { NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
Object answer = method.invoke(proxy, new Object[] { rootNodeRef });
assertNotNull(answer);
}
catch (InvocationTargetException e)
{
}
}
public void testBasicAllowNode() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoNodeRef", new Class[] { NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object answer = method.invoke(proxy, new Object[] { rootNodeRef });
assertEquals(answer, rootNodeRef);
}
public void testBasicAllowStore() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoStoreRef", new Class[] { StoreRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object answer = method.invoke(proxy, new Object[] { rootNodeRef.getStoreRef() });
assertEquals(answer, rootNodeRef.getStoreRef());
}
public void testBasicAllowNodeParent() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoNodeRef", new Class[] { NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_PARENT.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
Object answer = method.invoke(proxy, new Object[] { rootNodeRef });
assertEquals(answer, rootNodeRef);
try
{
answer = method.invoke(proxy, new Object[] { systemNodeRef });
assertNotNull(answer);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
answer = method.invoke(proxy, new Object[] { systemNodeRef });
assertEquals(answer, systemNodeRef);
}
public void testBasicAllowNullChildAssociationRef1() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoChildAssocRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
Object answer = method.invoke(proxy, new Object[] { null });
assertNull(answer);
}
public void testBasicAllowNullChildAssociationRef2() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoChildAssocRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_PARENT.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
Object answer = method.invoke(proxy, new Object[] { null });
assertNull(answer);
}
public void testBasicDenyChildAssocRef1() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoChildAssocRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
Object answer = method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef) });
assertNotNull(answer);
}
catch (InvocationTargetException e)
{
}
try
{
Object answer = method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(systemNodeRef) });
assertNotNull(answer);
}
catch (InvocationTargetException e)
{
}
}
public void testBasicDenyChildAssocRef2() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoChildAssocRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_PARENT.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
Object answer = method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef) });
assertNotNull(answer);
try
{
answer = method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(systemNodeRef) });
assertNotNull(answer);
}
catch (InvocationTargetException e)
{
}
}
public void testBasicAllowChildAssociationRef1() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoChildAssocRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object answer = method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef) });
assertEquals(answer, nodeService.getPrimaryParent(rootNodeRef));
answer = method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(systemNodeRef) });
assertEquals(answer, nodeService.getPrimaryParent(systemNodeRef));
}
public void testBasicAllowChildAssociationRef2() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("echoChildAssocRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_PARENT.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object answer = method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef) });
assertEquals(answer, nodeService.getPrimaryParent(rootNodeRef));
answer = method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(systemNodeRef) });
assertEquals(answer, nodeService.getPrimaryParent(systemNodeRef));
}
public void testBasicAllowNullResultSet() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method methodResultSet = o.getClass().getMethod("echoResultSet", new Class[] { ResultSet.class });
Method methodCollection = o.getClass().getMethod("echoCollection", new Class[] { Collection.class });
Method methodArray = o.getClass().getMethod("echoArray", new Class[] { Object[].class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
List<NodeRef> nodeRefList = new ArrayList<NodeRef>();
NodeRef[] nodeRefArray = new NodeRef[0];
Set<NodeRef> nodeRefSet = new HashSet<NodeRef>();
List<ChildAssociationRef> carList = new ArrayList<ChildAssociationRef>();
ChildAssociationRef[] carArray = new ChildAssociationRef[0];
Set<ChildAssociationRef> carSet = new HashSet<ChildAssociationRef>();
ChildAssocRefResultSet rsIn = new ChildAssocRefResultSet(nodeService, nodeRefList, null, false);
assertEquals(0, rsIn.length());
ResultSet answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(0, answerResultSet.length());
Collection answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(0, answerCollection.size());
Object[] answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(0, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(0, answerArray.length);
assertEquals(0, rsIn.length());
answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { null });
assertNull(answerResultSet);
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { null });
assertNull(answerCollection);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { null });
assertNull(answerArray);
}
public void testResultSetFilterAll() throws Exception
{
runAs("admin");
NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN,
QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef();
runAs("andy");
Object o = new ClassWithMethods();
Method methodResultSet = o.getClass().getMethod("echoResultSet", new Class[] { ResultSet.class });
Method methodCollection = o.getClass().getMethod("echoCollection", new Class[] { Collection.class });
Method methodArray = o.getClass().getMethod("echoArray", new Class[] { Object[].class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
List<NodeRef> nodeRefList = new ArrayList<NodeRef>();
nodeRefList.add(rootNodeRef);
nodeRefList.add(systemNodeRef);
nodeRefList.add(n1);
nodeRefList.add(n1);
NodeRef[] nodeRefArray = nodeRefList.toArray(new NodeRef[] {});
Set<NodeRef> nodeRefSet = new HashSet<NodeRef>();
nodeRefSet.addAll(nodeRefList);
List<ChildAssociationRef> carList = new ArrayList<ChildAssociationRef>();
carList.add(nodeService.getPrimaryParent(rootNodeRef));
carList.add(nodeService.getPrimaryParent(systemNodeRef));
carList.add(nodeService.getPrimaryParent(n1));
carList.add(nodeService.getPrimaryParent(n1));
ChildAssociationRef[] carArray = carList.toArray(new ChildAssociationRef[] {});
Set<ChildAssociationRef> carSet = new HashSet<ChildAssociationRef>();
carSet.addAll(carList);
ChildAssocRefResultSet rsIn = new ChildAssocRefResultSet(nodeService, nodeRefList, null, false);
assertEquals(4, rsIn.length());
ResultSet answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(0, answerResultSet.length());
Collection answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(0, answerCollection.size());
Object[] answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(0, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(0, answerArray.length);
}
public void testResultSetFilterForNullParentOnly() throws Exception
{
runAs("admin");
NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN,
QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef();
runAs("andy");
Object o = new ClassWithMethods();
Method methodResultSet = o.getClass().getMethod("echoResultSet", new Class[] { ResultSet.class });
Method methodCollection = o.getClass().getMethod("echoCollection", new Class[] { Collection.class });
Method methodArray = o.getClass().getMethod("echoArray", new Class[] { Object[].class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_PARENT.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
List<NodeRef> nodeRefList = new ArrayList<NodeRef>();
nodeRefList.add(rootNodeRef);
nodeRefList.add(systemNodeRef);
nodeRefList.add(n1);
nodeRefList.add(n1);
NodeRef[] nodeRefArray = nodeRefList.toArray(new NodeRef[] {});
Set<NodeRef> nodeRefSet = new HashSet<NodeRef>();
nodeRefSet.addAll(nodeRefList);
List<ChildAssociationRef> carList = new ArrayList<ChildAssociationRef>();
carList.add(nodeService.getPrimaryParent(rootNodeRef));
carList.add(nodeService.getPrimaryParent(systemNodeRef));
carList.add(nodeService.getPrimaryParent(n1));
carList.add(nodeService.getPrimaryParent(n1));
ChildAssociationRef[] carArray = carList.toArray(new ChildAssociationRef[] {});
Set<ChildAssociationRef> carSet = new HashSet<ChildAssociationRef>();
carSet.addAll(carList);
ChildAssocRefResultSet rsIn = new ChildAssocRefResultSet(nodeService, nodeRefList, null, false);
assertEquals(4, rsIn.length());
ResultSet answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(1, answerResultSet.length());
Collection answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(1, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(1, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(1, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(1, answerCollection.size());
Object[] answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(1, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(1, answerArray.length);
}
public void testResultSetFilterNone1() throws Exception
{
runAs("admin");
NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN,
QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef();
runAs("andy");
Object o = new ClassWithMethods();
Method methodResultSet = o.getClass().getMethod("echoResultSet", new Class[] { ResultSet.class });
Method methodCollection = o.getClass().getMethod("echoCollection", new Class[] { Collection.class });
Method methodArray = o.getClass().getMethod("echoArray", new Class[] { Object[].class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_NODE.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
List<NodeRef> nodeRefList = new ArrayList<NodeRef>();
nodeRefList.add(rootNodeRef);
nodeRefList.add(systemNodeRef);
nodeRefList.add(n1);
nodeRefList.add(n1);
List<Object> mixedRefList = new ArrayList<Object>();
mixedRefList.add(rootNodeRef);
mixedRefList.add(systemNodeRef);
mixedRefList.add(n1);
mixedRefList.add(n1);
mixedRefList.add(rootNodeRef.getStoreRef());
NodeRef[] nodeRefArray = nodeRefList.toArray(new NodeRef[] {});
Set<NodeRef> nodeRefSet = new HashSet<NodeRef>();
nodeRefSet.addAll(nodeRefList);
Set<Object> mixedRefSet = new HashSet<Object>();
mixedRefSet.addAll(mixedRefList);
List<ChildAssociationRef> carList = new ArrayList<ChildAssociationRef>();
carList.add(nodeService.getPrimaryParent(rootNodeRef));
carList.add(nodeService.getPrimaryParent(systemNodeRef));
carList.add(nodeService.getPrimaryParent(n1));
carList.add(nodeService.getPrimaryParent(n1));
ChildAssociationRef[] carArray = carList.toArray(new ChildAssociationRef[] {});
Set<ChildAssociationRef> carSet = new HashSet<ChildAssociationRef>();
carSet.addAll(carList);
ChildAssocRefResultSet rsIn = new ChildAssocRefResultSet(nodeService, nodeRefList, null, false);
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
assertEquals(4, rsIn.length());
ResultSet answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(4, answerResultSet.length());
Collection answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefList });
assertEquals(5, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(3, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefSet });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(3, answerCollection.size());
Object[] answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(4, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(4, answerArray.length);
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "andy", AccessStatus.DENIED));
assertEquals(4, rsIn.length());
answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(2, answerResultSet.length());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(2, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefList });
assertEquals(3, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(2, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefSet });
assertEquals(3, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(2, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(2, answerCollection.size());
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(2, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(2, answerArray.length);
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.DENIED));
assertEquals(4, rsIn.length());
answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(0, answerResultSet.length());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefList });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefSet });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(0, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(0, answerCollection.size());
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(0, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(0, answerArray.length);
}
public void testResultSetFilterNone2() throws Exception
{
runAs("admin");
NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN,
QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef();
runAs("andy");
Object o = new ClassWithMethods();
Method methodResultSet = o.getClass().getMethod("echoResultSet", new Class[] { ResultSet.class });
Method methodCollection = o.getClass().getMethod("echoCollection", new Class[] { Collection.class });
Method methodArray = o.getClass().getMethod("echoArray", new Class[] { Object[].class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("AFTER_ACL_PARENT.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
List<NodeRef> nodeRefList = new ArrayList<NodeRef>();
nodeRefList.add(rootNodeRef);
nodeRefList.add(systemNodeRef);
nodeRefList.add(n1);
nodeRefList.add(n1);
List<Object> mixedRefList = new ArrayList<Object>();
mixedRefList.add(rootNodeRef);
mixedRefList.add(systemNodeRef);
mixedRefList.add(n1);
mixedRefList.add(n1);
mixedRefList.add(rootNodeRef.getStoreRef());
NodeRef[] nodeRefArray = nodeRefList.toArray(new NodeRef[] {});
Set<NodeRef> nodeRefSet = new HashSet<NodeRef>();
nodeRefSet.addAll(nodeRefList);
Set<Object> mixedRefSet = new HashSet<Object>();
mixedRefSet.addAll(mixedRefList);
List<ChildAssociationRef> carList = new ArrayList<ChildAssociationRef>();
carList.add(nodeService.getPrimaryParent(rootNodeRef));
carList.add(nodeService.getPrimaryParent(systemNodeRef));
carList.add(nodeService.getPrimaryParent(n1));
carList.add(nodeService.getPrimaryParent(n1));
ChildAssociationRef[] carArray = carList.toArray(new ChildAssociationRef[] {});
Set<ChildAssociationRef> carSet = new HashSet<ChildAssociationRef>();
carSet.addAll(carList);
ChildAssocRefResultSet rsIn = new ChildAssocRefResultSet(nodeService, nodeRefList, null, false);
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
assertEquals(4, rsIn.length());
ResultSet answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(4, answerResultSet.length());
Collection answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefList });
assertEquals(5, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(3, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefSet });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(3, answerCollection.size());
Object[] answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(4, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(4, answerArray.length);
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "andy", AccessStatus.DENIED));
assertEquals(4, rsIn.length());
answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(4, answerResultSet.length());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefList });
assertEquals(5, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(3, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefSet });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(4, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(3, answerCollection.size());
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(4, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(4, answerArray.length);
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.DENIED));
assertEquals(4, rsIn.length());
answerResultSet = (ResultSet) methodResultSet.invoke(proxy, new Object[] { rsIn });
assertEquals(1, answerResultSet.length());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefList });
assertEquals(1, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefList });
assertEquals(2, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { nodeRefSet });
assertEquals(1, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { mixedRefSet });
assertEquals(2, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carList });
assertEquals(1, answerCollection.size());
answerCollection = (Collection) methodCollection.invoke(proxy, new Object[] { carSet });
assertEquals(1, answerCollection.size());
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { nodeRefArray });
assertEquals(1, answerArray.length);
answerArray = (Object[]) methodArray.invoke(proxy, new Object[] { carArray });
assertEquals(1, answerArray.length);
}
public static class ClassWithMethods
{
public Object echoObject(Object o)
{
return o;
}
public StoreRef echoStoreRef(StoreRef storeRef)
{
return storeRef;
}
public NodeRef echoNodeRef(NodeRef nodeRef)
{
return nodeRef;
}
public ChildAssociationRef echoChildAssocRef(ChildAssociationRef car)
{
return car;
}
public ResultSet echoResultSet(ResultSet rs)
{
return rs;
}
public <T> Collection<T> echoCollection(Collection<T> nrc)
{
return nrc;
}
public <T> T[] echoArray(T[] nra)
{
return nra;
}
}
public class Interceptor implements MethodInterceptor
{
ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
Interceptor(final String config)
{
cad.addConfigAttribute(new ConfigAttribute()
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 1L;
public String getAttribute()
{
return config;
}
});
}
public Object invoke(MethodInvocation invocation) throws Throwable
{
ACLEntryAfterInvocationProvider after = new ACLEntryAfterInvocationProvider();
after.setNamespacePrefixResolver(namespacePrefixResolver);
after.setPermissionService(permissionService);
after.setNodeService(nodeService);
after.setAuthenticationService(authenticationService);
Object returnObject = invocation.proceed();
return after.decide(null, invocation, cad, returnObject);
}
}
}

View File

@@ -0,0 +1,402 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.acegi;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
/**
*
* @author andyh
*/
public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
{
private static Log log = LogFactory.getLog(ACLEntryVoter.class);
private static final String ACL_NODE = "ACL_NODE";
private static final String ACL_PARENT = "ACL_PARENT";
private static final String ACL_ALLOW = "ACL_ALLOW";
private static final String ACL_METHOD = "ACL_METHOD";
private PermissionService permissionService;
private NamespacePrefixResolver nspr;
private NodeService nodeService;
private AuthenticationService authenticationService;
private AuthorityService authorityService;
public ACLEntryVoter()
{
super();
}
// ~ Methods
// ================================================================
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public PermissionService getPermissionService()
{
return permissionService;
}
public NamespacePrefixResolver getNamespacePrefixResolver()
{
return nspr;
}
public void setNamespacePrefixResolver(NamespacePrefixResolver nspr)
{
this.nspr = nspr;
}
public NodeService getNodeService()
{
return nodeService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public AuthenticationService getAuthenticationService()
{
return authenticationService;
}
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
public void setAuthorityService(AuthorityService authorityService)
{
this.authorityService = authorityService;
}
public void afterPropertiesSet() throws Exception
{
if (permissionService == null)
{
throw new IllegalArgumentException("There must be a permission service");
}
if (nspr == null)
{
throw new IllegalArgumentException("There must be a namespace service");
}
if (nodeService == null)
{
throw new IllegalArgumentException("There must be a node service");
}
if (authenticationService == null)
{
throw new IllegalArgumentException("There must be an authentication service");
}
if (authorityService == null)
{
throw new IllegalArgumentException("There must be an authority service");
}
}
public boolean supports(ConfigAttribute attribute)
{
if ((attribute.getAttribute() != null)
&& (attribute.getAttribute().startsWith(ACL_NODE)
|| attribute.getAttribute().startsWith(ACL_PARENT)
|| attribute.getAttribute().startsWith(ACL_ALLOW) || attribute.getAttribute().startsWith(
ACL_METHOD)))
{
return true;
}
else
{
return false;
}
}
/**
* This implementation supports only <code>MethodSecurityInterceptor</code>,
* because it queries the presented <code>MethodInvocation</code>.
*
* @param clazz
* the secure object
*
* @return <code>true</code> if the secure object is
* <code>MethodInvocation</code>, <code>false</code> otherwise
*/
public boolean supports(Class clazz)
{
return (MethodInvocation.class.isAssignableFrom(clazz));
}
public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config)
{
if (log.isDebugEnabled())
{
MethodInvocation mi = (MethodInvocation) object;
log.debug("Method: " + mi.getMethod().toString());
}
if (authenticationService.isCurrentUserTheSystemUser())
{
if (log.isDebugEnabled())
{
log.debug("Access granted for the system user");
}
return AccessDecisionVoter.ACCESS_GRANTED;
}
List<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
if (supportedDefinitions.size() == 0)
{
return AccessDecisionVoter.ACCESS_GRANTED;
}
MethodInvocation invocation = (MethodInvocation) object;
Method method = invocation.getMethod();
Class[] params = method.getParameterTypes();
for (ConfigAttributeDefintion cad : supportedDefinitions)
{
NodeRef testNodeRef = null;
if (cad.typeString.equals(ACL_ALLOW))
{
return AccessDecisionVoter.ACCESS_GRANTED;
}
else if (cad.typeString.equals(ACL_METHOD))
{
if (authenticationService.getCurrentUserName().equals(cad.authority))
{
return AccessDecisionVoter.ACCESS_GRANTED;
}
else
{
return authorityService.getAuthorities().contains(cad.authority) ? AccessDecisionVoter.ACCESS_GRANTED
: AccessDecisionVoter.ACCESS_DENIED;
}
}
else if (cad.parameter >= invocation.getArguments().length)
{
continue;
}
else if (cad.typeString.equals(ACL_NODE))
{
if (StoreRef.class.isAssignableFrom(params[cad.parameter]))
{
if (invocation.getArguments()[cad.parameter] != null)
{
if (log.isDebugEnabled())
{
log.debug("\tPermission test against the store - using permissions on the root node");
}
StoreRef storeRef = (StoreRef) invocation.getArguments()[cad.parameter];
if (nodeService.exists(storeRef))
{
testNodeRef = nodeService.getRootNode(storeRef);
}
}
}
else if (NodeRef.class.isAssignableFrom(params[cad.parameter]))
{
testNodeRef = (NodeRef) invocation.getArguments()[cad.parameter];
if (log.isDebugEnabled())
{
log.debug("\tPermission test on node " + nodeService.getPath(testNodeRef));
}
}
else if (ChildAssociationRef.class.isAssignableFrom(params[cad.parameter]))
{
if (invocation.getArguments()[cad.parameter] != null)
{
testNodeRef = ((ChildAssociationRef) invocation.getArguments()[cad.parameter]).getChildRef();
if (log.isDebugEnabled())
{
log.debug("\tPermission test on node " + nodeService.getPath(testNodeRef));
}
}
}
else
{
throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef");
}
}
else if (cad.typeString.equals(ACL_PARENT))
{
// There is no point having parent permissions for store
// refs
if (NodeRef.class.isAssignableFrom(params[cad.parameter]))
{
NodeRef child = (NodeRef) invocation.getArguments()[cad.parameter];
if (child != null)
{
testNodeRef = nodeService.getPrimaryParent(child).getParentRef();
if (log.isDebugEnabled())
{
log.debug("\tPermission test for parent on node " + nodeService.getPath(testNodeRef));
}
}
}
else if (ChildAssociationRef.class.isAssignableFrom(params[cad.parameter]))
{
if (invocation.getArguments()[cad.parameter] != null)
{
testNodeRef = ((ChildAssociationRef) invocation.getArguments()[cad.parameter]).getParentRef();
if (log.isDebugEnabled())
{
log.debug("\tPermission test for parent on child assoc ref for node "
+ nodeService.getPath(testNodeRef));
}
}
}
else
{
throw new ACLEntryVoterException("The specified parameter is not a ChildAssociationRef");
}
}
if (testNodeRef != null)
{
if (log.isDebugEnabled())
{
log.debug("\t\tNode ref is not null");
}
if (permissionService.hasPermission(testNodeRef, cad.required.toString()) == AccessStatus.DENIED)
{
if (log.isDebugEnabled())
{
log.debug("\t\tPermission is denied");
Thread.dumpStack();
}
return AccessDecisionVoter.ACCESS_DENIED;
}
}
}
return AccessDecisionVoter.ACCESS_GRANTED;
}
private List<ConfigAttributeDefintion> extractSupportedDefinitions(ConfigAttributeDefinition config)
{
List<ConfigAttributeDefintion> definitions = new ArrayList<ConfigAttributeDefintion>();
Iterator iter = config.getConfigAttributes();
while (iter.hasNext())
{
ConfigAttribute attr = (ConfigAttribute) iter.next();
if (this.supports(attr))
{
definitions.add(new ConfigAttributeDefintion(attr));
}
}
return definitions;
}
private class ConfigAttributeDefintion
{
String typeString;
SimplePermissionReference required;
int parameter;
String authority;
ConfigAttributeDefintion(ConfigAttribute attr)
{
StringTokenizer st = new StringTokenizer(attr.getAttribute(), ".", false);
if (st.countTokens() < 1)
{
throw new ACLEntryVoterException("There must be at least one token in a config attribute");
}
typeString = st.nextToken();
if (!(typeString.equals(ACL_NODE) || typeString.equals(ACL_PARENT) || typeString.equals(ACL_ALLOW) || typeString
.equals(ACL_METHOD)))
{
throw new ACLEntryVoterException("Invalid type: must be ACL_NODE, ACL_PARENT or ACL_ALLOW");
}
if (typeString.equals(ACL_NODE) || typeString.equals(ACL_PARENT))
{
if (st.countTokens() != 3)
{
throw new ACLEntryVoterException("There must be four . separated tokens in each config attribute");
}
String numberString = st.nextToken();
String qNameString = st.nextToken();
String permissionString = st.nextToken();
parameter = Integer.parseInt(numberString);
QName qName = QName.createQName(qNameString, nspr);
required = new SimplePermissionReference(qName, permissionString);
}
else if (typeString.equals(ACL_METHOD))
{
if (st.countTokens() != 1)
{
throw new ACLEntryVoterException(
"There must be two . separated tokens in each group or role config attribute");
}
authority = st.nextToken();
}
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.acegi;
import org.alfresco.error.AlfrescoRuntimeException;
public class ACLEntryVoterException extends AlfrescoRuntimeException
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = -674195849623480512L;
public ACLEntryVoterException(String msg)
{
super(msg);
}
public ACLEntryVoterException(String msg, Throwable cause)
{
super(msg, cause);
}
}

View File

@@ -0,0 +1,805 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.acegi;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
import org.alfresco.repo.security.permissions.impl.AbstractPermissionTest;
import org.alfresco.repo.security.permissions.impl.SimplePermissionEntry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.target.SingletonTargetSource;
public class ACLEntryVoterTest extends AbstractPermissionTest
{
public ACLEntryVoterTest()
{
super();
}
public void testBasicDenyNode() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneNodeRef", new Class[] { NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
method.invoke(proxy, new Object[] { rootNodeRef });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
try
{
method.invoke(proxy, new Object[] { systemNodeRef });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
// Check we are allowed access to deleted nodes ..
nodeService.deleteNode(systemNodeRef);
assertNull(method.invoke(proxy, new Object[] { systemNodeRef }));
}
public void testBasicDenyStore() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneStoreRef", new Class[] { StoreRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
method.invoke(proxy, new Object[] { rootNodeRef.getStoreRef() });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
}
public void testAllowNullNode() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneNodeRef", new Class[] { NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null });
}
public void testAllowNullStore() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneStoreRef", new Class[] { StoreRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null });
}
public void testAllowNullParentOnRealChildAssoc() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_PARENT.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef) });
}
public void testAllowNullParent() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_PARENT.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null });
}
public void testAllowNullChild() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null });
}
public void testBasicDenyChildAssocNode() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef) });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
}
public void testBasicDenyParentAssocNode() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_PARENT.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(systemNodeRef) });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
}
public void testBasicAllowNode() throws Exception
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneNodeRef", new Class[] { NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { rootNodeRef });
}
public void testBasicAllow() throws Exception
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneNodeRef", new Class[] { NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_ALLOW")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { rootNodeRef });
}
public void testBasicAllowStore() throws Exception
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneStoreRef", new Class[] { StoreRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { rootNodeRef.getStoreRef() });
}
public void testBasicAllowChildAssocNode() throws Exception
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef) });
}
public void testBasicAllowParentAssocNode() throws Exception
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_PARENT.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(systemNodeRef) });
}
public void testDenyParentAssocNode() throws Exception
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(systemNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_PARENT.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(systemNodeRef) });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
}
public void testAllowChildAssocNode() throws Exception
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(systemNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ_CHILDREN), "andy",
AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(systemNodeRef) });
}
public void testMultiNodeMethodsArg0() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testManyNodeRef",
new Class[] { NodeRef.class, NodeRef.class, NodeRef.class, NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null, null, null, null });
try
{
method.invoke(proxy, new Object[] { rootNodeRef, null, null, null });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { rootNodeRef, null, null, null });
}
public void testMultiNodeMethodsArg1() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testManyNodeRef",
new Class[] { NodeRef.class, NodeRef.class, NodeRef.class, NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.1.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null, null, null, null });
try
{
method.invoke(proxy, new Object[] { null, rootNodeRef, null, null });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, rootNodeRef, null, null });
}
public void testMultiNodeMethodsArg2() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testManyNodeRef",
new Class[] { NodeRef.class, NodeRef.class, NodeRef.class, NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.2.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null, null, null, null });
try
{
method.invoke(proxy, new Object[] { null, null, rootNodeRef, null });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, null, rootNodeRef, null });
}
public void testMultiNodeMethodsArg3() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testManyNodeRef",
new Class[] { NodeRef.class, NodeRef.class, NodeRef.class, NodeRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.3.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null, null, null, null });
try
{
method.invoke(proxy, new Object[] { null, null, null, rootNodeRef });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, null, null, rootNodeRef });
}
public void testMultiChildAssocRefMethodsArg0() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod(
"testManyChildAssociationRef",
new Class[] { ChildAssociationRef.class, ChildAssociationRef.class, ChildAssociationRef.class,
ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.0.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null, null, null, null });
try
{
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef), null, null, null });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef), null, null, null });
}
public void testMultiChildAssocRefMethodsArg1() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod(
"testManyChildAssociationRef",
new Class[] { ChildAssociationRef.class, ChildAssociationRef.class, ChildAssociationRef.class,
ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.1.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null, null, null, null });
try
{
method.invoke(proxy, new Object[] { null, nodeService.getPrimaryParent(rootNodeRef), null, null });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, nodeService.getPrimaryParent(rootNodeRef), null, null });
}
public void testMultiChildAssocRefMethodsArg2() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod(
"testManyChildAssociationRef",
new Class[] { ChildAssociationRef.class, ChildAssociationRef.class, ChildAssociationRef.class,
ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.2.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null, null, null, null });
try
{
method.invoke(proxy, new Object[] { null, null, nodeService.getPrimaryParent(rootNodeRef), null });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, null, nodeService.getPrimaryParent(rootNodeRef), null });
}
public void testMultiChildAssocRefMethodsArg3() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod(
"testManyChildAssociationRef",
new Class[] { ChildAssociationRef.class, ChildAssociationRef.class, ChildAssociationRef.class,
ChildAssociationRef.class });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_NODE.3.sys:base.Read")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { null, null, null, null });
try
{
method.invoke(proxy, new Object[] { null, null, null, nodeService.getPrimaryParent(rootNodeRef) });
assertNotNull(null);
}
catch (InvocationTargetException e)
{
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, null, null, nodeService.getPrimaryParent(rootNodeRef) });
}
public void testMethodACL() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod(
"testMethod",
new Class[] { });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_METHOD.andy")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { });
}
public void testMethodACL2() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod(
"testMethod",
new Class[] { });
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_METHOD."+PermissionService.ALL_AUTHORITIES)));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { });
}
public static class ClassWithMethods
{
public void testMethod()
{
}
public void testOneStoreRef(StoreRef storeRef)
{
}
public void testOneNodeRef(NodeRef nodeRef)
{
}
public void testManyNodeRef(NodeRef nodeRef1, NodeRef nodeRef2, NodeRef nodeRef3, NodeRef nodeRef4)
{
}
public void testOneChildAssociationRef(ChildAssociationRef car)
{
}
public void testManyChildAssociationRef(ChildAssociationRef car1, ChildAssociationRef car2,
ChildAssociationRef car3, ChildAssociationRef car4)
{
}
}
public class Interceptor implements MethodInterceptor
{
ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
Interceptor(final String config)
{
cad.addConfigAttribute(new ConfigAttribute()
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 1L;
public String getAttribute()
{
return config;
}
});
}
public Object invoke(MethodInvocation invocation) throws Throwable
{
ACLEntryVoter voter = new ACLEntryVoter();
voter.setNamespacePrefixResolver(namespacePrefixResolver);
voter.setPermissionService(permissionService);
voter.setNodeService(nodeService);
voter.setAuthenticationService(authenticationService);
voter.setAuthorityService(authorityService);
if (!(voter.vote(null, invocation, cad) == AccessDecisionVoter.ACCESS_DENIED))
{
return invocation.proceed();
}
else
{
throw new ACLEntryVoterException("Access denied");
}
}
}
}

View File

@@ -0,0 +1,247 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.acegi;
import java.util.BitSet;
import java.util.List;
import java.util.ListIterator;
import org.alfresco.repo.search.ResultSetRowIterator;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
public class FilteringResultSet extends ACLEntryAfterInvocationProvider implements ResultSet
{
private ResultSet unfiltered;
private BitSet inclusionMask;
FilteringResultSet(ResultSet unfiltered)
{
super();
this.unfiltered = unfiltered;
inclusionMask = new BitSet(unfiltered.length());
}
/* package */ResultSet getUnFilteredResultSet()
{
return unfiltered;
}
/* package */void setIncluded(int i, boolean excluded)
{
inclusionMask.set(i, excluded);
}
/* package */boolean getIncluded(int i)
{
return inclusionMask.get(i);
}
public Path[] getPropertyPaths()
{
return unfiltered.getPropertyPaths();
}
public int length()
{
return inclusionMask.cardinality();
}
private int translateIndex(int n)
{
if (n > length())
{
throw new IndexOutOfBoundsException();
}
int count = -1;
for (int i = 0, l = unfiltered.length(); i < l; i++)
{
if (inclusionMask.get(i))
{
count++;
}
if (count == n)
{
return i;
}
}
throw new IndexOutOfBoundsException();
}
public NodeRef getNodeRef(int n)
{
return unfiltered.getNodeRef(translateIndex(n));
}
public float getScore(int n)
{
return unfiltered.getScore(translateIndex(n));
}
public void close()
{
unfiltered.close();
}
public ResultSetRow getRow(int i)
{
return unfiltered.getRow(translateIndex(i));
}
public List<NodeRef> getNodeRefs()
{
List<NodeRef> answer = unfiltered.getNodeRefs();
for (int i = unfiltered.length() - 1; i >= 0; i--)
{
if (!inclusionMask.get(i))
{
answer.remove(i);
}
}
return answer;
}
public List<ChildAssociationRef> getChildAssocRefs()
{
List<ChildAssociationRef> answer = unfiltered.getChildAssocRefs();
for (int i = unfiltered.length() - 1; i >= 0; i--)
{
if (!inclusionMask.get(i))
{
answer.remove(i);
}
}
return answer;
}
public ChildAssociationRef getChildAssocRef(int n)
{
return unfiltered.getChildAssocRef(translateIndex(n));
}
public ListIterator<ResultSetRow> iterator()
{
return new FilteringIterator();
}
class FilteringIterator implements ResultSetRowIterator
{
// -1 at the start
int underlyingPosition = -1;
public boolean hasNext()
{
return inclusionMask.nextSetBit(underlyingPosition + 1) != -1;
}
public ResultSetRow next()
{
underlyingPosition = inclusionMask.nextSetBit(underlyingPosition + 1);
if( underlyingPosition == -1)
{
throw new IllegalStateException();
}
return unfiltered.getRow(underlyingPosition);
}
public boolean hasPrevious()
{
if (underlyingPosition <= 0)
{
return false;
}
else
{
for (int i = underlyingPosition - 1; i >= 0; i--)
{
if (inclusionMask.get(i))
{
return true;
}
}
}
return false;
}
public ResultSetRow previous()
{
if (underlyingPosition <= 0)
{
throw new IllegalStateException();
}
for (int i = underlyingPosition - 1; i >= 0; i--)
{
if (inclusionMask.get(i))
{
underlyingPosition = i;
return unfiltered.getRow(underlyingPosition);
}
}
throw new IllegalStateException();
}
public int nextIndex()
{
return inclusionMask.nextSetBit(underlyingPosition+1);
}
public int previousIndex()
{
if (underlyingPosition <= 0)
{
return -1;
}
for (int i = underlyingPosition - 1; i >= 0; i--)
{
if (inclusionMask.get(i))
{
return i;
}
}
return -1;
}
/*
* Mutation is not supported
*/
public void remove()
{
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
public void set(ResultSetRow o)
{
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
public void add(ResultSetRow o)
{
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.acegi;
import java.util.ArrayList;
import java.util.ListIterator;
import junit.framework.TestCase;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.search.results.ChildAssocRefResultSet;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.namespace.QName;
public class FilteringResultSetTest extends TestCase
{
public FilteringResultSetTest()
{
super();
}
public FilteringResultSetTest(String arg0)
{
super(arg0);
}
public void test()
{
StoreRef storeRef = new StoreRef("protocol", "test");
NodeRef root = new NodeRef(storeRef, "n0");
NodeRef n1 = new NodeRef(storeRef, "n1");
NodeRef n2 = new NodeRef(storeRef, "n2");
NodeRef n3 = new NodeRef(storeRef, "n3");
NodeRef n4 = new NodeRef(storeRef, "n4");
NodeRef n5 = new NodeRef(storeRef, "n5");
ArrayList<ChildAssociationRef> cars = new ArrayList<ChildAssociationRef>();
ChildAssociationRef car0 = new ChildAssociationRef(null, null, null, root);
ChildAssociationRef car1 = new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, root, QName.createQName("{test}n2"), n1);
ChildAssociationRef car2 = new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, n1, QName.createQName("{test}n3"), n2);
ChildAssociationRef car3 = new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, n2, QName.createQName("{test}n4"), n3);
ChildAssociationRef car4 = new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, n3, QName.createQName("{test}n5"), n4);
ChildAssociationRef car5 = new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, n4, QName.createQName("{test}n6"), n5);
cars.add(car0);
cars.add(car1);
cars.add(car2);
cars.add(car3);
cars.add(car4);
cars.add(car5);
ResultSet in = new ChildAssocRefResultSet(null, cars, null);
FilteringResultSet filtering = new FilteringResultSet(in);
assertEquals(0, filtering.length());
for(int i = 0; i < 6; i++)
{
filtering.setIncluded(i, true);
assertEquals(1, filtering.length());
assertEquals("n"+i, filtering.getNodeRef(0).getId());
filtering.setIncluded(i, false);
assertEquals(0, filtering.length());
}
for(int i = 0; i < 6; i++)
{
filtering.setIncluded(i, true);
assertEquals(i+1, filtering.length());
assertEquals("n"+i, filtering.getNodeRef(i).getId());
}
int count = 0;
for(ResultSetRow row : filtering)
{
assertNotNull(row);
assertTrue(count < 6);
count++;
}
ResultSetRow last = null;
for(ListIterator<ResultSetRow> it = filtering.iterator(); it.hasNext(); /**/)
{
ResultSetRow row = it.next();
if(last != null)
{
assertTrue(it.hasPrevious());
ResultSetRow previous = it.previous();
assertEquals(last.getIndex(), previous.getIndex());
row = it.next();
}
else
{
assertFalse(it.hasPrevious());
}
last = row;
}
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.acegi;
public class MethodSecurityInterceptor extends
net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor
{
public MethodSecurityInterceptor()
{
super();
}
}

View File

@@ -0,0 +1,209 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
import java.io.Serializable;
import org.alfresco.repo.domain.NodeKey;
import org.alfresco.util.BaseSpringTest;
/**
* Test persistence and retrieval of Hibernate-specific implementations of the
* {@link org.alfresco.repo.domain.Node} interface
*
* @author Andy Hind
*/
public class HibernatePermissionTest extends BaseSpringTest
{
public HibernatePermissionTest()
{
}
protected void onSetUpInTransaction() throws Exception
{
}
protected void onTearDownInTransaction()
{
// force a flush to ensure that the database updates succeed
getSession().flush();
getSession().clear();
}
public void testSimpleNodePermission() throws Exception
{
// create a new Node
NodePermissionEntry nodePermission = new NodePermissionEntryImpl();
NodeKey key = new NodeKey("Random Protocol", "Random Identifier", "AAA");
nodePermission.setNodeKey(key);
nodePermission.setInherits(true);
Serializable id = getSession().save(nodePermission);
// throw the reference away and get the a new one for the id
nodePermission = (NodePermissionEntry) getSession().load(NodePermissionEntryImpl.class, id);
assertNotNull("Node not found", nodePermission);
assertTrue(nodePermission.getInherits());
// Update inherits
nodePermission.setInherits(false);
id = getSession().save(nodePermission);
// throw the reference away and get the a new one for the id
nodePermission = (NodePermissionEntry) getSession().load(NodePermissionEntryImpl.class, id);
assertNotNull("Node not found", nodePermission);
assertFalse(nodePermission.getInherits());
}
public void testSimplePermissionReference()
{
PermissionReference permissionReference = new PermissionReferenceImpl();
permissionReference.setName("Test");
permissionReference.setTypeUri("TestUri");
permissionReference.setTypeName("TestName");
Serializable id = getSession().save(permissionReference);
// throw the reference away and get the a new one for the id
permissionReference = (PermissionReference) getSession().load(PermissionReferenceImpl.class, id);
assertNotNull("Node not found", permissionReference);
assertEquals("Test", permissionReference.getName());
assertEquals("TestUri", permissionReference.getTypeUri());
assertEquals("TestName", permissionReference.getTypeName());
// Test key
PermissionReference key = new PermissionReferenceImpl();
key.setName("Test");
key.setTypeUri("TestUri");
key.setTypeName("TestName");
permissionReference = (PermissionReference) getSession().load(PermissionReferenceImpl.class, key);
assertNotNull("Node not found", permissionReference);
assertEquals("Test", permissionReference.getName());
assertEquals("TestUri", permissionReference.getTypeUri());
assertEquals("TestName", permissionReference.getTypeName());
}
public void testSimpleRecipient()
{
Recipient recipient = new RecipientImpl();
recipient.setRecipient("Test");
recipient.getExternalKeys().add("One");
Serializable id = getSession().save(recipient);
// throw the reference away and get the a new one for the id
recipient = (Recipient) getSession().load(RecipientImpl.class, id);
assertNotNull("Node not found", recipient);
assertEquals("Test", recipient.getRecipient());
assertEquals(1, recipient.getExternalKeys().size());
// Key
Recipient key = new RecipientImpl();
key.setRecipient("Test");
recipient = (Recipient) getSession().load(RecipientImpl.class, key);
assertNotNull("Node not found", recipient);
assertEquals("Test", recipient.getRecipient());
assertEquals(1, recipient.getExternalKeys().size());
// Update
recipient.getExternalKeys().add("Two");
id = getSession().save(recipient);
// throw the reference away and get the a new one for the id
recipient = (Recipient) getSession().load(RecipientImpl.class, id);
assertNotNull("Node not found", recipient);
assertEquals("Test", recipient.getRecipient());
assertEquals(2, recipient.getExternalKeys().size());
// complex
recipient.getExternalKeys().add("Three");
recipient.getExternalKeys().remove("One");
recipient.getExternalKeys().remove("Two");
id = getSession().save(recipient);
// Throw the reference away and get the a new one for the id
recipient = (Recipient) getSession().load(RecipientImpl.class, id);
assertNotNull("Node not found", recipient);
assertEquals("Test", recipient.getRecipient());
assertEquals(1, recipient.getExternalKeys().size());
}
public void testNodePermissionEntry()
{
// create a new Node
NodePermissionEntry nodePermission = new NodePermissionEntryImpl();
NodeKey key = new NodeKey("Random Protocol", "Random Identifier", "AAA");
nodePermission.setNodeKey(key);
nodePermission.setInherits(true);
Recipient recipient = new RecipientImpl();
recipient.setRecipient("Test");
recipient.getExternalKeys().add("One");
PermissionReference permissionReference = new PermissionReferenceImpl();
permissionReference.setName("Test");
permissionReference.setTypeUri("TestUri");
permissionReference.setTypeName("TestName");
PermissionEntry permissionEntry = PermissionEntryImpl.create(nodePermission, permissionReference, recipient, true);
Serializable idNodePermision = getSession().save(nodePermission);
getSession().save(recipient);
getSession().save(permissionReference);
Serializable idPermEnt = getSession().save(permissionEntry);
permissionEntry = (PermissionEntry) getSession().load(PermissionEntryImpl.class, idPermEnt);
assertNotNull("Permission entry not found", permissionEntry);
assertTrue(permissionEntry.isAllowed());
assertNotNull(permissionEntry.getNodePermissionEntry());
assertTrue(permissionEntry.getNodePermissionEntry().getInherits());
assertNotNull(permissionEntry.getPermissionReference());
assertEquals("Test", permissionEntry.getPermissionReference().getName());
assertNotNull(permissionEntry.getRecipient());
assertEquals("Test", permissionEntry.getRecipient().getRecipient());
assertEquals(1, permissionEntry.getRecipient().getExternalKeys().size());
// Check traversal down
nodePermission = (NodePermissionEntry) getSession().load(NodePermissionEntryImpl.class, idNodePermision);
assertEquals(1, nodePermission.getPermissionEntries().size());
permissionEntry.delete();
getSession().delete(permissionEntry);
nodePermission = (NodePermissionEntry) getSession().load(NodePermissionEntryImpl.class, idNodePermision);
assertEquals(0, nodePermission.getPermissionEntries().size());
}
}

View File

@@ -0,0 +1,421 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.domain.NodeKey;
import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.PermissionsDAO;
import org.alfresco.repo.security.permissions.impl.SimpleNodePermissionEntry;
import org.alfresco.repo.security.permissions.impl.SimplePermissionEntry;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
import org.hibernate.ObjectDeletedException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* Support for accessing persisted permission information.
*
* This class maps between persisted objects and the external API defined in the
* PermissionsDAO interface.
*
* @author andyh
*/
public class HibernatePermissionsDAO extends HibernateDaoSupport implements PermissionsDAO
{
private SimpleCache<NodeRef, SimpleNodePermissionEntry> nullPermissionCache;
public HibernatePermissionsDAO()
{
super();
}
public void setNullPermissionCache(SimpleCache<NodeRef, SimpleNodePermissionEntry> nullPermissionCache)
{
this.nullPermissionCache = nullPermissionCache;
}
public NodePermissionEntry getPermissions(NodeRef nodeRef)
{
// Create the object if it is not found.
// Null objects are not cached in hibernate
// If the object does not exist it will repeatedly query to check its
// non existence.
NodePermissionEntry npe = nullPermissionCache.get(nodeRef);
if (npe != null)
{
return npe;
}
npe = createSimpleNodePermissionEntry(getHibernateNodePermissionEntry(nodeRef, false));
if (npe == null)
{
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(nodeRef, true, Collections
.<SimplePermissionEntry> emptySet());
npe = snpe;
nullPermissionCache.put(nodeRef, snpe);
}
return npe;
}
/**
* Get the persisted NodePermissionEntry
*
* @param nodeRef
* @param create -
* create the object if it is missing
* @return
*/
private org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntry getHibernateNodePermissionEntry(
NodeRef nodeRef, boolean create)
{
// Build the key
NodeKey nodeKey = getNodeKey(nodeRef);
try
{
Object obj = getHibernateTemplate().get(NodePermissionEntryImpl.class, nodeKey);
// Create if required
if ((obj == null) && create)
{
NodePermissionEntryImpl entry = new NodePermissionEntryImpl();
entry.setNodeKey(nodeKey);
entry.setInherits(true);
getHibernateTemplate().save(entry);
nullPermissionCache.remove(nodeRef);
return entry;
}
return (org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntry) obj;
}
catch (DataAccessException e)
{
if (e.contains(ObjectDeletedException.class))
{
// the object no loner exists
if (create)
{
NodePermissionEntryImpl entry = new NodePermissionEntryImpl();
entry.setNodeKey(nodeKey);
entry.setInherits(true);
getHibernateTemplate().save(entry);
nullPermissionCache.remove(nodeRef);
return entry;
}
else
{
return null;
}
}
throw e;
}
}
/**
* Get a node key from a node reference
*
* @param nodeRef
* @return
*/
private NodeKey getNodeKey(NodeRef nodeRef)
{
NodeKey nodeKey = new NodeKey(nodeRef.getStoreRef().getProtocol(), nodeRef.getStoreRef().getIdentifier(),
nodeRef.getId());
return nodeKey;
}
public void deletePermissions(NodeRef nodeRef)
{
org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntry found = getHibernateNodePermissionEntry(
nodeRef, false);
if (found != null)
{
deleteHibernateNodePermissionEntry(found);
}
}
private void deleteHibernateNodePermissionEntry(
org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntry hibernateNodePermissionEntry)
{
deleteHibernatePermissionEntries(hibernateNodePermissionEntry.getPermissionEntries());
getHibernateTemplate().delete(hibernateNodePermissionEntry);
}
private void deleteHibernatePermissionEntries(
Set<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry> permissionEntries)
{
// Avoid concurrent access problems during deletion
Set<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry> copy = new HashSet<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry>();
for (org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry permissionEntry : copy)
{
deleteHibernatePermissionEntry(permissionEntry);
}
}
private void deleteHibernatePermissionEntry(
org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry permissionEntry)
{
// Unhook bidirectoinal relationships
permissionEntry.delete();
getHibernateTemplate().delete(permissionEntry);
}
public void deletePermissions(NodePermissionEntry nodePermissionEntry)
{
deletePermissions(nodePermissionEntry.getNodeRef());
}
public void deletePermissions(PermissionEntry permissionEntry)
{
org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntry found = getHibernateNodePermissionEntry(
permissionEntry.getNodeRef(), false);
if (found != null)
{
Set<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry> deletable = new HashSet<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry>();
for (org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry current : found
.getPermissionEntries())
{
if (permissionEntry.equals(createSimplePermissionEntry(current)))
{
deletable.add(current);
}
}
for (org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry current : deletable)
{
deleteHibernatePermissionEntry(current);
}
}
}
public void clearPermission(NodeRef nodeRef, String authority)
{
org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntry found = getHibernateNodePermissionEntry(
nodeRef, false);
if (found != null)
{
Set<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry> deletable = new HashSet<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry>();
for (org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry current : found
.getPermissionEntries())
{
if (createSimplePermissionEntry(current).getAuthority().equals(authority))
{
deletable.add(current);
}
}
for (org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry current : deletable)
{
deleteHibernatePermissionEntry(current);
}
}
}
public void deletePermissions(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow)
{
SimplePermissionEntry spe = new SimplePermissionEntry(nodeRef, perm == null ? null
: new SimplePermissionReference(perm.getQName(), perm.getName()), authority,
allow ? AccessStatus.ALLOWED : AccessStatus.DENIED);
deletePermissions(spe);
}
public void setPermission(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow)
{
deletePermissions(nodeRef, authority, perm, allow);
PermissionEntryImpl entry = PermissionEntryImpl.create(getHibernateNodePermissionEntry(nodeRef, true),
getHibernatePermissionReference(perm, true), getHibernateAuthority(authority, true), allow);
getHibernateTemplate().save(entry);
nullPermissionCache.remove(nodeRef);
}
/**
* Utility method to find or create a persisted authority
*
* @param authority
* @param create
* @return
*/
private Recipient getHibernateAuthority(String authority, boolean create)
{
Recipient key = new RecipientImpl();
key.setRecipient(authority);
Recipient found = (Recipient) getHibernateTemplate().get(RecipientImpl.class, key);
if ((found == null) && create)
{
getHibernateTemplate().save(key);
return key;
}
else
{
return found;
}
}
/**
* Utility method to find and optionally create a persisted permission
* reference.
*
* @param perm
* @param create
* @return
*/
private org.alfresco.repo.security.permissions.impl.hibernate.PermissionReference getHibernatePermissionReference(
PermissionReference perm, boolean create)
{
org.alfresco.repo.security.permissions.impl.hibernate.PermissionReference key = new PermissionReferenceImpl();
key.setTypeUri(perm.getQName().getNamespaceURI());
key.setTypeName(perm.getQName().getLocalName());
key.setName(perm.getName());
org.alfresco.repo.security.permissions.impl.hibernate.PermissionReference found;
found = (org.alfresco.repo.security.permissions.impl.hibernate.PermissionReference) getHibernateTemplate().get(
PermissionReferenceImpl.class, key);
if ((found == null) && create)
{
getHibernateTemplate().save(key);
return key;
}
else
{
return found;
}
}
public void setPermission(PermissionEntry permissionEntry)
{
setPermission(permissionEntry.getNodeRef(), permissionEntry.getAuthority(), permissionEntry
.getPermissionReference(), permissionEntry.isAllowed());
}
public void setPermission(NodePermissionEntry nodePermissionEntry)
{
deletePermissions(nodePermissionEntry);
NodePermissionEntryImpl entry = new NodePermissionEntryImpl();
entry.setInherits(nodePermissionEntry.inheritPermissions());
entry.setNodeKey(getNodeKey(nodePermissionEntry.getNodeRef()));
getHibernateTemplate().save(entry);
nullPermissionCache.remove(nodePermissionEntry.getNodeRef());
for (PermissionEntry pe : nodePermissionEntry.getPermissionEntries())
{
setPermission(pe);
}
}
public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions)
{
getHibernateNodePermissionEntry(nodeRef, true).setInherits(inheritParentPermissions);
}
public boolean getInheritParentPermissions(NodeRef nodeRef)
{
return getHibernateNodePermissionEntry(nodeRef, true).getInherits();
}
@SuppressWarnings("unchecked")
public void deleteAllPermissionsForAuthority(final String authority)
{
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery("permission.GetPermissionsForRecipient");
query.setString("recipientKey", authority);
return query.list();
}
};
List<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry> queryResults = (List) getHibernateTemplate().execute(callback);
for (org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry current : queryResults)
{
deleteHibernatePermissionEntry(current);
}
}
// Utility methods to create simple detached objects for the outside
// // world
// We do not pass out the hibernate objects
private static SimpleNodePermissionEntry createSimpleNodePermissionEntry(
org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntry npe)
{
if (npe == null)
{
return null;
}
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(npe.getNodeRef(), npe.getInherits(),
createSimplePermissionEntries(npe.getPermissionEntries()));
return snpe;
}
private static Set<SimplePermissionEntry> createSimplePermissionEntries(
Set<org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry> nes)
{
if (nes == null)
{
return null;
}
HashSet<SimplePermissionEntry> spes = new HashSet<SimplePermissionEntry>();
for (org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry pe : nes)
{
spes.add(createSimplePermissionEntry(pe));
}
return spes;
}
private static SimplePermissionEntry createSimplePermissionEntry(
org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry pe)
{
if (pe == null)
{
return null;
}
return new SimplePermissionEntry(pe.getNodePermissionEntry().getNodeRef(), createSimplePermissionReference(pe
.getPermissionReference()), pe.getRecipient().getRecipient(), pe.isAllowed() ? AccessStatus.ALLOWED
: AccessStatus.DENIED);
}
private static SimplePermissionReference createSimplePermissionReference(
org.alfresco.repo.security.permissions.impl.hibernate.PermissionReference pr)
{
if (pr == null)
{
return null;
}
return new SimplePermissionReference(QName.createQName(pr.getTypeUri(), pr.getTypeName()), pr.getName());
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
import java.util.Set;
import org.alfresco.repo.domain.NodeKey;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* The interface to support persistence of node permission entries in hibernate
*
* @author andyh
*/
public interface NodePermissionEntry
{
/**
* Get the node key.
*
* @return
*/
public NodeKey getNodeKey();
/**
* Set the node key.
*
* @param key
*/
public void setNodeKey(NodeKey key);
/**
* Get the node ref
*
* @return
*/
public NodeRef getNodeRef();
/**
* Get inheritance behaviour
* @return
*/
public boolean getInherits();
/**
* Set inheritance behaviour
* @param inherits
*/
public void setInherits(boolean inherits);
/**
* Get the permission entries set for the node
* @return
*/
public Set<PermissionEntry> getPermissionEntries();
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
import java.util.HashSet;
import java.util.Set;
import org.alfresco.repo.domain.NodeKey;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* The hibernate persisted class for node permission entries.
*
* @author andyh
*/
public class NodePermissionEntryImpl implements NodePermissionEntry
{
/**
* The key to find node permission entries
*/
private NodeKey nodeKey;
/**
* Inherit permissions from the parent node?
*/
private boolean inherits;
/**
* The set of permission entries.
*/
private Set<PermissionEntry> permissionEntries = new HashSet<PermissionEntry>();
public NodePermissionEntryImpl()
{
super();
}
public NodeKey getNodeKey()
{
return nodeKey;
}
public void setNodeKey(NodeKey nodeKey)
{
this.nodeKey = nodeKey;
}
public NodeRef getNodeRef()
{
return new NodeRef(new StoreRef(nodeKey.getProtocol(), nodeKey
.getIdentifier()), nodeKey.getGuid());
}
public boolean getInherits()
{
return inherits;
}
public void setInherits(boolean inherits)
{
this.inherits = inherits;
}
public Set<PermissionEntry> getPermissionEntries()
{
return permissionEntries;
}
// Hibernate
/* package */ void setPermissionEntries(Set<PermissionEntry> permissionEntries)
{
this.permissionEntries = permissionEntries;
}
// Hibernate pattern
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof NodePermissionEntryImpl))
{
return false;
}
NodePermissionEntryImpl other = (NodePermissionEntryImpl) o;
return this.nodeKey.equals(other.nodeKey)
&& (this.inherits == other.inherits)
&& (this.permissionEntries.equals(other.permissionEntries));
}
@Override
public int hashCode()
{
return nodeKey.hashCode();
}
}

View File

@@ -0,0 +1,143 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
'-//Hibernate/Hibernate Mapping DTD 3.0//EN'
'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'>
<hibernate-mapping>
<class
name="org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntryImpl"
proxy="org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntry"
table="node_permission"
dynamic-insert="false"
dynamic-update="false"
select-before-update="false"
lazy="true"
optimistic-lock="version" >
<composite-id name="nodeKey" class="org.alfresco.repo.domain.NodeKey">
<key-property name="protocol" length="50" />
<key-property name="identifier" length="100" />
<key-property name="guid" length="36"/>
</composite-id>
<property name="inherits" column="inherits" type="boolean" not-null="true" />
<set
name="permissionEntries"
lazy="true"
sort="unsorted"
inverse="true"
fetch="select"
optimistic-lock="true"
cascade="delete" >
<key>
<column name="protocol" length="50" />
<column name="identifier" length="100" />
<column name="guid" length="36" />
</key>
<one-to-many class="org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntryImpl" />
</set>
</class>
<class
name="org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntryImpl"
proxy="org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntry"
table="node_perm_entry"
dynamic-insert="false"
dynamic-update="false"
select-before-update="false"
lazy="true"
optimistic-lock="version" >
<id
name="id"
column="id"
type="long" >
<generator class="increment" />
</id>
<many-to-one
name="nodePermissionEntry"
class="org.alfresco.repo.security.permissions.impl.hibernate.NodePermissionEntryImpl"
lazy="no-proxy" fetch="select" optimistic-lock="true" not-null="true" >
<column name="protocol" length="50" />
<column name="identifier" length="100" />
<column name="guid" length="36"/>
</many-to-one>
<many-to-one
name="permissionReference"
class="org.alfresco.repo.security.permissions.impl.hibernate.PermissionReferenceImpl"
lazy="no-proxy" fetch="select" optimistic-lock="true" not-null="false">
<column name="typeUri" length="100" />
<column name="typeName" length="100" />
<column name="name" length="100" />
</many-to-one>
<many-to-one
name="recipient"
class="org.alfresco.repo.security.permissions.impl.hibernate.RecipientImpl"
lazy="no-proxy" fetch="select" optimistic-lock="true" not-null="false">
</many-to-one>
<property name="allowed" column="allowed" type="boolean" not-null="true" />
</class>
<class
name="org.alfresco.repo.security.permissions.impl.hibernate.PermissionReferenceImpl"
proxy="org.alfresco.repo.security.permissions.impl.hibernate.PermissionReference"
table="permission_ref"
dynamic-insert="false"
dynamic-update="false"
select-before-update="false"
lazy="true"
optimistic-lock="version" >
<composite-id>
<key-property name="typeUri" type="string" length="100" column="type_uri"/>
<key-property name="typeName" type="string" length="100" column="type_name"/>
<key-property name="name" type="string" length="100" column="name" />
</composite-id>
</class>
<class
name="org.alfresco.repo.security.permissions.impl.hibernate.RecipientImpl"
proxy="org.alfresco.repo.security.permissions.impl.hibernate.Recipient"
table="recipient"
dynamic-insert="false"
dynamic-update="false"
select-before-update="false"
lazy="true"
optimistic-lock="version" >
<composite-id>
<key-property name="recipient"
column="recipient"
type="string" length="100" />
</composite-id>
<set name="externalKeys" lazy="true"
sort="unsorted"
fetch="select"
optimistic-lock="true" >
<key >
<column name="id" />
</key>
<element column="externalKey" length="100" not-null="true" type="string" />
</set>
</class>
<query name="permission.GetPermissionsForRecipient">
select
permissionEntry
from
org.alfresco.repo.security.permissions.impl.hibernate.PermissionEntryImpl as permissionEntry
join permissionEntry.recipient as recipient
where
recipient = :recipientKey
</query>
</hibernate-mapping>

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
/**
* The interface against which permission entries are persisted
*
* @author andyh
*/
public interface PermissionEntry
{
/**
* Get the identifier for this object.
*
* @return
*/
public long getId();
/**
* Get the containing node permission entry.
*
* @return
*/
public NodePermissionEntry getNodePermissionEntry();
/**
* Get the permission to which this entry applies.
*
* @return
*/
public PermissionReference getPermissionReference();
/**
* Get the recipient to which this entry applies.
*
* @return
*/
public Recipient getRecipient();
/**
* Is this permission allowed?
* @return
*/
public boolean isAllowed();
/**
* Set if this permission is allowed, otherwise it is denied.
*
* @param allowed
*/
public void setAllowed(boolean allowed);
/**
* Delete this permission entry - allows for deleting of the bidirectional relationship to the node permission entry.
*
*/
public void delete();
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
import org.alfresco.util.EqualsHelper;
/**
* Persisted permission entries
*
* @author andyh
*/
public class PermissionEntryImpl implements PermissionEntry
{
/**
* The object id
*/
private long id;
/**
* The container of this permissions
*/
private NodePermissionEntry nodePermissionEntry;
/**
* The permission to which this applies
* (non null - all is a special string)
*/
private PermissionReference permissionReference;
/**
* The recipient to which this applies
* (non null - all is a special string)
*/
private Recipient recipient;
/**
* Is this permission allowed?
*/
private boolean allowed;
public PermissionEntryImpl()
{
super();
}
public long getId()
{
return id;
}
// Hibernate
/* package */ void setId(long id)
{
this.id = id;
}
public NodePermissionEntry getNodePermissionEntry()
{
return nodePermissionEntry;
}
private void setNodePermissionEntry(NodePermissionEntry nodePermissionEntry)
{
this.nodePermissionEntry = nodePermissionEntry;
}
public PermissionReference getPermissionReference()
{
return permissionReference;
}
private void setPermissionReference(PermissionReference permissionReference)
{
this.permissionReference = permissionReference;
}
public Recipient getRecipient()
{
return recipient;
}
private void setRecipient(Recipient recipient)
{
this.recipient = recipient;
}
public boolean isAllowed()
{
return allowed;
}
public void setAllowed(boolean allowed)
{
this.allowed = allowed;
}
/**
* Factory method to create an entry and wire it in to the contained nodePermissionEntry
*
* @param nodePermissionEntry
* @param permissionReference
* @param recipient
* @param allowed
* @return
*/
public static PermissionEntryImpl create(NodePermissionEntry nodePermissionEntry, PermissionReference permissionReference, Recipient recipient, boolean allowed)
{
PermissionEntryImpl permissionEntry = new PermissionEntryImpl();
permissionEntry.setNodePermissionEntry(nodePermissionEntry);
permissionEntry.setPermissionReference(permissionReference);
permissionEntry.setRecipient(recipient);
permissionEntry.setAllowed(allowed);
nodePermissionEntry.getPermissionEntries().add(permissionEntry);
return permissionEntry;
}
/**
* Unwire
*/
public void delete()
{
nodePermissionEntry.getPermissionEntries().remove(this);
}
//
// Hibernate object pattern
//
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof PermissionEntryImpl))
{
return false;
}
PermissionEntryImpl other = (PermissionEntryImpl) o;
return EqualsHelper.nullSafeEquals(this.nodePermissionEntry,
other.nodePermissionEntry)
&& EqualsHelper.nullSafeEquals(this.permissionReference,
other.permissionReference)
&& EqualsHelper.nullSafeEquals(this.recipient, other.recipient)
&& (this.allowed == other.allowed);
}
@Override
public int hashCode()
{
int hashCode = nodePermissionEntry.hashCode();
if (permissionReference != null)
{
hashCode = hashCode * 37 + permissionReference.hashCode();
}
if (recipient != null)
{
hashCode = hashCode * 37 + recipient.hashCode();
}
hashCode = hashCode * 37 + (allowed ? 1 : 0);
return hashCode;
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
import java.io.Serializable;
/**
* The interface against which permission references are persisted in hibernate.
*
* @author andyh
*/
public interface PermissionReference extends Serializable
{
/**
* Get the URI for the type to which this permission applies.
*
* @return
*/
public String getTypeUri();
/**
* Set the URI for the type to which this permission applies.
*
* @param typeUri
*/
public void setTypeUri(String typeUri);
/**
* Get the local name of the type to which this permission applies.
*
* @return
*/
public String getTypeName();
/**
* Set the local name of the type to which this permission applies.
*
* @param typeName
*/
public void setTypeName(String typeName);
/**
* Get the name of the permission.
*
* @return
*/
public String getName();
/**
* Set the name of the permission.
*
* @param name
*/
public void setName(String name);
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
/**
* The persisted class for permission references.
*
* @author andyh
*/
public class PermissionReferenceImpl implements PermissionReference
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = -6352566900815035461L;
private String typeUri;
private String typeName;
private String name;
public PermissionReferenceImpl()
{
super();
}
public String getTypeUri()
{
return typeUri;
}
public void setTypeUri(String typeUri)
{
this.typeUri = typeUri;
}
public String getTypeName()
{
return typeName;
}
public void setTypeName(String typeName)
{
this.typeName = typeName;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
// Hibernate pattern
@Override
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if(!(o instanceof PermissionReference))
{
return false;
}
PermissionReference other = (PermissionReference)o;
return this.getTypeUri().equals(other.getTypeUri()) && this.getTypeName().equals(other.getTypeName()) && this.getName().equals(other.getName());
}
@Override
public int hashCode()
{
return ((typeUri.hashCode() * 37) + typeName.hashCode() ) * 37 + name.hashCode();
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
import java.io.Serializable;
import java.util.Set;
/**
* The interface against which recipients of permission are persisted
* @author andyh
*/
public interface Recipient extends Serializable
{
/**
* Get the recipient.
*
* @return
*/
public String getRecipient();
/**
* Set the recipient
*
* @param recipient
*/
public void setRecipient(String recipient);
/**
* Get the external keys that map to this recipient.
*
* @return
*/
public Set<String> getExternalKeys();
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.hibernate;
import java.util.HashSet;
import java.util.Set;
/**
* The persisted class for recipients.
*
* @author andyh
*/
public class RecipientImpl implements Recipient
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = -5582068692208928127L;
private String recipient;
private Set<String> externalKeys = new HashSet<String>();
public RecipientImpl()
{
super();
}
public String getRecipient()
{
return recipient;
}
public void setRecipient(String recipient)
{
this.recipient = recipient;
}
public Set<String> getExternalKeys()
{
return externalKeys;
}
// Hibernate
/* package */ void setExternalKeys(Set<String> externalKeys)
{
this.externalKeys = externalKeys;
}
// Hibernate pattern
@Override
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if(!(o instanceof Recipient))
{
return false;
}
Recipient other = (Recipient)o;
return this.getRecipient().equals(other.getRecipient());
}
@Override
public int hashCode()
{
return getRecipient().hashCode();
}
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.alfresco.repo.security.permissions.impl.AbstractPermissionReference;
import org.alfresco.repo.security.permissions.impl.RequiredPermission;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.dom4j.Attribute;
import org.dom4j.Element;
/**
* Support to read and store common properties for permissions
*
* @author andyh
*/
public abstract class AbstractPermission extends AbstractPermissionReference implements XMLModelInitialisable
{
/* XML Constants */
private static final String NAME = "name";
private static final String REQUIRED_PERMISSION = "requiredPermission";
private static final String RP_NAME = "name";
private static final String RP_TYPE = "type";
private static final String RP_ON = "on";
private static final String RP_IMPLIES = "implies";
private static final String NODE_ENTRY = "node";
private static final String PARENT_ENTRY = "parent";
private static final String CHILDREN_ENTRY = "children";
/* Instance variables */
private String name;
private QName typeQName;
private Set<RequiredPermission> requiredPermissions = new HashSet<RequiredPermission>();
public AbstractPermission(QName typeQName)
{
super();
this.typeQName = typeQName;
}
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel)
{
name = element.attributeValue(NAME);
for (Iterator rpit = element.elementIterator(REQUIRED_PERMISSION); rpit.hasNext(); /**/)
{
QName qName;
Element requiredPermissionElement = (Element) rpit.next();
Attribute typeAttribute = requiredPermissionElement.attribute(RP_TYPE);
if (typeAttribute != null)
{
qName = QName.createQName(typeAttribute.getStringValue(), nspr);
}
else
{
qName = typeQName;
}
String requiredName = requiredPermissionElement.attributeValue(RP_NAME);
RequiredPermission.On on;
String onString = requiredPermissionElement.attributeValue(RP_ON);
if (onString.equalsIgnoreCase(NODE_ENTRY))
{
on = RequiredPermission.On.NODE;
}
else if (onString.equalsIgnoreCase(PARENT_ENTRY))
{
on = RequiredPermission.On.PARENT;
}
else if (onString.equalsIgnoreCase(CHILDREN_ENTRY))
{
on = RequiredPermission.On.CHILDREN;
}
else
{
throw new PermissionModelException("Required permission must specify parent or node for the on attribute.");
}
boolean implies = false;
Attribute impliesAttribute = requiredPermissionElement.attribute(RP_IMPLIES);
if( impliesAttribute != null)
{
implies = Boolean.parseBoolean(impliesAttribute.getStringValue());
}
RequiredPermission rq = new RequiredPermission(qName, requiredName, on, implies);
requiredPermissions.add(rq);
}
}
public String getName()
{
return name;
}
public Set<RequiredPermission> getRequiredPermissions()
{
return Collections.unmodifiableSet(requiredPermissions);
}
public QName getTypeQName()
{
return typeQName;
}
public QName getQName()
{
return getTypeQName();
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.dom4j.Element;
/**
* The definition of a required permission
*
* @author andyh
*/
public class DynamicPermission extends AbstractPermission implements XMLModelInitialisable
{
private static final String EVALUATOR = "evaluator";
private String evaluatorFullyQualifiedClassName;
public DynamicPermission(QName typeQName)
{
super(typeQName);
}
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel)
{
super.initialise(element, nspr, permissionModel);
evaluatorFullyQualifiedClassName = element.attributeValue(EVALUATOR);
}
public String getEvaluatorFullyQualifiedClassName()
{
return evaluatorFullyQualifiedClassName;
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.dom4j.Attribute;
import org.dom4j.Element;
public class GlobalPermissionEntry implements XMLModelInitialisable, PermissionEntry
{
private static final String AUTHORITY = "authority";
private static final String PERMISSION = "permission";
private String authority;
private PermissionReference permissionReference;
public GlobalPermissionEntry()
{
super();
// TODO Auto-generated constructor stub
}
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel)
{
Attribute authorityAttribute = element.attribute(AUTHORITY);
if(authorityAttribute != null)
{
authority = authorityAttribute.getStringValue();
}
Attribute permissionAttribute = element.attribute(PERMISSION);
if(permissionAttribute != null)
{
permissionReference = permissionModel.getPermissionReference(null, permissionAttribute.getStringValue());
}
}
public String getAuthority()
{
return authority;
}
public PermissionReference getPermissionReference()
{
return permissionReference;
}
public NodeRef getNodeRef()
{
return null;
}
public boolean isDenied()
{
return false;
}
public boolean isAllowed()
{
return true;
}
public AccessStatus getAccessStatus()
{
return AccessStatus.ALLOWED;
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.PermissionReferenceImpl;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.dom4j.Attribute;
import org.dom4j.Element;
/**
* Support to read and store the definion of a permission entry.
*
* @author andyh
*/
public class ModelPermissionEntry implements PermissionEntry, XMLModelInitialisable
{
// XML Constants
private static final String PERMISSION_REFERENCE = "permissionReference";
private static final String RECIPIENT = "recipient";
private static final String ACCESS = "access";
private static final String DENY = "deny";
private static final String ALLOW = "allow";
private static final String TYPE = "type";
private static final String NAME = "name";
// Instance variables
private String recipient;
private AccessStatus access;
private PermissionReference permissionReference;
private NodeRef nodeRef;
public ModelPermissionEntry(NodeRef nodeRef)
{
super();
this.nodeRef = nodeRef;
}
public PermissionReference getPermissionReference()
{
return permissionReference;
}
public String getAuthority()
{
return getRecipient();
}
public String getRecipient()
{
return recipient;
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public boolean isDenied()
{
return access == AccessStatus.DENIED;
}
public boolean isAllowed()
{
return access == AccessStatus.ALLOWED;
}
public AccessStatus getAccessStatus()
{
return access;
}
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel)
{
Attribute recipientAttribute = element.attribute(RECIPIENT);
if (recipientAttribute != null)
{
recipient = recipientAttribute.getStringValue();
}
else
{
recipient = null;
}
Attribute accessAttribute = element.attribute(ACCESS);
if (accessAttribute != null)
{
if (accessAttribute.getStringValue().equalsIgnoreCase(ALLOW))
{
access = AccessStatus.ALLOWED;
}
else if (accessAttribute.getStringValue().equalsIgnoreCase(DENY))
{
access = AccessStatus.DENIED;
}
else
{
throw new PermissionModelException("The default permission must be deny or allow");
}
}
else
{
access = AccessStatus.DENIED;
}
Element permissionReferenceElement = element.element(PERMISSION_REFERENCE);
QName typeQName = QName.createQName(permissionReferenceElement.attributeValue(TYPE), nspr);
String name = permissionReferenceElement.attributeValue(NAME);
permissionReference = new PermissionReferenceImpl(typeQName, name);
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.dom4j.Attribute;
import org.dom4j.Element;
/**
* Support to read and store the definition of node permissions
* @author andyh
*/
public class NodePermission implements NodePermissionEntry, XMLModelInitialisable
{
// XML Constants
private static final String NODE_REF = "nodeRef";
private static final String NODE_PERMISSION = "nodePermission";
private static final String INHERIT_FROM_PARENT = "inheritFromParent";
// Instance variables
// If null then it is the root.
private NodeRef nodeRef;
private Set<PermissionEntry> permissionEntries = new HashSet<PermissionEntry>();
private boolean inheritPermissionsFromParent;
public NodePermission()
{
super();
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public boolean inheritPermissions()
{
return inheritPermissionsFromParent;
}
public Set<PermissionEntry> getPermissionEntries()
{
return Collections.unmodifiableSet(permissionEntries);
}
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel)
{
Attribute nodeRefAttribute = element.attribute(NODE_REF);
if(nodeRefAttribute != null)
{
nodeRef = new NodeRef(nodeRefAttribute.getStringValue());
}
Attribute inheritFromParentAttribute = element.attribute(INHERIT_FROM_PARENT);
if(inheritFromParentAttribute != null)
{
inheritPermissionsFromParent = Boolean.parseBoolean(inheritFromParentAttribute.getStringValue());
}
else
{
inheritPermissionsFromParent = true;
}
// Node Permissions Entry
for (Iterator npit = element.elementIterator(NODE_PERMISSION); npit.hasNext(); /**/)
{
Element permissionEntryElement = (Element) npit.next();
ModelPermissionEntry permissionEntry = new ModelPermissionEntry(nodeRef);
permissionEntry.initialise(permissionEntryElement, nspr, permissionModel);
permissionEntries.add(permissionEntry);
}
}
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.PermissionReferenceImpl;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.dom4j.Attribute;
import org.dom4j.Element;
/**
* Support to read and store the definition of a permission.
*
* @author andyh
*/
public class Permission extends AbstractPermission implements XMLModelInitialisable
{
// XML Constants
private static final String GRANTED_TO_GROUP = "grantedToGroup";
private static final String GTG_NAME = "permissionGroup";
private static final String GTG_TYPE = "type";
private Set<PermissionReference> grantedToGroups = new HashSet<PermissionReference>();
private static final String DENY = "deny";
private static final String ALLOW = "allow";
private static final String DEFAULT_PERMISSION = "defaultPermission";
private static final String EXPOSE = "expose";
private static final String REQUIRES_TYPE = "requiresType";
private AccessStatus defaultPermission;
private boolean isExposed;
private boolean requiresType;
public Permission(QName typeQName)
{
super(typeQName);
}
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel)
{
super.initialise(element, nspr, permissionModel);
Attribute att = element.attribute(EXPOSE);
if (att != null)
{
isExposed = Boolean.parseBoolean(att.getStringValue());
}
else
{
isExposed = true;
}
att = element.attribute(REQUIRES_TYPE);
if (att != null)
{
requiresType = Boolean.parseBoolean(att.getStringValue());
}
else
{
requiresType = true;
}
Attribute defaultPermissionAttribute = element.attribute(DEFAULT_PERMISSION);
if(defaultPermissionAttribute != null)
{
if(defaultPermissionAttribute.getStringValue().equalsIgnoreCase(ALLOW))
{
defaultPermission = AccessStatus.ALLOWED;
}
else if(defaultPermissionAttribute.getStringValue().equalsIgnoreCase(DENY))
{
defaultPermission = AccessStatus.DENIED;
}
else
{
throw new PermissionModelException("The default permission must be deny or allow");
}
}
else
{
defaultPermission = AccessStatus.DENIED;
}
for (Iterator gtgit = element.elementIterator(GRANTED_TO_GROUP); gtgit.hasNext(); /**/)
{
QName qName;
Element grantedToGroupsElement = (Element) gtgit.next();
Attribute typeAttribute = grantedToGroupsElement.attribute(GTG_TYPE);
if (typeAttribute != null)
{
qName = QName.createQName(typeAttribute.getStringValue(), nspr);
}
else
{
qName = getTypeQName();
}
String grantedName = grantedToGroupsElement.attributeValue(GTG_NAME);
grantedToGroups.add(new PermissionReferenceImpl(qName, grantedName));
}
}
public AccessStatus getDefaultPermission()
{
return defaultPermission;
}
public Set<PermissionReference> getGrantedToGroups()
{
return Collections.unmodifiableSet(grantedToGroups);
}
public boolean isExposed()
{
return isExposed;
}
public boolean isTypeRequired()
{
return requiresType;
}
}

View File

@@ -0,0 +1,195 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.AbstractPermissionReference;
import org.alfresco.repo.security.permissions.impl.PermissionReferenceImpl;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.dom4j.Attribute;
import org.dom4j.Element;
/**
* Support to read and store the defintion of permission groups.
*
* @author andyh
*/
public class PermissionGroup extends AbstractPermissionReference implements XMLModelInitialisable
{
// XML Constants
private static final String NAME = "name";
private static final String EXTENDS = "extends";
private static final String ALLOW_FULL_CONTOL = "allowFullControl";
private static final String INCLUDE_PERMISSION_GROUP = "includePermissionGroup";
private static final String PERMISSION_GROUP = "permissionGroup";
private static final String TYPE = "type";
private static final String EXPOSE = "expose";
private static final String REQUIRES_TYPE = "requiresType";
private String name;
private QName type;
private boolean extendz;
private boolean isExposed;
private boolean allowFullControl;
private QName container;
private Set<PermissionReference> includedPermissionGroups = new HashSet<PermissionReference>();
private boolean requiresType;
public PermissionGroup(QName container)
{
super();
this.container = container;
}
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel)
{
// Name
name = element.attributeValue(NAME);
// Allow full control
Attribute att = element.attribute(ALLOW_FULL_CONTOL);
if (att != null)
{
allowFullControl = Boolean.parseBoolean(att.getStringValue());
}
else
{
allowFullControl = false;
}
att = element.attribute(REQUIRES_TYPE);
if (att != null)
{
requiresType = Boolean.parseBoolean(att.getStringValue());
}
else
{
requiresType = true;
}
att = element.attribute(EXTENDS);
if (att != null)
{
extendz = Boolean.parseBoolean(att.getStringValue());
}
else
{
extendz = false;
}
att = element.attribute(EXPOSE);
if (att != null)
{
isExposed = Boolean.parseBoolean(att.getStringValue());
}
else
{
isExposed = true;
}
att = element.attribute(TYPE);
if (att != null)
{
type = QName.createQName(att.getStringValue(),nspr);
}
else
{
type = null;
}
// Include permissions defined for other permission groups
for (Iterator ipgit = element.elementIterator(INCLUDE_PERMISSION_GROUP); ipgit.hasNext(); /**/)
{
QName qName;
Element includePermissionGroupElement = (Element) ipgit.next();
Attribute typeAttribute = includePermissionGroupElement.attribute(TYPE);
if (typeAttribute != null)
{
qName = QName.createQName(typeAttribute.getStringValue(), nspr);
}
else
{
qName = container;
}
String refName = includePermissionGroupElement.attributeValue(PERMISSION_GROUP);
PermissionReference permissionReference = new PermissionReferenceImpl(qName, refName);
includedPermissionGroups.add(permissionReference);
}
}
public Set<PermissionReference> getIncludedPermissionGroups()
{
return Collections.unmodifiableSet(includedPermissionGroups);
}
public String getName()
{
return name;
}
public boolean isAllowFullControl()
{
return allowFullControl;
}
public QName getQName()
{
return container;
}
public boolean isExtends()
{
return extendz;
}
public QName getTypeQName()
{
return type;
}
public boolean isExposed()
{
return isExposed;
}
public boolean isTypeRequired()
{
return requiresType;
}
}

View File

@@ -0,0 +1,944 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.ModelDAO;
import org.alfresco.repo.security.permissions.impl.RequiredPermission;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.DynamicNamespacePrefixResolver;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.InitializingBean;
/**
* The implementation of the model DAO
*
* Reads and stores the top level model information
*
* Encapsulates access to this information
*
* @author andyh
*/
public class PermissionModel implements ModelDAO, InitializingBean
{
// IOC
private NodeService nodeService;
private DictionaryService dictionaryService;
// XML Constants
private static final String NAMESPACES = "namespaces";
private static final String NAMESPACE = "namespace";
private static final String NAMESPACE_URI = "uri";
private static final String NAMESPACE_PREFIX = "prefix";
private static final String PERMISSION_SET = "permissionSet";
private static final String GLOBAL_PERMISSION = "globalPermission";
private static final String DENY = "deny";
private static final String ALLOW = "allow";
private static final String DEFAULT_PERMISSION = "defaultPermission";
// Instance variables
private String model;
private Map<QName, PermissionSet> permissionSets = new HashMap<QName, PermissionSet>();
private Set<GlobalPermissionEntry> globalPermissions = new HashSet<GlobalPermissionEntry>();
private AccessStatus defaultPermission;
// Cache granting permissions
private HashMap<PermissionReference, Set<PermissionReference>> grantingPermissions = new HashMap<PermissionReference, Set<PermissionReference>>();
// Cache grantees
private HashMap<PermissionReference, Set<PermissionReference>> granteePermissions = new HashMap<PermissionReference, Set<PermissionReference>>();
// Cache the mapping of extended groups to the base
private HashMap<PermissionGroup, PermissionGroup> groupsToBaseGroup = new HashMap<PermissionGroup, PermissionGroup>();
private HashMap<String, PermissionReference> uniqueMap;
private HashMap<PermissionReference, Permission> permissionMap;
private HashMap<PermissionReference, PermissionGroup> permissionGroupMap;
private HashMap<String, PermissionReference> permissionReferenceMap;
public PermissionModel()
{
super();
}
// IOC
public void setModel(String model)
{
this.model = model;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/*
* Initialise from file
*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet()
{
Document document = createDocument(model);
Element root = document.getRootElement();
Attribute defaultPermissionAttribute = root.attribute(DEFAULT_PERMISSION);
if (defaultPermissionAttribute != null)
{
if (defaultPermissionAttribute.getStringValue().equalsIgnoreCase(ALLOW))
{
defaultPermission = AccessStatus.ALLOWED;
}
else if (defaultPermissionAttribute.getStringValue().equalsIgnoreCase(DENY))
{
defaultPermission = AccessStatus.DENIED;
}
else
{
throw new PermissionModelException("The default permission must be deny or allow");
}
}
else
{
defaultPermission = AccessStatus.DENIED;
}
DynamicNamespacePrefixResolver nspr = new DynamicNamespacePrefixResolver();
// Namespaces
for (Iterator nsit = root.elementIterator(NAMESPACES); nsit.hasNext(); /**/)
{
Element namespacesElement = (Element) nsit.next();
for (Iterator it = namespacesElement.elementIterator(NAMESPACE); it.hasNext(); /**/)
{
Element nameSpaceElement = (Element) it.next();
nspr.registerNamespace(nameSpaceElement.attributeValue(NAMESPACE_PREFIX), nameSpaceElement
.attributeValue(NAMESPACE_URI));
}
}
// Permission Sets
for (Iterator psit = root.elementIterator(PERMISSION_SET); psit.hasNext(); /**/)
{
Element permissionSetElement = (Element) psit.next();
PermissionSet permissionSet = new PermissionSet();
permissionSet.initialise(permissionSetElement, nspr, this);
permissionSets.put(permissionSet.getQName(), permissionSet);
}
buildUniquePermissionMap();
// NodePermissions
for (Iterator npit = root.elementIterator(GLOBAL_PERMISSION); npit.hasNext(); /**/)
{
Element globalPermissionElement = (Element) npit.next();
GlobalPermissionEntry globalPermission = new GlobalPermissionEntry();
globalPermission.initialise(globalPermissionElement, nspr, this);
globalPermissions.add(globalPermission);
}
}
/*
* Create the XML document from the file location
*/
private Document createDocument(String model)
{
InputStream is = this.getClass().getClassLoader().getResourceAsStream(model);
if (is == null)
{
throw new PermissionModelException("File not found: " + model);
}
SAXReader reader = new SAXReader();
try
{
Document document = reader.read(is);
is.close();
return document;
}
catch (DocumentException e)
{
throw new PermissionModelException("Failed to create permission model document ", e);
}
catch (IOException e)
{
throw new PermissionModelException("Failed to close permission model document ", e);
}
}
public AccessStatus getDefaultPermission()
{
return defaultPermission;
}
public AccessStatus getDefaultPermission(PermissionReference pr)
{
Permission p = permissionMap.get(pr);
if (p == null)
{
return defaultPermission;
}
else
{
return p.getDefaultPermission();
}
}
public Set<? extends PermissionEntry> getGlobalPermissionEntries()
{
return Collections.unmodifiableSet(globalPermissions);
}
public Map<QName, PermissionSet> getPermissionSets()
{
return Collections.unmodifiableMap(permissionSets);
}
public Set<PermissionReference> getAllPermissions(QName type)
{
return getAllPermissionsImpl(type, false);
}
public Set<PermissionReference> getExposedPermissions(QName type)
{
return getAllPermissionsImpl(type, true);
}
private Set<PermissionReference> getAllPermissionsImpl(QName type, boolean exposedOnly)
{
Set<PermissionReference> permissions = new HashSet<PermissionReference>();
if (dictionaryService.getClass(type).isAspect())
{
addAspectPermissions(type, permissions, exposedOnly);
}
else
{
mergeGeneralAspectPermissions(permissions, exposedOnly);
addTypePermissions(type, permissions, exposedOnly);
}
return permissions;
}
/**
* Support to add permissions for types
*
* @param type
* @param permissions
*/
private void addTypePermissions(QName type, Set<PermissionReference> permissions, boolean exposedOnly)
{
TypeDefinition typeDef = dictionaryService.getType(type);
if (typeDef.getParentName() != null)
{
PermissionSet permissionSet = permissionSets.get(type);
if (!exposedOnly || (permissionSet == null) || permissionSet.exposeAll())
{
addTypePermissions(typeDef.getParentName(), permissions, exposedOnly);
}
}
for (AspectDefinition ad : typeDef.getDefaultAspects())
{
addAspectPermissions(ad.getName(), permissions, exposedOnly);
}
mergePermissions(permissions, type, exposedOnly, true);
}
/**
* Support to add permissions for aspects.
*
* @param type
* @param permissions
*/
private void addAspectPermissions(QName type, Set<PermissionReference> permissions, boolean exposedOnly)
{
AspectDefinition aspectDef = dictionaryService.getAspect(type);
if (aspectDef.getParentName() != null)
{
PermissionSet permissionSet = permissionSets.get(type);
if (!exposedOnly || (permissionSet == null) || permissionSet.exposeAll())
{
addAspectPermissions(aspectDef.getParentName(), permissions, exposedOnly);
}
}
mergePermissions(permissions, type, exposedOnly, true);
}
/**
* Support to merge permissions together. Respects extended permissions.
*
* @param target
* @param type
*/
private void mergePermissions(Set<PermissionReference> target, QName type, boolean exposedOnly, boolean typeRequired)
{
PermissionSet permissionSet = permissionSets.get(type);
if (permissionSet != null)
{
for (PermissionGroup pg : permissionSet.getPermissionGroups())
{
if (!exposedOnly || permissionSet.exposeAll() || pg.isExposed())
{
if (!pg.isExtends())
{
if (pg.isTypeRequired() == typeRequired)
{
target.add(pg);
}
}
else if (exposedOnly)
{
if (pg.isTypeRequired() == typeRequired)
{
target.add(getBasePermissionGroup(pg));
}
}
}
}
for (Permission p : permissionSet.getPermissions())
{
if (!exposedOnly || permissionSet.exposeAll() || p.isExposed())
{
if (p.isTypeRequired() == typeRequired)
{
target.add(p);
}
}
}
}
}
private void mergeGeneralAspectPermissions(Set<PermissionReference> target, boolean exposedOnly)
{
for(QName aspect : dictionaryService.getAllAspects())
{
mergePermissions(target, aspect, exposedOnly, false);
}
}
public Set<PermissionReference> getAllPermissions(NodeRef nodeRef)
{
return getExposedPermissionsImpl(nodeRef, false);
}
public Set<PermissionReference> getExposedPermissions(NodeRef nodeRef)
{
return getExposedPermissionsImpl(nodeRef, true);
}
public Set<PermissionReference> getExposedPermissionsImpl(NodeRef nodeRef, boolean exposedOnly)
{
QName typeName = nodeService.getType(nodeRef);
Set<PermissionReference> permissions = getAllPermissions(typeName);
mergeGeneralAspectPermissions(permissions, exposedOnly);
// Add non mandatory aspects..
Set<QName> defaultAspects = new HashSet<QName>();
for (AspectDefinition aspDef : dictionaryService.getType(typeName).getDefaultAspects())
{
defaultAspects.add(aspDef.getName());
}
for (QName aspect : nodeService.getAspects(nodeRef))
{
if (!defaultAspects.contains(aspect))
{
addAspectPermissions(aspect, permissions, exposedOnly);
}
}
return permissions;
}
public synchronized Set<PermissionReference> getGrantingPermissions(PermissionReference permissionReference)
{
// Cache the results
Set<PermissionReference> granters = grantingPermissions.get(permissionReference);
if (granters == null)
{
granters = getGrantingPermissionsImpl(permissionReference);
grantingPermissions.put(permissionReference, granters);
}
return granters;
}
private Set<PermissionReference> getGrantingPermissionsImpl(PermissionReference permissionReference)
{
// Query the model
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>();
permissions.add(permissionReference);
for (PermissionSet ps : permissionSets.values())
{
for (PermissionGroup pg : ps.getPermissionGroups())
{
if (grants(pg, permissionReference))
{
permissions.add(getBasePermissionGroup(pg));
}
if (pg.isAllowFullControl())
{
permissions.add(pg);
}
}
for (Permission p : ps.getPermissions())
{
if (p.equals(permissionReference))
{
for (PermissionReference pg : p.getGrantedToGroups())
{
permissions.add(getBasePermissionGroup(getPermissionGroup(pg)));
}
}
for (RequiredPermission rp : p.getRequiredPermissions())
{
if (rp.equals(permissionReference) && rp.isImplies())
{
permissions.add(p);
break;
}
}
}
}
return permissions;
}
private boolean grants(PermissionGroup pg, PermissionReference permissionReference)
{
if (pg.getIncludedPermissionGroups().contains(permissionReference))
{
return true;
}
if (getGranteePermissions(pg).contains(permissionReference))
{
return true;
}
for (PermissionReference nested : pg.getIncludedPermissionGroups())
{
if (grants(getPermissionGroup(nested), permissionReference))
{
return true;
}
}
return false;
}
public synchronized Set<PermissionReference> getGranteePermissions(PermissionReference permissionReference)
{
// Cache the results
Set<PermissionReference> grantees = granteePermissions.get(permissionReference);
if (grantees == null)
{
grantees = getGranteePermissionsImpl(permissionReference);
granteePermissions.put(permissionReference, grantees);
}
return grantees;
}
private Set<PermissionReference> getGranteePermissionsImpl(PermissionReference permissionReference)
{
// Query the model
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>();
permissions.add(permissionReference);
for (PermissionSet ps : permissionSets.values())
{
for (PermissionGroup pg : ps.getPermissionGroups())
{
if (pg.equals(permissionReference))
{
for (PermissionReference included : pg.getIncludedPermissionGroups())
{
permissions.addAll(getGranteePermissions(included));
}
if (pg.isExtends())
{
if (pg.getTypeQName() != null)
{
permissions.addAll(getGranteePermissions(new SimplePermissionReference(pg.getTypeQName(),
pg.getName())));
}
else
{
ClassDefinition classDefinition = dictionaryService.getClass(pg.getQName());
QName parent = classDefinition.getParentName();
if (parent != null)
{
classDefinition = dictionaryService.getClass(parent);
PermissionGroup attempt = getPermissionGroupOrNull(new SimplePermissionReference(
parent, pg.getName()));
if (attempt != null)
{
permissions.addAll(getGranteePermissions(attempt));
}
}
}
}
if (pg.isAllowFullControl())
{
// add all available
permissions.addAll(getAllPermissions());
}
}
}
PermissionGroup baseGroup = getBasePermissionGroupOrNull(getPermissionGroupOrNull(permissionReference));
if (baseGroup != null)
{
for (Permission p : ps.getPermissions())
{
for (PermissionReference grantedTo : p.getGrantedToGroups())
{
PermissionGroup base = getBasePermissionGroupOrNull(getPermissionGroupOrNull(grantedTo));
if (baseGroup.equals(base))
{
permissions.add(p);
}
}
}
}
}
return permissions;
}
private Set<PermissionReference> getAllPermissions()
{
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>();
for (PermissionSet ps : permissionSets.values())
{
for (PermissionGroup pg : ps.getPermissionGroups())
{
permissions.add(pg);
}
for (Permission p : ps.getPermissions())
{
permissions.add(p);
}
}
return permissions;
}
/**
* Support to find permission groups
*
* @param target
* @return
*/
private PermissionGroup getPermissionGroupOrNull(PermissionReference target)
{
PermissionGroup pg = permissionGroupMap.get(target);
return pg == null ? null : pg;
}
/**
* Support to get a permission group
*
* @param target
* @return
*/
private PermissionGroup getPermissionGroup(PermissionReference target)
{
PermissionGroup pg = getPermissionGroupOrNull(target);
if (pg == null)
{
throw new PermissionModelException("There is no permission group :"
+ target.getQName() + " " + target.getName());
}
return pg;
}
/**
* Get the base permission group for a given permission group.
*
* @param pg
* @return
*/
private synchronized PermissionGroup getBasePermissionGroupOrNull(PermissionGroup pg)
{
if (groupsToBaseGroup.containsKey(pg))
{
return groupsToBaseGroup.get(pg);
}
else
{
PermissionGroup answer = getBasePermissionGroupOrNullImpl(pg);
groupsToBaseGroup.put(pg, answer);
return answer;
}
}
/**
* Query the model for a base permission group
*
* Uses the Data Dictionary to reolve inheritance
*
* @param pg
* @return
*/
private PermissionGroup getBasePermissionGroupOrNullImpl(PermissionGroup pg)
{
if (pg == null)
{
return null;
}
if (pg.isExtends())
{
if (pg.getTypeQName() != null)
{
return getPermissionGroup(new SimplePermissionReference(pg.getTypeQName(), pg.getName()));
}
else
{
ClassDefinition classDefinition = dictionaryService.getClass(pg.getQName());
QName parent;
while ((parent = classDefinition.getParentName()) != null)
{
classDefinition = dictionaryService.getClass(parent);
PermissionGroup attempt = getPermissionGroupOrNull(new SimplePermissionReference(parent, pg
.getName()));
if ((attempt != null) && (!attempt.isExtends()))
{
return attempt;
}
}
return null;
}
}
else
{
return pg;
}
}
private PermissionGroup getBasePermissionGroup(PermissionGroup target)
{
PermissionGroup pg = getBasePermissionGroupOrNull(target);
if (pg == null)
{
throw new PermissionModelException("There is no parent for permission group :"
+ target.getQName() + " " + target.getName());
}
return pg;
}
public Set<PermissionReference> getRequiredPermissions(PermissionReference required, QName qName,
Set<QName> aspectQNames, RequiredPermission.On on)
{
PermissionGroup pg = getBasePermissionGroupOrNull(getPermissionGroupOrNull(required));
if (pg == null)
{
return getRequirementsForPermission(required, on);
}
else
{
return getRequirementsForPermissionGroup(pg, on, qName, aspectQNames);
}
}
/**
* Get the requirements for a permission
*
* @param required
* @param on
* @return
*/
private Set<PermissionReference> getRequirementsForPermission(PermissionReference required, RequiredPermission.On on)
{
HashSet<PermissionReference> requiredPermissions = new HashSet<PermissionReference>();
Permission p = getPermissionOrNull(required);
if (p != null)
{
for (RequiredPermission rp : p.getRequiredPermissions())
{
if (!rp.isImplies() && rp.getOn().equals(on))
{
requiredPermissions.add(rp);
}
}
}
return requiredPermissions;
}
/**
* Get the requirements for a permission set
*
* @param target
* @param on
* @param qName
* @param aspectQNames
* @return
*/
private Set<PermissionReference> getRequirementsForPermissionGroup(PermissionGroup target,
RequiredPermission.On on, QName qName, Set<QName> aspectQNames)
{
HashSet<PermissionReference> requiredPermissions = new HashSet<PermissionReference>();
if (target == null)
{
return requiredPermissions;
}
for (PermissionSet ps : permissionSets.values())
{
for (PermissionGroup pg : ps.getPermissionGroups())
{
if (target.equals(getBasePermissionGroupOrNull(pg))
&& isPartOfDynamicPermissionGroup(pg, qName, aspectQNames))
{
// Add includes
for (PermissionReference pr : pg.getIncludedPermissionGroups())
{
requiredPermissions.addAll(getRequirementsForPermissionGroup(
getBasePermissionGroupOrNull(getPermissionGroupOrNull(pr)), on, qName, aspectQNames));
}
}
}
for (Permission p : ps.getPermissions())
{
for (PermissionReference grantedTo : p.getGrantedToGroups())
{
PermissionGroup base = getBasePermissionGroupOrNull(getPermissionGroupOrNull(grantedTo));
if (target.equals(base) && (!base.isTypeRequired() || isPartOfDynamicPermissionGroup(grantedTo, qName, aspectQNames)))
{
if (on == RequiredPermission.On.NODE)
{
requiredPermissions.add(p);
}
}
}
}
}
return requiredPermissions;
}
/**
* Check type specifc extension of permission sets.
*
* @param pr
* @param typeQname
* @param aspects
* @return
*/
private boolean isPartOfDynamicPermissionGroup(PermissionReference pr, QName typeQname, Set<QName> aspects)
{
if (dictionaryService.isSubClass(typeQname, pr.getQName()))
{
return true;
}
for (QName aspect : aspects)
{
if (dictionaryService.isSubClass(aspect, pr.getQName()))
{
return true;
}
}
return false;
}
/**
* Utility method to find a permission
*
* @param perm
* @return
*/
private Permission getPermissionOrNull(PermissionReference perm)
{
Permission p = permissionMap.get(perm);
return p == null ? null : p;
}
public boolean checkPermission(PermissionReference required)
{
Permission permission = getPermissionOrNull(required);
if (permission != null)
{
return true;
}
PermissionGroup pg = getPermissionGroupOrNull(required);
if (pg != null)
{
if (pg.isExtends())
{
if (pg.getTypeQName() != null)
{
return checkPermission(new SimplePermissionReference(pg.getTypeQName(), pg.getName()));
}
else
{
ClassDefinition classDefinition = dictionaryService.getClass(pg.getQName());
QName parent;
while ((parent = classDefinition.getParentName()) != null)
{
classDefinition = dictionaryService.getClass(parent);
PermissionGroup attempt = getPermissionGroupOrNull(new SimplePermissionReference(parent, pg
.getName()));
if ((attempt != null) && attempt.isAllowFullControl())
{
return true;
}
}
return false;
}
}
else
{
return pg.isAllowFullControl();
}
}
else
{
return false;
}
}
public PermissionReference getPermissionReference(QName qname, String permissionName)
{
if(permissionName == null)
{
return null;
}
PermissionReference pr = uniqueMap.get(permissionName);
if (pr == null)
{
pr = permissionReferenceMap.get(permissionName);
if (pr == null)
{
throw new UnsupportedOperationException("Can not find " + permissionName);
}
}
return pr;
}
public boolean isUnique(PermissionReference permissionReference)
{
return uniqueMap.containsKey(permissionReference.getName());
}
private void buildUniquePermissionMap()
{
Set<String> excluded = new HashSet<String>();
uniqueMap = new HashMap<String, PermissionReference>();
permissionReferenceMap = new HashMap<String, PermissionReference>();
permissionGroupMap = new HashMap<PermissionReference, PermissionGroup>();
permissionMap = new HashMap<PermissionReference, Permission>();
for (PermissionSet ps : permissionSets.values())
{
for (PermissionGroup pg : ps.getPermissionGroups())
{
if (uniqueMap.containsKey(pg.getName()) && !excluded.contains(pg.getName()))
{
PermissionReference value = uniqueMap.get(pg.getName());
if (!value.equals(getBasePermissionGroup(pg)))
{
uniqueMap.remove(pg.getName());
excluded.add(pg.getName());
}
}
else
{
uniqueMap.put(pg.getName(), getBasePermissionGroup(pg));
}
permissionReferenceMap.put(pg.toString(), pg);
permissionGroupMap.put(pg, pg);
}
for (Permission p : ps.getPermissions())
{
if (uniqueMap.containsKey(p.getName()) && !excluded.contains(p.getName()))
{
PermissionReference value = uniqueMap.get(p.getName());
if (!value.equals(p))
{
uniqueMap.remove(p.getName());
excluded.add(p.getName());
}
}
else
{
uniqueMap.put(p.getName(), p);
}
permissionReferenceMap.put(p.toString(), p);
permissionMap.put(p, p);
}
}
// Add all permissions to the unique list
if (uniqueMap.containsKey(PermissionService.ALL_PERMISSIONS))
{
throw new IllegalStateException(
"There must not be a permission with the same name as the ALL_PERMISSION constant: "
+ PermissionService.ALL_PERMISSIONS);
}
uniqueMap.put(PermissionService.ALL_PERMISSIONS, new SimplePermissionReference(QName.createQName(
NamespaceService.SECURITY_MODEL_1_0_URI, PermissionService.ALL_PERMISSIONS), PermissionService.ALL_PERMISSIONS));
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* Exceptions related to the permissions model
*
* @author andyh
*/
public class PermissionModelException extends AlfrescoRuntimeException
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = -5156253607792153538L;
public PermissionModelException(String msg)
{
super(msg);
}
public PermissionModelException(String msg, Throwable cause)
{
super(msg, cause);
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import java.util.Set;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.AbstractPermissionTest;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.service.namespace.QName;
public class PermissionModelTest extends AbstractPermissionTest
{
public PermissionModelTest()
{
super();
}
public void testIncludePermissionGroups()
{
Set<PermissionReference> grantees = permissionModelDAO.getGranteePermissions(new SimplePermissionReference(QName.createQName("cm", "folder",
namespacePrefixResolver), "Guest"));
assertEquals(5, grantees.size());
}
public void testGetGrantingPermissions()
{
Set<PermissionReference> granters = permissionModelDAO.getGrantingPermissions(new SimplePermissionReference(QName.createQName("sys", "base",
namespacePrefixResolver), "ReadProperties"));
assertEquals(8, granters.size());
}
public void testGlobalPermissions()
{
Set<? extends PermissionEntry> globalPermissions = permissionModelDAO.getGlobalPermissionEntries();
assertEquals(5, globalPermissions.size());
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.dom4j.Attribute;
import org.dom4j.Element;
/**
* Store and read the definition of a permission set
* @author andyh
*/
public class PermissionSet implements XMLModelInitialisable
{
private static final String TYPE = "type";
private static final String PERMISSION_GROUP = "permissionGroup";
private static final String PERMISSION = "permission";
private static final String EXPOSE = "expose";
private static final String EXPOSE_ALL = "all";
//private static final String EXPOSE_SELECTED = "selected";
private QName qname;
private boolean exposeAll;
private Set<PermissionGroup> permissionGroups = new HashSet<PermissionGroup>();
private Set<Permission> permissions = new HashSet<Permission>();
public PermissionSet()
{
super();
}
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel)
{
qname = QName.createQName(element.attributeValue(TYPE), nspr);
Attribute exposeAttribute = element.attribute(EXPOSE);
if(exposeAttribute != null)
{
exposeAll = exposeAttribute.getStringValue().equalsIgnoreCase(EXPOSE_ALL);
}
else
{
exposeAll = true;
}
for(Iterator pgit = element.elementIterator(PERMISSION_GROUP); pgit.hasNext(); /**/)
{
Element permissionGroupElement = (Element)pgit.next();
PermissionGroup permissionGroup = new PermissionGroup(qname);
permissionGroup.initialise(permissionGroupElement, nspr, permissionModel);
permissionGroups.add(permissionGroup);
}
for(Iterator pit = element.elementIterator(PERMISSION); pit.hasNext(); /**/)
{
Element permissionElement = (Element)pit.next();
Permission permission = new Permission(qname);
permission.initialise(permissionElement, nspr, permissionModel);
permissions.add(permission);
}
}
public Set<PermissionGroup> getPermissionGroups()
{
return Collections.unmodifiableSet(permissionGroups);
}
public Set<Permission> getPermissions()
{
return Collections.unmodifiableSet(permissions);
}
public QName getQName()
{
return qname;
}
public boolean exposeAll()
{
return exposeAll;
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.impl.model;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.dom4j.Element;
/**
* Interface to initialise a component of the permission mode from its XML representation.
*
* @author andyh
*/
public interface XMLModelInitialisable
{
public void initialise(Element element, NamespacePrefixResolver nspr, PermissionModel permissionModel);
}

View File

@@ -0,0 +1,219 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.permissions.noop;
import java.util.HashSet;
import java.util.Set;
import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
/**
* Dummy implementation of Permissions Service
*
*/
public class PermissionServiceNOOPImpl
implements PermissionServiceSPI
{
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#getOwnerAuthority()
*/
public String getOwnerAuthority()
{
return OWNER_AUTHORITY;
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#getAllAuthorities()
*/
public String getAllAuthorities()
{
return ALL_AUTHORITIES;
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#getAllPermission()
*/
public String getAllPermission()
{
return ALL_PERMISSIONS;
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#getPermissions(org.alfresco.service.cmr.repository.NodeRef)
*/
public Set<AccessPermission> getPermissions(NodeRef nodeRef)
{
return null;
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#getAllPermissions(org.alfresco.service.cmr.repository.NodeRef)
*/
public Set<AccessPermission> getAllSetPermissions(NodeRef nodeRef)
{
return null;
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#getSettablePermissions(org.alfresco.service.cmr.repository.NodeRef)
*/
public Set<String> getSettablePermissions(NodeRef nodeRef)
{
return getSettablePermissions((QName)null);
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#getSettablePermissions(org.alfresco.service.namespace.QName)
*/
public Set<String> getSettablePermissions(QName type)
{
HashSet<String> permissions = new HashSet<String>();
permissions.add(ALL_PERMISSIONS);
return permissions;
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#hasPermission(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.repo.security.permissions.PermissionReference)
*/
public AccessStatus hasPermission(NodeRef nodeRef, String perm)
{
return AccessStatus.ALLOWED;
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#deletePermissions(org.alfresco.service.cmr.repository.NodeRef)
*/
public void deletePermissions(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#deletePermission(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.repo.security.permissions.PermissionReference, boolean)
*/
public void deletePermission(NodeRef nodeRef, String authority, String perm, boolean allow)
{
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#setPermission(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.repo.security.permissions.PermissionReference, boolean)
*/
public void setPermission(NodeRef nodeRef, String authority, String perm, boolean allow)
{
}
/* (non-Javadoc)
* @see org.alfresco.repo.security.permissions.PermissionService#setInheritParentPermissions(org.alfresco.service.cmr.repository.NodeRef, boolean)
*/
public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.security.PermissionService#getInheritParentPermissions(org.alfresco.service.cmr.repository.NodeRef)
*/
public boolean getInheritParentPermissions(NodeRef nodeRef)
{
// TODO Auto-generated method stub
return true;
}
public void clearPermission(NodeRef nodeRef, String authority)
{
}
// SPI
public void deletePermission(PermissionEntry permissionEntry)
{
}
public void deletePermissions(NodePermissionEntry nodePermissionEntry)
{
}
public void deletePermissions(String recipient)
{
}
public NodePermissionEntry explainPermission(NodeRef nodeRef, PermissionReference perm)
{
throw new UnsupportedOperationException();
}
public PermissionReference getAllPermissionReference()
{
throw new UnsupportedOperationException();
}
public String getPermission(PermissionReference permissionReference)
{
throw new UnsupportedOperationException();
}
public PermissionReference getPermissionReference(QName qname, String permissionName)
{
throw new UnsupportedOperationException();
}
public PermissionReference getPermissionReference(String permissionName)
{
throw new UnsupportedOperationException();
}
public NodePermissionEntry getSetPermissions(NodeRef nodeRef)
{
throw new UnsupportedOperationException();
}
public Set<PermissionReference> getSettablePermissionReferences(NodeRef nodeRef)
{
throw new UnsupportedOperationException();
}
public Set<PermissionReference> getSettablePermissionReferences(QName type)
{
throw new UnsupportedOperationException();
}
public AccessStatus hasPermission(NodeRef nodeRef, PermissionReference perm)
{
throw new UnsupportedOperationException();
}
public void setPermission(NodePermissionEntry nodePermissionEntry)
{
throw new UnsupportedOperationException();
}
public void setPermission(PermissionEntry permissionEntry)
{
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.person;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* All exceptions related to the person service.
*
* @author Andy Hind
*/
public class PersonException extends AlfrescoRuntimeException
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 2802163127696444600L;
public PersonException(String msgId)
{
super(msgId);
}
public PersonException(String msgId, Object[] msgParams)
{
super(msgId, msgParams);
}
public PersonException(String msgId, Throwable cause)
{
super(msgId, cause);
}
public PersonException(String msgId, Object[] msgParams, Throwable cause)
{
super(msgId, msgParams, cause);
}
}

View File

@@ -0,0 +1,323 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.person;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.search.QueryParameterDefImpl;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.search.QueryParameterDefinition;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
public class PersonServiceImpl implements PersonService
{
public static final String SYSTEM_FOLDER = "/sys:system";
public static final String PEOPLE_FOLDER = SYSTEM_FOLDER + "/sys:people";
// IOC
private StoreRef storeRef;
private NodeService nodeService;
private DictionaryService dictionaryService;
private SearchService searchService;
private NamespacePrefixResolver namespacePrefixResolver;
private boolean createMissingPeople;
private boolean userNamesAreCaseSensitive;
private String companyHomePath;
private NodeRef companyHomeNodeRef;
private static Set<QName> mutableProperties;
static
{
Set<QName> props = new HashSet<QName>();
props.add(ContentModel.PROP_HOMEFOLDER);
props.add(ContentModel.PROP_FIRSTNAME);
// Middle Name
props.add(ContentModel.PROP_LASTNAME);
props.add(ContentModel.PROP_EMAIL);
props.add(ContentModel.PROP_ORGID);
mutableProperties = Collections.unmodifiableSet(props);
}
public PersonServiceImpl()
{
super();
}
public boolean getUserNamesAreCaseSensitive()
{
return userNamesAreCaseSensitive;
}
public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive)
{
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
}
public NodeRef getPerson(String caseSensitiveUserName)
{
String userName = userNamesAreCaseSensitive ? caseSensitiveUserName : caseSensitiveUserName.toLowerCase();
NodeRef personNode = getPersonOrNull(userName);
if (personNode == null)
{
if (createMissingPeople())
{
return createMissingPerson(userName);
}
else
{
throw new PersonException("No person found for user name " + userName);
}
}
else
{
return personNode;
}
}
public boolean personExists(String caseSensitiveUserName)
{
return getPersonOrNull(caseSensitiveUserName) != null;
}
public NodeRef getPersonOrNull(String caseSensitiveUserName)
{
String userName = userNamesAreCaseSensitive ? caseSensitiveUserName : caseSensitiveUserName.toLowerCase();
NodeRef rootNode = nodeService.getRootNode(storeRef);
QueryParameterDefinition[] defs = new QueryParameterDefinition[1];
DataTypeDefinition text = dictionaryService.getDataType(DataTypeDefinition.TEXT);
defs[0] = new QueryParameterDefImpl(QName.createQName("cm", "var", namespacePrefixResolver), text, true,
userName);
List<NodeRef> results = searchService.selectNodes(rootNode, PEOPLE_FOLDER
+ "/cm:person[@cm:userName = $cm:var ]", defs, namespacePrefixResolver, false);
if (results.size() != 1)
{
return null;
}
return results.get(0);
}
public boolean createMissingPeople()
{
return createMissingPeople;
}
public Set<QName> getMutableProperties()
{
return mutableProperties;
}
public void setPersonProperties(String caseSensitiveUserName, Map<QName, Serializable> properties)
{
String userName = userNamesAreCaseSensitive ? caseSensitiveUserName : caseSensitiveUserName.toLowerCase();
NodeRef personNode = getPersonOrNull(userName);
if (personNode == null)
{
if (createMissingPeople())
{
personNode = createMissingPerson(userName);
}
else
{
throw new PersonException("No person found for user name " + userName);
}
}
properties.put(ContentModel.PROP_USERNAME, userName);
nodeService.setProperties(personNode, properties);
}
public boolean isMutable()
{
return true;
}
private NodeRef createMissingPerson(String userName)
{
HashMap<QName, Serializable> properties = getDefaultProperties(userName);
return createPerson(properties);
}
private HashMap<QName, Serializable> getDefaultProperties(String userName)
{
HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME, userName);
properties.put(ContentModel.PROP_HOMEFOLDER, getCompanyHome());
properties.put(ContentModel.PROP_FIRSTNAME, userName);
properties.put(ContentModel.PROP_LASTNAME, "");
properties.put(ContentModel.PROP_EMAIL, "");
properties.put(ContentModel.PROP_ORGID, "");
return properties;
}
public NodeRef createPerson(Map<QName, Serializable> properties)
{
String caseSensitiveUserName = DefaultTypeConverter.INSTANCE.convert(String.class, properties
.get(ContentModel.PROP_USERNAME));
String userName = userNamesAreCaseSensitive ? caseSensitiveUserName : caseSensitiveUserName.toLowerCase();
properties.put(ContentModel.PROP_USERNAME, userName);
return nodeService.createNode(getPeopleContainer(), ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_PERSON,
ContentModel.TYPE_PERSON, properties).getChildRef();
}
public NodeRef getPeopleContainer()
{
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
List<NodeRef> results = searchService.selectNodes(rootNodeRef, PEOPLE_FOLDER, null, namespacePrefixResolver,
false);
NodeRef typesNode = null;
if (results.size() == 0)
{
List<ChildAssociationRef> result = nodeService.getChildAssocs(rootNodeRef, RegexQNamePattern.MATCH_ALL,
QName.createQName("sys", "system", namespacePrefixResolver));
NodeRef sysNode = null;
if (result.size() == 0)
{
sysNode = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN,
QName.createQName("sys", "system", namespacePrefixResolver), ContentModel.TYPE_CONTAINER)
.getChildRef();
}
else
{
sysNode = result.get(0).getChildRef();
}
result = nodeService.getChildAssocs(sysNode, RegexQNamePattern.MATCH_ALL, QName.createQName("sys",
"people", namespacePrefixResolver));
if (result.size() == 0)
{
typesNode = nodeService.createNode(sysNode, ContentModel.ASSOC_CHILDREN,
QName.createQName("sys", "people", namespacePrefixResolver), ContentModel.TYPE_CONTAINER)
.getChildRef();
return typesNode;
}
else
{
return result.get(0).getChildRef();
}
}
else
{
return results.get(0);
}
}
public void deletePerson(String userName)
{
NodeRef personNodeRef = getPersonOrNull(userName);
if (personNodeRef != null)
{
nodeService.deleteNode(personNodeRef);
}
}
public Set<NodeRef> getAllPeople()
{
NodeRef rootNode = nodeService.getRootNode(storeRef);
List<NodeRef> results = searchService.selectNodes(rootNode, PEOPLE_FOLDER + "/cm:person", null,
namespacePrefixResolver, false);
HashSet<NodeRef> all = new HashSet<NodeRef>();
all.addAll(results);
return all;
}
public void setCreateMissingPeople(boolean createMissingPeople)
{
this.createMissingPeople = createMissingPeople;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver)
{
this.namespacePrefixResolver = namespacePrefixResolver;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
public void setStoreUrl(String storeUrl)
{
this.storeRef = new StoreRef(storeUrl);
}
public void setCompanyHomePath(String companyHomePath)
{
this.companyHomePath = companyHomePath;
}
public synchronized NodeRef getCompanyHome()
{
if (companyHomeNodeRef == null)
{
List<NodeRef> refs = searchService.selectNodes(nodeService.getRootNode(storeRef), companyHomePath, null,
namespacePrefixResolver, false);
if (refs.size() != 1)
{
throw new IllegalStateException("Invalid company home path: found : " + refs.size());
}
companyHomeNodeRef = refs.get(0);
}
return companyHomeNodeRef;
}
// IOC Setters
}

View File

@@ -0,0 +1,258 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.security.person;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseSpringTest;
public class PersonTest extends BaseSpringTest
{
private PersonService personService;
private NodeService nodeService;
private NodeRef rootNodeRef;
public PersonTest()
{
super();
// TODO Auto-generated constructor stub
}
protected void onSetUpInTransaction() throws Exception
{
personService = (PersonService) applicationContext.getBean("personService");
nodeService = (NodeService) applicationContext.getBean("nodeService");
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef);
for(NodeRef nodeRef: personService.getAllPeople())
{
nodeService.deleteNode(nodeRef);
}
}
protected void onTearDownInTransaction()
{
super.onTearDownInTransaction();
flushAndClear();
}
public void testCreateMissingPeople()
{
personService.setCreateMissingPeople(false);
assertFalse(personService.createMissingPeople());
personService.setCreateMissingPeople(true);
assertTrue(personService.createMissingPeople());
personService.setCreateMissingPeople(false);
try
{
personService.getPerson("andy");
assertNotNull(null);
}
catch (PersonException pe)
{
}
personService.setCreateMissingPeople(true);
NodeRef nodeRef = personService.getPerson("andy");
assertNotNull(nodeRef);
testProperties(nodeRef, "andy", "andy", "", "", "");
personService.setCreateMissingPeople(false);
try
{
personService.setPersonProperties("derek", createDefaultProperties("derek", "Derek", "Hulley", "dh@dh",
"alfresco", rootNodeRef));
assertNotNull(null);
}
catch (PersonException pe)
{
}
personService.setCreateMissingPeople(true);
personService.setPersonProperties("derek", createDefaultProperties("derek", "Derek", "Hulley", "dh@dh",
"alfresco", rootNodeRef));
testProperties(personService.getPerson("derek"), "derek", "Derek", "Hulley", "dh@dh", "alfresco");
testProperties(personService.getPerson("andy"), "andy", "andy", "", "", "");
assertEquals(2, personService.getAllPeople().size());
assertTrue(personService.getAllPeople().contains(personService.getPerson("andy")));
assertTrue(personService.getAllPeople().contains(personService.getPerson("derek")));
setComplete();
endTransaction();
}
public void testMutableProperties()
{
assertEquals(5, personService.getMutableProperties().size());
assertTrue(personService.getMutableProperties().contains(ContentModel.PROP_HOMEFOLDER));
assertTrue(personService.getMutableProperties().contains(ContentModel.PROP_FIRSTNAME));
assertTrue(personService.getMutableProperties().contains(ContentModel.PROP_LASTNAME));
assertTrue(personService.getMutableProperties().contains(ContentModel.PROP_EMAIL));
assertTrue(personService.getMutableProperties().contains(ContentModel.PROP_ORGID));
setComplete();
endTransaction();
}
public void testPersonCRUD()
{
personService.setCreateMissingPeople(false);
try
{
personService.getPerson("derek");
assertNotNull(null);
}
catch (PersonException pe)
{
}
personService.setCreateMissingPeople(false);
personService.createPerson(createDefaultProperties("derek", "Derek", "Hulley", "dh@dh",
"alfresco", rootNodeRef));
testProperties(personService.getPerson("derek"), "derek", "Derek", "Hulley", "dh@dh", "alfresco");
personService.setPersonProperties("derek", createDefaultProperties("derek", "Derek_", "Hulley_", "dh@dh_",
"alfresco_", rootNodeRef));
testProperties(personService.getPerson("derek"), "derek", "Derek_", "Hulley_", "dh@dh_", "alfresco_");
personService.setPersonProperties("derek", createDefaultProperties("derek", "Derek", "Hulley", "dh@dh",
"alfresco", rootNodeRef));
testProperties(personService.getPerson("derek"), "derek", "Derek", "Hulley", "dh@dh", "alfresco");
assertEquals(1, personService.getAllPeople().size());
assertTrue(personService.getAllPeople().contains(personService.getPerson("derek")));
personService.deletePerson("derek");
assertEquals(0, personService.getAllPeople().size());
try
{
personService.getPerson("derek");
assertNotNull(null);
}
catch (PersonException pe)
{
}
setComplete();
endTransaction();
}
private void testProperties(NodeRef nodeRef, String userName, String firstName, String lastName, String email,
String orgId)
{
assertEquals(userName, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
ContentModel.PROP_USERNAME)));
assertNotNull(nodeService.getProperty(nodeRef, ContentModel.PROP_HOMEFOLDER));
assertEquals(firstName, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
ContentModel.PROP_FIRSTNAME)));
assertEquals(lastName, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
ContentModel.PROP_LASTNAME)));
assertEquals(email, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
ContentModel.PROP_EMAIL)));
assertEquals(orgId, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
ContentModel.PROP_ORGID)));
}
private Map<QName, Serializable> createDefaultProperties(String userName, String firstName, String lastName,
String email, String orgId, NodeRef home)
{
HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME, userName);
properties.put(ContentModel.PROP_HOMEFOLDER, home);
properties.put(ContentModel.PROP_FIRSTNAME, firstName);
properties.put(ContentModel.PROP_LASTNAME, lastName);
properties.put(ContentModel.PROP_EMAIL, email);
properties.put(ContentModel.PROP_ORGID, orgId);
return properties;
}
public void testCaseSensitive()
{
if(personService.getUserNamesAreCaseSensitive())
{
personService.createPerson(createDefaultProperties("Derek", "Derek", "Hulley", "dh@dh",
"alfresco", rootNodeRef));
try
{
personService.getPerson("derek");
assertNotNull(null);
}
catch (PersonException pe)
{
}
try
{
personService.getPerson("deRek");
assertNotNull(null);
}
catch (PersonException pe)
{
}
try
{
personService.getPerson("DEREK");
assertNotNull(null);
}
catch (PersonException pe)
{
}
personService.getPerson("Derek");
}
}
public void testCaseInsensitive()
{
if(!personService.getUserNamesAreCaseSensitive())
{
personService.createPerson(createDefaultProperties("Derek", "Derek", "Hulley", "dh@dh",
"alfresco", rootNodeRef));
personService.getPerson("derek");
personService.getPerson("deRek");
personService.getPerson("Derek");
personService.getPerson("DEREK");
}
}
}