Package: rbact
rbactA simple RBAC library with different ORM adaptershas sync and async implementationsupports peewee/peewee_asyncstores access data in normal formdoesn't use cache (at least right now), so doesn't need to reload data and performs best with small role inheritance treeContentInstallationDocsPeewee hello worldPeewee async exampleHow it works?SuperuserGet all user rules/rolesFake rolesInstallation# Basic
pip install rbact

# With adapter's dependencies
pip install rbact[peewee]
pip install rbact[peewee_async]DocsPeewee hello worldfrompeeweeimportPostgresqlDatabaseimportrbactdb=PostgresqlDatabase('my_app',user='postgres',password='secret',host='10.1.0.9',port=5432)adapter=rbact.peewee.PeeweeAdapter(db)adapter.create_tables()inspector=rbact.Inspector(adapter)result=inspector.has_access('user','resource','write')With peewee your application needs to close connections explicitly.adapter.create_tables()andinspector.has_access()methods follow this logic and don't close connections by themselves.Peewee async example with a connection pool and model extensionsimportpeeweeaspwfrompeewee_asyncimportPooledPostgresqlDatabase,Managerfromrbactimportpeewee_asyncasrbact_peewee,AsyncInspectordb=PooledPostgresqlDatabase('my_app',user='postgres',password='secret',host='10.1.0.9',port=5432)db_manager=Manager(db)# model extensionclassUsers(rbact_peewee.Users):classMeta:table_name='custom_users'email=pw.TextField()asyncdefmain():loader=rbact_peewee.ModelsLoader(db_manager.database,users_model=Users)adapter=rbact_peewee.AsyncPeeweeAdapter(db_manager,models_loader=loader)inspector=AsyncInspector(adapter)has_access=awaitinspector.has_access('user','resource','write')role_with_access=awaitinspector.get_first_role_with_access('user','resource','read')How it works?Rbact uses 4 tables to store data, default tables look like this:All these tables can be created automatically withadapter.create_tables(). You can extend any table using inheritance but default columns mustn't be changed.Rbact rules examplesThe user who wants to access, the object (or resource) to which access is requested, the action that the user wants to doanalyst, company_metrics, read
employee, /api/write_task, writeSuperuserimportrbactdb=...adapter=rbact.peewee.PeeweeAdapter(db)inspector=rbact.Inspector(adapter)inspector.superuser='root'# default value is admininspector.superuser=None# disable superuserGet all user rules/rolesimportrbactdb=...adapter=rbact.peewee.PeeweeAdapter(db)inspector=rbact.Inspector(adapter)# list of tupleslist_rules=inspector.get_user_rules('user',orient='list')# dict with resource key and list of actions valuedict_rules=inspector.get_user_rules('user',orient='dict')# list of rolesroles=inspector.get_user_roles('user')Fake rolesFake role is an intermediate role that mustn't be assigned to any user. All its rules will be used, but you can't get this role byget_user_rolesorget_first_role_with_accessmethodsimportrbact.peeweeasrbact_peeweefromrbactimportInspectordb=...loader=rbact_peewee.ModelsLoader(db,with_fake_roles=True)adapter=rbact_peewee.PeeweeAdapter(db,models_loader=loader)adapter.create_tables()rbact_peewee.Roles.create(name="development_department",id=1,is_rbact_fake=True)rbact_peewee.Rules.create(role=1,obj="docs",act="read")rbact_peewee.Roles.create(name="software_developer",id=2,parent=1)rbact_peewee.Rules.create(role=2,obj="code",act="write")rbact_peewee.Users.create(login="user1",id=1)rbact_peewee.UsersRoles.create(user=1,role=2)rbact_peewee.Roles.create(name="project_manager",id=3)# all this users can read docs due to root fake roleinspector=Inspector(adapter)result=inspector.get_user_roles('user1')# ["software_developer"]role_with_access=inspector.get_first_role_with_access('user1','docs','read')# software_developer