Merge pull request #1 from yogsototh/oauth2-phaseA
closer to OAuth2 vocabulary
This commit is contained in:
commit
bbb99b9abc
3 changed files with 79 additions and 64 deletions
62
README.md
62
README.md
|
@ -31,14 +31,13 @@ An `IdentityInfo` is defined as:
|
|||
data by some authentication layer. Typically, an email, a phone number, etc...
|
||||
"
|
||||
(st/merge
|
||||
{:id s/Str
|
||||
:name s/Str}
|
||||
;; could contain other meta datas (email, address, phone number, etc...)
|
||||
{:id s/Str}
|
||||
;; could contain other meta datas (name, nickname, email, address, phone number, etc...)
|
||||
{s/Keyword s/Any}))
|
||||
|
||||
(s/defschema Group
|
||||
"A Group can be understood as a Community of People, an Organization, a
|
||||
Business, etc...
|
||||
(s/defschema Org
|
||||
"An Org can be understood as a Community of People, an Organization, a
|
||||
Business, etc... This also can be thought as a UNIX group.
|
||||
|
||||
Mainly this should provide a way to filter document for an organization.
|
||||
|
||||
|
@ -47,36 +46,48 @@ An `IdentityInfo` is defined as:
|
|||
A group could also have some meta informations. For example, a physical
|
||||
address, an Identity Provider URL, etc.."
|
||||
(st/merge
|
||||
{:id s/Str
|
||||
:name s/Str}
|
||||
;; could contain other meta datas (Identity Provider URL, etc...)
|
||||
{:id s/Str}
|
||||
;; could contain other meta datas (name, Identity Provider URL, etc...)
|
||||
{s/Keyword s/Any}))
|
||||
|
||||
(def Role
|
||||
"What are the roles of the user.
|
||||
(def Scope
|
||||
"The scope of an user.
|
||||
|
||||
The scope is a string without any space.
|
||||
Mainly this should provide a way to filter route access.
|
||||
|
||||
Typical values are: :admin :user :read-only etc... "
|
||||
s/Keyword)
|
||||
Typical values are:
|
||||
|
||||
- \"admin\"
|
||||
- \"service\"
|
||||
- \"service/subservice:read-only\"
|
||||
|
||||
etc..."
|
||||
s/Str)
|
||||
|
||||
(s/defschema IdentityInfo
|
||||
"An IdentityInfo provide the information to identify and determine the
|
||||
permissions relative to some request.
|
||||
|
||||
It provide an user, a set of groups and a set of roles.
|
||||
It provide an user, a main org and a set of scopes.
|
||||
|
||||
It is important to note that roles aren't associated to an user but to an
|
||||
IdentityInfo. This enable the same user to provide different roles via
|
||||
It is important to note that scopes aren't associated to an user but to an
|
||||
IdentityInfo. This enable the same user to provide different scopes via
|
||||
different API-Key for example.
|
||||
|
||||
An IdentityInfo while having some mandatory informations could also contains
|
||||
some other informations generally for dealing with technical details and ease
|
||||
the debugging."
|
||||
the debugging.
|
||||
|
||||
But they could also be used to extend the actual spec.
|
||||
For example, we could imagine that we might want to associate a set of orgs
|
||||
to an identity.
|
||||
|
||||
But that's out of the scope of this specific spec."
|
||||
(st/merge
|
||||
{:user User
|
||||
:groups #{Group}
|
||||
:roles #{Role}}
|
||||
{:user User
|
||||
:org Org
|
||||
:scopes #{Scope}}
|
||||
{s/Keyword s/Any}))
|
||||
```
|
||||
|
||||
|
@ -100,16 +111,17 @@ Where here are some example of extractors:
|
|||
|
||||
(s/defn extract-identity-infos :- IdentityInfo
|
||||
[jwt-info]
|
||||
{:id {:id (:sub jwt-info)
|
||||
:name (:sub jwt-info)}
|
||||
{:user {:id (:sub jwt-info)
|
||||
:name (:sub jwt-info)
|
||||
:email (:user_email jwt-info)}
|
||||
:groups #{{:id (:org_guid jwt-info)
|
||||
:name (:org_name jwt-info)}}
|
||||
:roles (if (= "true"
|
||||
:scopes (if (= "true"
|
||||
;; this test handle the case when :user_admin is a string
|
||||
;; and when its a boolean
|
||||
(str (:user_admin jwt-info)))
|
||||
#{:admin :user}
|
||||
#{:user})
|
||||
#{"admin" "user"}
|
||||
#{"user"})
|
||||
:auth-type :jwt})
|
||||
|
||||
(s/defn jwt-extractor :- (s/maybe IdentityInfo)
|
||||
|
|
|
@ -13,14 +13,6 @@
|
|||
[compojure.api.meta :as meta]
|
||||
[schema.core :as s]))
|
||||
|
||||
(s/defn get-identity-info :- (s/maybe IdentityInfo)
|
||||
"Given a ring request and and a couple auth-key auth-info->identity-info.
|
||||
We return the identity-info if possible"
|
||||
[request
|
||||
[auth-key auth-infos->identity-info]]
|
||||
(when-let [auth-infos (get request auth-key)]
|
||||
(auth-infos->identity-info auth-infos)))
|
||||
|
||||
(s/defn wrap-auths-fn
|
||||
"You should provide a list of [[AuthExtractor]]s your ring request should have
|
||||
a :auth key in them."
|
||||
|
@ -46,32 +38,32 @@
|
|||
new-letks [id-infos (meta/src-coerce! schema :identity-info :string)]]
|
||||
(update-in acc [:letks] into new-letks)))
|
||||
|
||||
;; Add the :roles-filter
|
||||
;; Add the :scopes-filter
|
||||
;; to compojure api params
|
||||
;; it should contains a set of hash-maps
|
||||
;; example:
|
||||
;;
|
||||
;; ~~~
|
||||
;; (POST "/foo" [] :roles-filter #{:admin})
|
||||
;; (POST "/foo" [] :scopes-filter #{:admin})
|
||||
;; ~~~
|
||||
;;
|
||||
;; Will be accepted only for requests having a role in the authorized set.
|
||||
;; Will be accepted only for requests having a scope in the authorized set.
|
||||
|
||||
(defn check-roles-filter!
|
||||
[authorized-roles request-roles]
|
||||
(when-not (set? authorized-roles)
|
||||
(throw (ex-info ":roles-filter argument in compojure-api must be a set!" {})))
|
||||
(when-not (and (set? request-roles)
|
||||
(set/intersection authorized-roles request-roles))
|
||||
(defn check-scopes-filter!
|
||||
[authorized-scopes request-scopes]
|
||||
(when-not (set? authorized-scopes)
|
||||
(throw (ex-info ":scopes-filter argument in compojure-api must be a set!" {})))
|
||||
(when-not (and (set? request-scopes)
|
||||
(set/intersection authorized-scopes request-scopes))
|
||||
(ring.util.http-response/unauthorized!
|
||||
{:msg "You don't have the required credentials to access this route"})))
|
||||
|
||||
(defmethod compojure.api.meta/restructure-param
|
||||
:roles-filter [_ authorized acc]
|
||||
:scopes-filter [_ authorized acc]
|
||||
(update-in
|
||||
acc
|
||||
[:lets]
|
||||
into
|
||||
['_ `(check-roles-filter!
|
||||
['_ `(check-scopes-filter!
|
||||
~authorized
|
||||
(:identity-info ~'+compojure-api-request+))]))
|
||||
|
|
|
@ -11,14 +11,13 @@
|
|||
data by some authentication layer. Typically, an email, a phone number, etc...
|
||||
"
|
||||
(st/merge
|
||||
{:id s/Str
|
||||
:name s/Str}
|
||||
;; could contain other meta datas (email, address, phone number, etc...)
|
||||
{:id s/Str}
|
||||
;; could contain other meta datas (name, nickname, email, address, phone number, etc...)
|
||||
{s/Keyword s/Any}))
|
||||
|
||||
(s/defschema Group
|
||||
"A Group can be understood as a Community of People, an Organization, a
|
||||
Business, etc...
|
||||
(s/defschema Org
|
||||
"An Org can be understood as a Community of People, an Organization, a
|
||||
Business, etc... This also can be thought as a UNIX group.
|
||||
|
||||
Mainly this should provide a way to filter document for an organization.
|
||||
|
||||
|
@ -27,34 +26,46 @@
|
|||
A group could also have some meta informations. For example, a physical
|
||||
address, an Identity Provider URL, etc.."
|
||||
(st/merge
|
||||
{:id s/Str
|
||||
:name s/Str}
|
||||
;; could contain other meta datas (Identity Provider URL, etc...)
|
||||
{:id s/Str}
|
||||
;; could contain other meta datas (name, Identity Provider URL, etc...)
|
||||
{s/Keyword s/Any}))
|
||||
|
||||
(def Role
|
||||
"What are the roles of the user.
|
||||
(def Scope
|
||||
"The scope of an user.
|
||||
|
||||
The scope is a string without any space.
|
||||
Mainly this should provide a way to filter route access.
|
||||
|
||||
Typical values are: :admin :user :read-only etc... "
|
||||
s/Keyword)
|
||||
Typical values are:
|
||||
|
||||
- \"admin\"
|
||||
- \"service\"
|
||||
- \"service/subservice:read-only\"
|
||||
|
||||
etc..."
|
||||
s/Str)
|
||||
|
||||
(s/defschema IdentityInfo
|
||||
"An IdentityInfo provide the information to identify and determine the
|
||||
permissions relative to some request.
|
||||
|
||||
It provide an user, a set of groups and a set of roles.
|
||||
It provide an user, a main org and a set of scopes.
|
||||
|
||||
It is important to note that roles aren't associated to an user but to an
|
||||
IdentityInfo. This enable the same user to provide different roles via
|
||||
It is important to note that scopes aren't associated to an user but to an
|
||||
IdentityInfo. This enable the same user to provide different scopes via
|
||||
different API-Key for example.
|
||||
|
||||
An IdentityInfo while having some mandatory informations could also contains
|
||||
some other informations generally for dealing with technical details and ease
|
||||
the debugging."
|
||||
the debugging.
|
||||
|
||||
But they could also be used to extend the actual spec.
|
||||
For example, we could imagine that we might want to associate a set of orgs
|
||||
to an identity.
|
||||
|
||||
But that's out of the scope of this specific spec."
|
||||
(st/merge
|
||||
{:user User
|
||||
:groups #{Group}
|
||||
:roles #{Role}}
|
||||
{:user User
|
||||
:org Org
|
||||
:scopes #{Scope}}
|
||||
{s/Keyword s/Any}))
|
||||
|
|
Loading…
Reference in a new issue