# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: C:\workspace\trunk\apps\weblogger
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and \n newlines.
# Above lines and this line are ignored by the patching process.
Index: build.xml
--- build.xml Base (BASE)
+++ build.xml Locally Modified (Based On LOCAL)
@@ -676,15 +676,6 @@
-
-
-
-
-
-
-
-
-
Index: src/java/META-INF/persistence.xml
--- src/java/META-INF/persistence.xml Base (BASE)
+++ src/java/META-INF/persistence.xml Locally Modified (Based On LOCAL)
@@ -27,6 +27,7 @@
org/apache/roller/weblogger/pojos/ObjectPermission.orm.xml
org/apache/roller/weblogger/pojos/WeblogPermission.orm.xml
org/apache/roller/weblogger/pojos/Weblog.orm.xml
+ org/apache/roller/weblogger/pojos/UserPermission.orm.xml
Index: src/java/org/apache/roller/weblogger/business/jpa/CustomJPAUserManagerImpl.java
--- src/java/org/apache/roller/weblogger/business/jpa/CustomJPAUserManagerImpl.java Locally New
+++ src/java/org/apache/roller/weblogger/business/jpa/CustomJPAUserManagerImpl.java Locally New
@@ -0,0 +1,800 @@
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.roller.weblogger.business.jpa;
+
+import java.sql.Timestamp;
+import javax.persistence.NoResultException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.roller.weblogger.WebloggerException;
+import org.apache.roller.weblogger.business.UserManager;
+import org.apache.roller.weblogger.pojos.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Comparator;
+import javax.persistence.Query;
+import org.apache.roller.weblogger.business.Weblogger;
+import org.apache.roller.weblogger.config.WebloggerConfig;
+
+
+@com.google.inject.Singleton
+public class CustomJPAUserManagerImpl implements UserManager {
+
+ /** The logger instance for this class. */
+ private static Log log = LogFactory.getLog(CustomJPAUserManagerImpl.class);
+
+ private static final Comparator statCountCountReverseComparator =
+ Collections.reverseOrder(StatCountCountComparator.getInstance());
+
+ private final Weblogger roller;
+ private final JPAPersistenceStrategy strategy;
+
+ // cached mapping of weblogHandles -> weblogIds
+ private Map weblogHandleToIdMap = new Hashtable();
+
+ // cached mapping of userNames -> userIds
+ private Map userNameToIdMap = new Hashtable();
+
+
+ @com.google.inject.Inject
+ protected CustomJPAUserManagerImpl(Weblogger roller, JPAPersistenceStrategy strat) {
+ log.debug("Instantiating JPA User Manager");
+ this.roller = roller;
+ this.strategy = strat;
+ }
+
+
+ public void release() {}
+
+
+ //--------------------------------------------------------------- user CRUD
+
+ public void saveUser(User data) throws WebloggerException {
+ this.strategy.store(data);
+ }
+
+
+ public void removeUser(User user) throws WebloggerException {
+ //remove permissions
+ // make sure that both sides of the relationship are maintained
+ List perms = getWeblogPermissions(user);
+ for (WeblogPermission perm : perms) {
+
+ //Remove it from database
+ this.strategy.remove(perms);
+ }
+
+ this.strategy.remove(user);
+
+ // remove entry from cache mapping
+ this.userNameToIdMap.remove(user.getUserName());
+ }
+
+
+ public void addUser(User newUser) throws WebloggerException {
+
+ if(newUser == null)
+ throw new WebloggerException("cannot add null user");
+
+ // TODO BACKEND: we must do this in a better fashion, like getUserCnt()?
+ boolean adminUser = false;
+ List existingUsers = this.getUsers(Boolean.TRUE, null, null, 0, 1);
+ boolean firstUserAdmin = WebloggerConfig.getBooleanProperty("users.firstUserAdmin");
+ if (existingUsers.size() == 0 && firstUserAdmin) {
+ // Make first user an admin
+ adminUser = true;
+
+ //if user was disabled (because of activation user
+ // account with e-mail property), enable it for admin user
+ newUser.setEnabled(Boolean.TRUE);
+ newUser.setActivationCode(null);
+ }
+
+ if (getUserByUserName(newUser.getUserName()) != null ||
+ getUserByUserName(newUser.getUserName().toLowerCase()) != null) {
+ throw new WebloggerException("error.add.user.userNameInUse");
+ }
+
+ this.strategy.store(newUser);
+
+ grantRole("editor", newUser);
+ if (adminUser) {
+ grantRole("admin", newUser);
+ }
+ }
+
+
+ public User getUser(String id) throws WebloggerException {
+ return (User)this.strategy.load(User.class, id);
+ }
+
+
+ //------------------------------------------------------------ user queries
+
+ public User getUserByUserName(String userName) throws WebloggerException {
+ return getUserByUserName(userName, Boolean.TRUE);
+ }
+
+
+ public User getUserByUserName(String userName, Boolean enabled)
+ throws WebloggerException {
+
+ if (userName==null )
+ throw new WebloggerException("userName cannot be null");
+
+ // check cache first
+ // NOTE: if we ever allow changing usernames then this needs updating
+ if(this.userNameToIdMap.containsKey(userName)) {
+
+ User user = this.getUser(
+ (String) this.userNameToIdMap.get(userName));
+ if(user != null) {
+ // only return the user if the enabled status matches
+ if(enabled == null || enabled.equals(user.getEnabled())) {
+ log.debug("userNameToIdMap CACHE HIT - "+userName);
+ return user;
+ }
+ } else {
+ // mapping hit with lookup miss? mapping must be old, remove it
+ this.userNameToIdMap.remove(userName);
+ }
+ }
+
+ // cache failed, do lookup
+ Query query;
+ Object[] params;
+ if (enabled != null) {
+ query = strategy.getNamedQuery(
+ "User.getByUserName&Enabled");
+ params = new Object[] {userName, enabled};
+ } else {
+ query = strategy.getNamedQuery(
+ "User.getByUserName");
+ params = new Object[] {userName};
+ }
+ for (int i=0; i ?" + size);
+ params.add(size++, end);
+ whereClause.append(" AND u.dateCreated < ?" + size);
+ }
+ whereClause.append(" ORDER BY u.dateCreated DESC");
+ query = strategy.getDynamicQuery(queryString.toString() + whereClause.toString());
+
+ if (offset != 0) {
+ query.setFirstResult(offset);
+ }
+ if (length != -1) {
+ query.setMaxResults(length);
+ }
+ for (int i=0; i actions) throws WebloggerException {
+
+ // first, see if user already has a permission for the specified object
+ Query q = strategy.getNamedQuery("WeblogPermission.getByUserName&WeblogId");
+ q.setParameter(1, user.getUserName());
+ q.setParameter(2, weblog.getHandle());
+ WeblogPermission existingPerm = null;
+ try {
+ existingPerm = (WeblogPermission)q.getSingleResult();
+ } catch (NoResultException ignored) {}
+
+ // permission already exists, so add any actions specified in perm argument
+ if (existingPerm != null) {
+ existingPerm.addActions(actions);
+ this.strategy.store(existingPerm);
+ } else {
+ // it's a new permission, so store it
+ WeblogPermission perm = new WeblogPermission(weblog, user, actions);
+ this.strategy.store(perm);
+ }
+ }
+
+
+ public void grantWeblogPermissionPending(Weblog weblog, User user, List actions) throws WebloggerException {
+
+ // first, see if user already has a permission for the specified object
+ Query q = strategy.getNamedQuery("WeblogPermission.getByUserName&WeblogId");
+ q.setParameter(1, user.getUserName());
+ q.setParameter(2, weblog.getHandle());
+ WeblogPermission existingPerm = null;
+ try {
+ existingPerm = (WeblogPermission)q.getSingleResult();
+ } catch (NoResultException ignored) {}
+
+ // permission already exists, so complain
+ if (existingPerm != null) {
+ throw new WebloggerException("Cannot make existing permission into pending permission");
+
+ } else {
+ // it's a new permission, so store it
+ WeblogPermission perm = new WeblogPermission(weblog, user, actions);
+ perm.setPending(true);
+ this.strategy.store(perm);
+ }
+ }
+
+
+ public void confirmWeblogPermission(Weblog weblog, User user) throws WebloggerException {
+
+ // get specified permission
+ Query q = strategy.getNamedQuery("WeblogPermission.getByUserName&WeblogId");
+ q.setParameter(1, user.getUserName());
+ q.setParameter(2, weblog.getHandle());
+ WeblogPermission existingPerm = null;
+ try {
+ existingPerm = (WeblogPermission)q.getSingleResult();
+
+ } catch (NoResultException ignored) {
+ throw new WebloggerException("ERROR: permission not found");
+ }
+ // set pending to false
+ existingPerm.setPending(false);
+ this.strategy.store(existingPerm);
+ }
+
+
+ public void declineWeblogPermission(Weblog weblog, User user) throws WebloggerException {
+
+ // get specified permission
+ Query q = strategy.getNamedQuery("WeblogPermission.getByUserName&WeblogId");
+ q.setParameter(1, user.getUserName());
+ q.setParameter(2, weblog.getHandle());
+ WeblogPermission existingPerm = null;
+ try {
+ existingPerm = (WeblogPermission)q.getSingleResult();
+ } catch (NoResultException ignored) {
+ throw new WebloggerException("ERROR: permission not found");
+ }
+ // remove permission
+ this.strategy.remove(existingPerm);
+ }
+
+
+ public void revokeWeblogPermission(Weblog weblog, User user, List actions) throws WebloggerException {
+
+ // get specified permission
+ Query q = strategy.getNamedQuery("WeblogPermission.getByUserName&WeblogId");
+ q.setParameter(1, user.getUserName());
+ q.setParameter(2, weblog.getHandle());
+ WeblogPermission oldperm = null;
+ try {
+ oldperm = (WeblogPermission)q.getSingleResult();
+ } catch (NoResultException ignored) {
+ throw new WebloggerException("ERROR: permission not found");
+ }
+
+ // remove actions specified in perm agument
+ oldperm.removeActions(actions);
+
+ if (oldperm.isEmpty()) {
+ // no actions left in permission so remove it
+ this.strategy.remove(oldperm);
+ } else {
+ // otherwise save it
+ this.strategy.store(oldperm);
+ }
+ }
+
+
+ public List getWeblogPermissions(User user) throws WebloggerException {
+ Query q = strategy.getNamedQuery("WeblogPermission.getByUserName");
+ q.setParameter(1, user.getUserName());
+ return (List)q.getResultList();
+ }
+
+
+ public List getWeblogPermissions(Weblog weblog) throws WebloggerException {
+ Query q = strategy.getNamedQuery("WeblogPermission.getByWeblogId");
+ q.setParameter(1, weblog.getHandle());
+ return (List)q.getResultList();
+ }
+
+
+ public List getWeblogPermissionsPending(User user) throws WebloggerException {
+ Query q = strategy.getNamedQuery("WeblogPermission.getByUserName&Pending");
+ q.setParameter(1, user.getUserName());
+ return (List)q.getResultList();
+ }
+
+
+ public List getWeblogPermissionsPending(Weblog weblog) throws WebloggerException {
+ Query q = strategy.getNamedQuery("WeblogPermission.getByWeblogId&Pending");
+ q.setParameter(1, weblog.getHandle());
+ return (List)q.getResultList();
+ }
+
+
+ //-------------------------------------------------------------- role CRUD
+
+
+ /**
+ * Returns true if user has role specified.
+ */
+ public boolean hasRole(String roleName, User user) throws WebloggerException {
+ Query q = strategy.getNamedQuery("UserRole.getByUserNameAndRole");
+ q.setParameter(1, user.getUserName());
+ q.setParameter(2, roleName);
+ try {
+ q.getSingleResult();
+ } catch (NoResultException e) {
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * Get all of user's roles.
+ */
+ public List getRoles(User user) throws WebloggerException {
+ Query q = strategy.getNamedQuery("UserRole.getByUserName");
+ q.setParameter(1, user.getUserName());
+ List roles = q.getResultList();
+ List roleNames = new ArrayList();
+ for (Iterator it = roles.iterator(); it.hasNext();) {
+ UserRole userRole = (UserRole)it.next();
+ roleNames.add(userRole.getRole());
+ }
+ return roleNames;
+ }
+
+
+ /**
+ * Grant to user role specified by role name.
+ */
+ public void grantRole(String roleName, User user) throws WebloggerException {
+ if (!hasRole(roleName, user)) {
+ UserRole role = new UserRole(user.getUserName(), roleName);
+ this.strategy.store(role);
+ }
+ }
+
+
+ public void revokeRole(String roleName, User user) throws WebloggerException {
+ Query q = strategy.getNamedQuery("UserRole.getByUserNameAndRole");
+ q.setParameter(1, user.getUserName());
+ q.setParameter(2, roleName);
+ try {
+ UserRole role = (UserRole)q.getSingleResult();
+ this.strategy.remove(role);
+
+ } catch (NoResultException e) {
+ throw new WebloggerException("ERROR: removing role", e);
+ }
+ }
+
+
+ public boolean checkPermission(User user, WebloggerPermission requiredPerm)
+ throws WebloggerException {
+
+ // first see if the user has this permission defined
+ WebloggerPermission userPerm =
+ getPermission(user, requiredPerm.getType(), requiredPerm.getObject());
+ if(userPerm != null) {
+ // yes they do, now lets see if they have the required actions
+ return userPerm.implies(requiredPerm);
+ }
+
+ return false;
+ }
+
+ public void grantPermission(User user, WebloggerPermission perm)
+ throws WebloggerException {
+
+ // first, see if user already has a permission for the specified object
+ UserPermission userPerm = getUserPermission(user, perm.getObject(), perm.getType());
+
+ if (userPerm != null) {
+ // permission already exists, so just add actions
+ userPerm.addActions(perm.getActions());
+ this.strategy.store(userPerm);
+ } else {
+ // it's a new permission
+ UserPermission newPerm = new UserPermission(user, perm.getType(), perm.getObject(), perm.getActions());
+ this.strategy.store(newPerm);
+ }
+ }
+
+ public void revokePermission(User user, WebloggerPermission perm)
+ throws WebloggerException {
+
+ // first, see if user already has a permission for the specified object
+ UserPermission oldPerm = getUserPermission(user, perm.getObject(), perm.getType());
+ if(oldPerm == null) {
+ return;
+ }
+
+ // remove actions specified in perm agument
+ oldPerm.removeActions(perm.getActions());
+
+ if (oldPerm.getActions() == null || oldPerm.getActions().trim().length() == 0) {
+ // no actions left in permission so remove it
+ this.strategy.remove(oldPerm);
+ } else {
+ // otherwise save it
+ this.strategy.store(oldPerm);
+ }
+ }
+
+ public List getPermissions(User user, String type)
+ throws WebloggerException {
+
+ Query q = strategy.getNamedQuery("UserPermission.getByUser&Type");
+ q.setParameter(1, user);
+ q.setParameter(2, type);
+ List results = q.getResultList();
+ List perms = new ArrayList();
+ for ( UserPermission uperm : results) {
+ perms.add(userPermissionToWebloggerPermission(uperm));
+ }
+ return perms;
+ }
+
+ public List getPermissions(String object, String type)
+ throws WebloggerException {
+
+ Query q = strategy.getNamedQuery("UserPermission.getByObject&Type");
+ q.setParameter(1, object);
+ q.setParameter(2, type);
+ List results = q.getResultList();
+ List perms = new ArrayList();
+ for ( UserPermission uperm : results) {
+ perms.add(userPermissionToWebloggerPermission(uperm));
+ }
+ return perms;
+ }
+
+ public WebloggerPermission getPermission(User user, String type, String object)
+ throws WebloggerException {
+
+ UserPermission userPerm = getUserPermission(user, object, type);
+
+ // transform into WebloggerPermission
+ if(userPerm != null && !userPerm.isPending()) {
+ return userPermissionToWebloggerPermission(userPerm);
+ } else {
+ return null;
+ }
+ }
+
+ private UserPermission getUserPermission(User user, String object, String type)
+ throws WebloggerException {
+
+ Query q = strategy.getNamedQuery("UserPermission.getByUser&Object&Type");
+ q.setParameter(1, user);
+ q.setParameter(2, object);
+ q.setParameter(3, type);
+ try {
+ return (UserPermission) q.getSingleResult();
+ } catch (NoResultException ignored) {
+ return null;
+ }
+ }
+
+ private WebloggerPermission userPermissionToWebloggerPermission(UserPermission perm) {
+ return new WebloggerPermission(perm.getType(), perm.getObject(), perm.getActions());
+ }
+
+}
Index: src/java/org/apache/roller/weblogger/business/jpa/JPAUserManagerImpl.java
--- src/java/org/apache/roller/weblogger/business/jpa/JPAUserManagerImpl.java Base (BASE)
+++ src/java/org/apache/roller/weblogger/business/jpa/JPAUserManagerImpl.java Locally Modified (Based On LOCAL)
@@ -684,7 +684,31 @@
throw new WebloggerException("ERROR: removing role", e);
}
}
+
+ public boolean checkPermission(User user, WebloggerPermission perm) throws WebloggerException {
+ throw new UnsupportedOperationException("Not supported yet.");
}
+ public void grantPermission(User user, WebloggerPermission perm) throws WebloggerException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ public void revokePermission(User user, WebloggerPermission perm) throws WebloggerException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ public List getPermissions(User user, String type) throws WebloggerException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public List getPermissions(String object, String type) throws WebloggerException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public WebloggerPermission getPermission(User user, String object, String type) throws WebloggerException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
+
+
+
Index: src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java
--- src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java Base (BASE)
+++ src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java Locally Modified (Based On LOCAL)
@@ -64,7 +64,7 @@
binder.bind(PropertiesManager.class).to( JPAPropertiesManagerImpl.class);
binder.bind(RefererManager.class).to( JPARefererManagerImpl.class);
binder.bind(ThreadManager.class).to( JPAThreadManagerImpl.class);
- binder.bind(UserManager.class).to( JPAUserManagerImpl.class);
+ binder.bind(UserManager.class).to( CustomJPAUserManagerImpl.class);
binder.bind(WeblogManager.class).to( JPAWeblogManagerImpl.class);
binder.bind(WeblogEntryManager.class).to( JPAWeblogEntryManagerImpl.class);
Index: src/java/org/apache/roller/weblogger/business/UserManager.java
--- src/java/org/apache/roller/weblogger/business/UserManager.java Base (BASE)
+++ src/java/org/apache/roller/weblogger/business/UserManager.java Locally Modified (Based On LOCAL)
@@ -26,6 +26,7 @@
import org.apache.roller.weblogger.pojos.User;
import org.apache.roller.weblogger.pojos.Weblog;
import org.apache.roller.weblogger.pojos.WeblogPermission;
+import org.apache.roller.weblogger.pojos.WebloggerPermission;
/**
@@ -167,6 +168,25 @@
//-------------------------------------------------------- permissions CRUD
+ public boolean checkPermission(User user, WebloggerPermission perm)
+ throws WebloggerException;
+
+ public void grantPermission(User user, WebloggerPermission perm)
+ throws WebloggerException;
+
+ public void revokePermission(User user, WebloggerPermission perm)
+ throws WebloggerException;
+
+ public List getPermissions(User user, String type)
+ throws WebloggerException;
+
+ public List getPermissions(String object, String type)
+ throws WebloggerException;
+
+ public WebloggerPermission getPermission(User user, String object, String type)
+ throws WebloggerException;
+
+
/**
* Return true if user has permission specified.
*/
Index: src/java/org/apache/roller/weblogger/pojos/UserPermission.java
--- src/java/org/apache/roller/weblogger/pojos/UserPermission.java Locally New
+++ src/java/org/apache/roller/weblogger/pojos/UserPermission.java Locally New
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.pojos;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.util.UUIDGenerator;
+import org.apache.roller.weblogger.util.Utilities;
+
+
+/**
+ * Permissions for a specific user.
+ */
+public class UserPermission implements Serializable {
+
+ private static Log log = LogFactory.getLog(UserPermission.class);
+
+ private String id = UUIDGenerator.generateUUID();
+ private User user = null;
+ private String type = null;
+ private String object = null;
+ private String actions = null;
+ private Date dateCreated = new Date();
+ private boolean pending = false;
+
+
+ public UserPermission() {}
+
+ public UserPermission(User user, String type, String object, String actions) {
+ this.user = user;
+ this.type = type;
+ this.object = object;
+ this.actions = actions;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getObject() {
+ return object;
+ }
+
+ public void setObject(String object) {
+ this.object = object;
+ }
+
+ public void setActions(String actions) {
+ this.actions = actions;
+ }
+
+ public String getActions() {
+ return actions;
+ }
+
+ public Date getDateCreated() {
+ return dateCreated;
+ }
+
+ public void setDateCreated(Date dateCreated) {
+ this.dateCreated = dateCreated;
+ }
+
+ public boolean isPending() {
+ return pending;
+ }
+
+ public void setPending(boolean pending) {
+ this.pending = pending;
+ }
+
+ public void addActions(String newActions) {
+ Set existing = Utilities.stringToStringSet(actions, ",");
+ Set newActs = Utilities.stringToStringSet(newActions, ",");
+ existing.addAll(newActs);
+ setActions(Utilities.stringSetToString(existing, ","));
+ }
+
+ public void removeActions(String removeActions) {
+ Set existing = Utilities.stringToStringSet(actions, ",");
+ Set removeActs = Utilities.stringToStringSet(removeActions, ",");
+ existing.removeAll(removeActs);
+ setActions(Utilities.stringSetToString(existing, ","));
+ }
+
+}
Index: src/java/org/apache/roller/weblogger/pojos/UserPermission.orm.xml
--- src/java/org/apache/roller/weblogger/pojos/UserPermission.orm.xml Locally New
+++ src/java/org/apache/roller/weblogger/pojos/UserPermission.orm.xml Locally New
@@ -0,0 +1,60 @@
+
+
+ Persistence Metadata for Roller
+
+
+ PROPERTY
+
+
+ org.apache.roller.weblogger.pojos
+
+
+
+ SELECT p FROM UserPermission p
+
+
+ SELECT p FROM UserPermission p WHERE p.user = ?1 AND p.type = ?2 AND p.pending <> TRUE
+
+
+ SELECT p FROM UserPermission p WHERE p.object = ?1 AND p.type = ?2 AND p.pending <> TRUE
+
+
+ SELECT p FROM UserPermission p WHERE p.user = ?1 AND p.object = ?2 AND p.type = ?3
+
+
+ SELECT p FROM UserPermission p WHERE p.user = ?1 AND p.object = ?2 AND p.type = ?3 AND p.pending <> TRUE
+
+
+ SELECT p FROM UserPermission p WHERE p.user = ?1 AND p.pending = TRUE
+
+
+ SELECT p FROM UserPermission p WHERE p.object = ?1 AND p.pending = TRUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: src/java/org/apache/roller/weblogger/pojos/WebloggerPermission.java
--- src/java/org/apache/roller/weblogger/pojos/WebloggerPermission.java Locally New
+++ src/java/org/apache/roller/weblogger/pojos/WebloggerPermission.java Locally New
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.pojos;
+
+import java.security.Permission;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.weblogger.util.Utilities;
+
+
+/**
+ * Base permission class for Weblogger.
+ */
+public class WebloggerPermission extends java.security.Permission {
+
+ private static Log log = LogFactory.getLog(WebloggerPermission.class);
+
+ private final String type;
+ private final String object;
+ private final String actions;
+ private final Set actionsAsSet;
+ private final Set completeActionsAsSet;
+
+
+ public WebloggerPermission(String type, String object, String actions) {
+ super("WebloggerPermission");
+ this.type = type;
+ this.object = object;
+ this.actions = actions;
+ this.actionsAsSet = Utilities.stringToStringSet(actions, ",");
+ this.completeActionsAsSet = buildFullActionsSet(actionsAsSet);
+ }
+
+
+ public String getType() {
+ return type;
+ }
+
+ public String getObject() {
+ return object;
+ }
+
+ public String getActions() {
+ return actions;
+ }
+
+ public Set getActionsAsSet() {
+ return actionsAsSet;
+ }
+
+
+ public boolean implies(Permission permission) {
+
+ // only compare WebloggerPermission objects
+ if (!(permission instanceof WebloggerPermission))
+ return false;
+
+ WebloggerPermission that = (WebloggerPermission) permission;
+
+ // only compare 2 permissions of the same name ("type")
+ // name ("type") cannot be null
+ if(this.getName() == null || that.getName() == null ||
+ !(this.getName().equals(that.getName())))
+ return false;
+
+ // does "this" permission contain all actions of "that" permission?
+
+ // we consider a permission implied if our set of granted actions
+ // contains all of the granted actions of the permission we are checking
+ if(this.completeActionsAsSet.containsAll(that.completeActionsAsSet))
+ return true;
+
+ return false;
+ }
+
+
+ public boolean equals(Object arg0) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public int hashCode() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(getName()).append(" : ");
+ for (String action : getActionsAsSet()) {
+ sb.append(" ").append(action).append(" ");
+ }
+ return sb.toString();
+ }
+
+
+ // --------------------------------------------------- Private Methods
+
+
+ // build an expanded Set of all actions implied by a Set of actions
+ private Set buildFullActionsSet(Set actions) {
+
+ Set fullSet = new HashSet();
+
+ for( String action : actions ) {
+ Set impliedActions = getImpliedActions(action);
+ if(impliedActions.size() > 0) {
+ // if an action implies other actions, recurse
+ fullSet.addAll(buildFullActionsSet(impliedActions));
+ } else {
+ fullSet.add(action);
+ }
+ }
+
+ return fullSet;
+ }
+
+ // get implied actions for an action
+ private Set getImpliedActions(String action) {
+ // TODO: lookup if action implies other actions
+ // this would likely be a function of the UserManager somehow
+ return Collections.EMPTY_SET;
+ }
+
+}
Index: src/java/org/apache/roller/weblogger/util/Utilities.java
--- src/java/org/apache/roller/weblogger/util/Utilities.java Base (BASE)
+++ src/java/org/apache/roller/weblogger/util/Utilities.java Locally Modified (Based On LOCAL)
@@ -15,9 +15,11 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -303,6 +305,19 @@
return ret;
}
+ //------------------------------------------------------------------------
+ /** Convert string array to string with delimeters. */
+ public static String stringSetToString(Set stringList, String delim) {
+ String ret = "";
+ for (String s : stringList) {
+ if (ret.length() > 0)
+ ret = ret + delim + s;
+ else
+ ret = s;
+ }
+ return ret;
+ }
+
//--------------------------------------------------------------------------
/** Convert string with delimeters to string array. */
public static String[] stringToStringArray(String instr, String delim)
@@ -330,6 +345,18 @@
}
//--------------------------------------------------------------------------
+ /** Convert string with delimeters to string list. */
+ public static Set stringToStringSet(String instr, String delim)
+ throws NoSuchElementException, NumberFormatException {
+ StringTokenizer toker = new StringTokenizer(instr, delim);
+ Set stringSet = new HashSet();
+ while (toker.hasMoreTokens()) {
+ stringSet.add(toker.nextToken());
+ }
+ return stringSet;
+ }
+
+ //--------------------------------------------------------------------------
/** Convert string to integer array. */
public static int[] stringToIntArray(String instr, String delim)
throws NoSuchElementException, NumberFormatException {
Index: test/java/org/apache/roller/weblogger/business/CoreWeblogPlatformTestSuite.java
--- test/java/org/apache/roller/weblogger/business/CoreWeblogPlatformTestSuite.java Base (BASE)
+++ test/java/org/apache/roller/weblogger/business/CoreWeblogPlatformTestSuite.java Locally Modified (Based On LOCAL)
@@ -45,6 +45,9 @@
// test permissions
suite.addTestSuite(PermissionTest.class);
+ // test permissions
+ suite.addTestSuite(CustomPermissionsTest.class);
+
return suite;
}
Index: test/java/org/apache/roller/weblogger/business/CustomPermissionsTest.java
--- test/java/org/apache/roller/weblogger/business/CustomPermissionsTest.java Locally New
+++ test/java/org/apache/roller/weblogger/business/CustomPermissionsTest.java Locally New
@@ -0,0 +1,180 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.roller.weblogger.business;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.weblogger.TestUtils;
+import org.apache.roller.weblogger.pojos.User;
+import org.apache.roller.weblogger.pojos.Weblog;
+import org.apache.roller.weblogger.pojos.WebloggerPermission;
+
+
+/**
+ * Test User/Weblog Permissions related business operations.
+ */
+public class CustomPermissionsTest extends TestCase {
+
+ public static Log log = LogFactory.getLog(CustomPermissionsTest.class);
+
+ User testUser = null;
+ Weblog testWeblog = null;
+
+
+ public CustomPermissionsTest(String name) {
+ super(name);
+ }
+
+
+ public static Test suite() {
+ return new TestSuite(PermissionTest.class);
+ }
+
+
+ /**
+ * All tests in this suite require a user and a weblog.
+ */
+ @Override
+ public void setUp() throws Exception {
+
+ log.info("BEGIN");
+
+ // setup weblogger
+ TestUtils.setupWeblogger();
+
+ try {
+ testUser = TestUtils.setupUser("custPermsTestUser");
+ testWeblog = TestUtils.setupWeblog("custPermsTestWeblog", testUser);
+ TestUtils.endSession(true);
+ } catch (Exception ex) {
+ log.error("ERROR in setup", ex);
+ throw new Exception("Test setup failed", ex);
+ }
+
+ log.info("END");
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+
+ log.info("BEGIN");
+
+ try {
+ TestUtils.teardownWeblog(testWeblog.getId());
+ TestUtils.teardownUser(testUser.getUserName());
+ TestUtils.endSession(true);
+ } catch (Exception ex) {
+ log.error("ERROR in tear down", ex);
+ throw new Exception("Test teardown failed", ex);
+ }
+
+ log.info("END");
+ }
+
+
+ /**
+ * Test basic persistence operations ... Create, Update, Delete.
+ */
+ public void testPermissionsCRUD() throws Exception {
+
+ log.info("BEGIN");
+
+ UserManager mgr = WebloggerFactory.getWeblogger().getUserManager();
+
+ WebloggerPermission p1 = new WebloggerPermission("test1", "app", "action1");
+ WebloggerPermission p2 = new WebloggerPermission("test2", "obj1", "action1,action2");
+
+ WebloggerPermission perm = null;
+
+ // grant permissions
+ testUser = TestUtils.getManagedUser(testUser);
+ mgr.grantPermission(testUser, p1);
+ mgr.grantPermission(testUser, p2);
+ TestUtils.endSession(true);
+
+ // check that grant on p2 was successful
+ testUser = TestUtils.getManagedUser(testUser);
+ perm = null;
+ perm = mgr.getPermission(testUser, "test2", "obj1");
+ assertNotNull(perm);
+ assertTrue(perm.getActionsAsSet().contains("action1"));
+ assertTrue(perm.getActionsAsSet().contains("action2"));
+
+ // check that grant on p1 was successful
+ testUser = TestUtils.getManagedUser(testUser);
+ perm = null;
+ perm = mgr.getPermission(testUser, "test1", "app");
+ assertNotNull(perm);
+ assertTrue(perm.getActionsAsSet().contains("action1"));
+
+ // revoke permissions
+ mgr.revokePermission(testUser, p1);
+ TestUtils.endSession(true);
+
+ // check that revoke was successful
+ testUser = TestUtils.getManagedUser(testUser);
+ perm = null;
+ perm = mgr.getPermission(testUser, "test1", "app");
+ assertNull(perm);
+
+ // test more inclusive checkPermission() method
+ boolean result = mgr.checkPermission(testUser, p2);
+ assertTrue(result);
+
+ // cleanup remaining permission
+ mgr.revokePermission(testUser, p2);
+ TestUtils.endSession(true);
+
+ // check that revoke was successful
+ testUser = TestUtils.getManagedUser(testUser);
+ perm = null;
+ perm = mgr.getPermission(testUser, "test2", "obj1");
+ assertNull(perm);
+
+ log.info("END");
+ }
+
+
+ /**
+ * Tests weblog invitation process.
+ */
+// public void testPermissionChecks() throws Exception {
+//
+// log.info("BEGIN");
+//
+// UserPermission perm =
+// new UserPermission(testWeblog, testUser, UserPermission.POST);
+// UserManager umgr = WebloggerFactory.getWeblogger().getUserManager();
+// assertTrue(umgr.checkPermission(perm, testUser));
+//
+// // we need a second user for this test
+// User adminUser = TestUtils.setupUser("adminUser");
+// umgr.grantRole("admin", adminUser);
+// TestUtils.endSession(true);
+//
+// // because adminUser is a global admin, they should have POST perm
+// UserPermission perm2 =
+// new UserPermission(testWeblog, testUser, UserPermission.POST);
+// assertTrue(umgr.checkPermission(perm, testUser));
+//
+// log.info("END");
+// }
+}