-
Notifications
You must be signed in to change notification settings - Fork 9
Permission周り仕様まとめ
third-impact
では、Userモデルを継承したPersona
モデルをユーザーモデルとして扱う。
Persona
には、通常のUserに加えて以下のようなフィールドが存在する。
フィールド名 | 型 | 概要 |
---|---|---|
nickname | varchar | ユーザーのニックネーム |
avatar | varchar | ユーザーのプロフィール画像 |
gender | varchar | ユーザーの性別。man/woman/unknown |
quotes | varchar | ユーザーのムードメッセージ |
role | varchar | ユーザーの役職(後述) |
Personaはroleを持ち、以下の5つのroleが存在する。概ね、権限順の並び順となっている
役職名 | 概要 |
---|---|
Adam | superuser。全てのパーミッションを持ちます。神聖にして不可侵な存在 |
Seele | sudoer。Nervに加え、Adam化できる権限、他人のroleを操作する権限を持ちます。 |
Nerv | staff。スタッフ権限を持ちます。一部のデータの操作や閲覧が可能です。 |
Children | 一般ユーザー。Kawazポータルにモデルを作成したり、通常の権限を持ちます。 |
Wille | 外部ユーザー。イベントに参加する、コメントを書くと言ったことができます。内部公開のドキュメントを閲覧したり、他のオブジェクトを操作することはできません。 |
各アプリケーションで定義されているパーミッションと、その操作可能範囲です。 Adamについては、全てのパーミッションを所持していると考えられるため、記述していません。
また、それぞれについて表中の記号は以下のような意味を持ちます。」
記号 | 説明 |
---|---|
○ | そのモデルのオブジェクトどれか一つでも該当のパーミッションが存在する |
× | そのモデルのオブジェクト全てに該当のパーミッションが存在しない |
記号 | 説明 |
---|---|
○ | そのモデルのオブジェクト全てに該当のパーミッションが存在する |
× | そのモデルのオブジェクト全てに該当のパーミッションが存在しない |
[A]uthor | そのオブジェクトを所持している |
[C]ollaborator | そのオブジェクトを所持、またはメンバーである |
[D]raft | pub_stateがDraftである |
[P]ublic | そのオブジェクトのpub_stateがPublicである |
[I]nternal | そのオブジェクトのpub_stateがPublicまたはPrivateである |
[S]elf | 操作者と対象者が同じである |
また、通常、addはオブジェクトパーミッションでは扱わない。
また、これらの条件式は、普通の論理演算のように扱える。
例えばI or (D and A)
は、「pub_stateがPublic または Privateである、もしくはpub_stateがDraftかつ、自分の所属しているオブジェクト」となる。
また!
は反転であり、!S
は対象が自分以外となる
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
announcements.add_announcement | ○ | ○ | × | × |
announcements.change_announcement | ○ | ○ | × | × |
announcements.delete_announcement | ○ | ○ | × | × |
announcements.view_announcement | ○ | ○ | ○ | ○ |
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
announcements.change_announcement | ○ | ○ | × | × |
announcements.delete_announcement | ○ | ○ | × | × |
announcements.view_announcement | ○ | ○ | I | P |
作成、変更、削除共にNerv以上の権限が必要で、モデルの権限があれば、基本的に全てのモデルを操作可能。 要はスタッフであれば、他のスタッフが作ったモノでも変更削除が可能という点が他のモデルとの一番大きな違い。
ViewはWilleはProtected/Draftを閲覧できない。スタッフはDraftでも閲覧できる。ChildrenはPublic/Protectedが閲覧可能。
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
blogs.add_entry | ○ | ○ | ○ | × |
blogs.change_entry | ○ | ○ | ○ | × |
blogs.delete_entry | ○ | ○ | ○ | × |
blogs.view_entry | ○ | ○ | ○ | ○ |
blogs.add_category | ○ | ○ | ○ | × |
blogs.change_category | ○ | ○ | ○ | × |
blogs.delete_category | ○ | ○ | ○ | × |
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
blogs.change_entry | A | A | A | × |
blogs.delete_entry | A | A | A | × |
blogs.view_entry | I or (D and A) | I or (D and A) | I or (D and A) | P |
blogs.change_category | A | A | A | × |
blogs.delete_category | A | A | A | × |
権限の数は多いが、一番オーソドックスなアプリケーション。
自分で作成したモノのみ編集、削除可能。
閲覧はWilleは全て、Children以上はPublic/Privateと自分が作成したDraftのみ。これが基本形と言っても過言ではない。
カテゴリに関しては、設定しないことが許されているので削除できる。これはプロジェクトのカテゴリーとの違い。
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
events.add_event | ○ | ○ | ○ | × |
events.change_event | ○ | ○ | ○ | × |
events.delete_event | ○ | ○ | ○ | × |
events.view_event | ○ | ○ | ○ | ○ |
events.attend_event | ○ | ○ | ○ | ○ |
events.quit_event | ○ | ○ | ○ | ○ |
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
events.change_event | A | A | A | × |
events.delete_event | A | A | A | × |
events.view_event | I or (D and A) | I or (D and A) | I or (D and A) | P |
events.attend_event | I and S | I and S | I and S | P and S |
events.quit_event | I and (S or A) | I and (S or A) | I and (S or A) | P and (S or A) |
数少ないWilleが操作できるモデルで、権限の数と扱いが両方とも複雑。
まず、追加はログインユーザー全員、変更削除は作者のみ。
閲覧は通常通り
参加はログインユーザーはdraftでないものに自分が参加可能 WilleはPublicなイベントに自分が参加可能
退出は基本的に同じだが、authorのみkickが可能
要議論な点としては
- 開催者や参加者が他のメンバーを参加者にできる
- Wille以外の参加者がイベントを編集できるようにする
という点か。現段階では認めていない。
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
profiles.add_profile | ○ | ○ | ○ | × |
profiles.change_profile | ○ | ○ | ○ | × |
profiles.delete_profile | × | × | × | × |
profiles.view_profile | ○ | ○ | ○ | ○ |
profiles.add_skill | ○ | ○ | × | × |
profiles.change_skill | ○ | ○ | × | × |
profiles.delete_skill | ○ | ○ | × | × |
profiles.add_service | ○ | ○ | × | × |
profiles.change_service | ○ | ○ | × | × |
profiles.delete_service | ○ | ○ | × | × |
profiles.add_account | ○ | ○ | ○ | × |
profiles.change_account | ○ | ○ | ○ | × |
profiles.delete_account | ○ | ○ | ○ | × |
profiles.view_account | ○ | ○ | ○ | ○ |
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
profiles.change_profile | A | A | A | × |
profiles.delete_profile | × | × | × | × |
profiles.view_profile | ○ | ○ | ○ | P |
profiles.change_skill | ○ | ○ | × | × |
profiles.delete_skill | ○ | ○ | × | × |
profiles.change_service | ○ | ○ | × | × |
profiles.delete_service | ○ | ○ | × | × |
profiles.change_account | A | A | A | × |
profiles.delete_account | A | A | A | × |
profiles.view_account | ○ | ○ | ○ | P |
権限自体は多いが、どれもオーソドックス。
まずProfile、基本的にはblogの基本形同様。大きな違いとして
- Profileは何者も削除できない
- Draft状態が存在しない
この2点がプロフィール特有。
Skill, Serviceは管理者のみが作成、変更、削除可能
Accountは作成者のみが削除可能。閲覧権限は同様。
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
personas.add_persona | ○ | ○ | × | × |
personas.change_persona | ○ | ○ | ○ | × |
personas.delete_persona | × | × | × | × |
personas.view_persona | ○ | ○ | ○ | ○ |
personas.activate_persona | ○ | ○ | × | × |
personas.assign_role_persona | ○ | × | × | × |
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
personas.change_persona | A | A | A | × |
personas.delete_persona | × | × | × | × |
personas.view_persona | ○ | ○ | ○※ | ○※ |
personas.activate_persona | ○ | !S | × | × |
personas.assign_role_persona | ○ | × | × | × |
基本は同様。自分のモノのみ変更可能。削除は不可能。
view権限に関しては、今、全ての情報が一つのパーミッションで管理されているが、 avatar/gender/quotes/nicknameなどのpublicな情報と、email/first name/last nameなどのセンシティブな情報が混在しているため、パーミッションをわけたい感じがある(為、※印を付けておいた)
activateはis_activeを切り替える権限。スタッフのみ持っているが、Nervは自分のis_activeを切り替えることはできない。(参加申請の承認などはこれで行う)
assign_roleはroleを変更する権限で、Seeleのみ可能である。これで神化したり、Nervを増やしたりできる。
唯一、SeeleとNervの扱いが異なるモデルでもある。
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
products.add_product | ○ | ○ | ○ | × |
products.change_product | ○ | ○ | ○ | × |
products.delete_product | ○ | ○ | ○ | × |
products.add_category | ○ | ○ | × | × |
products.change_category | ○ | ○ | × | × |
products.delete_category | ○ | ○ | × | × |
products.add_platform | ○ | ○ | × | × |
products.change_platform | ○ | ○ | × | × |
products.delete_platform | ○ | ○ | × | × |
products.add_package_release | ○ | ○ | ○ | × |
products.change_package_release | ○ | ○ | ○ | × |
products.delete_package_release | ○ | ○ | ○ | × |
products.add_url_release | ○ | ○ | ○ | × |
products.change_url_release | ○ | ○ | ○ | × |
products.delete_url_release | ○ | ○ | ○ | × |
products.add_screenshot | ○ | ○ | ○ | × |
products.change_screenshot | ○ | ○ | ○ | × |
products.delete_screenshot | ○ | ○ | ○ | × |
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
products.change_product | C | C | C | × |
products.delete_product | C | C | C | × |
products.change_category | ○ | ○ | × | × |
products.delete_category | ○ | ○ | × | × |
products.change_platform | ○ | ○ | × | × |
products.delete_platform | ○ | ○ | × | × |
products.change_package_release | C | C | C | × |
products.delete_package_release | C | C | C | × |
products.change_url_release | C | C | C | × |
products.delete_url_release | C | C | C | × |
products.change_screenshot | C | C | C | × |
products.delete_screenshot | C | C | C | × |
1アプリケーションにモデルが6つもあってヤバい。
が、基本的にパーミッションの扱いはメチャクチャシンプル。 まず、公開状態が存在しないため、全てのオブジェクトはpublicになる。
category, platformはネルフのみ全て編集・削除可能 その他の物は持ち主(管理者)のみ編集・削除可能。めっちゃシンプル
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
projects.add_project | ○ | ○ | ○ | × |
projects.change_project | ○ | ○ | ○ | × |
projects.delete_project | ○ | ○ | ○ | × |
projects.view_project | ○ | ○ | ○ | ○ |
projects.join_project | ○ | ○ | ○ | × |
projects.quit_project | ○ | ○ | ○ | × |
projects.add_category | ○ | ○ | × | × |
projects.change_category | ○ | ○ | × | × |
projects.delete_category | × | × | × | × |
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
projects.change_project | C | C | C | × |
projects.delete_project | A | A | A | × |
projects.view_project | I or C | I or C | I or C | P |
projects.join_project | I and (S or C) | I and (S or C) | I and (S or C) | × |
projects.quit_project | I and (S or A) | I and (S or A) | I and (S or A) | × |
projects.change_category | ○ | ○ | × | × |
projects.delete_category | × | × | × | × |
基本的にはblogsと一緒。大きな違いは参加メンバーもコラボレーターとして編集可能な点。
参加メンバーであれば、draft状態の記事も変更、閲覧可能。
ただし、削除は作者のみ。
参加はS or C、つまりコラボレーターである、または自分自身であるときのみ可能。プロジェクトメンバーは任意の人をメンバーにできるし、そうじゃない場合は自分のみをメンバーにできる。
参加取り消しはS or A、自分で抜けるか、管理者(作者)がキックするかのいずれかのみ認めている。
カテゴリーはスタッフ以上が追加可能。ただし誰も削除はできない。これはProjectのカテゴリの未設定が許されないためである。
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
stars.add_star | ○ | ○ | ○ | × |
stars.change_star | × | × | × | × |
stars.delete_star | ○ | ○ | ○ | × |
stars.view_star | ○ | ○ | ○ | ○ |
パーミッション名 | Seele | Nerv | Children | Wille |
---|---|---|---|---|
stars.add_star | ※ | ※ | ※ | × |
stars.change_star | × | × | × | × |
stars.delete_star | ※ | ※ | ※ | × |
stars.view_star | ※ | ※ | ※ | ※ |
※ がついた権限については複雑なので解説を参照
基本的には以下のルールに従う
- Children 以上がスターの追加・削除が可能
- 一切の変更は不可
- 閲覧権限を持たないオブジェクトに対しては追加・閲覧・削除が出来ない
- 基本的に削除は自身が所有するスターのみ可能
- 自分が編集権限を所有するオブジェクトについたスターは自身が所有者でなくても削除可能
閲覧権限を持たないオブジェクトにスターを付加することは権限レベルで制限されている。
また、同様に閲覧権限を持たないオブジェクトについたスターを削除することも出来ない。
これは閲覧権限を持たないオブジェクトについたスターの閲覧権限を持たないことに起因する。
具体的に説明すると、閲覧権限を持たないオブジェクトに付いているスターは、そのオブジェクトに由来する引用(quote
)を持つ可能性が存在する。
これはセキュリティ的に問題があるため、スターの閲覧権限は付加対象オブジェクトの閲覧権限に左右される。
それに伴い、スターの付加・削除権限も決定される。
なお、付加先のオブジェクトに閲覧権限という概念が存在しない場合は、常に閲覧可能(メンバーの場合は追加・削除も可能)。
注意点としてstars.add_star自体は非オブジェクトパーミッションなのでuser.has_perm()
などでチェックする場合は常にTrue
を返す(メンバーの場合)。
自身が特定のオブジェクトに対してスターの付加権限を持つか否かはstars.add_star
を対象のオブジェクトを渡してuser.has_perm()
を呼び出すという少しイレギュラーなチェック方法を取る。以下参照
>>> user = User.objects.get(pk=1) # childrenだと仮定
>>> article = Article.objects.get(pk=1) # 上記ユーザーが閲覧権限を持たないと仮定
>>> user.has_perm('stars.add_star') # 非オブジェクトパーミッションなのでメンバーであれば常にTrue
True
>>> user.has_perm('stars.add_star', # 通常追加権限でオブジェクトを渡すことはないが、この場合は渡されたオブジェクトに対する
... obj=article) # 付加権限を持つかどうかを表すと定義する
False