Bloks¶
Blok Auth¶
-
class
anyblok_pyramid.bloks.auth.
Auth
(registry) Bases:
anyblok.blok.Blok
-
author
= 'Jean-Sébastien Suzanne'
-
conditional_by
= []
-
conflicting_by
= []
-
classmethod
import_declaration_module
() Do the python import for the Declaration of the model or other
-
name
= 'auth'
-
optional_by
= []
-
classmethod
reload_declaration_module
(reload)
-
required
= ['anyblok-core', 'pyramid']
-
required_by
= ['auth-password', 'authorization', 'user-identity']
-
version
= '0.1.0'
-
How to use it¶
This blok define a User model and add the basics of Pyramid Authentication and Authorization policy. It is required by the ‘password’ and ‘authorization’ bloks. Used alone it adds :
- Pyramid.User and Pyramid.Role models
- login / logout extendable views (That will throw an exception until you require ‘password’ and ‘authorization’ bloks into your project.)
Basically you can:
Create a new user:
user = registry.Pyramid.User.insert(login='jssuzanne') user.login # jssuzanne
Add a role to the created user:
role = registry.Pyramid.Role.insert( name='admin', label='Administrator' ) user.roles.append(role) user.roles # [<Model.Pyramid.Role(children=[], label='Administrator', name='admin', parents=<not loaded>, users=<Model.Pyramid.User len(1)>)>] role.users # [<Model.Pyramid.User(login='jssuzanne', roles=<Model.Pyramid.Role len(1)>)>]
Check a permission for a user to use a resource:
from anyblok_pyramid.security import AnyBlokResourceFactory @view_config( route_name='my_view', factory=AnyBlokResourceFactory('my_resource') permission='my_permission' ) def my_view(request): return Response('Ok I have the permission')
Warning
Remember that until you had credential behaviours, the ‘login’ view from ‘auth.views’ will raise an ‘HTTPUnauthorized’ exception.
User¶
-
class
anyblok_pyramid.bloks.auth.user.
User
Bases:
object
User declaration need for Auth
AnyBlok registration:
- Type: Model
- Registry name: Model.Pyramid.User
- Tablename: pyramid_user
Fields login Type
-anyblok.column.String
primary_key
-True
nullable
-False
default
-anyblok.column.NoDefaultValue
size
-64
-
classmethod
check_acl
(login, resource, type_) Overwrite the method to return the ACL for the resource and user
Parameters: - login – str, login of the user
- resource – str, name of the resource
- type – str, name of the action
-
classmethod
check_login
(login=None, password=None, **kwargs) Check login / password
This method raise an exception, because any credential is stored in this bloks
Warning
This method must be overwriting by anycredential blok
Parameters: - login – str, the login attribute of the user
- password – str
- kwargs – any options need to validate credential
-
classmethod
get_acl
(login, resource, params=None) Retun the ACL for a ressource and a user
Auth, does not implement any rule to compute ACL, This method allow all user to use the resource ask by controllers.
For other configuration, this method must be overwrite
Parameters: - login – str, login attribute of the user
- resource – str, name of a resource
- params – all options need to compute ACL
-
classmethod
get_login_location_to
(login, request) Return the default path after the login
-
classmethod
get_logout_location_to
(request) Return the default path after the logout
-
classmethod
get_roles
(login) Return the roles of an user
Parameters: login – str, login attribute of the user Return type: list of str (name of the roles)
-
login
= <anyblok.column.String object>
Role¶
-
class
anyblok_pyramid.bloks.auth.role.
Role
Bases:
object
Role, allow to group some authorization for an user
AnyBlok registration:
- Type: Model
- Registry name: Model.Pyramid.Role
- Tablename: pyramid_role
Fields name Type
-anyblok.column.String
primary_key
-True
nullable
-False
default
-anyblok.column.NoDefaultValue
size
-64
label Type
-anyblok.column.String
nullable
-False
default
-anyblok.column.NoDefaultValue
size
-64
children Type
-anyblok.relationship.Many2Many
backref
-'parents'
model
- Model.Pyramid.Roleremote_columns
-None
m2m_remote_columns
-None
local_columns
-None
m2m_local_columns
-None
compute_join
-False
users Type
-anyblok.relationship.Many2Many
backref
-'roles'
model
- Model.Pyramid.Userremote_columns
-None
m2m_remote_columns
-None
local_columns
-None
m2m_local_columns
-None
compute_join
-False
roles_name Type
-anyblok.field.Function
fget
-'get_all_roles_name'
-
classmethod
before_update_orm_event
(mapper, connection, target) Check if the role has not any cyclical dependencies
-
children
= <anyblok.relationship.Many2Many object>
-
get_all_roles_name
() Return all the name of the roles self and dependencies
-
label
= <anyblok.column.String object>
-
name
= <anyblok.column.String object>
-
roles_name
= <anyblok.field.Function object>
-
users
= <anyblok.relationship.Many2Many object>
Views¶
Define views for login and logout. Those views are not automatically applied to your project. You must declare the route to use them in the pyramid_load_config method of your project blok.
First import them in your blok definition __init__.py file:
from anyblok_pyramid.bloks.auth.views import login, logout
Then set route path in pyramid_load_config method:
- def pyramid_load_config(cls, config):
- config.add_route(‘login’, ‘/login’, request_method=’POST’) config.add_view(view=login, route_name=’login’, renderer=”JSON”) config.add_route(‘logout’, ‘/logout’, request_method=’POST’) config.add_view(view=logout, route_name=’logout’)
-
anyblok_pyramid.bloks.auth.views.
login
(request)¶ Default view to login a user
-
anyblok_pyramid.bloks.auth.views.
logout
(request)¶ Default view to logout a user
Configuration¶
Define the authentification / authorization policies, This depend on the options defined in global configuration.
Blok Password¶
-
class
anyblok_pyramid.bloks.password.
Password
(registry) Bases:
anyblok.blok.Blok
-
author
= 'Jean-Sébastien Suzanne'
-
conditional_by
= []
-
conflicting_by
= []
-
classmethod
import_declaration_module
() Do the python import for the Declaration of the model or other
-
name
= 'auth-password'
-
optional_by
= []
-
classmethod
reload_declaration_module
(reload)
-
required
= ['auth']
-
required_by
= []
-
version
= '0.1.0'
-
How to use it¶
This Blok add Pyramid.CredentialStore model, a simple login / password table. You can not add credential for an unexisting user because one foreign key constraint is defined between both.
Before all you must create a new user:
user = registry.Pyramid.User.insert(login='jssuzanne')
Then define a credential for this user:
user_credential = registry.Pyramid.CredentialStore.insert( login=user.login, password='secret password', )
At this point you can check if a given password is the good one:
user_credential.password == "not the good one" # False user_credential.password == "secret password" # True
You can also use ‘registry.Pyramid.User.check_login’ method to check that a password and a login match:
registry.Pyramid.User.check_login(login='jssuzanne', password='a bad one') # Will raise an HTTPUnauthorized exception registry.Pyramid.User.check_login(login='jssuzanne', password='secret password') # 'jssuzanne'
Note
The password use the Password column, the value is an encrypted string in database and can not be revealed during the execution of the application, you can only compare it.
User¶
-
class
anyblok_pyramid.bloks.password.user.
CredentialStore
Bases:
object
Simple login / password table
AnyBlok registration:
- Type: Model
- Registry name: Model.Pyramid.CredentialStore
- Tablename: pyramid_credentialstore
Fields login Type
-anyblok.column.String
primary_key
-True
nullable
-False
foreign_key
-Model.Pyramid.User => login
default
-anyblok.column.NoDefaultValue
size
-64
password Type
-anyblok.column.Password
nullable
-False
default
-anyblok.column.NoDefaultValue
size
-64
-
login
= <anyblok.column.String object>
-
password
= <anyblok.column.Password object>
-
class
anyblok_pyramid.bloks.password.user.
User
Bases:
object
AnyBlok registration:
- Type: Model
- Registry name: Model.Pyramid.User
- Tablename: pyramid_user
-
classmethod
check_login
(login=None, password=None, **kwargs) Overwrite the initial method to check if the given login match with an existing user that has the same password.
Parameters: - login – str
- password – str
Exception: HTTPUnauthorized
Blok Authorization¶
-
class
anyblok_pyramid.bloks.authorization.
Authorization
(registry) Bases:
anyblok.blok.Blok
-
author
= 'Jean-Sébastien Suzanne'
-
conditional_by
= []
-
conflicting_by
= []
-
classmethod
import_declaration_module
() Do the python import for the Declaration of the model or other
-
name
= 'authorization'
-
optional_by
= []
-
classmethod
reload_declaration_module
(reload)
-
required
= ['auth']
-
required_by
= []
-
version
= '0.1.0'
-
How to use it¶
This blok helps defining authorization for User or Role on a resource or model.
Create an user:
user = registry.Pyramid.User.insert(login='jssuzanne')
Add an authorization for the user to access a Pyramid resource:
registry.Pyramid.Authorization.insert( resource='something', user=user, perm_create=dict(matched=True), perm_read=dict(matched=True), perm_update=dict(matched=True), perm_delete=dict(matched=True) ) registry.Pyramid.Authorization.get_acl('jssuzanne', 'something') # [ # (Allow, 'jssuzanne', ['create', 'delete', 'read', 'update']), # (Deny, 'jssuzanne', ALL_PERMISSIONS), # ]
An user can have roles, this way you can define an authorization for a role and all users that have this role will be authorized:
role = registry.Pyramid.Role.insert( name='admin', label='Administrator' ) user.roles.append(role) registry.Pyramid.Authorization.insert( resource='otherthing', role=role, perm_create=dict(matched=True), perm_read=dict(matched=True), perm_update=dict(matched=True), perm_delete=dict(matched=True) ) registry.Pyramid.Authorization.get_acl('jssuzanne', 'otherthing') # [ # (Allow, 'jssuzanne', ['create', 'delete', 'read', 'update']), # (Deny, 'jssuzanne', ALL_PERMISSIONS), # ]
The permission is stored in a Json column, the permissions can be CRUD or any other one that is defined.
Each permission can defined three keys:
- condition:
Query.filter_condition
, if it’s empty then the condition is marked as True - matched: If condition is True, the entry indicate the value (default None)
- unmatched: If condition is False, the entry indicate the value (default None)
matched
and unmatched
can have three values:
- True: Add the permission in Allow list,
- False: Add the permission in the Deny list,
- None: Do nothing, because this rule can not Allow or Deny
User¶
-
class
anyblok_pyramid.bloks.authorization.user.
User
Bases:
object
AnyBlok registration:
- Type: Model
- Registry name: Model.Pyramid.User
- Tablename: pyramid_user
-
classmethod
check_acl
(login, resource, type_) Overwrite the method to return the ACL for the resource and user
Parameters: - login – str, login of the user
- resource – str, name of the resource
- type – str, name of the action
-
classmethod
get_acl
(login, resource, params=None) Overwrite the method to return the ACL for the resource and user
Parameters: - login – str, login of the user
- resource – str, name of the resource
Authorization¶
-
class
anyblok_pyramid.bloks.authorization.authorization.
Authorization
Bases:
object
A model to store autorization rules (permissions for users against an Anyblok model or a Pyramid resource)
AnyBlok registration:
- Type: Model
- Registry name: Model.Pyramid.Authorization
- Tablename: pyramid_authorization
Fields id Type
-anyblok.column.Integer
primary_key
-True
autoincrement
-True
default
-anyblok.column.NoDefaultValue
code Type
-anyblok.column.String
nullable
-True
unique
-True
default
-anyblok.column.NoDefaultValue
size
-256
order Type
-anyblok.column.Integer
nullable
-False
default
-100
resource Type
-anyblok.column.String
default
-anyblok.column.NoDefaultValue
size
-64
model Type
-anyblok.column.String
foreign_key
-Model.System.Model => name
default
-anyblok.column.NoDefaultValue
size
-256
primary_keys Type
-anyblok.column.Json
filter Type
-anyblok.column.Json
role Type
-anyblok.relationship.Many2One
model
- Model.Pyramid.Roleindex
-False
login Type
-anyblok.column.String
foreign_key
-Model.Pyramid.User => login
default
-anyblok.column.NoDefaultValue
size
-64
user Type
-anyblok.relationship.Many2One
model
- Model.Pyramid.Userindex
-False
perms Type
-anyblok.column.Json
perm_create Type
-anyblok.field.JsonRelated
json_column
-'perms'
keys
-'create'
perm_read Type
-anyblok.field.JsonRelated
json_column
-'perms'
keys
-'read'
perm_update Type
-anyblok.field.JsonRelated
json_column
-'perms'
keys
-'update'
perm_delete Type
-anyblok.field.JsonRelated
json_column
-'perms'
keys
-'delete'
-
classmethod
before_insert_orm_event
(mapper, connection, target)
-
classmethod
before_update_orm_event
(mapper, connection, target)
-
classmethod
check_acl
(login, resource, type_) Return the Pyramid ACL in function of the resource and user
Parameters: - login – str, login of the user
- resource – str, name of the resource
- type – str, name of the action
-
check_validity
() When creating or updating a User.Authorization, check that all rules objects exists or return an AuthorizationValidationException
Exception: AuthorizationValidationException
-
code
= <anyblok.column.String object>
-
classmethod
ensure_exists
(code, **kwargs) Ensure role’s authorization is present
Parameters: - code – String, authorization code.
- kwargs – authorization fields
-
filter
= <anyblok.column.Json object>
-
classmethod
get_acl
(login, resource, params=None) Return the Pyramid ACL in function of the resource and user
Parameters: - login – str, login of the user
- resource – str, name of the resource
-
classmethod
get_acl_filter_model
() Return the Model to use to check the permission
-
id
= <anyblok.column.Integer object>
-
login
= <anyblok.column.String object>
-
model
= <anyblok.column.String object>
-
order
= <anyblok.column.Integer object>
-
perm_create
= <anyblok.field.JsonRelated object>
-
perm_delete
= <anyblok.field.JsonRelated object>
-
perm_read
= <anyblok.field.JsonRelated object>
-
perm_update
= <anyblok.field.JsonRelated object>
-
perms
= <anyblok.column.Json object>
-
primary_keys
= <anyblok.column.Json object>
-
resource
= <anyblok.column.String object>
-
role
= <anyblok.relationship.Many2One object>
-
user
= <anyblok.relationship.Many2One object>
Exceptions¶
-
class
anyblok_pyramid.bloks.authorization.exceptions.
AuthorizationValidationException
Bases:
Exception
Simple exception when Authorization entry is wrong
Blok Pyramid¶
-
class
anyblok_pyramid.bloks.pyramid.
Pyramid
(registry) Bases:
anyblok.blok.Blok
-
author
= 'Jean-Sébastien Suzanne'
-
conditional_by
= []
-
conflicting_by
= []
-
classmethod
import_declaration_module
() Do the python import for the Declaration of the model or other
-
name
= 'pyramid'
-
optional_by
= []
-
classmethod
pyramid_load_config
(config)
-
classmethod
reload_declaration_module
(reload)
-
required
= ['anyblok-core']
-
required_by
= ['auth']
-
version
= '0.1.0'
-
Pyramid Blok¶
OpenID Connect¶
This blok provide an integration with oic an OpenID Connect library, to make your service an Relying Party (not a provider).
The api documentation.
Requirements¶
install OIDC’s extra requirements:
pip install anyblok_pyramid[oidc]
confiugre a server session management (we suggest to use anyblok_pyramid_beaker
Configuration¶
Following settings are available:
--oidc-provider-issuer OIDC_PROVIDER_ISSUER
he OIDC Provider urls (ie: https://gitlab.com)
--oidc-relying-party-callback OIDC_RELYING_PARTY_CALLBACK
The Relaying Party callback, once the user is
authenticate on the OIDC provider he will be redirect
to that uri to the RP service (ie:
http://localhost:8080/callback). In general this value
is also configured in your OIDC provider to avoid
redirection issues.
--oidc-relying-party-client-id OIDC_RELYING_PARTY_CLIENT_ID
The client id to authenticate the relying party (this
application) to the OIDC provider. This information
should be provide by your OIDC provider.
--oidc-relying-party-secret-id OIDC_RELYING_PARTY_SECRET_ID
The secret id to authenticate the relying party (this
application) to the OIDC provider. This information
should be provide by your OIDC provider.
--oidc-scope OIDC_SCOPE
Specify what access privileges are being requested for
Access Tokens. `cf Requesting claims using scope
values <https://openid.net/specs/openid-connect-
core-1_0.html#ScopeClaims`_. a list of claims
usingcoma separator.
--oidc-userinfo-field OIDC_USERINFO_FIELD
Specify which field to use from the response of the
OIDC provider `userinfo endpoint
<https://openid.net/specs/openid-connect-
core-1_0.html#UserInfoResponse>`_. To make sure it's a
known user
Pyramid¶
Pyramid model¶
-
class
anyblok_pyramid.bloks.pyramid.model.
Pyramid
Bases:
object
AnyBlok registration:
- Type: Model
- Registry name: Model.Pyramid
- Tablename: pyramid
-
classmethod
check_acl
(login, resource, type_) Retun True if user is allowed to make action type of the resource
This method must be ober writting by the auth blok
Parameters: - login – str, login attribute of the user
- resource – str, name of a resource
- type – str, name of the action
- params – all options need to compute ACL
-
classmethod
check_login
(**kwargs) Check login / password
This method raise an exception, because any credential is stored in this bloks
Warning
This method must be overwriting by anycredential blok
Parameters: kwargs – any options need to validate credential
-
classmethod
check_user_exists
(login)
-
classmethod
format_login_params
(request) Return the login and password from query
By default the query come from json_body and are named login and password
If the entries come from another place, this method must be overwrite :param request: the request from the controllers
-
classmethod
get_acl
(login, resource, params=None) Retun the ACL for a ressource and a user
Auth, does not implement any rule to compute ACL, This method allow all user to use the resource ask by controllers.
For other configuration, this method must be overwrite
This method must be ober writting by the auth blok
Parameters: - login – str, login attribute of the user
- resource – str, name of a resource
- params – all options need to compute ACL
-
classmethod
get_roles
(login) Return the roles of an user
This method must be ober writting by the auth blok
Parameters: login – str, login attribute of the user Return type: list of str (name of the roles)
-
get_user
(user_id) Cached _get_user results in order to use it by
restrict_query_by_user
decorators. Invalidate cache has to be implemented by user who use itCached classmethod with size=128
-
classmethod
restrict_query_by_user
(query, user_code) Call registered decorated method (by
from anyblok_pyramid.bloks.pyramid.restrict.restrict_query_by_user
) to add filters on current query according the selected model.Parameters: query – A query object which you have to add filters User_code: User primary key value used to retreive users. Note
This method is using get_user which cached user instance, you have to manage or mind to cache invalidation while using this method.
-
class
anyblok_pyramid.bloks.pyramid.restrict.
RestrictQueryByUserIdPlugin
(registry) Bases:
anyblok.model.plugins.ModelPluginBase
An AnyBlok plugin that helps to add extra filters on queries according the current user
-
transform_base_attribute
(attr, method, namespace, base, transformation_properties, new_type_properties) Find restricted methods in the base to save the namespace and the method in the registry :param attr: attribute name :param method: method pointer of the attribute :param namespace: the namespace of the model :param base: One of the base of the model :param transformation_properties: the properties of the model :param new_type_properties: param to add in a new base if need
-
-
anyblok_pyramid.bloks.pyramid.restrict.
restrict_query_by_user
()