aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2016-11-07 19:39:16 +0100
committerGuido Günther <agx@sigxcpu.org>2016-11-07 19:49:57 +0100
commit7cddb49d0a525bcf72f4ea5a23caea36ad5e0192 (patch)
treec538674fa7e048793f630aa07f0d9a856a800da4
parent3b5f2a40a4d57934825896ba31a1d929ebf02603 (diff)
Allow for group membership policies
-rw-r--r--priv/policy.conf7
-rw-r--r--priv/policy.erl51
2 files changed, 55 insertions, 3 deletions
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.