{"id":13625952,"url":"https://github.com/cocoakekeyu/cancan","last_synced_at":"2025-04-07T05:16:41.436Z","repository":{"id":62560805,"uuid":"99400786","full_name":"cocoakekeyu/cancan","owner":"cocoakekeyu","description":"cancan is a tiny permission controller base on ruby cancan library.","archived":false,"fork":false,"pushed_at":"2020-06-04T15:14:41.000Z","size":14,"stargazers_count":245,"open_issues_count":1,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T18:11:09.659Z","etag":null,"topics":["django","flask","permission","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cocoakekeyu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-05T05:11:02.000Z","updated_at":"2023-11-07T12:46:16.000Z","dependencies_parsed_at":"2022-11-03T14:45:34.494Z","dependency_job_id":null,"html_url":"https://github.com/cocoakekeyu/cancan","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoakekeyu%2Fcancan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoakekeyu%2Fcancan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoakekeyu%2Fcancan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoakekeyu%2Fcancan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cocoakekeyu","download_url":"https://codeload.github.com/cocoakekeyu/cancan/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247595335,"owners_count":20963943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","flask","permission","python"],"created_at":"2024-08-01T21:02:06.430Z","updated_at":"2025-04-07T05:16:41.406Z","avatar_url":"https://github.com/cocoakekeyu.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# cancan\n\n## Introduction\n\n**cancan** is a tiny permission controller base on ruby cancan library. Once defined user ability, can easily check user's permission.\n\n## Install\n\n`pip install cancan`\n\n## Basic Usage\n\ninherit from cancan.Ability\n\nuse `add` method to add user Ability\n\n```python\ndef add(self, action=None, subject=None, **conditions)`\n    \"\"\"\n    Add ability are allowed using two arguments.\n\n    The first one is the action you're setting the permission for,\n    the second one is the class of object you're setting it on.\n    the third one is the subject's attributes must be matches or a function\n    to be test.\n\n    self.add('update', Article)\n    self.add('update', Article, user_id=1)\n    self.add('update', Article, user_id=1, title='hello')\n    self.add('update', Article, function=test_title)\n    \"\"\"\n```\n\n```python\nimport cancan\n\nclass User(object):\n    def __init__(self, id, name, role):\n        self.id = id\n        self.name = name\n        self.role = role\n\nclass Article(object):\n    def __init__(self, title, user_id):\n        self.title = title\n        self.user_id = user_id\n\nclass Ability(cancan.Ability):\n    def __init__(self, user):\n        if user.role == 'admin':\n            self.add('manage', 'all')\n        else:\n            self.add('read', Article)\n            self.add('create', Article)\n            self.add('update', Article, user_id=user.id)\n            self.add('create', 'bbb')\n\n\nadmin = User(1, 'neven', 'admin')\nability = Ability(admin)\n\n# admin\nability.can('read', Article)    # True\nability.can('create', Article)  # True\nability.can('delete', Article)  # True\nability.can('aaa', Article)     # True\nability.can('create', 'bbb')    # True\nability.can('create', 'ccc')    # True\n\nuser = User(2, 'joe', 'user')\nability2 = Ability(user)\n\n# user\nability2.can('read', Article)   # True\nability2.can('create', Article) # True\nability2.can('delete', Article) # False\nability2.can('aaa', Article)    # False\nability2.can('create', 'bbb')   # True\nability2.can('create', 'ccc')   # False\n\narticle = Article('hello', 2)\n# admin\nability.can('update', article) # True\n\n# user\nability2.can('update', article) # True\nability2.can('update', Article) # True(class dont check conditions)\n```\n\n## Advanced\n\n```python\nimport cancan\n\n\ndef test_title_gt_100(article):\n    return len(article.title) \u003e 100\n\ndef anoter_test(article, id, len_title):\n    return article.user_id \u003c id and len(article.title) \u003e len_article\n\nclass Ability(cancan.Ability):\n    def __init__(self, user):\n        self.alias_action('create', 'read', 'update', to='cru')\n\n        if user.role == 'admin':\n            self.add('manage', 'all')\n            self.addnot('destroy', 'gem')\n        elif user.role == 'editor':\n            self.add('cru', Article)\n            self.add(['read', 'create'], 'gem')\n            self.add('update', Article, function=test_title_gt_100)\n            self.add('delete', Article, function=another_test, func_args=(10,), func_kwargs={\"len_title\": 4})\n        else:\n            self.add('create', Article)\n            self.add('update', Article, user_id=user.id)\n            self.add('create', 'bbb')\n\neditor = User(3, 'kali', 'editor')\nability3 = Ability(editor)\n\n# editor\nability3.can('create', Article)  # True\nability3.can('update', Article)  # True\nability3.can('cru', Article)  # True\nability3.can('read', 'gem')  # True\nability3.can('create', 'gem')  # True\n\narticle = Article('world', 1)\nability3.can('update', article)  # False\nability3.can('delete', article)  # True\n\narticle = Article('world'*100, 1)\nability3.can('delete', article)  # True\n\n```\n\n## Example\n\nsee example.py\n\n## Integrate Django\n\nsee django_example\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcocoakekeyu%2Fcancan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcocoakekeyu%2Fcancan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcocoakekeyu%2Fcancan/lists"}