From 7cddb49d0a525bcf72f4ea5a23caea36ad5e0192 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 7 Nov 2016 19:39:16 +0100 Subject: Allow for group membership policies --- priv/policy.conf | 7 +++++++ priv/policy.erl | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 priv/policy.conf diff --git a/priv/policy.conf b/priv/policy.conf new file mode 100644 index 0000000..f47d442 --- /dev/null +++ b/priv/policy.conf @@ -0,0 +1,7 @@ +%% -*- mode: erlang -*- +%% coding: utf-8 +{defaults, ["cn=default,dc=example,dc=com"]}. + +{mappings, [{"cn=productA,dc=example,dc=com", ["app1", "app2", "app3", "app4"]}, + {"cn=productB,dc=example,dc=com", ["appA", "appB", "appC", "app4"]}] +}. diff --git a/priv/policy.erl b/priv/policy.erl index bca21da..99dc02e 100644 --- a/priv/policy.erl +++ b/priv/policy.erl @@ -10,10 +10,13 @@ del_host/2 ]). +-define(POLICY_CONF, "priv/policy.conf"). + % -> data to return add_host(Hostname, Class, Realm) -> Dn = host2dn(Hostname, Realm), - Attrs = class2attr(Hostname, Class, Realm), + Members = members(Class), + Attrs = class2attr(Hostname, Class, Realm, Members), ok = ldapsp_ldap:add(Dn, Attrs), [{dn, list_to_binary(Dn)}, {randompassword, <<"UNSET">>}]. @@ -28,12 +31,54 @@ host2dn(Host, Realm) -> Base = string:join([ "dc=" ++ C || C <- string:tokens(Realm, ".")], ", "), "cn=" ++ hd(string:tokens(Host, ".")) ++ ", " ++ Base. -class2attr(Host, _Class, Realm) -> +class2attr(Host, _Class, _Realm, Members) -> [{"objectclass", ["top", "groupOfUniqueNames"]}, {"cn", [Host]}, - {"uniqueMember", [host2dn(Host, Realm)]}]. + {"uniqueMember", Members}]. + del_result({error,noSuchObject}) -> true; del_result(ok) -> true; del_result(_) -> false. + +members(Class, [{Dn,Classes}|Tail], Members) -> + NewMembers = case lists:member(Class, Classes) of + true -> Members ++ [Dn]; + _ -> Members + end, + members(Class, Tail, NewMembers); +members(_Class, [], Members) -> Members. + +members(Class) -> + {ok, Config} = file:consult(?POLICY_CONF), + + Defaults = proplists:get_value(defaults, Config, []), + Mappings = proplists:get_value(mappings, Config, []), + + Members = members(Class, Mappings, []), + case Members of + [] -> Defaults; + _ -> Members + end. + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +members_nonexistent_test() -> + ?assertEqual( + ["cn=default,dc=example,dc=com"], + members("nonexistent")). + +members_existent_test() -> + ?assertEqual( + ["cn=productA,dc=example,dc=com"], + members("app1")). + +members_multiple_test() -> + ?assertEqual( + ["cn=productA,dc=example,dc=com", + "cn=productB,dc=example,dc=com"], + members("app4")). + +-endif. -- cgit v1.2.3