Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E92A5D5A6 for ; Thu, 6 Dec 2012 20:11:13 +0000 (UTC) Received: (qmail 2170 invoked by uid 500); 6 Dec 2012 20:11:13 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 2140 invoked by uid 500); 6 Dec 2012 20:11:13 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 2133 invoked by uid 99); 6 Dec 2012 20:11:13 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Dec 2012 20:11:13 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Dec 2012 20:11:12 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 412252388ABC; Thu, 6 Dec 2012 20:10:52 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1418052 - /subversion/branches/in-repo-authz/subversion/tests/libsvn_repos/repos-test.c Date: Thu, 06 Dec 2012 20:10:51 -0000 To: commits@subversion.apache.org From: breser@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121206201052.412252388ABC@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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,