123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- #ifndef ACL_LOADER_H
- #define ACL_LOADER_H
- #include "acl.h"
- #include <cc/data.h>
- #include <boost/function.hpp>
- #include <boost/shared_ptr.hpp>
- #include <map>
- namespace isc {
- namespace acl {
- class LoaderError : public BadValue {
- private:
- const data::ConstElementPtr element_;
- public:
-
- LoaderError(const char* file, size_t line, const char* what,
- data::ConstElementPtr element = data::ConstElementPtr()) :
- BadValue(file, line, what),
- element_(element)
- {}
- ~ LoaderError() throw() {}
-
- const data::ConstElementPtr& element() const {
- return (element_);
- }
- };
- Action defaultActionLoader(data::ConstElementPtr action);
- template<typename Context, typename Action = isc::acl::Action> class Loader {
- public:
-
- Loader(const Action& defaultAction,
- const boost::function1<Action, data::ConstElementPtr>
- &actionLoader = &defaultActionLoader) :
- default_action_(defaultAction),
- action_loader_(actionLoader)
- {}
-
- class CheckCreator {
- public:
-
- virtual std::vector<std::string> names() const = 0;
-
- virtual boost::shared_ptr<Check<Context> > create(
- const std::string& name, data::ConstElementPtr definition) = 0;
-
- virtual bool allowListAbbreviation() const {
- return (true);
- }
- };
-
- void registerCreator(boost::shared_ptr<CheckCreator> creator) {
-
- typedef std::vector<std::string> Strings;
- const Strings names(creator->names());
- for (Strings::const_iterator i(names.begin()); i != names.end();
- ++i) {
- if (creators_.find(*i) != creators_.end()) {
- isc_throw(LoaderError, "The loader already contains creator "
- "named " << *i);
- }
- }
-
- for (Strings::const_iterator i(names.begin()); i != names.end();
- ++i) {
- creators_[*i] = creator;
- }
- }
-
- boost::shared_ptr<Check<Context> > loadCheck(const data::ConstElementPtr&
- description)
- {
-
- typedef std::map<std::string, data::ConstElementPtr> Map;
- Map map;
- try {
- map = description->mapValue();
- }
- catch (const data::TypeError&) {
- throw LoaderError(__FILE__, __LINE__,
- "Check description is not a map",
- description);
- }
-
- return (loadCheck(description, map));
- }
-
- boost::shared_ptr<Acl<Context, Action> > load(const data::ConstElementPtr&
- description)
- {
-
-
- if (description->getType() != data::Element::list) {
- throw LoaderError(__FILE__, __LINE__, "ACL not a list",
- description);
- }
-
- const List &list(description->listValue());
- boost::shared_ptr<Acl<Context, Action> > result(
- new Acl<Context, Action>(default_action_));
-
- for (List::const_iterator i(list.begin()); i != list.end(); ++i) {
- Map map;
- try {
- map = (*i)->mapValue();
- }
- catch (const data::TypeError&) {
- throw LoaderError(__FILE__, __LINE__, "ACL element not a map",
- *i);
- }
-
- const Map::const_iterator action(map.find("action"));
- if (action == map.end()) {
- throw LoaderError(__FILE__, __LINE__,
- "No action in ACL element", *i);
- }
- const Action acValue(action_loader_(action->second));
-
- if (map.size() >= 2) {
- result->append(loadCheck(*i, map), acValue);
- } else {
-
-
- result->append(boost::shared_ptr<Check<Context> >(new True()),
- acValue);
- }
- }
- return (result);
- }
- private:
-
- typedef std::map<std::string, boost::shared_ptr<CheckCreator> > Creators;
- typedef std::map<std::string, data::ConstElementPtr> Map;
- typedef std::vector<data::ConstElementPtr> List;
-
- Creators creators_;
- const Action default_action_;
- const boost::function1<Action, data::ConstElementPtr> action_loader_;
-
- boost::shared_ptr<Check<Context> > loadCheck(const data::ConstElementPtr&
- description, Map& map)
- {
-
- map.erase("action");
-
- switch (map.size()) {
- case 0:
- throw LoaderError(__FILE__, __LINE__,
- "Check description is empty",
- description);
- case 1: {
-
- const Map::const_iterator checkDesc(map.begin());
- const std::string& name(checkDesc->first);
- const typename Creators::const_iterator
- creatorIt(creators_.find(name));
- if (creatorIt == creators_.end()) {
- throw LoaderError(__FILE__, __LINE__,
- ("No creator for ACL check " +
- name).c_str(),
- description);
- }
- if (creatorIt->second->allowListAbbreviation() &&
- checkDesc->second->getType() == data::Element::list) {
- throw LoaderError(__FILE__, __LINE__,
- "Not implemented (OR-abbreviated form)",
- checkDesc->second);
- }
-
- return (creatorIt->second->create(name, checkDesc->second));
- }
- default:
- throw LoaderError(__FILE__, __LINE__,
- "Not implemented (AND-abbreviated form)",
- description);
- }
- }
-
- class True : public Check<Context> {
- public:
- virtual bool matches(const Context&) const { return (true); };
- virtual unsigned cost() const { return (1); }
-
-
- virtual std::string toText() const { return ""; }
- };
- };
- }
- }
- #endif
|