closer to OAuth2 vocabulary

This commit is contained in:
Yann Esposito (Yogsototh) 2018-02-01 17:21:57 +01:00
parent 94bea324e5
commit 70cf6f7d31
Signed by untrusted user who does not match committer: yogsototh
GPG key ID: 7B19A4C650D59646
3 changed files with 79 additions and 64 deletions

View file

@ -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}}
: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)

View file

@ -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+))]))

View file

@ -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}}
:org Org
:scopes #{Scope}}
{s/Keyword s/Any}))