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 -*-
|
||||
|
||||
{["static", '*'], 'elmdap-static', []}.
|
||||
{["uid", uid], 'elmdap-uid', []}.
|
||||
{["users", uid], 'elmdap-user', []}.
|
||||
{["users"], 'elmdap-users', []}.
|
||||
{["groups"], 'elmdap-groups', []}.
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
{deps, [
|
||||
{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"}}}
|
||||
]}.
|
||||
|
||||
{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, [
|
||||
|
@ -30,8 +31,8 @@
|
|||
{profiles, [
|
||||
{dev, [
|
||||
{plugins, [
|
||||
{'lfe-version', ".*", {git, "https://github.com/lfe-rebar3/version.git", {tag, "0.3.0"}}},
|
||||
{'lfe-repl', ".*", {git, "https://github.com/lfe-rebar3/repl.git", {tag, "0.2.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.1"}}},
|
||||
{'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)
|
||||
(service_available 2)
|
||||
(resource_exists 2)
|
||||
|
@ -22,35 +22,20 @@
|
|||
|
||||
(defun resource_exists (req-data state)
|
||||
(let ((`[#(uid ,uid)] (wrq:path_info req-data)))
|
||||
(case (elmdap:from-uid uid)
|
||||
(case (elmdap:from-uid (state-connection state) uid)
|
||||
(`#(ok ,entry)
|
||||
`#(true ,req-data ,(set-state state entry entry)))
|
||||
(_ `#(false ,req-data ,state)))))
|
||||
|
||||
(defun is_authorized (req-data state)
|
||||
(let ((auth-header "Basic realm=Elmdap"))
|
||||
(case (elmdap:basic-auth-credentials req-data)
|
||||
(`#(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)))))
|
||||
(elmdap:is_authorized (state-connection state)
|
||||
req-data state))
|
||||
|
||||
(defun content_types_provided (req-data state)
|
||||
`#((#("application/json" to_json)) ,req-data ,state))
|
||||
|
||||
(defun to_json (req-data state)
|
||||
(let* ((entry (state-entry state)))
|
||||
(tuple (mochijson:encode
|
||||
`#(struct [#(dn ,(elmdap:entry-dn entry))
|
||||
#(attributes
|
||||
#(struct ,(lists:map
|
||||
(match-lambda ((`#(,k ,v)) `#(,k #(array ,v))))
|
||||
(elmdap:entry-attributes entry))))]))
|
||||
(tuple (mochijson:encode (elmdap-entry:to_json entry))
|
||||
req-data
|
||||
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,
|
||||
[kernel,
|
||||
stdlib,
|
||||
calrissian,
|
||||
inets,
|
||||
crypto,
|
||||
mochiweb,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
(defmodule elmdap
|
||||
(export all))
|
||||
|
||||
(include-lib "calrissian/include/monads.lfe")
|
||||
|
||||
;; Public API
|
||||
|
||||
(defun entry-dn
|
||||
|
@ -12,6 +14,11 @@
|
|||
attributes))
|
||||
|
||||
(defun from-uid (uid)
|
||||
(do-m (monad 'error)
|
||||
(connection <- (open))
|
||||
(from-uid connection uid)))
|
||||
|
||||
(defun from-uid (connection uid)
|
||||
(let* ((`#(ok ,connection) (open))
|
||||
(base "ou=people,dc=coredial,dc=com")
|
||||
(filter (eldap:equalityMatch "uid" uid))
|
||||
|
@ -37,11 +44,20 @@
|
|||
((binary "Basic " (base64 binary))
|
||||
(case (string:tokens (base64:mime_decode_to_string base64) ":")
|
||||
((list uid password)
|
||||
`#(ok ,uid ,password))
|
||||
`#(ok #(,uid ,password)))
|
||||
(_ #(error bad_data))))
|
||||
(_ #(error bad_method))))))
|
||||
|
||||
(defun valid-auth? (connection dn password)
|
||||
(case (eldap:simple_bind connection dn password)
|
||||
('ok 'true)
|
||||
(_ 'false)))
|
||||
(defun is_authorized (connection req-data state)
|
||||
(let-function ((fst (match-lambda ((`#(,a ,_)) a)))
|
||||
(snd (match-lambda ((`#(,_ ,b)) b))))
|
||||
(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