Author: rhillegas
Date: Tue Jun 12 17:11:11 2007
New Revision: 546683
URL: http://svn.apache.org/viewvc?view=rev&rev=546683
Log:
DERBY-2109: Commit Martin's refinement of DatabasePrincipal wildcarding.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/authentication/DatabasePrincipal.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.policy
Modified: db/derby/code/trunk/java/engine/org/apache/derby/authentication/DatabasePrincipal.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/authentication/DatabasePrincipal.java?view=diff&rev=546683&r1=546682&r2=546683
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/authentication/DatabasePrincipal.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/authentication/DatabasePrincipal.java
Tue Jun 12 17:11:11 2007
@@ -29,21 +29,98 @@
* user identity with controlled access to Derby-specific privileges.
* An authenticated user may have other identities which make sense in
* other code domains.
+ *
+ * A principal represents an identity characterized by a user name.
+ * The wildcard user name "*" can be used to declare a policy grant to
+ * "all users".
+ *
+ * In future, database-scoped identities will be supported by appending
+ * the user name with the distinguished character "@" followed by a
+ * database name or the wildcard "*" meaning all databases.
+ *
+ * Note that the special characters "@" and "*" may be part of the user
+ * or database names if escaped by a "\" character; the escaping "\"
+ * character itself may be included in a name if doubled.
*/
public class DatabasePrincipal implements Principal, Serializable {
/**
+ * A principal with the distinguished name "*" representing a grant
+ * for "all user names".
+ */
+ static public final DatabasePrincipal ANY_DATABASE_PRINCIPAL
+ = new DatabasePrincipal("*");
+
+ /**
* The name of the principal.
+ *
+ * The distinguished "*" character means "all user names" if not
+ * escaped by a "\" character.
*/
private final String userName;
/**
* Constructs a principal with the specified name.
*
- * @param userName the name of the principal
+ * @param name the name of the principal
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if name is not a legal Principal name
*/
- public DatabasePrincipal(String userName) {
- this.userName = userName;
+ public DatabasePrincipal(String name) {
+ parsePrincipalName(name);
+ this.userName = name;
+ }
+
+ /**
+ * Parses a principal name for a user name and an optional database name.
+ *
+ * @param name the name of the principal
+ */
+ private void parsePrincipalName(String name) {
+ // note that exception messages on the Principal name aren't localized,
+ // as is the general rule with runtime exceptions indicating
+ // internal coding errors
+
+ // analog to org.apache.derby.security.*Permission, we check that
+ // the name is not null nor empty
+ if (name == null) {
+ throw new NullPointerException("actions can't be null");
+ }
+ if (name.length() == 0) {
+ throw new IllegalArgumentException("actions can't be empty");
+ }
+
+ // handle the "*" wildcard meaning "all user names"
+ if (name.equals("*")) {
+ return;
+ }
+
+ // future releases will support Database-scoped identities by
+ // names of the form "userName@databaseName"; until then, however,
+ // we throw an exception if we find a databaseName clause.
+ for (int i = 0; i < name.length(); i++) {
+ switch (name.charAt(i)) {
+ case '\\' : {
+ // ignore any escaped character
+ i++;
+ break;
+ }
+ case '*' : {
+ // disallow unescaped special characters
+ final String msg
+ = "unescaped '*' character not allowed in name";
+ throw new IllegalArgumentException(msg);
+ }
+ case '@' : {
+ // beginning of databaseName clause
+ final String msg
+ = "unescaped '@' starting a databaseName not supported";
+ throw new IllegalArgumentException(msg);
+ }
+ default:
+ // ignore other character (including ' ')
+ }
+ }
}
/**
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.java?view=diff&rev=546683&r1=546682&r2=546683
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.java
Tue Jun 12 17:11:11 2007
@@ -189,19 +189,58 @@
* Tests SystemPermissions.
*/
public void execute() throws IOException {
+ checkDatabasePrincipal();
checkSystemPermission();
checkDatabasePermission();
}
/**
+ * Tests DatabasePrincipal.
+ */
+ private void checkDatabasePrincipal() throws IOException {
+ // test DatabasePrincipal with null name argument
+ try {
+ new DatabasePrincipal(null);
+ fail("expected NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected exception
+ }
+
+ // test DatabasePrincipal with empty name argument
+ try {
+ new DatabasePrincipal("");
+ fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected exception
+ }
+
+ // test DatabasePrincipal with illegal name argument
+ try {
+ new DatabasePrincipal("disallowed: unescaped *");
+ fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected exception
+ }
+
+ // test DatabasePrincipal with illegal name argument
+ try {
+ new DatabasePrincipal("not yet supported: userName@databaseName");
+ fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected exception
+ }
+
+ // test DatabasePrincipal with legal name argument
+ new DatabasePrincipal("supported: userNameWith\\\\character");
+ new DatabasePrincipal("supported: userNameWith\\*character");
+ new DatabasePrincipal("supported: userNameWith\\@character");
+ new DatabasePrincipal("*");
+ }
+
+ /**
* Tests SystemPermission.
*/
private void checkSystemPermission() throws IOException {
- final DatabasePrincipal authorizedUser
- = new DatabasePrincipal("authorizedSystemUser");
- final DatabasePrincipal unAuthorizedUser
- = new DatabasePrincipal("unAuthorizedSystemUser");
-
// test SystemPermission with null name argument
try {
new SystemPermission(null);
@@ -249,9 +288,13 @@
assertTrue(sp1.implies(sp0));
// test SystemPermission for authorized user against policy file
+ final DatabasePrincipal authorizedUser
+ = new DatabasePrincipal("authorizedSystemUser");
execute(authorizedUser, new ShutdownEngineAction(sp0), true);
// test SystemPermission for unauthorized user against policy file
+ final DatabasePrincipal unAuthorizedUser
+ = new DatabasePrincipal("unAuthorizedSystemUser");
execute(unAuthorizedUser, new ShutdownEngineAction(sp0), false);
}
@@ -259,11 +302,6 @@
* Tests DatabasePermission.
*/
private void checkDatabasePermission() throws IOException {
- final DatabasePrincipal authorizedUser
- = new DatabasePrincipal("authorizedSystemUser");
- final DatabasePrincipal unAuthorizedUser
- = new DatabasePrincipal("unAuthorizedSystemUser");
-
// test DatabasePermission with null url
try {
new DatabasePermission(null, DatabasePermission.CREATE);
@@ -399,6 +437,8 @@
// test DatabasePermission for authorized user against policy file
+ final DatabasePrincipal authorizedUser
+ = new DatabasePrincipal("authorizedSystemUser");
execute(authorizedUser,
new CreateDatabaseAction(relDirPathPermissions[2]), true);
execute(authorizedUser,
@@ -409,6 +449,8 @@
new CreateDatabaseAction(relDirPathPermissions[7]), true);
// test DatabasePermission for unauthorized user against policy file
+ final DatabasePrincipal unAuthorizedUser
+ = new DatabasePrincipal("unAuthorizedSystemUser");
execute(unAuthorizedUser,
new CreateDatabaseAction(relDirPathPermissions[2]), false);
execute(unAuthorizedUser,
@@ -417,6 +459,15 @@
new CreateDatabaseAction(relDirPathPermissions[6]), false);
execute(unAuthorizedUser,
new CreateDatabaseAction(relDirPathPermissions[7]), false);
+
+ // test DatabasePermission for authorized user against policy file
+ final DatabasePrincipal anyUser
+ = new DatabasePrincipal("anyUser");
+ final DatabasePermission dbPerm
+ = new DatabasePermission("directory:dir",
+ DatabasePermission.CREATE);
+ execute(anyUser,
+ new CreateDatabaseAction(dbPerm), true);
}
/**
@@ -567,7 +618,10 @@
final Set principalSet = new HashSet();
final Set noPublicCredentials = new HashSet();
final Set noPrivateCredentials = new HashSet();
+ // add the given principal
principalSet.add(principal);
+ // add a principal that matches an "all user names" grant
+ principalSet.add(DatabasePrincipal.ANY_DATABASE_PRINCIPAL);
final Subject subject = new Subject(true, principalSet,
noPublicCredentials,
noPrivateCredentials);
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.policy
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.policy?view=diff&rev=546683&r1=546682&r2=546683
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.policy
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/SystemPrivilegesPermissionTest.policy
Tue Jun 12 17:11:11 2007
@@ -54,6 +54,11 @@
permission org.apache.derby.security.DatabasePermission "directory:/level0/level1/-", "create";
};
+// specific test authorizations for System Privileges
+grant principal org.apache.derby.authentication.DatabasePrincipal "*" {
+ permission org.apache.derby.security.DatabasePermission "directory:dir", "create";
+};
+
//
// Permissions for the tests (derbyTesting.jar)
// We are liberal here, it's not a goal to make the test harness
|