Author: breser
Date: Thu Dec 6 20:10:51 2012
New Revision: 1418052
URL: http://svn.apache.org/viewvc?rev=1418052&view=rev
Log:
On the in-repo-authz branch: Add tests for in repo authz.
I know some of the tests are failing, I'll be fixing that shortly. The API
guarantees a given error code and we're not returning the correct code in a few
cases.
* subversion/tests/libsvn_repos/repos-test.c
(check_access_tests): Add struct to describe tests used by ...
(authz_check_access): Factor out some code from authz() so I can reuse it.
(authz): Adjust test_set to be a check_access_tests struct and use
authz_check_access().
(in_repo_authz): Add.
(test_funcs): Add in_repo_authz() to the list of tests to run.
Modified:
subversion/branches/in-repo-authz/subversion/tests/libsvn_repos/repos-test.c
Modified:
subversion/branches/in-repo-authz/subversion/tests/libsvn_repos/repos-test.c
URL:
http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/tests/libsvn_repos/repos-test.c?rev=1418052&r1=1418051&r2=1418052&view=diff
==============================================================================
---
subversion/branches/in-repo-authz/subversion/tests/libsvn_repos/repos-test.c
(original)
+++
subversion/branches/in-repo-authz/subversion/tests/libsvn_repos/repos-test.c
Thu Dec 6 20:10:51 2012
@@ -1147,6 +1147,60 @@ authz_get_handle(svn_authz_t **authz_p,
return SVN_NO_ERROR;
}
+struct check_access_tests {
+ const char *path;
+ const char *repo_name;
+ const char *user;
+ const svn_repos_authz_access_t required;
+ const svn_boolean_t expected;
+};
+
+/* Helper for the authz test. Runs a set of tests against AUTHZ_CFG
+ * as defined in TESTS. */
+static svn_error_t *
+authz_check_access(svn_authz_t *authz_cfg,
+ const struct check_access_tests *tests,
+ apr_pool_t *pool)
+{
+ int i;
+ svn_boolean_t access_granted;
+
+ /* Loop over the test array and test each case. */
+ for (i = 0; !(tests[i].path == NULL
+ && tests[i].required == svn_authz_none); i++)
+ {
+ SVN_ERR(svn_repos_authz_check_access(authz_cfg,
+ tests[i].repo_name,
+ tests[i].path,
+ tests[i].user,
+ tests[i].required,
+ &access_granted, pool));
+
+ if (access_granted != tests[i].expected)
+ {
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Authz incorrectly %s %s%s access "
+ "to %s%s%s for user %s",
+ access_granted ?
+ "grants" : "denies",
+ tests[i].required
+ & svn_authz_recursive ?
+ "recursive " : "",
+ tests[i].required
+ & svn_authz_read ?
+ "read" : "write",
+ tests[i].repo_name ?
+ tests[i].repo_name : "",
+ tests[i].repo_name ?
+ ":" : "",
+ tests[i].path,
+ tests[i].user ?
+ tests[i].user : "-");
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
/* Test that authz is giving out the right authorizations. */
@@ -1160,34 +1214,28 @@ authz(apr_pool_t *pool)
apr_pool_t *subpool = svn_pool_create(pool);
int i;
/* Definition of the paths to test and expected replies for each. */
- struct
- {
- const char *path;
- const char *user;
- const svn_repos_authz_access_t required;
- const svn_boolean_t expected;
- } test_set[] = {
+ struct check_access_tests test_set[] = {
/* Test that read rules are correctly used. */
- { "/A", NULL, svn_authz_read, TRUE },
- { "/iota", NULL, svn_authz_read, FALSE },
+ { "/A", "greek", NULL, svn_authz_read, TRUE },
+ { "/iota", "greek", NULL, svn_authz_read, FALSE },
/* Test that write rules are correctly used. */
- { "/A", "plato", svn_authz_write, TRUE },
- { "/A", NULL, svn_authz_write, FALSE },
+ { "/A", "greek", "plato", svn_authz_write, TRUE },
+ { "/A", "greek", NULL, svn_authz_write, FALSE },
/* Test that pan-repository rules are found and used. */
- { "/A/B/lambda", "plato", svn_authz_read, TRUE },
- { "/A/B/lambda", NULL, svn_authz_read, FALSE },
+ { "/A/B/lambda", "greek", "plato", svn_authz_read, TRUE },
+ { "/A/B/lambda", "greek", NULL, svn_authz_read, FALSE },
/* Test that authz uses parent path ACLs if no rule for the path
exists. */
- { "/A/C", NULL, svn_authz_read, TRUE },
+ { "/A/C", "greek", NULL, svn_authz_read, TRUE },
/* Test that recursive access requests take into account the rules
of subpaths. */
- { "/A/D", "plato", svn_authz_read | svn_authz_recursive, TRUE },
- { "/A/D", NULL, svn_authz_read | svn_authz_recursive, FALSE },
+ { "/A/D", "greek", "plato", svn_authz_read | svn_authz_recursive, TRUE },
+ { "/A/D", "greek", NULL, svn_authz_read | svn_authz_recursive, FALSE },
/* Test global write access lookups. */
- { NULL, "plato", svn_authz_read, TRUE },
- { NULL, NULL, svn_authz_write, FALSE },
+ { NULL, "greek", "plato", svn_authz_read, TRUE },
+ { NULL, "greek", NULL, svn_authz_write, FALSE },
/* Sentinel */
- { NULL, NULL, svn_authz_none, FALSE }
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
};
/* The test logic:
@@ -1242,34 +1290,7 @@ authz(apr_pool_t *pool)
SVN_ERR(authz_get_handle(&authz_cfg, contents, subpool));
/* Loop over the test array and test each case. */
- for (i = 0; !(test_set[i].path == NULL
- && test_set[i].required == svn_authz_none); i++)
- {
- SVN_ERR(svn_repos_authz_check_access(authz_cfg, "greek",
- test_set[i].path,
- test_set[i].user,
- test_set[i].required,
- &access_granted, subpool));
-
- if (access_granted != test_set[i].expected)
- {
- return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
- "Authz incorrectly %s %s%s access "
- "to greek:%s for user %s",
- access_granted ?
- "grants" : "denies",
- test_set[i].required
- & svn_authz_recursive ?
- "recursive " : "",
- test_set[i].required
- & svn_authz_read ?
- "read" : "write",
- test_set[i].path,
- test_set[i].user ?
- test_set[i].user : "-");
- }
- }
-
+ SVN_ERR(authz_check_access(authz_cfg, test_set, subpool));
/* The authz rules for the phase 2 tests, first case (cyclic
dependency). */
@@ -1341,6 +1362,119 @@ authz(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+
+/* Test in-repo authz paths */
+static svn_error_t *
+in_repo_authz(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos;
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_revnum_t youngest_rev;
+ svn_authz_t *authz_cfg;
+ const char *authz_contents;
+ const char *repos_root;
+ const char *repos_url;
+ const char *authz_url;
+ svn_error_t *err;
+ struct check_access_tests test_set[] = {
+ /* reads */
+ { "/A", NULL, NULL, svn_authz_read, FALSE },
+ { "/A", NULL, "plato", svn_authz_read, TRUE },
+ { "/A", NULL, "socrates", svn_authz_read, TRUE },
+ /* writes */
+ { "/A", NULL, NULL, svn_authz_write, FALSE },
+ { "/A", NULL, "socrates", svn_authz_write, FALSE },
+ { "/A", NULL, "plato", svn_authz_write, TRUE },
+ /* Sentinel */
+ { NULL, NULL, NULL, svn_authz_none, FALSE }
+ };
+
+ /* Test plan:
+ * Create an authz file and put it in the repository.
+ * Verify it can be read with an relative URL.
+ * Verify it can be read with an absolute URL.
+ * Verify non-existant path does not error out when must_exist is FALSE.
+ * Verify non-existant path does error out when must_exist is TRUE.
+ * Verify that an http:// URL produces an error.
+ * Verify that an svn:// URL produces an error.
+ */
+
+ /* What we'll put in the authz file, it's simple since we're not testing
+ * the parsing, just that we got what we expected. */
+ authz_contents =
+ "" NL
+ "" NL
+ "[/]" NL
+ "plato = rw" NL
+ "socrates = r";
+
+ /* Create a filesystem and repository. */
+ SVN_ERR(svn_test__create_repos(&repos, "test-repo-in-repo-authz",
+ opts, pool));
+ fs = svn_repos_fs(repos);
+
+ /* Commit the authz file to the repo. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "authz", pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "authz", authz_contents,
+ pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+ SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+
+ /* repos relative URL */
+ repos_root = svn_repos_path(repos, pool);
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/authz", TRUE, repos_root,
+ pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* absolute file URL, repos_root is NULL to validate the contract that it
+ * is not needed except when a repos relative URL is passed. */
+ SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_root, pool));
+ authz_url = apr_pstrcat(pool, repos_url, "/authz", (char *)NULL);
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, authz_url, TRUE, NULL, pool));
+ SVN_ERR(authz_check_access(authz_cfg, test_set, pool));
+
+ /* Non-existant path in the repo with must_exist set to FALSE */
+ SVN_ERR(svn_repos_authz_read2(&authz_cfg, "^/A/authz", FALSE, repos_root,
+ pool));
+
+ /* Non-existant path in the repo with must_exist set to TRUE */
+ err = svn_repos_authz_read2(&authz_cfg, "^/A/authz", TRUE, repos_root,
+ pool);
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* http:// URL which is unsupported */
+ err = svn_repos_authz_read2(&authz_cfg, "http://example.com/repo/authz",
+ TRUE, repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+ /* svn:// URL which is unsupported */
+ err = svn_repos_authz_read2(&authz_cfg, "svn://example.com/repo/authz",
+ TRUE, repos_root, pool);
+ if (!err || err->apr_err != SVN_ERR_AUTHZ_INVALID_CONFIG)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, err,
+ "Got %s error instead of expected "
+ "SVN_ERR_AUTHZ_INVALID_CONFIG",
+ err ? "unexpected" : "no");
+ svn_error_clear(err);
+
+
+ return SVN_NO_ERROR;
+}
/* Callback for the commit editor tests that relays requests to
@@ -2585,6 +2719,8 @@ struct svn_test_descriptor_t test_funcs[
"test removal of defunct locks"),
SVN_TEST_PASS2(authz,
"test authz access control"),
+ SVN_TEST_OPTS_PASS(in_repo_authz,
+ "test authz stored in the repo"),
SVN_TEST_OPTS_PASS(commit_editor_authz,
"test authz in the commit editor"),
SVN_TEST_OPTS_PASS(commit_continue_txn,