Author: chathura
Date: Sat Jan 26 02:06:09 2008
New Revision: 12957
Log:
Allowed the author of the comment to delete his own comments on other's
resources.
Secure registry only checks the permissions of pure resources.
URL handlers should check permissions for the tasks they perform in handler
specific way.
Secure registry cannot check these permissions as it does not have an idea about
the actions referred by specific url patterns. Those action are determined only
by its
url handler.
Added:
trunk/registry/modules/core/src/test/java/org/wso2/registry/secure/CommentsTest.java
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/urlhandlers/CommentURLHandler.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/secure/SecureRegistry.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/utils/AuthorizationUtil.java
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/urlhandlers/CommentURLHandler.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/urlhandlers/CommentURLHandler.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/urlhandlers/CommentURLHandler.java
Sat Jan 26 02:06:09 2008
@@ -18,12 +18,12 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.wso2.registry.Comment;
-import org.wso2.registry.RegistryConstants;
-import org.wso2.registry.RegistryException;
-import org.wso2.registry.Resource;
+import org.wso2.registry.*;
+import org.wso2.registry.secure.AuthorizationFailedException;
+import org.wso2.registry.utils.AuthorizationUtil;
import org.wso2.registry.jdbc.dao.CommentsDAO;
import org.wso2.usermanager.Realm;
+import org.wso2.usermanager.UserManagerException;
import javax.sql.DataSource;
import java.sql.Connection;
@@ -92,7 +92,7 @@
} catch (SQLException e) {
String msg = "Could not get the comment with ID: " + cID +
- ". Caused by: " + e.getMessage();
+ ". Caused by: " + e.getMessage();
log.error(msg, e);
throw new RegistryException(msg);
@@ -153,22 +153,69 @@
return false;
}
- Connection conn;
+ String userID = User.getCurrentUser();
+ String authPath = AuthorizationUtil.getAuthorizationPath(path);
+ String commentAuthor;
+
+ Connection conn1 = null;
try {
- conn = dataSource.getConnection();
+ conn1 = dataSource.getConnection();
+
+ Comment comment = commentsDAO.getComment(cID, conn1);
+ commentAuthor = comment.getUser();
+
+ } catch (SQLException e) {
+
+ String msg = "Failed to get the author of the comment.";
+ log.error(msg, e);
+ throw new RegistryException(msg, e);
+
+ } finally {
+ if (conn1 != null) {
+ try {
+ conn1.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+
+ // check if the current user has permission to delete this comment.
+ // users who have PUT permission on the commented resource can delete
any comment on
+ // that resource. Any user can delete his own comment.
+
+ try {
+ if (!userID.equals(commentAuthor) &&
+ !realm.getAuthorizer().isUserAuthorized(userID, authPath,
ActionConstants.PUT)) {
+
+ String msg = "User: " + userID +
+ " is not authorized to delete the comment on the
resource: " + authPath;
+ log.info(msg);
+ throw new AuthorizationFailedException(msg);
+ }
+
+ } catch (UserManagerException e) {
+ e.printStackTrace();
+ }
+
+
+ Connection conn2;
+ try {
+ conn2 = dataSource.getConnection();
} catch (SQLException e) {
throw new RegistryException(e.getMessage());
}
try {
- commentsDAO.deleteComment(cID, conn);
+
+ commentsDAO.deleteComment(cID, conn2);
+
} catch (SQLException e) {
String msg = "Could not delete the comment with the path: " + path;
throw new RegistryException(msg, e);
} finally {
- if (conn != null) {
+ if (conn2 != null) {
try {
- conn.close();
+ conn2.close();
} catch (SQLException ignore) {}
}
}
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/secure/SecureRegistry.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/secure/SecureRegistry.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/secure/SecureRegistry.java
Sat Jan 26 02:06:09 2008
@@ -266,11 +266,15 @@
public void delete(String path) throws RegistryException {
String authPath = getAuthorizationPath(path);
try {
- if (path.indexOf(";") > 0) {
+ if (path.indexOf(";") == -1) {
- // user is trying to perform a delete on resource metadata. so
put permission
- // is sufficient.
- if (!authorizer.isUserAuthorized(userID, authPath,
ActionConstants.PUT)) {
+ // if the request is for deleting an actual resource, we
should check if the
+ // user has delete permission of the resource. If the request
is for deleting
+ // a resource metadata, the permission stuff should also be
handled in
+ // the url handlers. Because there is no way to interpret the
path and identify
+ // the action at his point.
+
+ if (!authorizer.isUserAuthorized(userID, authPath,
ActionConstants.DELETE)) {
String msg = "Attempted to perform unauthorized
operation.";
log.info(msg);
throw new AuthorizationFailedException(msg);
@@ -278,11 +282,13 @@
} else {
- if (!authorizer.isUserAuthorized(userID, authPath,
ActionConstants.DELETE)) {
- String msg = "Attempted to perform unauthorized
operation.";
- log.info(msg);
- throw new AuthorizationFailedException(msg);
- }
+ // user is trying to perform a delete on resource metadata. so
put permission
+ // is sufficient.
+ //if (!authorizer.isUserAuthorized(userID, authPath,
ActionConstants.PUT)) {
+ // String msg = "Attempted to perform unauthorized
operation.";
+ // log.info(msg);
+ // throw new AuthorizationFailedException(msg);
+ //}
}
} catch (UserManagerException e) {
String msg = "Could not check authorization. \nCaused by " +
e.getMessage();
@@ -579,6 +585,15 @@
return (LogEntry[])authorizedEnListList.toArray(new
LogEntry[authorizedEnListList.size()]);
}
+ /**
+ * Path of a resource given to the Registry interface may contain
extensions to refer metadata
+ * about resources. But we always store the authorization for resources
against the pure
+ * resource path, stored in the ARTIFACTS table. This methods extracts
that pure resource path
+ * from a given path.
+ *
+ * @param resourcePath A path string, which may contain extensions
+ * @return pure resource path for the given path
+ */
private String getAuthorizationPath(String resourcePath) {
// if the user has permission to the current version, he will get
permission to all
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/utils/AuthorizationUtil.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/utils/AuthorizationUtil.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/utils/AuthorizationUtil.java
Sat Jan 26 02:06:09 2008
@@ -277,6 +277,44 @@
return childPath.substring(0, parentPathLength);
}
+ /**
+ * Path of a resource given to the Registry interface may contain
extensions to refer metadata
+ * about resources. But we always store the authorization for resources
against the pure
+ * resource path, stored in the ARTIFACTS table. This methods extracts
that pure resource path
+ * from a given path.
+ *
+ * @param resourcePath A path string, which may contain extensions
+ * @return pure resource path for the given path
+ */
+ public static String getAuthorizationPath(String resourcePath) {
+
+ // if the user has permission to the current version, he will get
permission to all
+ // previous versions of the same resource
+
+ String preparedPath = resourcePath;
+ if (resourcePath.indexOf("?") > 0) {
+ preparedPath = resourcePath.split("\\?")[0];
+ } else if (resourcePath.indexOf(";") > 0) {
+ preparedPath = resourcePath.split("\\;")[0];
+ }
+
+ if (preparedPath.equals(RegistryConstants.ROOT_PATH)) {
+ return preparedPath;
+
+ } else {
+
+ if (!preparedPath.startsWith(RegistryConstants.ROOT_PATH)) {
+ preparedPath = RegistryConstants.ROOT_PATH + preparedPath;
+ }
+
+ if (preparedPath.endsWith(RegistryConstants.PATH_SEPARATOR)) {
+ preparedPath = preparedPath.substring(0, preparedPath.length()
- 1);
+ }
+ }
+
+ return preparedPath;
+ }
+
private static boolean containsString(String value, String[] array) {
for (int i = 0; i < array.length; i++) {
if (value.equals(array[i])) {
Added:
trunk/registry/modules/core/src/test/java/org/wso2/registry/secure/CommentsTest.java
==============================================================================
--- (empty file)
+++
trunk/registry/modules/core/src/test/java/org/wso2/registry/secure/CommentsTest.java
Sat Jan 26 02:06:09 2008
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2006, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wso2.registry.secure;
+
+import junit.framework.TestCase;
+import org.wso2.registry.*;
+import org.wso2.registry.jdbc.realm.RegistryRealm;
+import org.wso2.registry.jdbc.realm.InMemoryRegistryRealm;
+import org.wso2.registry.jdbc.InMemoryJDBCRegistry;
+import org.wso2.usermanager.Realm;
+
+public class CommentsTest extends TestCase {
+
+ private static Registry registry = null;
+ private static RegistryRealm realm = null;
+
+ public void setUp() {
+ try {
+ if (registry == null) {
+ realm = new InMemoryRegistryRealm();
+ registry = new InMemoryJDBCRegistry(realm);
+ }
+ } catch (RegistryException e) {
+ fail("Failed to initialize the registry.");
+ }
+ }
+
+ public void testCommentDelete() {
+
+ try {
+ SecureRegistry adminReg =
+ new SecureRegistry(
+ RegistryConstants.ADMIN_USER,
+ RegistryConstants.ADMIN_PASSWORD,
+ registry,
+ realm);
+
+
+ Realm adminRealm = adminReg.getUserRealm();
+ adminRealm.getUserStoreAdmin().addUser("cu1", "cu1");
+
+ SecureRegistry cu1Reg = new SecureRegistry("cu1", "cu1", registry,
realm);
+
+ Resource r1 = new Resource();
+ r1.setContent("r1 content");
+ adminReg.put("/crtest/r1", r1);
+
+ adminRealm.getAccessControlAdmin().
+ authorizeUser("cu1", "/crtest/r1", ActionConstants.PUT);
+
+ Resource r2 = new Resource();
+ r2.setContent("r2 content");
+ adminReg.put("/crtest/r2", r2);
+
+ String c1 =
+ adminReg.addComment("/crtest/r1", new Comment("admin's
comment on /crtest/r1"));
+
+ String c2 =
+ adminReg.addComment("/crtest/r2", new Comment("admin's
comment on /crtest/r2"));
+
+ String c3 =
+ cu1Reg.addComment("/crtest/r1", new Comment("cu1's comment
on /crtest/r1"));
+
+ String c4 =
+ cu1Reg.addComment("/crtest/r2", new Comment("cu1's comment
on /crtest/r2"));
+
+ try {
+ cu1Reg.delete(c1);
+ } catch (RegistryException e) {
+ fail("cu1 should be able to delete admin's comment on admin's
resource as he has" +
+ " write prmissions on it.");
+ }
+
+ boolean failed = false;
+ try {
+ cu1Reg.delete(c2);
+ } catch (RegistryException e) {
+ failed = true;
+ }
+ assertTrue("cu1 should not have " +
+ "permission to delete admin's comment on admin's
resource.", failed);
+
+ try {
+ cu1Reg.delete(c3);
+ } catch (RegistryException e) {
+ fail("cu1 should be able to delete cu1's comment on admin's
resource even he does" +
+ " not have write permissions for it.");
+ }
+
+ try {
+ cu1Reg.delete(c4);
+ } catch (RegistryException e) {
+ fail("cu1 should be able to delete cu1's comment on admin's
resource. In this case" +
+ "cu1 also has write permissions on admin's resource.");
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ }
+}
_______________________________________________
Registry-dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/registry-dev