Users & Groups
This commit is contained in:
parent
06bd134426
commit
e37ac34629
8 changed files with 141 additions and 29 deletions
|
@ -1,4 +1,6 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
|
|
||||||
{["static", '*'], 'elmdap-static', []}.
|
{["static", '*'], 'elmdap-static', []}.
|
||||||
{["uid", uid], 'elmdap-uid', []}.
|
{["users", uid], 'elmdap-user', []}.
|
||||||
|
{["users"], 'elmdap-users', []}.
|
||||||
|
{["groups"], 'elmdap-groups', []}.
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
|
|
||||||
{deps, [
|
{deps, [
|
||||||
{lfe, {git, "git://github.com/rvirding/lfe", {tag, "1.0"}}},
|
{lfe, {git, "git://github.com/rvirding/lfe", {tag, "1.0"}}},
|
||||||
|
{calrissian, {git, "git://github.com/correl/calrissian", {branch, "rebar3"}}},
|
||||||
{webmachine, ".*", {git, "git://github.com/basho/webmachine.git", {branch, "master"}}}
|
{webmachine, ".*", {git, "git://github.com/basho/webmachine.git", {branch, "master"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{plugins, [
|
{plugins, [
|
||||||
{'lfe-compile', {git, "https://github.com/lfe-rebar3/compile.git", {tag, "0.3.0"}}}
|
{'lfe-compile', {git, "https://github.com/lfe-rebar3/compile.git", {tag, "0.4.0"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{provider_hooks, [
|
{provider_hooks, [
|
||||||
|
@ -30,8 +31,8 @@
|
||||||
{profiles, [
|
{profiles, [
|
||||||
{dev, [
|
{dev, [
|
||||||
{plugins, [
|
{plugins, [
|
||||||
{'lfe-version', ".*", {git, "https://github.com/lfe-rebar3/version.git", {tag, "0.3.0"}}},
|
{'lfe-version', ".*", {git, "https://github.com/lfe-rebar3/version.git", {tag, "0.4.0"}}},
|
||||||
{'lfe-repl', ".*", {git, "https://github.com/lfe-rebar3/repl.git", {tag, "0.2.0"}}},
|
{'lfe-repl', ".*", {git, "https://github.com/lfe-rebar3/repl.git", {tag, "0.2.1"}}},
|
||||||
{'lfe-clean', ".*", {git, "https://github.com/lfe-rebar3/clean.git", {tag, "0.2.0"}}}
|
{'lfe-clean', ".*", {git, "https://github.com/lfe-rebar3/clean.git", {tag, "0.2.0"}}}
|
||||||
]}
|
]}
|
||||||
]},
|
]},
|
||||||
|
|
17
src/elmdap-entry.lfe
Normal file
17
src/elmdap-entry.lfe
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
(defmodule elmdap-entry
|
||||||
|
(export all))
|
||||||
|
|
||||||
|
(defun dn
|
||||||
|
((`#(eldap_entry ,dn ,_))
|
||||||
|
dn))
|
||||||
|
|
||||||
|
(defun attributes
|
||||||
|
((`#(eldap_entry ,_ ,attributes))
|
||||||
|
attributes))
|
||||||
|
|
||||||
|
(defun to_json (entry)
|
||||||
|
`#(struct [#(dn ,(dn entry))
|
||||||
|
#(attributes
|
||||||
|
#(struct ,(lists:map
|
||||||
|
(match-lambda ((`#(,k ,v)) `#(,k #(array ,v))))
|
||||||
|
(attributes entry))))]))
|
45
src/elmdap-groups.lfe
Normal file
45
src/elmdap-groups.lfe
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
(defmodule elmdap-groups
|
||||||
|
(export (init 1)
|
||||||
|
(service_available 2)
|
||||||
|
(is_authorized 2)
|
||||||
|
(content_types_provided 2)
|
||||||
|
(to_json 2)))
|
||||||
|
|
||||||
|
(include-lib "webmachine/include/webmachine.hrl")
|
||||||
|
(include-lib "calrissian/include/monads.lfe")
|
||||||
|
|
||||||
|
(defrecord state
|
||||||
|
connection)
|
||||||
|
|
||||||
|
(defun service_available (req-data state)
|
||||||
|
(case (elmdap:open)
|
||||||
|
((tuple 'ok connection)
|
||||||
|
`#(true ,req-data ,(set-state state connection connection)))
|
||||||
|
(_
|
||||||
|
`#(false ,req-data ,state))))
|
||||||
|
|
||||||
|
(defun is_authorized (req-data state)
|
||||||
|
(elmdap:is_authorized (state-connection state)
|
||||||
|
req-data state))
|
||||||
|
|
||||||
|
(defun init (args)
|
||||||
|
`#(ok ,(make-state)))
|
||||||
|
|
||||||
|
(defun content_types_provided (req-data state)
|
||||||
|
`#([#("application/json" to_json)] ,req-data ,state))
|
||||||
|
|
||||||
|
(defun to_json (req-data state)
|
||||||
|
(tuple (mochijson:encode
|
||||||
|
`#(array ,(lists:map (fun elmdap-entry to_json 1)
|
||||||
|
(groups (state-connection state)))))
|
||||||
|
req-data
|
||||||
|
state))
|
||||||
|
|
||||||
|
(defun groups (connection)
|
||||||
|
(let* ((base "ou=groups,dc=coredial,dc=com")
|
||||||
|
(filter (eldap:equalityMatch "objectClass" "groupOfNames"))
|
||||||
|
(`#(ok #(eldap_search_result ,results ,_))
|
||||||
|
(eldap:search connection
|
||||||
|
`[#(base ,base)
|
||||||
|
#(filter ,filter)])))
|
||||||
|
results))
|
|
@ -1,4 +1,4 @@
|
||||||
(defmodule elmdap-uid
|
(defmodule elmdap-user
|
||||||
(export (init 1)
|
(export (init 1)
|
||||||
(service_available 2)
|
(service_available 2)
|
||||||
(resource_exists 2)
|
(resource_exists 2)
|
||||||
|
@ -22,35 +22,20 @@
|
||||||
|
|
||||||
(defun resource_exists (req-data state)
|
(defun resource_exists (req-data state)
|
||||||
(let ((`[#(uid ,uid)] (wrq:path_info req-data)))
|
(let ((`[#(uid ,uid)] (wrq:path_info req-data)))
|
||||||
(case (elmdap:from-uid uid)
|
(case (elmdap:from-uid (state-connection state) uid)
|
||||||
(`#(ok ,entry)
|
(`#(ok ,entry)
|
||||||
`#(true ,req-data ,(set-state state entry entry)))
|
`#(true ,req-data ,(set-state state entry entry)))
|
||||||
(_ `#(false ,req-data ,state)))))
|
(_ `#(false ,req-data ,state)))))
|
||||||
|
|
||||||
(defun is_authorized (req-data state)
|
(defun is_authorized (req-data state)
|
||||||
(let ((auth-header "Basic realm=Elmdap"))
|
(elmdap:is_authorized (state-connection state)
|
||||||
(case (elmdap:basic-auth-credentials req-data)
|
req-data state))
|
||||||
(`#(ok ,uid ,password)
|
|
||||||
(case (elmdap:from-uid uid)
|
|
||||||
(`#(ok ,entry)
|
|
||||||
(case (eldap:simple_bind (state-connection state)
|
|
||||||
(elmdap:entry-dn entry)
|
|
||||||
password)
|
|
||||||
('ok `#(true ,req-data ,state))
|
|
||||||
(_ `#(,auth-header ,req-data ,state))))
|
|
||||||
(_ `#(,auth-header ,req-data ,state))))
|
|
||||||
(_ `#(,auth-header ,req-data ,state)))))
|
|
||||||
|
|
||||||
(defun content_types_provided (req-data state)
|
(defun content_types_provided (req-data state)
|
||||||
`#((#("application/json" to_json)) ,req-data ,state))
|
`#((#("application/json" to_json)) ,req-data ,state))
|
||||||
|
|
||||||
(defun to_json (req-data state)
|
(defun to_json (req-data state)
|
||||||
(let* ((entry (state-entry state)))
|
(let* ((entry (state-entry state)))
|
||||||
(tuple (mochijson:encode
|
(tuple (mochijson:encode (elmdap-entry:to_json entry))
|
||||||
`#(struct [#(dn ,(elmdap:entry-dn entry))
|
|
||||||
#(attributes
|
|
||||||
#(struct ,(lists:map
|
|
||||||
(match-lambda ((`#(,k ,v)) `#(,k #(array ,v))))
|
|
||||||
(elmdap:entry-attributes entry))))]))
|
|
||||||
req-data
|
req-data
|
||||||
state)))
|
state)))
|
45
src/elmdap-users.lfe
Normal file
45
src/elmdap-users.lfe
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
(defmodule elmdap-users
|
||||||
|
(export (init 1)
|
||||||
|
(service_available 2)
|
||||||
|
(is_authorized 2)
|
||||||
|
(content_types_provided 2)
|
||||||
|
(to_json 2)))
|
||||||
|
|
||||||
|
(include-lib "webmachine/include/webmachine.hrl")
|
||||||
|
(include-lib "calrissian/include/monads.lfe")
|
||||||
|
|
||||||
|
(defrecord state
|
||||||
|
connection)
|
||||||
|
|
||||||
|
(defun service_available (req-data state)
|
||||||
|
(case (elmdap:open)
|
||||||
|
((tuple 'ok connection)
|
||||||
|
`#(true ,req-data ,(set-state state connection connection)))
|
||||||
|
(_
|
||||||
|
`#(false ,req-data ,state))))
|
||||||
|
|
||||||
|
(defun is_authorized (req-data state)
|
||||||
|
(elmdap:is_authorized (state-connection state)
|
||||||
|
req-data state))
|
||||||
|
|
||||||
|
(defun init (args)
|
||||||
|
`#(ok ,(make-state)))
|
||||||
|
|
||||||
|
(defun content_types_provided (req-data state)
|
||||||
|
`#([#("application/json" to_json)] ,req-data ,state))
|
||||||
|
|
||||||
|
(defun to_json (req-data state)
|
||||||
|
(tuple (mochijson:encode
|
||||||
|
`#(array ,(lists:map (fun elmdap-entry to_json 1)
|
||||||
|
(users (state-connection state)))))
|
||||||
|
req-data
|
||||||
|
state))
|
||||||
|
|
||||||
|
(defun users (connection)
|
||||||
|
(let* ((base "ou=people,dc=coredial,dc=com")
|
||||||
|
(filter (eldap:equalityMatch "objectClass" "inetOrgPerson"))
|
||||||
|
(`#(ok #(eldap_search_result ,results ,_))
|
||||||
|
(eldap:search connection
|
||||||
|
`[#(base ,base)
|
||||||
|
#(filter ,filter)])))
|
||||||
|
results))
|
|
@ -5,6 +5,7 @@
|
||||||
{applications,
|
{applications,
|
||||||
[kernel,
|
[kernel,
|
||||||
stdlib,
|
stdlib,
|
||||||
|
calrissian,
|
||||||
inets,
|
inets,
|
||||||
crypto,
|
crypto,
|
||||||
mochiweb,
|
mochiweb,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
(defmodule elmdap
|
(defmodule elmdap
|
||||||
(export all))
|
(export all))
|
||||||
|
|
||||||
|
(include-lib "calrissian/include/monads.lfe")
|
||||||
|
|
||||||
;; Public API
|
;; Public API
|
||||||
|
|
||||||
(defun entry-dn
|
(defun entry-dn
|
||||||
|
@ -12,6 +14,11 @@
|
||||||
attributes))
|
attributes))
|
||||||
|
|
||||||
(defun from-uid (uid)
|
(defun from-uid (uid)
|
||||||
|
(do-m (monad 'error)
|
||||||
|
(connection <- (open))
|
||||||
|
(from-uid connection uid)))
|
||||||
|
|
||||||
|
(defun from-uid (connection uid)
|
||||||
(let* ((`#(ok ,connection) (open))
|
(let* ((`#(ok ,connection) (open))
|
||||||
(base "ou=people,dc=coredial,dc=com")
|
(base "ou=people,dc=coredial,dc=com")
|
||||||
(filter (eldap:equalityMatch "uid" uid))
|
(filter (eldap:equalityMatch "uid" uid))
|
||||||
|
@ -37,11 +44,20 @@
|
||||||
((binary "Basic " (base64 binary))
|
((binary "Basic " (base64 binary))
|
||||||
(case (string:tokens (base64:mime_decode_to_string base64) ":")
|
(case (string:tokens (base64:mime_decode_to_string base64) ":")
|
||||||
((list uid password)
|
((list uid password)
|
||||||
`#(ok ,uid ,password))
|
`#(ok #(,uid ,password)))
|
||||||
(_ #(error bad_data))))
|
(_ #(error bad_data))))
|
||||||
(_ #(error bad_method))))))
|
(_ #(error bad_method))))))
|
||||||
|
|
||||||
(defun valid-auth? (connection dn password)
|
(defun is_authorized (connection req-data state)
|
||||||
(case (eldap:simple_bind connection dn password)
|
(let-function ((fst (match-lambda ((`#(,a ,_)) a)))
|
||||||
('ok 'true)
|
(snd (match-lambda ((`#(,_ ,b)) b))))
|
||||||
(_ 'false)))
|
(let ((result
|
||||||
|
(do-m (monad 'error)
|
||||||
|
(credentials <- (elmdap:basic-auth-credentials req-data))
|
||||||
|
(entry <- (elmdap:from-uid (fst credentials)))
|
||||||
|
(eldap:simple_bind connection
|
||||||
|
(elmdap:entry-dn entry)
|
||||||
|
(snd credentials)))))
|
||||||
|
(case result
|
||||||
|
('ok (tuple 'true req-data state))
|
||||||
|
(_ (tuple "Basic realm=Elmdap" req-data state))))))
|
||||||
|
|
Loading…
Reference in a new issue