# # # patch "cmd_policy.cc" # from [d7da097ee02143da4b25fb5fce8ad7bec785a76a] # to [5f5db2161539493e77190e965adb7b08cb30ace9] # # patch "database.cc" # from [39d2a1485b7c7950c526213947f2059f99d15d6e] # to [ef99937af2d57f2726d80037bdb20e82faedf4e9] # # patch "database.hh" # from [93d9cc24f2e244097eb07b13825629a9d5cd0241] # to [c0ae9e7cf842b2d639e95d2dff57ad34984621ec] # # patch "policies/branch.cc" # from [3bd0cffe26cab385a546c33bcf07eab8ae5737c9] # to [5b6b0d65bf8419f2961f228f9e3cc42ade0ba9f4] # # patch "policies/branch.hh" # from [9ceb051153d9d73a97d4e265a8000edaa17cd72d] # to [9256039b60c07de4b55bebe64ef3137b0608375f] # # patch "policies/delegation.cc" # from [4a7c89808693be8687cb1b20a3e1b0b4ea9e39dc] # to [b8d40b10773d64081b0d73f558e297eb5c6d459b] # # patch "policies/delegation.hh" # from [cba55a5ff7473b89df71c49363c2c71932d314a1] # to [e97d2d4daae6a861c4ad757fcf973a92157accc4] # # patch "policies/editable_policy.cc" # from [06796791844f610c07db45ed0418890b40f76337] # to [4b51aa214719e1fb198d510ed59b7ce0ba149727] # # patch "policies/editable_policy.hh" # from [aaa986ebda3403ab4a87c4bb7b9764ea95cd44d8] # to [d05ff58508caf9bb0bc87ffd14061839359fa08b] # # patch "policies/policy_branch.cc" # from [06796791844f610c07db45ed0418890b40f76337] # to [d7ae6973b3a68fe37eb5faca4174f705e336692b] # # patch "policies/policy_branch.hh" # from [aa0e52cfa7cbab51fe992effc8e8d1b5204aff95] # to [d9b4d6a763de19864950b3ede9b4c29c19f121ec] # # patch "project.cc" # from [e57cda13c4b33fd4c8d0d539a6d6b41eb06a67bc] # to [d117abfb5529ddd56bee8c288e2a846299d7f736] # # patch "project.hh" # from [ca380355b0b360f9cb68b97149df84dc4f46d21f] # to [17810c296afb72c1a8de0ac154e147c3418aa4f5] # ============================================================ --- cmd_policy.cc d7da097ee02143da4b25fb5fce8ad7bec785a76a +++ cmd_policy.cc 5f5db2161539493e77190e965adb7b08cb30ace9 @@ -70,13 +70,10 @@ CMD(create_project, "create_project", "" std::set signers; signers.insert(key_id_to_external_name(keys.signing_key)); - policies::policy_branch br = policies::policy_branch::new_branch(signers); - policies::editable_policy ep(br.create_initial_revision()); - br.commit(ep, utf8(N_("Create new policy branch"))); policies::editable_policy bp(project.get_base_policy()); - bp.set_delegation(project_name, policies::delegation(br.get_spec())); + bp.set_delegation(project_name, policies::delegation::create(app, signers)); policies::base_policy::write(bp); } @@ -102,9 +99,10 @@ CMD(create_subpolicy, "create_subpolicy" F("Cannot find a parent policy for '%s'") % name); E(gov.back().full_policy_name != name(), origin::user, F("Policy '%s' already exists") % name); + E(gov.back().delegation.is_branch_type(), origin::user, + F("cannot edit '%s', it is delegated to a specific revision") % name); + policies::policy_branch parent_branch(gov.back().delegation.get_branch_spec()); - policies::policy_branch parent_branch(gov.back().delegation); - policies::editable_policy parent(**parent_branch.begin()); std::set admin_keys; @@ -116,7 +114,7 @@ CMD(create_subpolicy, "create_subpolicy" } 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)); + parent.set_delegation(del_name(), policies::delegation::create(app, admin_keys)); parent_branch.commit(parent, utf8("Add delegation to new child policy")); } @@ -140,8 +138,9 @@ CMD(create_branch, "create_branch", "", E(!gov.empty(), origin::user, F("Cannot find policy over '%s'") % branch); - - policies::policy_branch parent(gov.back().delegation); + E(gov.back().delegation.is_branch_type(), origin::user, + F("cannot edit '%s', it is delegated to a specific revision") % branch); + policies::policy_branch parent(gov.back().delegation.get_branch_spec()); policies::editable_policy ppol(**parent.begin()); std::set admin_keys; { @@ -154,7 +153,7 @@ CMD(create_branch, "create_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)); + ppol.set_branch(suffix(), policies::branch::create(app, admin_keys)); parent.commit(ppol, utf8("Add branch.")); } ============================================================ --- database.cc 39d2a1485b7c7950c526213947f2059f99d15d6e +++ database.cc ef99937af2d57f2726d80037bdb20e82faedf4e9 @@ -4346,19 +4346,6 @@ database_impl::close() I(!__sql); } - -// Get a meaningless, unique value for use in branch certs. -branch_uid -database::generate_uid() const -{ - // FIXME: I'm sure there's a better way to do this. - std::string when = date_t::now().as_iso_8601_extended(); - char buf[20]; - rng->get().randomize(reinterpret_cast(buf), 20); - return branch_uid(when + "--" + encode_hexenc(std::string(buf, 20), - origin::internal), - origin::internal); -} // transaction guards conditional_transaction_guard::~conditional_transaction_guard() ============================================================ --- database.hh 93d9cc24f2e244097eb07b13825629a9d5cd0241 +++ database.hh c0ae9e7cf842b2d639e95d2dff57ad34984621ec @@ -440,9 +440,6 @@ public: void delete_existing_rosters(); void put_roster_for_revision(revision_id const & new_id, revision_t const & rev); - - // This wants to be somewhere with access to a RNG. - branch_uid generate_uid() const; private: boost::shared_ptr imp; lua_hooks & lua; ============================================================ --- policies/branch.cc 3bd0cffe26cab385a546c33bcf07eab8ae5737c9 +++ policies/branch.cc 5b6b0d65bf8419f2961f228f9e3cc42ade0ba9f4 @@ -11,12 +11,40 @@ #include "base.hh" #include "policies/branch.hh" +#include "app_state.hh" +#include "lazy_rng.hh" +#include "transforms.hh" + +namespace { + branch_uid generate_uid(app_state & app) + { + std::string when = date_t::now().as_iso_8601_extended(); + char buf[20]; + app.rng->get().randomize(reinterpret_cast(buf), 20); + return branch_uid(when + "--" + encode_hexenc(std::string(buf, 20), + origin::internal), + origin::internal); + } +} + namespace policies { branch::branch() { } + branch branch::create(app_state & app, + std::set const & admins) + { + branch ret; + ret.signers = admins; + ret.uid = generate_uid(app); + return ret; + } branch_uid const & branch::get_uid() const { return uid; } + std::set const & branch::get_signers() const + { + return signers; + } } // Local Variables: ============================================================ --- policies/branch.hh 9ceb051153d9d73a97d4e265a8000edaa17cd72d +++ policies/branch.hh 9256039b60c07de4b55bebe64ef3137b0608375f @@ -16,6 +16,8 @@ #include "vocab.hh" +class app_state; + class external_key_name; namespace policies { @@ -26,7 +28,8 @@ namespace policies { std::set signers; public: branch(); - static branch create(std::set const & admins); + static branch create(app_state & app, + std::set const & admins); branch_uid const & get_uid() const; std::set const & get_signers() const; ============================================================ --- policies/delegation.cc 4a7c89808693be8687cb1b20a3e1b0b4ea9e39dc +++ policies/delegation.cc b8d40b10773d64081b0d73f558e297eb5c6d459b @@ -11,6 +11,82 @@ #include "base.hh" #include "policies/delegation.hh" +#include "basic_io.hh" +#include "transforms.hh" + +using std::string; + +namespace basic_io { + namespace syms { + static symbol revision_id("revision_id"); + } +} + +namespace policies { + delegation::delegation() {} + delegation::delegation(revision_id const & r) + : type(revision_type), + revid(r) + { } + delegation::delegation(branch const & b) + : type(branch_type), + branch_desc(b) + { } + delegation delegation::create(app_state & app, + std::set const & admins) + { + delegation ret; + ret.type = branch_type; + ret.branch_desc = branch::create(app, admins); + return ret; + } + + bool delegation::is_branch_type() const + { + return type == branch_type; + } + branch const & delegation::get_branch_spec() const + { + I(is_branch_type()); + return branch_desc; + } + + void delegation::serialize(std::string & out) const + { + if (type == revision_type) + { + basic_io::printer p; + basic_io::stanza s; + s.push_binary_pair(basic_io::syms::revision_id, revid.inner()); + p.print_stanza(s); + out = p.buf; + } + else + { + branch_desc.serialize(out); + } + } + void delegation::deserialize(std::string const & in) + { + { + basic_io::input_source s(in, "delegation"); + basic_io::tokenizer t(s); + basic_io::parser p(t); + if (p.symp(basic_io::syms::revision_id)) + { + type = revision_type; + p.sym(); + string rev; + p.hex(rev); + revid = decode_hexenc_as(rev, p.tok.in.made_from); + return; + } + } + type = branch_type; + branch_desc.deserialize(in); + } +} + // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- policies/delegation.hh cba55a5ff7473b89df71c49363c2c71932d314a1 +++ policies/delegation.hh e97d2d4daae6a861c4ad757fcf973a92157accc4 @@ -18,6 +18,7 @@ #include "policies/branch.hh" +class app_state; class external_key_name; namespace policies { @@ -33,8 +34,12 @@ namespace policies { delegation(); explicit delegation(revision_id const & r); explicit delegation(branch const & b); - static delegation create(std::set const & admins); + static delegation create(app_state & app, + std::set const & admins); + bool is_branch_type() const; + branch const & get_branch_spec() const; + void serialize(std::string & out) const; void deserialize(std::string const & in); ============================================================ --- policies/editable_policy.cc 06796791844f610c07db45ed0418890b40f76337 +++ policies/editable_policy.cc 4b51aa214719e1fb198d510ed59b7ce0ba149727 @@ -9,9 +9,45 @@ // PURPOSE. #include "base.hh" +#include "editable_policy.hh" +namespace policies { + editable_policy::editable_policy(policy const & p) + : policy(p) + { } + void editable_policy::set_branch(std::string const & name, + branch const & value) + { + branches[name] = value; + } + void editable_policy::remove_branch(std::string const & name) + { + branches.erase(name); + } + void editable_policy::set_tag(std::string const & name, + revision_id const & value) + { + tags[name] = value; + } + void editable_policy::remove_tag(std::string const & name) + { + tags.erase(name); + } + + void editable_policy::set_delegation(std::string const & name, + delegation const & value) + { + delegations[name] = value; + } + void editable_policy::remove_delegation(std::string const & name) + { + delegations.erase(name); + } +} + + // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- policies/editable_policy.hh aaa986ebda3403ab4a87c4bb7b9764ea95cd44d8 +++ policies/editable_policy.hh d05ff58508caf9bb0bc87ffd14061839359fa08b @@ -19,8 +19,8 @@ namespace policies { public: explicit editable_policy(policy const & p); - void set_key_name(key_id const & ident, key_name const & name); - void remove_key(key_id const & ident); + //void set_key_name(key_id const & ident, key_name const & name); + //void remove_key(key_id const & ident); void set_branch(std::string const & name, branch const & value); void remove_branch(std::string const & name); ============================================================ --- policies/policy_branch.cc 06796791844f610c07db45ed0418890b40f76337 +++ policies/policy_branch.cc d7ae6973b3a68fe37eb5faca4174f705e336692b @@ -9,9 +9,30 @@ // PURPOSE. #include "base.hh" +#include "policies/policy_branch.hh" +namespace policies { + policy_branch::policy_branch(branch const & b) + : spec(b) + { + reload(); + } + branch const & policy_branch::get_spec() const + { + return spec; + } + policy_branch::iterator policy_branch::begin() const + { + return policies.begin(); + } + policy_branch::iterator policy_branch::end() const + { + return policies.end(); + } +} + // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- policies/policy_branch.hh aa0e52cfa7cbab51fe992effc8e8d1b5204aff95 +++ policies/policy_branch.hh d9b4d6a763de19864950b3ede9b4c29c19f121ec @@ -30,8 +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); + //policy_branch(delegation const & d); branch const & get_spec() const; ============================================================ --- project.cc e57cda13c4b33fd4c8d0d539a6d6b41eb06a67bc +++ project.cc d117abfb5529ddd56bee8c288e2a846299d7f736 @@ -232,6 +232,12 @@ public: { } + policies::policy const & get_base_policy() const + { + I(!passthru); + return *policy; + } + void all_branches(set & branches) { branches.clear(); @@ -384,6 +390,11 @@ project_t::empty_project(database & db) return project_t(db); } +policies::policy const & project_t::get_base_policy() const +{ + return project_policy->get_base_policy(); +} + bool project_t::policy_exists(branch_name const & name) const { @@ -901,9 +912,10 @@ project_t::put_tag(key_store & keys, project_policy->find_governing_policy(name, info); E(!info.empty(), origin::user, F("Cannot find policy for tag '%s'") % name); + E(info.back().delegation.is_branch_type(), origin::user, + F("Cannot edit '%s', it is delegated to a specific revision") % name); + policies::policy_branch br(info.back().delegation.get_branch_spec()); - policies::policy_branch br(info.back().delegation); - I(br.begin() != br.end()); policies::editable_policy ep(**br.begin()); ============================================================ --- project.hh ca380355b0b360f9cb68b97149df84dc4f46d21f +++ project.hh 17810c296afb72c1a8de0ac154e147c3418aa4f5 @@ -113,7 +113,7 @@ public: // Used by migration code. static project_t empty_project(database & db); - policies::policy & get_base_policy() const; + policies::policy const & get_base_policy() const; void find_governing_policy(std::string const & of_what, policy_chain & info) const;