# # # patch "cmd_policy.cc" # from [e3d6ec064d5dfb48a169149baf63198c5b3ec996] # to [d7da097ee02143da4b25fb5fce8ad7bec785a76a] # # patch "policies/branch.hh" # from [c25aa6d7e6c48211fcefd83213ebe419725bbf83] # to [9ceb051153d9d73a97d4e265a8000edaa17cd72d] # # patch "policies/delegation.hh" # from [2e25046f2100fed7cbb1479a0b7cc6c4d2974292] # to [cba55a5ff7473b89df71c49363c2c71932d314a1] # # patch "policies/policy_branch.hh" # from [3fdcc5c21b9d9f72d001d4241d86b5f176b4fcce] # to [aa0e52cfa7cbab51fe992effc8e8d1b5204aff95] # # patch "project.cc" # from [9c1b0a62e26875c7b8991d5a3c3fdc57f894a347] # to [e57cda13c4b33fd4c8d0d539a6d6b41eb06a67bc] # # patch "project.hh" # from [8983d9b63cfab024393410d63da128a013e93219] # to [ca380355b0b360f9cb68b97149df84dc4f46d21f] # ============================================================ --- cmd_policy.cc e3d6ec064d5dfb48a169149baf63198c5b3ec996 +++ cmd_policy.cc d7da097ee02143da4b25fb5fce8ad7bec785a76a @@ -93,26 +93,32 @@ CMD(create_subpolicy, "create_subpolicy" database db(app); key_store keys(app); project_t project(db, app.lua, app.opts); - branch_name prefix = typecast_vocab(idx(args, 0)); - branch_name name = prefix; - name.append(branch_name("__policy__", origin::internal)); + branch_name name = typecast_vocab(idx(args, 0)); - governing_policy_info gov; + policy_chain gov; project.find_governing_policy(name(), gov); - policies::policy_branch parent_branch(gov.governing_policy_parent->get_delegation(gov.delegation_to_governing_policy)); + E(!gov.empty(), origin::user, + F("Cannot find a parent policy for '%s'") % name); + E(gov.back().full_policy_name != name(), origin::user, + F("Policy '%s' already exists") % name); - policies::editable_policy parent(*parent_branch.begin()); + policies::policy_branch parent_branch(gov.back().delegation); - policies::policy_branch new_policy_branch(policy_branch::new_branch()); - policies::policy new_policy(new_policy_branch.create_initial_revision()); + policies::editable_policy parent(**parent_branch.begin()); - parent.set_delegation(name, new_policy.get_delegation("__policy__")); + std::set admin_keys; + { + key_identity_info ident; + ident.id = keys.signing_key; + project.complete_key_identity(keys, app.lua, ident); + admin_keys.insert(typecast_vocab(ident.official_name)); + } + branch_name del_name(name); + del_name.strip_prefix(branch_name(gov.back().full_policy_name, origin::internal)); + parent.set_delegation(del_name(), policies::delegation::create(admin_keys)); - transaction_guard guard(db); - new_policy_branch.commit(new_policy, utf8("")); parent_branch.commit(parent, utf8("Add delegation to new child policy")); - guard.commit(); } CMD(create_branch, "create_branch", "", CMD_REF(policy), @@ -129,11 +135,14 @@ CMD(create_branch, "create_branch", "", project_t project(db, app.lua, app.opts); branch_name branch = typecast_vocab(idx(args, 0)); - governing_policy_info gov; + policy_chain gov; project.find_governing_policy(branch(), gov); - policies::policy_branch parent(gov.delegation_to_governing_policy()); - policies::editable_policy ppol(*parent.begin()); + E(!gov.empty(), origin::user, + F("Cannot find policy over '%s'") % branch); + + policies::policy_branch parent(gov.back().delegation); + policies::editable_policy ppol(**parent.begin()); std::set admin_keys; { key_identity_info ident; @@ -141,12 +150,11 @@ CMD(create_branch, "create_branch", "", project.complete_key_identity(keys, app.lua, ident); admin_keys.insert(typecast_vocab(ident.official_name)); } - std::string relative_name = branch().substr(parent_prefix().size()); - if (relative_name.size() > 0 && relative_name[0] == '.') - relative_name.erase(0, 1); - if (relative_name.empty()) - relative_name = "__main__"; - ppol.set_branch(relative_name, policies::branch(admin_keys)); + branch_name suffix(branch); + suffix.strip_prefix(branch_name(gov.back().full_policy_name, origin::internal)); + if (suffix().empty()) + suffix = branch_name("__main__", origin::internal); + ppol.set_branch(suffix(), policies::branch::create(admin_keys)); parent.commit(ppol, utf8("Add branch.")); } ============================================================ --- policies/branch.hh c25aa6d7e6c48211fcefd83213ebe419725bbf83 +++ policies/branch.hh 9ceb051153d9d73a97d4e265a8000edaa17cd72d @@ -16,6 +16,8 @@ #include "vocab.hh" +class external_key_name; + namespace policies { class branch @@ -24,6 +26,8 @@ namespace policies { std::set signers; public: branch(); + static branch create(std::set const & admins); + branch_uid const & get_uid() const; std::set const & get_signers() const; void serialize(std::string & out) const; ============================================================ --- policies/delegation.hh 2e25046f2100fed7cbb1479a0b7cc6c4d2974292 +++ policies/delegation.hh cba55a5ff7473b89df71c49363c2c71932d314a1 @@ -18,6 +18,8 @@ #include "policies/branch.hh" +class external_key_name; + namespace policies { class policy; @@ -31,6 +33,8 @@ namespace policies { delegation(); explicit delegation(revision_id const & r); explicit delegation(branch const & b); + static delegation create(std::set const & admins); + void serialize(std::string & out) const; void deserialize(std::string const & in); ============================================================ --- policies/policy_branch.hh 3fdcc5c21b9d9f72d001d4241d86b5f176b4fcce +++ policies/policy_branch.hh aa0e52cfa7cbab51fe992effc8e8d1b5204aff95 @@ -14,6 +14,7 @@ #include #include "policies/branch.hh" +#include "policies/delegation.hh" #include "policies/policy.hh" namespace policies { @@ -29,6 +30,7 @@ namespace policies { typedef policy_set::const_iterator iterator; policy_branch(branch const & b); + policy_branch(delegation const & d); static policy_branch new_branch(std::set const & signers); branch const & get_spec() const; ============================================================ --- project.cc 9c1b0a62e26875c7b8991d5a3c3fdc57f894a347 +++ project.cc e57cda13c4b33fd4c8d0d539a6d6b41eb06a67bc @@ -73,10 +73,12 @@ void walk_policies(shared_ptr ro // walk the tree of policies, resolving children if needed void walk_policies(shared_ptr root, child_policy_map & children, - boost::function, string)> fn, - string current_prefix = "") + boost::function, string, + policies::delegation const &)> fn, + string current_prefix = "", + policies::delegation del = policies::delegation()) { - fn(root, current_prefix); + fn(root, current_prefix, del); policy::del_map const & d(root->list_delegations()); for (policy::del_map::const_iterator i = d.begin(); i != d.end(); ++i) @@ -98,7 +100,7 @@ void walk_policies(shared_ptr ro c = x.first; } - walk_policies(c->second, children, fn, child_prefix); + walk_policies(c->second, children, fn, child_prefix, i->second); } } @@ -115,7 +117,8 @@ public: map & branches; public: branch_lister(map & b) : branches(b) { } - void operator()(shared_ptr pol, string prefix) + void operator()(shared_ptr pol, string prefix, + policies::delegation const & del) { map const & x = pol->list_branches(); for (map::const_iterator i = x.begin(); i != x.end(); ++i) @@ -134,12 +137,29 @@ public: } }; +class policy_lister +{ + branch_name const & base; + set & policies; +public: + policy_lister(branch_name const & b, set & p) + : base(b), policies(p) { } + void operator()(shared_ptr pol, string prefix, + policies::delegation const & del) + { + branch_name n(prefix, origin::internal); + if (n.has_prefix(n)) + policies.insert(n); + } +}; + class tag_lister { set & tags; public: tag_lister(set & t) : tags(t) { } - void operator()(shared_ptr pol, string prefix) + void operator()(shared_ptr pol, string prefix, + policies::delegation const & del) { map const & x = pol->list_tags(); for (map::const_iterator i = x.begin(); @@ -162,27 +182,36 @@ class policy_finder class policy_finder { string target; - governing_policy_info & info; + policy_chain & info; public: - policy_finder(string const & target, governing_policy_info & info) + policy_finder(string const & target, policy_chain & info) : target(target), info(info) { - info.governing_policy_name.clear(); - info.delegation_to_governing_policy.clear(); - info.governing_policy.reset(); - info.governing_policy_parent.reset(); + info.clear(); } - void operator()(shared_ptr pol, string prefix) + void operator()(shared_ptr pol, string prefix, + policies::delegation const & del) { if (prefix.empty()) { + policy_chain_item i; + i.policy = pol; + info.push_back(i); return; } - if (target.find(prefix) == 0 && prefix.size() > info.governing_policy_name.size()) + if (target.find(prefix) == 0) { - info.governing_policy_name = prefix; - info.governing_policy = pol; + bool equals = target == prefix; + bool is_prefix = target.length() > prefix.length() && target[prefix.length()] == '.'; + if (equals || is_prefix) + { + policy_chain_item i; + i.policy = pol; + i.full_policy_name = prefix; + i.delegation = del; + info.push_back(i); + } } } }; @@ -294,21 +323,18 @@ public: } void find_governing_policy(std::string const & of_what, - governing_policy_info & info) + policy_chain & info) { walk_policies(policy, child_policies, policy_finder(of_what, info)); - if (info.governing_policy) - { - // also return the parent, if it's a 'real' database policy rather - // than the synthesized root policy - info.governing_policy_parent = info.governing_policy->get_parent(); - if (info.governing_policy_parent == policy) - { - info.governing_policy_parent.reset(); - } - } } + + void list_policies(branch_name const & base, + set & children) + { + walk_policies(policy, child_policies, + policy_lister(base, children)); + } }; bool @@ -357,19 +383,6 @@ project_t::empty_project(database & db) { return project_t(db); } -/* -bool -project_t::get_policy_branch_policy_of(branch_name const & name, - editable_policy & policy_branch_policy, - branch_name & policy_prefix) -{ - shared_ptr result; - result = project_policy->policy->walk(name, policy_prefix); - if (!result) - return false; - policy_branch_policy = *result->get_policy(); - return true; -} bool project_t::policy_exists(branch_name const & name) const @@ -377,9 +390,11 @@ project_t::policy_exists(branch_name con if (project_policy->passthru) return name().empty(); - branch_name got; - shared_ptr sub = project_policy->policy->walk(name, got); - return sub && name == got; + policy_chain info; + find_governing_policy(name(), info); + if (info.empty()) + return false; + return info.back().full_policy_name == name(); } void @@ -389,23 +404,10 @@ project_t::get_subpolicies(branch_name c if (project_policy->passthru) return; - branch_name got; - shared_ptr sub = project_policy->policy->walk(name, got); - if (sub && got == name) - { - shared_ptr pol = sub->get_policy(); - editable_policy::const_delegation_map dels = pol->get_all_delegations(); - for (editable_policy::const_delegation_map::const_iterator i = dels.begin(); - i != dels.end(); ++i) - { - branch_name n(name); - n.append(branch_name(i->first, origin::internal)); - names.insert(n); - } - } + project_policy->list_policies(name, names); } -*/ + void project_t::get_branch_list(set & names, bool check_heads) @@ -880,7 +882,7 @@ project_t::find_governing_policy(string void project_t::find_governing_policy(string const & of_what, - governing_policy_info & info) + policy_chain & info) const { I(!project_policy->passthru); project_policy->find_governing_policy(of_what, info); @@ -895,15 +897,17 @@ project_t::put_tag(key_store & keys, put_cert(keys, id, tag_cert_name, cert_value(name, origin::user)); else { - governing_policy_info info; + policy_chain info; project_policy->find_governing_policy(name, info); - policies::branch pol_spec = info.governing_policy->get_branch("__policy__"); + E(!info.empty(), origin::user, + F("Cannot find policy for tag '%s'") % name); - policies::policy_branch br(pol_spec); + policies::policy_branch br(info.back().delegation); + I(br.begin() != br.end()); policies::editable_policy ep(**br.begin()); - ep.set_tag(name.substr(info.governing_policy_name.size() + 1), id); + ep.set_tag(name.substr(info.back().full_policy_name.size() + 1), id); br.commit(ep, utf8((F("Set tag %s") % name).str(), origin::internal)); ============================================================ --- project.hh 8983d9b63cfab024393410d63da128a013e93219 +++ project.hh ca380355b0b360f9cb68b97149df84dc4f46d21f @@ -17,6 +17,7 @@ #include "cert.hh" //#include "editable_policy.hh" #include "outdated_indicator.hh" +#include "policies/delegation.hh" #include "vocab.hh" class arg_type; @@ -78,15 +79,15 @@ namespace policies { class policy; } -struct governing_policy_info +struct policy_chain_item { - boost::shared_ptr governing_policy; - std::string governing_policy_name; - - boost::shared_ptr governing_policy_parent; - std::string delegation_to_governing_policy; + boost::shared_ptr policy; + std::string full_policy_name; + policies::delegation delegation; }; +typedef std::vector policy_chain; + class project_t { // In the hypothetical future situation where one monotone process is @@ -115,11 +116,8 @@ public: policies::policy & get_base_policy() const; void find_governing_policy(std::string const & of_what, - governing_policy_info & info); + policy_chain & info) const; - //bool get_policy_branch_policy_of(branch_name const & name, - // editable_policy & policy_branch_policy, - // branch_name & policy_prefix); bool policy_exists(branch_name const & name) const; void get_subpolicies(branch_name const & name, std::set & names) const;