Package: pyperms
PyPerms (Python Permissions)PyPerms is a library for convenient access control. The inspiration was the JS library -CASL.Simple UsagefrompypermsimportPermissionsBuilderfrom.modelsimportUserdefdefine_perms_for(user):builder=PermissionsBuilder()builder.can("read","Post")if"admin"inuser.roles:builder.can("*","*")returnbuilder.build()admin=User(id=1,roles=["admin"])user=User(id=2,roles=["user"])admin_perms=define_perms_for(admin)user_perms=define_perms_for(user)admin_perms=define_perms_for(admin)user_perms=define_perms_for(user)admin_perms.can("read","Post")# Trueadmin_perms.can("create","Post")# Trueadmin_perms.can("read","Article")# Trueuser_perms.can("read","Post")# Trueuser_perms.can("create","Post")# FalseTypingFor typingActionsandSubjects, you can useLiteralfrom the standard moduletyping.fromtypingimportLiteralfrompypermsimportPermissionsBuilderActions=Literal["*","read"]Subjects=Literal["*","Post"]defdefine_perms():builder=PermissionsBuilder[Actions,Subjects]()builder.can("read","Post")# OKbuilder.can("*","*")# OKbuilder.can("create","Post")# Errorreturnbuilder.build()FieldsFor more flexible permission settings, you can use thefieldsparameter.frompypermsimportPermissionsBuilderdefdefine_perms():builder=PermissionsBuilder()builder.can("read","Post",fields=["title","author"])returnbuilder.build()perms=define_perms()perms.can("read","Post",field="title")# Trueperms.can("read","Post",field="created_at")# FalseConditionsSometimes permission checks may require conditions, such as whether the user is the author of the post. For such cases, there is acondiotionparameter in the buildercanandcannotmethods. For it to work, it is necessary to pass an instance of the class with the same name in thesubject.frompypermsimportPermissionsBuilderfrompypermsimportoperatorsas_from.modelsimportPost,Userdefdefine_perms_for(user):builder=PermissionsBuilder()builder.can("update","Post",condition=_.Eq("author",user.id))returnbuilder.build()post=Post(id=1,author=1)user1=User(id=1)user2=User(id=2)user1_perms=define_perms_for(user1)user2_perms=define_perms_for(user2)user1_perms.can("update",post)# Trueuser2_perms.can("update",post)# FalseOperatoris a callable object that returns a boolean value. When it is initialized, the first parameter is the path to the attribute (can be separated by dot for recursive access), the second parameter is the value to be checked.Here is a list of default operators:Logical:AndOrNotOther:EqNeLtLeGtGeInNInAllSizeRegexAttributesEach operator, when called, tries to get the attribute usinggetattr. To reduce the number ofgetattrcalls, you can use theAttributeclass or theattrfunction. An instance of this class stores the received attribute value for each object (comparison by id).frompypermsimportPermissionsBuilder,attrfrompypermsimportoperatorsas_defdefine_perms_for(user):builder=PermissionsBuilder()author=attr("author")builder.can("read","Post",condition=_.Eq(author,user.id))builder.can("update","Post",condition=_.Eq(author,user.id))returnbuilder.build()Custom operatorsAll operators are subclasses of one of three base classes:BaseLogicOperator1,BaseLogicOperator2,BaseOperator.An example of your own operator:frompyperms.conditions.baseimportBaseOperatordefmy_func(__a:int,__b:int)->bool:return__a+__b==2classMyOperator(BaseOperator,func=my_func):"Docstring for MyOperator"...