You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2008/03/19 14:57:11 UTC
svn commit: r638834 [8/14] - in /jackrabbit/trunk:
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/principal/
jackr...
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalIterator.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalIterator.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalIterator.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
+
+import java.security.Principal;
+import java.util.NoSuchElementException;
+
+/**
+ * Lazy implementation of the <code>PrincipalIterator</code> that allows to
+ * avoid determing all elements of the iteration beforehand.
+ * NOTE: Subclasses must call {#link seekNext()}
+ * upon object construction and assign the value to the 'next' field.
+ */
+abstract class AbstractPrincipalIterator implements PrincipalIterator {
+
+ private static Logger log = LoggerFactory.getLogger(AbstractPrincipalIterator.class);
+
+ long size;
+ long position;
+ Principal next;
+
+ AbstractPrincipalIterator() {
+ size = -1;
+ position = 0;
+ }
+
+ /**
+ * Subclasses must call {#link seekNext()} upon object construction and
+ * assign the value to the 'next' field.
+ */
+ abstract Principal seekNext();
+
+ //--------------------------------------------------< PrincipalIterator >---
+ public Principal nextPrincipal() {
+ Principal p = next;
+ if (p == null) {
+ throw new NoSuchElementException();
+ }
+ next = seekNext();
+ position++;
+ return p;
+ }
+
+ //------------------------------------------------------< RangeIterator >---
+ public void skip(long skipNum) {
+ while (skipNum-- > 0) {
+ next();
+ }
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ public long getPosition() {
+ return position;
+ }
+
+ //-----------------------------------------------------------< Iterator >---
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ public Object next() {
+ return nextPrincipal();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalIterator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalIterator.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import org.apache.commons.collections.map.LRUMap;
+
+import java.security.Principal;
+import java.util.Properties;
+
+/**
+ * A base class of a principal provider implementing common tasks and a
+ * caching facility. Extending classes should only deal with the retrieval of
+ * {@link Principal}s from their source, the caching of the principials is done
+ * by this implementation.
+ * <p/>
+ * The {@link PrincipalProvider} mehtods that that involve searching like
+ * {@link PrincipalProvider#getGroupMembership(Principal)} are not cached.
+ */
+public abstract class AbstractPrincipalProvider implements PrincipalProvider {
+
+ /** Option name for the max size of the cache to use */
+ public static final String MAXSIZE_KEY = "cacheMaxSize";
+
+ /** flag indicating if the instance has not been {@link #close() closed} */
+ private boolean initialized;
+
+ /** the principal cache */
+ private LRUMap cache;
+
+ /**
+ * Create a new instance of <code>AbstractPrincipalProvider</code>.
+ * Initialization and cache are set up upon {@link #init(Properties)}
+ */
+ protected AbstractPrincipalProvider() {
+ }
+
+ /**
+ * Check if the instance has been closed {@link #close()}.
+ *
+ * @throws IllegalStateException if this instance was closed.
+ */
+ protected void checkInitialized() {
+ if (!initialized) {
+ throw new IllegalStateException("Not initialized.");
+ }
+ }
+
+ /**
+ * Clear the principal cache.
+ */
+ protected synchronized void clearCache() {
+ cache.clear();
+ }
+
+ /**
+ * Called if the cache does not contain the principal requested.<br>
+ * Implementations should return a {@link Principal} from their source,
+ * if it contains one for the given name or <code>null</code>.
+ *
+ * @param principalName
+ * @return Principal or null, if non provided for the given name
+ * @see #getPrincipal(String)
+ */
+ protected abstract Principal providePrincipal(String principalName);
+
+ //--------------------------------------------------< PrincipalProvider >---
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasPrincipal(String principalName) {
+ return getPrincipal(principalName) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * {@link #providePrincipal(String)} is called, if no principal with the
+ * given name is present in the cache.
+ */
+ public synchronized Principal getPrincipal(String principalName) {
+ checkInitialized();
+ Principal principal = (Principal) cache.get(principalName);
+ if (principal == null) {
+ principal = providePrincipal(principalName);
+ if (principal != null) {
+ cache.put(principalName, principal);
+ }
+ }
+ return principal;
+ }
+
+ /**
+ * @see PrincipalProvider#init(java.util.Properties)
+ */
+ public synchronized void init(Properties options) {
+ if (initialized) {
+ throw new IllegalStateException("already initialized");
+ }
+
+ int maxSize = Integer.parseInt(options.getProperty(MAXSIZE_KEY, "1000"));
+ cache = new LRUMap(maxSize);
+
+ initialized = true;
+ }
+
+ /**
+ * Clears the cache and calls the implementation to close their resources
+ * @see PrincipalProvider#close()
+ */
+ public synchronized void close() {
+ checkInitialized();
+ cache.clear();
+ initialized = false;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AbstractPrincipalProvider.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AdminPrincipal.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AdminPrincipal.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AdminPrincipal.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AdminPrincipal.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+/**
+ * This principal represents the admin user as a distinct principal having all
+ * the access rights and is being authenticated (in contrast to the
+ * {@link org.apache.jackrabbit.core.security.SystemPrincipal SystemPrincipal}).
+ */
+public final class AdminPrincipal implements JackrabbitPrincipal {
+
+ private final String adminId;
+
+ public AdminPrincipal(String adminId) {
+ if (adminId == null) {
+ throw new IllegalArgumentException("name can not be null");
+ }
+ this.adminId = adminId;
+ }
+
+ public String getName() {
+ return adminId;
+ }
+
+ public int hashCode() {
+ return adminId.hashCode();
+ }
+
+ public boolean equals(Object obj) {
+ return obj == this || obj instanceof AdminPrincipal;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AdminPrincipal.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/AdminPrincipal.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,342 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.commons.collections.map.LRUMap;
+import org.apache.commons.collections.set.ListOrderedSet;
+import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.core.security.user.UserManagerImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Provides principals for the users contained within the Repository.<p/>
+ * Each {@link Authorizable} accessible via {@link UserManager}
+ * is respected and the provider serves {@link Authorizable#getPrincipal()
+ * Principal}s retrieved from those <code>Authorizable</code> objects.
+ * <p/>
+ * In addition this provider exposes the <i>everyone</i> principal, which has no
+ * content (user/group) represention.
+ */
+public class DefaultPrincipalProvider extends AbstractPrincipalProvider implements EventListener {
+
+ /**
+ * the default logger
+ */
+ private static Logger log = LoggerFactory.getLogger(DefaultPrincipalProvider.class);
+
+ /**
+ * a cache for group memberships: maps principal-name to a set of principals
+ * representing the members.
+ */
+ private final LRUMap membershipCache;
+
+ /**
+ * Principal-Base of this Provider
+ */
+ private final UserManagerImpl userManager;
+
+ private final EveryonePrincipal everyonePrincipal;
+
+ /**
+ * Creates a new DefaultPrincipalProvider reading the principals from the
+ * storage below the given security root node.
+ *
+ * @param securitySession for Repository Access
+ * @throws RepositoryException if an error accessing the repository occurs.
+ */
+ public DefaultPrincipalProvider(Session securitySession,
+ UserManagerImpl userManager) throws RepositoryException {
+
+ this.userManager = userManager;
+ everyonePrincipal = EveryonePrincipal.getInstance();
+ membershipCache = new LRUMap();
+
+ // listen to any modifications for users and groups
+ securitySession.getWorkspace().getObservationManager().addEventListener(this,
+ Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED,
+ UserManagerImpl.SECURITY_ROOT_PATH,
+ true,
+ null,
+ null,
+ false);
+ }
+
+ //------------------------------------------< AbstractPrincipalProvider >---
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * This implementation uses the user and node resolver to find the
+ * appropriate nodes.
+ */
+ protected Principal providePrincipal(String principalName) {
+ // check for 'everyone'
+ if (everyonePrincipal.getName().equals(principalName)) {
+ return everyonePrincipal;
+ }
+ try {
+ Principal principal = new PrincipalImpl(principalName);
+ Authorizable ath = userManager.getAuthorizable(principal);
+ if (ath != null) {
+ return ath.getPrincipal();
+ }
+ } catch (RepositoryException e) {
+ log.error("Failed to access Authorizable for Principal " + principalName, e);
+ }
+ return null;
+ }
+
+ //--------------------------------------------------< PrincipalProvider >---
+ /**
+ * @see PrincipalProvider#findPrincipals(String)
+ */
+ public PrincipalIterator findPrincipals(String simpleFilter) {
+ return findPrincipals(simpleFilter, PrincipalManager.SEARCH_TYPE_ALL);
+ }
+
+ /**
+ * @see PrincipalProvider#findPrincipals(String, int)
+ */
+ public PrincipalIterator findPrincipals(String simpleFilter, int searchType) {
+ checkInitialized();
+ switch (searchType) {
+ case PrincipalManager.SEARCH_TYPE_GROUP:
+ return findGroupPrincipals(simpleFilter);
+ case PrincipalManager.SEARCH_TYPE_NOT_GROUP:
+ return findUserPrincipals(simpleFilter);
+ case PrincipalManager.SEARCH_TYPE_ALL:
+ PrincipalIterator[] its = new PrincipalIterator[] {
+ findUserPrincipals(simpleFilter),
+ findGroupPrincipals(simpleFilter)
+ };
+ return new PrincipalIteratorAdapter(new IteratorChain(its));
+ default:
+ throw new IllegalArgumentException("Invalid searchType");
+ }
+ }
+
+ /**
+ * @see PrincipalProvider#getPrincipals(int)
+ * @param searchType
+ */
+ public PrincipalIterator getPrincipals(int searchType) {
+ return findPrincipals("", searchType);
+ }
+
+ /**
+ * @see PrincipalProvider#getGroupMembership(Principal)
+ */
+ public PrincipalIterator getGroupMembership(Principal userPrincipal) {
+ checkInitialized();
+ Set mship;
+ synchronized (membershipCache) {
+ mship = (Set) membershipCache.get(userPrincipal.getName());
+ if (mship == null) {
+ mship = new ListOrderedSet();
+ // recursively collect group membership
+ collectGroupMembership(userPrincipal, mship);
+
+ // make sure everyone-group is not missing
+ if (!mship.contains(everyonePrincipal) && everyonePrincipal.isMember(userPrincipal)) {
+ mship.add(everyonePrincipal);
+ }
+ membershipCache.put(userPrincipal.getName(), mship);
+ }
+ }
+ return new PrincipalIteratorAdapter(mship);
+
+ }
+
+ /**
+ * @see PrincipalProvider#close()
+ */
+ public synchronized void close() {
+ super.close();
+ membershipCache.clear();
+ }
+
+ /**
+ * Always returns true.
+ *
+ * @see PrincipalProvider#canReadPrincipal(javax.jcr.Session,java.security.Principal)
+ */
+ public boolean canReadPrincipal(Session session, Principal principal) {
+ checkInitialized();
+ // by default (UserAccessControlProvider) READ-privilege is granted to
+ // everybody -> omit any (expensive) checks.
+ return true;
+ /*
+ // TODO: uncomment code if it turns out that the previous assumption is problematic.
+ // check if the session is granted read to the node.
+ if (session instanceof SessionImpl) {
+ SessionImpl sImpl = (SessionImpl) session;
+ Subject subject = sImpl.getSubject();
+ if (!subject.getPrincipals(SystemPrincipal.class).isEmpty()
+ || !subject.getPrincipals(AdminPrincipal.class).isEmpty()) {
+ return true;
+ }
+ try {
+ UserManager umgr = ((SessionImpl)session).getUserManager();
+ return umgr.getAuthorizable(principal) != null;
+ } catch (RepositoryException e) {
+ // ignore and return false
+ }
+ }
+ return false;
+ */
+ }
+
+ //------------------------------------------------------< EventListener >---
+ /**
+ * @see EventListener#onEvent(EventIterator)
+ */
+ public void onEvent(EventIterator eventIterator) {
+ // simple rule: flush all cached
+ clearCache();
+ synchronized (membershipCache) {
+ membershipCache.clear();
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * Recursively collect all Group-principals the specified principal is
+ * member of.
+ *
+ * @param princ
+ * @return all Group principals the specified <code>princ</code> is member of
+ * including inherited membership.
+ */
+ private Set collectGroupMembership(Principal princ, Set membership) {
+ String princName = princ.getName();
+ if (!hasPrincipal(princName)) {
+ return Collections.EMPTY_SET;
+ }
+ try {
+ Authorizable auth = userManager.getAuthorizable(princ);
+ if (auth != null) {
+ Iterator itr = auth.memberOf();
+ while (itr.hasNext()) {
+ Group group = (Group) itr.next();
+ Principal groupPrinc = group.getPrincipal();
+ if (membership.add(groupPrinc)) {
+ membership.addAll(collectGroupMembership(groupPrinc, membership));
+ } else {
+ String msg = "Cyclic group membership detected with Group " + groupPrinc.getName();
+ log.error(msg);
+ }
+ }
+ } else {
+ log.debug("Cannot find authorizable for principal " + princ.getName());
+ }
+ } catch (RepositoryException e) {
+ log.warn("Failed to determine membership for " + princName, e.getMessage());
+ }
+ return membership;
+ }
+
+ /**
+ * @param simpleFilter
+ * @return An iterator over the main principals of the authorizables found
+ * by the user manager.
+ */
+ private PrincipalIterator findUserPrincipals(String simpleFilter) {
+ synchronized (userManager) {
+ try {
+ Iterator itr = userManager.findUsers(simpleFilter);
+ return new PrincipalIteratorImpl(itr, false);
+ } catch (RepositoryException e) {
+ log.error("Error while searching user principals.", e);
+ return PrincipalIteratorAdapter.EMPTY;
+ }
+ }
+ }
+
+ /**
+ * @param simpleFilter
+ * @return An iterator over the main principals of the authorizables found
+ * by the user manager.
+ */
+ private PrincipalIterator findGroupPrincipals(final String simpleFilter) {
+ synchronized (userManager) {
+ try {
+ Iterator itr = userManager.findGroups(simpleFilter);
+
+ // everyone will not be found by the usermanager -> extra test
+ boolean addEveryone = everyonePrincipal.getName().matches(".*"+simpleFilter+".*");
+ return new PrincipalIteratorImpl(itr, addEveryone);
+
+ } catch (RepositoryException e) {
+ log.error("Error while searching group principals.", e);
+ return PrincipalIteratorAdapter.EMPTY;
+ }
+ }
+ }
+
+ //--------------------------------------------------------< inner class >---
+ /**
+ * Extension of AbstractPrincipalIterator that retrieves the next
+ * principal from the iterator over authorizables by calling
+ * {@link Authorizable#getPrincipal()}.
+ */
+ private class PrincipalIteratorImpl extends AbstractPrincipalIterator {
+
+ private final Iterator authorizableItr;
+ private boolean addEveryone;
+
+ private PrincipalIteratorImpl(Iterator authorizableItr, boolean addEveryone) {
+ this.authorizableItr = authorizableItr;
+ this.addEveryone = addEveryone;
+
+ next = seekNext();
+ }
+
+ protected Principal seekNext() {
+ while (authorizableItr.hasNext()) {
+ try {
+ return ((Authorizable) authorizableItr.next()).getPrincipal();
+ } catch (RepositoryException e) {
+ // should never get here
+ log.warn("Error while retrieving principal from group -> skip.");
+ }
+ }
+
+ if (addEveryone) {
+ addEveryone = false; // make sure iteration stops
+ return everyonePrincipal;
+ } else {
+ // end of iteration reached
+ return null;
+ }
+ }
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import java.security.Principal;
+import java.util.Enumeration;
+
+/**
+ * The EveryonePrincipal contains all principals (excluding itself).
+ */
+public final class EveryonePrincipal implements java.security.acl.Group {
+
+ private static final String NAME = "everyone";
+ private static final EveryonePrincipal INSTANCE = new EveryonePrincipal();
+
+ private EveryonePrincipal() {}
+
+ public static EveryonePrincipal getInstance() {
+ return INSTANCE;
+ }
+
+ //----------------------------------------------------------< Principal >---
+ public String getName() {
+ return NAME;
+ }
+
+ //--------------------------------------------------------------< Group >---
+ public boolean addMember(Principal user) {
+ return false;
+ }
+
+ public boolean removeMember(Principal user) {
+ throw new UnsupportedOperationException("Cannot remove a member from the everyone group.");
+ }
+
+ public boolean isMember(Principal member) {
+ return !member.equals(this);
+ }
+
+ public Enumeration members() {
+ throw new UnsupportedOperationException("Not implemented.");
+ }
+
+ //-------------------------------------------------------------< Object >---
+
+ public int hashCode() {
+ return NAME.hashCode();
+ }
+
+ public boolean equals(Object obj) {
+ return obj == this || obj instanceof EveryonePrincipal;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import javax.jcr.RepositoryException;
+import java.security.Principal;
+
+/**
+ * <code>ItemBasedPrincipal</code> is a <code>Principal</code> that is
+ * persisted as item within the repository. In addition to the methods
+ * inherited from the {@link Principal} interface it therefore provides
+ * a {@link #getPath()} method.
+ */
+public interface ItemBasedPrincipal extends JackrabbitPrincipal {
+
+ /**
+ * @return the path of the {@link javax.jcr.Item} that represents this
+ * <code>Principal</code>.
+ * @throws RepositoryException If an error occurs while retrieving the
+ * <code>Item</code> path.
+ */
+ String getPath() throws RepositoryException;
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/JackrabbitPrincipal.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/JackrabbitPrincipal.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/JackrabbitPrincipal.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/JackrabbitPrincipal.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import java.security.Principal;
+
+/**
+ * <code>JackrabbitPrincipal</code>
+ * Marks the principal to be the result of authentication against the repository.
+ */
+public interface JackrabbitPrincipal extends Principal {
+
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/JackrabbitPrincipal.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/JackrabbitPrincipal.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalImpl.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalImpl.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import java.io.Serializable;
+import java.security.Principal;
+
+/**
+ * Base class for implementations of <code>JackrabbitPrincipal</code>.
+ */
+public class PrincipalImpl implements JackrabbitPrincipal, Serializable {
+
+ /** the serial number */
+ private static final long serialVersionUID = 384040549033267804L;
+
+ /**
+ * the name of this principal
+ */
+ private final String name;
+
+
+ /**
+ * Creates a new principal with the given name.
+ *
+ * @param name the name of this principal
+ */
+ public PrincipalImpl(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("name can not be null");
+ }
+ this.name = name;
+ }
+
+ //----------------------------------------------------------< Principal >---
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ return name;
+ }
+
+ //-------------------------------------------------------------< Object >---
+ /**
+ * Two principals are equal, if their names are.
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof JackrabbitPrincipal) {
+ // TODO: check if correct
+ return name.equals(((Principal) obj).getName());
+ }
+ return false;
+ }
+
+ /**
+ * @return the hash code of the principals name.
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString() {
+ return getClass().getName() + ":" + name;
+ }
+}
+
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalImpl.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalIteratorAdapter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalIteratorAdapter.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalIteratorAdapter.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalIteratorAdapter.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
+import org.apache.jackrabbit.commons.iterator.RangeIteratorDecorator;
+import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
+
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * <code>PrincipalIteratorAdapter</code>...
+ */
+public class PrincipalIteratorAdapter extends RangeIteratorDecorator
+ implements PrincipalIterator {
+
+ /**
+ * Static instance of an empty {@link PrincipalIterator}.
+ */
+ public static final PrincipalIteratorAdapter EMPTY = new PrincipalIteratorAdapter(RangeIteratorAdapter.EMPTY);
+
+
+ /**
+ * Creates an adapter for the given {@link Iterator} of principals.
+ *
+ * @param iterator iterator of {@link Principal}s
+ */
+ public PrincipalIteratorAdapter(Iterator iterator) {
+ super(new RangeIteratorAdapter(iterator));
+ }
+
+ /**
+ * Creates an iterator for the given collection of <code>Principal</code>s.
+ *
+ * @param collection collection of {@link Principal} objects.
+ */
+ public PrincipalIteratorAdapter(Collection collection) {
+ super(new RangeIteratorAdapter(collection));
+ }
+
+ //----------------------------------------< AccessControlPolicyIterator >---
+ /**
+ * Returns the next policy.
+ *
+ * @return next policy.
+ * @throws NoSuchElementException if there is no next policy.
+ */
+ public Principal nextPrincipal() throws NoSuchElementException {
+ return (Principal) next();
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalIteratorAdapter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalIteratorAdapter.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalManagerImpl.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalManagerImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalManagerImpl.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import org.apache.jackrabbit.api.security.principal.NoSuchPrincipalException;
+import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This principal manager implementation uses the {@link DefaultPrincipalProvider}
+ * in order to dispatch the respective requests and assemble the required
+ * data. It is bound to a session and therefore obliges the access restrictions
+ * of the respective subject.
+ */
+public class PrincipalManagerImpl implements PrincipalManager {
+
+ /** the Session this manager has been created for*/
+ private final Session session;
+
+ /** the principalProviders */
+ private final PrincipalProvider[] providers;
+
+ private boolean closed;
+
+ /**
+ * Creates a new default principal manager implementation.
+ *
+ * @param session
+ * @param providers
+ */
+ public PrincipalManagerImpl(Session session, PrincipalProvider[] providers) {
+ this.session = session;
+ this.providers = providers;
+ closed = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasPrincipal(String principalName) {
+ return internalGetPrincipal(principalName) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Principal getPrincipal(String principalName) throws NoSuchPrincipalException {
+ Principal p = internalGetPrincipal(principalName);
+ if (p == null) {
+ // not found (or access denied)
+ throw new NoSuchPrincipalException("Unknown principal " + principalName);
+ } else {
+ return p;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PrincipalIterator findPrincipals(String simpleFilter) {
+ checkIsValid();
+ List entries = new ArrayList(providers.length);
+ for (int i = 0; i < providers.length; i++) {
+ PrincipalProvider pp = providers[i];
+ PrincipalIterator it = pp.findPrincipals(simpleFilter);
+ if (it.hasNext()) {
+ entries.add(new CheckedIteratorEntry(it, pp));
+ }
+ }
+ return new CheckedPrincipalIterator(entries);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PrincipalIterator findPrincipals(String simpleFilter, int searchType) {
+ checkIsValid();
+ List entries = new ArrayList(providers.length);
+ for (int i = 0; i < providers.length; i++) {
+ PrincipalProvider pp = providers[i];
+ PrincipalIterator it = pp.findPrincipals(simpleFilter, searchType);
+ if (it.hasNext()) {
+ entries.add(new CheckedIteratorEntry(it, pp));
+ }
+ }
+ return new CheckedPrincipalIterator(entries);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param searchType
+ */
+ public PrincipalIterator getPrincipals(int searchType) {
+ checkIsValid();
+ List entries = new ArrayList(providers.length);
+ for (int i = 0; i < providers.length; i++) {
+ PrincipalProvider pp = providers[i];
+ PrincipalIterator it = pp.getPrincipals(searchType);
+ if (it.hasNext()) {
+ entries.add(new CheckedIteratorEntry(it, pp));
+ }
+ }
+ return new CheckedPrincipalIterator(entries);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PrincipalIterator getGroupMembership(Principal principal) {
+ checkIsValid();
+ List entries = new ArrayList(providers.length + 1);
+ for (int i = 0; i < providers.length; i++) {
+ PrincipalProvider pp = providers[i];
+ PrincipalIterator groups = pp.getGroupMembership(principal);
+ if (groups.hasNext()) {
+ entries.add(new CheckedIteratorEntry(groups, pp));
+ }
+ }
+ // additional entry for the 'everyone' group
+ if (!(principal instanceof EveryonePrincipal)) {
+ Iterator it = Collections.singletonList(getEveryone()).iterator();
+ entries.add(new CheckedIteratorEntry(it, null));
+ }
+ return new CheckedPrincipalIterator(entries);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Principal getEveryone() {
+ checkIsValid();
+ return EveryonePrincipal.getInstance();
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * Check if the instance has been closed.
+ *
+ * @throws IllegalStateException if this instance was closed.
+ */
+ private void checkIsValid() {
+ if (closed) {
+ throw new IllegalStateException("PrincipalManagerImpl instance has been closed.");
+ }
+ }
+
+ /**
+ * @param principalName
+ * @return The principal with the given name or <code>null</code> if none
+ * of the providers knows that principal of if the Session is not allowed
+ * to see it.
+ */
+ private Principal internalGetPrincipal(String principalName) {
+ checkIsValid();
+ for (int i = 0; i < providers.length; i++) {
+ Principal principal = providers[i].getPrincipal(principalName);
+ if (principal != null && providers[i].canReadPrincipal(session, principal)) {
+ return disguise(principal, providers[i]);
+ }
+ }
+ // nothing found or not allowed to see it.
+ return null;
+ }
+
+ /**
+ * @param principal
+ * @return A group that only reveals those members that are visible to the
+ * current session or the specified principal if its not a group or the
+ * everyone principal.
+ */
+ private Principal disguise(Principal principal, PrincipalProvider provider) {
+ if (!(principal instanceof Group) || principal instanceof EveryonePrincipal) {
+ // nothing to do.
+ return principal;
+ }
+ Group gr = (Group) principal;
+ // make sure all groups except for the 'everyone' group expose only
+ // principals visible to the session.
+ if (principal instanceof ItemBasedPrincipal) {
+ return new ItemBasedCheckedGroup(gr, provider);
+ } else {
+ return new CheckedGroup(gr, provider);
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * An implementation of the <code>Group</code> interface that wrapps another
+ * Group and makes sure, that all exposed members are visible to the Session
+ * the <code>PrincipalManager</code> has been built for. This is required
+ * due to the fact, that the principal provider is not bound to a particular
+ * Session object.
+ */
+ private class CheckedGroup implements Group {
+
+ final Group delegatee;
+ private final PrincipalProvider provider;
+
+ private CheckedGroup(Group delegatee, PrincipalProvider provider) {
+ this.delegatee = delegatee;
+ this.provider = provider;
+ }
+
+ public boolean addMember(Principal user) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public boolean removeMember(Principal user) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public boolean isMember(Principal member) {
+ // TODO: check if access-restrictions should be checked
+ return delegatee.isMember(member);
+ }
+
+ public Enumeration members() {
+ Iterator it = Collections.list(delegatee.members()).iterator();
+ final Iterator members = new CheckedPrincipalIterator(it, provider);
+ return new Enumeration() {
+ public boolean hasMoreElements() {
+ return members.hasNext();
+ }
+ public Object nextElement() {
+ return members.next();
+ }
+ };
+ }
+
+ public String getName() {
+ return delegatee.getName();
+ }
+
+ //---------------------------------------------------------< Object >---
+ public int hashCode() {
+ return delegatee.hashCode();
+ }
+
+ public boolean equals(Object obj) {
+ return delegatee.equals(obj);
+ }
+ }
+
+ /**
+ * Same as {@link CheckedGroup} but wrapping an ItemBasePrincipal.
+ */
+ private class ItemBasedCheckedGroup extends CheckedGroup implements ItemBasedPrincipal {
+
+ private ItemBasedCheckedGroup(Group delegatee, PrincipalProvider provider) {
+ super(delegatee, provider);
+ if (!(delegatee instanceof ItemBasedPrincipal)) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public String getPath() throws RepositoryException {
+ return ((ItemBasedPrincipal) delegatee).getPath();
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * A PrincipalIterator implementation that tests for each principal
+ * in the passed base iterators whether it is visible to the Session
+ * the PrincipalManager has been built for. A principal that is not
+ * accessible is skipped during the iteration.
+ */
+ private class CheckedPrincipalIterator extends AbstractPrincipalIterator {
+
+ private final List entries;
+
+ private CheckedPrincipalIterator(Iterator it, PrincipalProvider provider) {
+ entries = new ArrayList(1);
+ entries.add(new CheckedIteratorEntry(it, provider));
+ next = seekNext();
+ }
+
+ private CheckedPrincipalIterator(List entries) {
+ this.entries = new ArrayList(entries);
+ next = seekNext();
+ }
+
+ protected final Principal seekNext() {
+ while (!entries.isEmpty()) {
+ // first test if current-itr has more elements
+ CheckedIteratorEntry current = (CheckedIteratorEntry) entries.get(0);
+ Iterator iterator = current.iterator;
+ while (iterator.hasNext()) {
+ Principal chk = (Principal) iterator.next();
+ if (current.provider == null ||
+ current.provider.canReadPrincipal(session, chk)) {
+ return disguise(chk, current.provider);
+ }
+ }
+ // ino more elements in current-itr -> move to next iterator.
+ entries.remove(0);
+ }
+ return null;
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ *
+ */
+ private static class CheckedIteratorEntry {
+
+ private final PrincipalProvider provider;
+ private final Iterator iterator;
+
+ private CheckedIteratorEntry(Iterator iterator, PrincipalProvider provider) {
+ this.iterator = iterator;
+ this.provider = provider;
+ }
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalManagerImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalManagerImpl.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+
+import javax.jcr.Session;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Properties;
+
+/**
+ * This interface defines methods to provide access to sources of
+ * {@link Principal}s. This allows the security framework share any external
+ * sources for authorization and authentication, as may be used by a custom
+ * {@link javax.security.auth.spi.LoginModule} for example.
+ *
+ * @see PrincipalManager for more details about principals, users and groups.
+ */
+public interface PrincipalProvider {
+
+ /**
+ * Checks if the principal with the given name is known to this provider.
+ *
+ * @param principalName the name of the principal to check
+ * @return return <code>true</code> if the principal with this name is known
+ * to this provider; <code>false</code> otherwise.
+ */
+ boolean hasPrincipal(String principalName);
+
+ /**
+ * Returns the principal with the given name if is known to this provider
+ *
+ * @param principalName the name of the principal to retrieve
+ * @return return the requested principal or <code>null</code>
+ */
+ Principal getPrincipal(String principalName);
+
+ /**
+ * Searches for <code>Principal</code>s that match the given String.
+ * NOTE: <code>Group</code>s are included in the search result.
+ *
+ * @param simpleFilter
+ * @return
+ * @see #findPrincipals(String,int)
+ */
+ PrincipalIterator findPrincipals(String simpleFilter);
+
+ /**
+ * Searches for <code>Principal</code>s that match the given String.
+ *
+ * @param simpleFilter
+ * @param searchType searchType Any of the following constants:
+ * <ul>
+ * <li>{@link PrincipalManager#SEARCH_TYPE_ALL}</li>
+ * <li>{@link PrincipalManager#SEARCH_TYPE_GROUP}</li>
+ * <li>{@link PrincipalManager#SEARCH_TYPE_NOT_GROUP}</li>
+ * </ul>
+ * @return
+ * @see #findPrincipals(String)
+ */
+ PrincipalIterator findPrincipals(String simpleFilter, int searchType);
+
+ /**
+ * Returns an iterator over all principals that match the given search type.
+ *
+ * @return an iterator over all principals that match the given search type.
+ * @param searchType searchType Any of the following constants:
+ * <ul>
+ * <li>{@link PrincipalManager#SEARCH_TYPE_ALL}</li>
+ * <li>{@link PrincipalManager#SEARCH_TYPE_GROUP}</li>
+ * <li>{@link PrincipalManager#SEARCH_TYPE_NOT_GROUP}</li>
+ * </ul>
+ */
+ PrincipalIterator getPrincipals(int searchType);
+
+ /**
+ * Returns an iterator over all group principals for which the given
+ * principal is either direct or indirect member of. If a principal is
+ * a direct member of a group, then <code>{@link Group#isMember(Principal)}</code>
+ * evaluates to <code>true</code>. A principal is an indirect member of a
+ * group if any of its groups (to any degree of separation) is direct memeber
+ * of the group.
+ * <p/>
+ * Example:<br>
+ * If Principal is member of Group A, and Group A is member of
+ * Group B, this method will return Group A and Group B.
+ *
+ * @param principal the principal to return it's membership from.
+ * @return an iterator returning all groups the given principal is member of.
+ */
+ PrincipalIterator getGroupMembership(Principal principal);
+
+ /**
+ * Initialize this provider.
+ *
+ * @param options the options that are set
+ */
+ void init(Properties options);
+
+ /**
+ * This is called when a provider is not longer used by the repository.
+ * An implementation can then release any resources bound to this
+ * provider, eg. disconnect from a backend system.
+ */
+ void close();
+
+ /**
+ * // TODO: review again.
+ * Tests if the provided session is allowed to read the given principal.
+ * Since the principal providers do not restrict the access
+ * on the prinicipals they provide, this method is used by the PrincipalManger
+ * to ensure proper access rights for the client requesting the principals.
+ *
+ * @param session
+ * @param principalToRead The principal to be accessed by the specified subject.
+ * @return <code>true</code> if the subject is allowed to read the principal;
+ * <code>false</code> otherwise.
+ */
+ boolean canReadPrincipal(Session session, Principal principalToRead);
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProviderRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProviderRegistry.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProviderRegistry.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProviderRegistry.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import javax.jcr.RepositoryException;
+import java.util.Properties;
+
+/**
+ * Registry used to store and retrieve <code>PrincipalProvider</code>s.
+ *
+ * @see PrincipalProvider
+ */
+public interface PrincipalProviderRegistry {
+
+ /**
+ * Registers a new provider by means of a configuration. The
+ * registry expects the properties to contain a
+ * {@link org.apache.jackrabbit.core.config.LoginModuleConfig#PARAM_PRINCIPAL_PROVIDER_CLASS}
+ * to be able to create a instance of PrincipalProvider.
+ * <p/>
+ * The Properties will be passed to the instanciated Provider via
+ * {@link PrincipalProvider#init(Properties)}
+ *
+ * @param configuration Properties for the Provider
+ * @return the newly added Provider or <code>null</code> if the configuration
+ * was incomplete.
+ * @throws RepositoryException if an error occurs while creating the
+ * provider instance.
+ */
+ PrincipalProvider registerProvider(Properties configuration) throws RepositoryException;
+
+ /**
+ * @return the default principal provider
+ */
+ PrincipalProvider getDefault();
+
+ /**
+ * @param className
+ * @return PrincipalProvider or <code>null</code> if no provider with
+ * the given class name was registered.
+ */
+ PrincipalProvider getProvider(String className);
+
+ /**
+ * Returns all registered providers.
+ *
+ * @return all registered providers.
+ */
+ PrincipalProvider[] getProviders();
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProviderRegistry.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProviderRegistry.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.principal;
+
+import org.apache.jackrabbit.core.config.BeanConfig;
+import org.apache.jackrabbit.core.config.LoginModuleConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.RepositoryException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This is the default implementation of the {@link PrincipalProviderRegistry}
+ * interface.
+ */
+public class ProviderRegistryImpl implements PrincipalProviderRegistry {
+
+ /** the default logger */
+ private static final Logger log = LoggerFactory.getLogger(ProviderRegistryImpl.class);
+
+ private final PrincipalProvider defaultPrincipalProvider;
+ private final Map providers = new HashMap();
+
+ /**
+ * Create an instance of <code>ProviderRegistryImpl</code> with the given
+ * default principal provider.
+ * NOTE that the provider must be initialized by the caller.
+ *
+ * @param defaultPrincipalProvider
+ */
+ public ProviderRegistryImpl(PrincipalProvider defaultPrincipalProvider) {
+ this.defaultPrincipalProvider = defaultPrincipalProvider;
+ providers.put(defaultPrincipalProvider.getClass().getName(), defaultPrincipalProvider);
+ }
+
+
+ //------------------------------------------< PrincipalProviderRegistry >---
+ /**
+ * @see PrincipalProviderRegistry#registerProvider(Properties)
+ */
+ public PrincipalProvider registerProvider(Properties config) throws RepositoryException {
+ PrincipalProvider provider = createProvider(config);
+ if (provider != null) {
+ synchronized(providers) {
+ providers.put(provider.getClass().getName(), provider);
+ }
+ } else {
+ log.debug("Could not register principal provider: " +
+ LoginModuleConfig.PARAM_PRINCIPAL_PROVIDER_CLASS +
+ " configuration entry missing.");
+ }
+ return provider;
+ }
+
+ /**
+ * @see PrincipalProviderRegistry#getDefault()
+ */
+ public PrincipalProvider getDefault() {
+ return defaultPrincipalProvider;
+ }
+
+ /**
+ * @see PrincipalProviderRegistry#getProviders()
+ */
+ public PrincipalProvider getProvider(String className) {
+ synchronized (providers) {
+ return (PrincipalProvider) providers.get(className);
+ }
+ }
+
+ /**
+ * @see PrincipalProviderRegistry#getProviders()
+ */
+ public PrincipalProvider[] getProviders() {
+ synchronized (providers) {
+ Collection pps = providers.values();
+ return (PrincipalProvider[]) pps.toArray(new PrincipalProvider[pps.size()]);
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * Read the map and instanciate the class indicated by the
+ * {@link LoginModuleConfig#PARAM_PRINCIPAL_PROVIDER_CLASS} key.<br>
+ * The class gets set the properties of the given map, via a Bean mechanism
+ *
+ * @param config
+ * @return the new provider instance or <code>null</code> if the
+ * configuration does not contain the required entry.
+ */
+ private PrincipalProvider createProvider(Properties config)
+ throws RepositoryException {
+
+ String className = config.getProperty(LoginModuleConfig.PARAM_PRINCIPAL_PROVIDER_CLASS);
+ if (className == null) {
+ return null;
+ }
+
+ try {
+ Class pc = Class.forName(className, true, BeanConfig.getDefaultClassLoader());
+ PrincipalProvider pp = (PrincipalProvider) pc.newInstance();
+ pp.init(config);
+ return pp;
+ } catch (ClassNotFoundException e) {
+ throw new RepositoryException("Unable to create new principal provider.", e);
+ } catch (IllegalAccessException e) {
+ throw new RepositoryException("Unable to create new principal provider.", e);
+ } catch (InstantiationException e) {
+ throw new RepositoryException("Unable to create new principal provider.", e);
+ } catch (ClassCastException e) {
+ throw new RepositoryException("Unable to create new principal provider.", e);
+ }
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.simple;
+
+import org.apache.jackrabbit.core.security.AbstractAccessControlManager;
+import org.apache.jackrabbit.core.security.AccessManager;
+import org.apache.jackrabbit.core.security.AMContext;
+import org.apache.jackrabbit.core.security.AnonymousPrincipal;
+import org.apache.jackrabbit.core.security.SystemPrincipal;
+import org.apache.jackrabbit.core.security.jsr283.security.Privilege;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlPolicy;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry;
+import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
+import org.apache.jackrabbit.core.security.authorization.AccessControlProvider;
+import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
+import org.apache.jackrabbit.core.security.authorization.Permission;
+import org.apache.jackrabbit.core.HierarchyManager;
+import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.Name;
+
+import javax.security.auth.Subject;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.PathNotFoundException;
+
+/**
+ * <code>SimpleAccessManager</code> ...
+ */
+public class SimpleAccessManager extends AbstractAccessControlManager implements AccessManager {
+
+ /**
+ * Subject whose access rights this AccessManager should reflect
+ */
+ private Subject subject;
+
+ /**
+ * hierarchy manager used for ACL-based access control model
+ */
+ private HierarchyManager hierMgr;
+
+ private NamePathResolver resolver;
+ private WorkspaceAccessManager wspAccessMgr;
+
+ private boolean initialized;
+
+ private boolean system;
+ private boolean anonymous;
+
+ /**
+ * Empty constructor
+ */
+ public SimpleAccessManager() {
+ initialized = false;
+ anonymous = false;
+ system = false;
+ }
+
+ //--------------------------------------------------------< AccessManager >
+ /**
+ * {@inheritDoc}
+ */
+ public void init(AMContext context)
+ throws AccessDeniedException, Exception {
+ init(context, null, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void init(AMContext context, AccessControlProvider acProvider, WorkspaceAccessManager wspAccessManager) throws AccessDeniedException, Exception {
+ if (initialized) {
+ throw new IllegalStateException("already initialized");
+ }
+
+ subject = context.getSubject();
+ hierMgr = context.getHierarchyManager();
+ resolver = context.getNamePathResolver();
+ wspAccessMgr = wspAccessManager;
+ anonymous = !subject.getPrincipals(AnonymousPrincipal.class).isEmpty();
+ system = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
+
+ // @todo check permission to access given workspace based on principals
+ initialized = true;
+
+ if (!canAccess(context.getWorkspaceName())) {
+ throw new AccessDeniedException("Not allowed to access Workspace " + context.getWorkspaceName());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public synchronized void close() throws Exception {
+ checkInitialized();
+ initialized = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void checkPermission(ItemId id, int permissions)
+ throws AccessDeniedException, ItemNotFoundException,
+ RepositoryException {
+ if (!isGranted(id, permissions)) {
+ throw new AccessDeniedException("Access denied");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isGranted(ItemId id, int permissions)
+ throws ItemNotFoundException, RepositoryException {
+ checkInitialized();
+ if (system) {
+ // system has always all permissions
+ return true;
+ } else if (anonymous) {
+ // anonymous is always denied WRITE & REMOVE premissions
+ if ((permissions & WRITE) == WRITE
+ || (permissions & REMOVE) == REMOVE) {
+ return false;
+ }
+ }
+
+ // @todo check permission based on principals
+ return true;
+ }
+
+ public boolean isGranted(Path absPath, int permissions) throws RepositoryException {
+ return internalIsGranted(absPath, permissions);
+ }
+
+ public boolean isGranted(Path parentPath, Name childName, int permissions) throws ItemNotFoundException, RepositoryException {
+ return internalIsGranted(parentPath, permissions);
+ }
+
+ private boolean internalIsGranted(Path absPath, int permissions) throws ItemNotFoundException, RepositoryException {
+ if (!absPath.isAbsolute()) {
+ throw new RepositoryException("Absolute path expected");
+ }
+ checkInitialized();
+ if (system) {
+ // system has always all permissions
+ return true;
+ } else if (anonymous) {
+ // anonymous is only granted READ premissions
+ return permissions == Permission.READ;
+ }
+
+ // @todo check permission based on principals
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canAccess(String workspaceName) throws NoSuchWorkspaceException, RepositoryException {
+ if (system || wspAccessMgr == null) {
+ return true;
+ }
+ return wspAccessMgr.grants(subject.getPrincipals(), workspaceName);
+ }
+
+ //-----------------------------------------------< AccessControlManager >---
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasPrivileges(String absPath, Privilege[] privileges) throws PathNotFoundException, RepositoryException {
+ checkInitialized();
+ // make sure absPath points to an existing node
+ getValidNodePath(absPath);
+
+ if (privileges == null || privileges.length == 0) {
+ // null or empty privilege array -> return true
+ return true;
+ } else {
+ int bits = PrivilegeRegistry.getBits(privileges);
+ if (system) {
+ // system has always all permissions
+ return true;
+ } else if (anonymous) {
+ if (bits != PrivilegeRegistry.READ) {
+ // anonymous is only granted READ premissions
+ return false;
+ }
+ }
+
+ // @todo check permission based on principals
+ return true;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Privilege[] getPrivileges(String absPath) throws PathNotFoundException, RepositoryException {
+ checkInitialized();
+ getValidNodePath(absPath);
+
+ if (anonymous) {
+ return new Privilege[] {PrivilegeRegistry.READ_PRIVILEGE};
+ } else if (system) {
+ return new Privilege[] {PrivilegeRegistry.ALL_PRIVILEGE};
+ } else {
+ // @todo check permission based on principals
+ return new Privilege[] {PrivilegeRegistry.ALL_PRIVILEGE};
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AccessControlPolicy getEffectivePolicy(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
+ checkInitialized();
+ Path p = getValidNodePath(absPath);
+ checkPrivileges(p, PrivilegeRegistry.READ_AC);
+
+ return new AccessControlPolicy() {
+ public String getName() throws RepositoryException {
+ return "Simple AccessControlPolicy";
+ }
+ public String getDescription() throws RepositoryException {
+ return null;
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AccessControlEntry[] getEffectiveAccessControlEntries(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
+ checkInitialized();
+ Path p = getValidNodePath(absPath);
+ checkPrivileges(p, PrivilegeRegistry.READ_AC);
+
+ return new AccessControlEntry[0];
+ }
+
+ //---------------------------------------< AbstractAccessControlManager >---
+ /**
+ * {@inheritDoc}
+ */
+ protected void checkInitialized() throws IllegalStateException {
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+ }
+
+ protected void checkPrivileges(Path absPath, int privileges) throws AccessDeniedException, PathNotFoundException, RepositoryException {
+ if (anonymous && privileges != PrivilegeRegistry.READ) {
+ throw new AccessDeniedException("Anonymous may only READ.");
+ }
+ }
+
+ protected Path getValidNodePath(String absPath) throws PathNotFoundException, RepositoryException {
+ Path path = resolver.getQPath(absPath);
+ if (!path.isAbsolute()) {
+ throw new RepositoryException("Absolute path expected. Found: " + absPath);
+ }
+
+ if (hierMgr.resolveNodePath(path) == null) {
+ throw new PathNotFoundException(absPath);
+ } else {
+ return path;
+ }
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.simple;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.core.security.authentication.Authentication;
+import org.apache.jackrabbit.core.security.authentication.AbstractLoginModule;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.Subject;
+import javax.jcr.Session;
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import java.util.Map;
+import java.security.Principal;
+import java.security.acl.Group;
+
+/**
+ * <code>SimpleLoginModule</code>...
+ */
+public class SimpleLoginModule extends AbstractLoginModule {
+
+ private static Logger log = LoggerFactory.getLogger(SimpleLoginModule.class);
+
+ protected void doInit(CallbackHandler callbackHandler, Session session, Map options) throws LoginException {
+ // nothing to do
+ log.debug("init: SimpleLoginModule. Done.");
+ }
+
+ protected boolean impersonate(Principal principal, Credentials credentials) throws RepositoryException, LoginException {
+ if (principal instanceof Group) {
+ return false;
+ }
+ Subject impersSubject = getImpersonatorSubject(credentials);
+ return impersSubject != null;
+ }
+
+ protected Authentication getAuthentication(Principal principal, Credentials creds) throws RepositoryException {
+ if (principal instanceof Group) {
+ return null;
+ }
+ return new Authentication() {
+ public boolean canHandle(Credentials credentials) {
+ return true;
+ }
+ public boolean authenticate(Credentials credentials) throws RepositoryException {
+ return true;
+ }
+ };
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url