📄 repos-test.c
字号:
SVN_ERR(svn_fs_lock(&l1, fs, "/iota", NULL, NULL, 0, 0, youngest_rev, FALSE, subpool)); SVN_ERR(svn_fs_lock(&l2, fs, "/A/mu", NULL, NULL, 0, 0, youngest_rev, FALSE, subpool)); SVN_ERR(svn_fs_lock(&l3, fs, "/A/D/gamma", NULL, NULL, 0, 0, youngest_rev, FALSE, subpool)); /* Break l2. */ SVN_ERR(svn_fs_unlock(fs, "/A/mu", NULL, TRUE, subpool)); /* Steal l3 from ourselves. */ SVN_ERR(svn_fs_lock(&l4, fs, "/A/D/gamma", NULL, NULL, 0, 0, youngest_rev, TRUE, subpool)); /* Create the editor. */ SVN_ERR(create_rmlocks_editor(&editor, &edit_baton, &removed, subpool)); /* Report what we have. */ SVN_ERR(svn_repos_begin_report(&report_baton, 1, "user1", repos, "/", "", NULL, FALSE, TRUE, FALSE, editor, edit_baton, NULL, NULL, subpool)); SVN_ERR(svn_repos_set_path2(report_baton, "", 1, FALSE, NULL, subpool)); SVN_ERR(svn_repos_set_path2(report_baton, "iota", 1, FALSE, l1->token, subpool)); SVN_ERR(svn_repos_set_path2(report_baton, "A/mu", 1, FALSE, l2->token, subpool)); SVN_ERR(svn_repos_set_path2(report_baton, "A/D/gamma", 1, FALSE, l3->token, subpool)); /* End the report. */ SVN_ERR(svn_repos_finish_report(report_baton, pool)); /* And check that the edit did what we wanted. */ SVN_ERR(rmlocks_check(expected, removed)); } svn_pool_destroy(subpool); return SVN_NO_ERROR;}/* Helper for the authz test. Set *AUTHZ_P to a representation of AUTHZ_CONTENTS, using POOL for temporary allocation. */static svn_error_t *authz_get_handle(svn_authz_t **authz_p, const char *authz_contents, apr_pool_t *pool){ apr_file_t *authz_file; apr_status_t apr_err; const char *authz_file_path; svn_error_t *err; /* Create a temporary file, and fetch its name. */ SVN_ERR_W(svn_io_open_unique_file2(&authz_file, &authz_file_path, "authz_file", "tmp", svn_io_file_del_none, pool), "Opening temporary file"); /* Write the authz ACLs to the file. */ if ((apr_err = apr_file_write_full(authz_file, authz_contents, strlen(authz_contents), NULL))) { (void) apr_file_close(authz_file); (void) apr_file_remove(authz_file_path, pool); return svn_error_wrap_apr(apr_err, "Writing test authz file"); } /* Close the temporary descriptor. */ if ((apr_err = apr_file_close(authz_file))) { (void) apr_file_remove(authz_file_path, pool); return svn_error_wrap_apr(apr_err, "Closing test authz file"); } /* Read the authz configuration back and start testing. */ if ((err = svn_repos_authz_read(authz_p, authz_file_path, TRUE, pool))) { (void) apr_file_remove(authz_file_path, pool); return svn_error_quick_wrap(err, "Opening test authz file"); } /* Delete the file, but ignore the error if we've a more important one. */ if ((apr_err = apr_file_remove(authz_file_path, pool))) return svn_error_wrap_apr(apr_err, "Removing test authz file"); return SVN_NO_ERROR;}/* Test that authz is giving out the right authorizations. */static svn_error_t *authz(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ const char *contents; svn_authz_t *authz_cfg; svn_error_t *err; svn_boolean_t access_granted; 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[] = { /* Test that read rules are correctly used. */ { "/A", NULL, svn_authz_read, TRUE }, { "/iota", NULL, svn_authz_read, FALSE }, /* Test that write rules are correctly used. */ { "/A", "plato", svn_authz_write, TRUE }, { "/A", 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 }, /* Test that authz uses parent path ACLs if no rule for the path exists. */ { "/A/C", 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 }, /* Test global write access lookups. */ { NULL, "plato", svn_authz_read, TRUE }, { NULL, NULL, svn_authz_write, FALSE }, /* Sentinel */ { NULL, NULL, svn_authz_none, FALSE } }; *msg = "test authz access control"; if (msg_only) return SVN_NO_ERROR; /* The test logic: * * 1. Perform various access tests on a set of authz rules. Each * test has a known outcome and tests different aspects of authz, * such as inheriting parent-path authz, pan-repository rules or * recursive access. 'plato' is our friendly neighborhood user with * more access rights than other anonymous philosophers. * * 2. Load an authz file containing a cyclic dependency in groups * and another containing a reference to an undefined group. Verify * that svn_repos_authz_read fails to load both and returns an * "invalid configuration" error. * * 3. Regression test for a bug in how recursion is handled in * authz. The bug was that paths not under the parent path * requested were being considered during the determination of * access rights (eg. a rule for /dir2 matched during a lookup for * /dir), due to incomplete tests on path relations. */ /* The authz rules for the phase 1 tests. */ contents = "[greek:/A]" APR_EOL_STR "* = r" APR_EOL_STR "plato = w" APR_EOL_STR APR_EOL_STR "[greek:/iota]" APR_EOL_STR "* =" APR_EOL_STR APR_EOL_STR "[/A/B/lambda]" APR_EOL_STR "plato = r" APR_EOL_STR "* =" APR_EOL_STR APR_EOL_STR "[greek:/A/D]" APR_EOL_STR "plato = r" APR_EOL_STR "* = r" APR_EOL_STR APR_EOL_STR "[greek:/A/D/G]" APR_EOL_STR "plato = r" APR_EOL_STR "* =" APR_EOL_STR APR_EOL_STR "[greek:/A/B/E/beta]" APR_EOL_STR "* =" APR_EOL_STR APR_EOL_STR; /* Load the test authz rules. */ 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; 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 : "-"); } } /* The authz rules for the phase 2 tests, first case (cyclic dependency). */ contents = "[groups]" APR_EOL_STR "slaves = cooks,scribes,@gladiators" APR_EOL_STR "gladiators = equites,thraces,@slaves" APR_EOL_STR APR_EOL_STR "[greek:/A]" APR_EOL_STR "@slaves = r" APR_EOL_STR; /* Load the test authz rules and check that group cycles are reported. */ err = authz_get_handle(&authz_cfg, contents, subpool); 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); /* The authz rules for the phase 2 tests, second case (missing group definition). */ contents = "[greek:/A]" APR_EOL_STR "@senate = r" APR_EOL_STR; /* Check that references to undefined groups are reported. */ err = authz_get_handle(&authz_cfg, contents, subpool); 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); /* The authz rules for the phase 3 tests */ contents = "[/]" APR_EOL_STR "* = rw" APR_EOL_STR APR_EOL_STR "[greek:/dir2/secret]" APR_EOL_STR "* =" APR_EOL_STR; /* Load the test authz rules. */ SVN_ERR(authz_get_handle(&authz_cfg, contents, subpool)); /* Verify that the rule on /dir2/secret doesn't affect this request */ SVN_ERR(svn_repos_authz_check_access(authz_cfg, "greek", "/dir", NULL, (svn_authz_read | svn_authz_recursive), &access_granted, subpool)); if (!access_granted) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Regression: incomplete ancestry test " "for recursive access lookup."); /* That's a wrap! */ svn_pool_destroy(subpool); return SVN_NO_ERROR;}/* Callback for the commit editor tests that relays requests to authz. */static svn_error_t *commit_authz_cb(svn_repos_authz_access_t required, svn_boolean_t *allowed, svn_fs_root_t *root, const char *path, void *baton, apr_pool_t *pool){ svn_authz_t *authz_file = baton; return svn_repos_authz_check_access(authz_file, "test", path, "plato", required, allowed, pool);}/* Test that the commit editor is taking authz into account properly */static svn_error_t *commit_editor_authz (const char **msg, svn_boolean_t msg_only, 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; void *edit_baton; void *root_baton, *dir_baton, *dir2_baton, *file_baton; svn_error_t *err; const svn_delta_editor_t *editor; svn_authz_t *authz_file; apr_pool_t *subpool = svn_pool_create(pool); const char *authz_contents; *msg = "test authz in the commit editor";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -