Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit5fb168a

Browse files
committed
rethink about authlayer
1 parent483140f commit5fb168a

30 files changed

+646
-250
lines changed

‎docs/tips.md‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44

55
```sh
66
env MIX_ENV=mock iex -S mix
7-
alias MastaniServer.CMS
8-
import Ecto.Query, warn:false
9-
alias MastaniServer.Repo
10-
CMS.Post|> order_by(desc: :views)|> Repo.one
11-
```
7+
8+
mix test.watch test/mastani_server/cms/cms_passport_test.exs --only wip
9+
10+
```
1211
`recompile()` to recompile your project
1312

1413
[tips#6](https://medium.com/blackode/10-killer-elixir-tips-2-c5f87f8a70c8)

‎lib/helper/query_builder.ex‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ defmodule Helper.QueryBuilder do
2424
|>select([f],count(f.id))
2525
end
2626

27-
defreactions_hanlder(queryable,%{arg_viewer_reacted:_,current_user:current_user})do
28-
queryable|>where([f],f.user_id==^current_user.id)
27+
defreactions_hanlder(queryable,%{arg_viewer_reacted:_,cur_user:cur_user})do
28+
queryable|>where([f],f.user_id==^cur_user.id)
2929
end
3030

3131
defreaction_members(queryable,filter)do

‎lib/mastani_server/cms/cms.ex‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ defmodule MastaniServer.CMS do
3434
3. check is viewer reacted
3535
"""
3636
defquery({"posts_favorites",PostFavorite},args)do
37+
# TODO rename to reactions_pack/builder
3738
PostFavorite|>QueryBuilder.reactions_hanlder(args)
3839
end
3940

‎lib/mastani_server/cms/community.ex‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ defmodule MastaniServer.CMS.Community do
1818
join_keys:[community_id::id,post_id::id]
1919
)
2020

21+
# posts_managers
22+
# jobs_managers
23+
# tuts_managers
24+
# videos_managers
25+
#
26+
# posts_block_list ...
27+
# videos_block_list ...
28+
#
29+
# settings: map %{"posts.needReview" => true ...}
30+
2131
timestamps(type::utc_datetime)
2232
end
2333

‎lib/mastani_server_web/context.ex‎

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ defmodule MastaniServerWeb.Context do
66
importPlug.Conn
77
# import Ecto.Query, only: [first: 1]
88

9-
aliasMastaniServer.{Repo,Accounts}
9+
aliasMastaniServer.{Accounts,CMS}
1010
aliasHelper.MastaniServer.Guardian
11+
aliasHelper.ORM
1112

1213
definit(opts),do:opts
1314

@@ -27,25 +28,33 @@ defmodule MastaniServerWeb.Context do
2728
"""
2829
defbuild_context(conn)do
2930
with["Bearer "<>token]<-get_req_header(conn,"authorization"),
30-
{:ok,current_user}<-authorize(token)do
31-
%{current_user:current_user}
31+
{:ok,cur_user}<-authorize(token)do
32+
%{cur_user:cur_user}
3233
else
3334
_->%{}
3435
end
3536
end
3637

3738
defpauthorize(token)do
3839
with{:ok,claims,_info}<-Guardian.jwt_decode(token)do
39-
caseRepo.get(Accounts.User,claims.id)do
40-
nil->
40+
caseORM.find(Accounts.User,claims.id)do
41+
{:ok,user}->
42+
check_passport(user)
43+
44+
{:error,_}->
4145
{:error,
4246
"user is not exsit, try revoke token, or if you in dev env run the seeds first."}
43-
44-
user->
45-
# TODO gather role info from CMS or other context
46-
{:ok,Map.put(user,:root,true)}
47-
# {:ok, user}
4847
end
4948
end
5049
end
50+
51+
# TODO gather role info from CMS or other context
52+
defpcheck_passport(%Accounts.User{}=user)do
53+
with{:ok,cms_passport}<-CMS.get_passport(%Accounts.User{id:user.id})do
54+
# IO.inspect(cms_passport.rules, label: "get cms passport")
55+
{:ok,Map.put(user,:cur_passport,cms_passport.rules)}
56+
else
57+
{:error,_}->{:ok,user}
58+
end
59+
end
5160
end

‎lib/mastani_server_web/middleware/authorize.ex‎

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,11 @@ defmodule MastaniServerWeb.Middleware.Authorize do
55
@behaviourAbsinthe.Middleware
66
importHelper.Utils,only:[handle_absinthe_error:2]
77

8-
defcall(%{context:%{current_user:current_user}}=resolution,role)do
9-
casevalid_role?(current_user,role)do
10-
true->resolution
11-
_->handle_error(resolution)
12-
end
13-
end
14-
15-
defcall(resolution,_)do
16-
handle_error(resolution)
17-
end
18-
19-
# defp valid_role?(%{}, :any), do: true
20-
defpvalid_role?(_,:login),do:true
21-
defpvalid_role?(%{role:role},role),do:true
22-
defpvalid_role?(_,_),do:false
23-
24-
defphandle_error(%{context:%{current_user:_}}=resolution)do
8+
defcall(%{context:%{cur_user:_}}=resolution,role)do
259
resolution
26-
|>handle_absinthe_error("Authorize: unauthorized role")
2710
end
2811

29-
defphandle_error(resolution)do
12+
defcall(resolution,_)do
3013
resolution
3114
|>handle_absinthe_error("Authorize: need login")
3215
end

‎lib/mastani_server_web/middleware/owner_required.ex‎

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,20 @@ defmodule MastaniServerWeb.Middleware.OwnerRequired do
1010

1111
aliasHelper.ORM
1212

13-
defppassport_checkin(user,author_id,others)do
14-
# IO.inspect(others, label: "others")
15-
# TODO other roles
16-
user.id==author_idoruser.rootoruser.roleinothers
17-
end
18-
1913
defcall(
20-
%{context:%{current_user:current_user},arguments:%{id:id},errors:[]}=resolution,
14+
%{context:%{cur_user:cur_user},arguments:%{id:id},errors:[]}=resolution,
2115
args
2216
)do
23-
with{:ok,part,react,others}<-parse_args(args),
17+
with{:ok,part,react}<-parse_args(args),
2418
{:ok,action}<-match_action(part,react),
2519
{:ok,content}<-ORM.find(action.reactor,id,preload:action.preload)do
2620
content_author_id=
2721
ifreact==:comment,
2822
do:content.author.id,
2923
else:content.author.user_id
3024

31-
casepassport_checkin(current_user,content_author_id,others)do
32-
true->
33-
arguments=resolution.arguments|>Map.merge(%{content_tobe_operate:content})
34-
%{resolution|arguments:arguments}
35-
36-
_->
37-
resolution
38-
|>handle_absinthe_error("OPERATION_DENY: owner or community admin/editor required")
39-
end
25+
arguments=resolution.arguments|>Map.merge(%{passport_source:content})
26+
%{resolution|arguments:arguments}
4027
else
4128
{:error,err_msg}->
4229
resolution
@@ -46,9 +33,6 @@ defmodule MastaniServerWeb.Middleware.OwnerRequired do
4633

4734
defcall(resolution,_),do:resolution
4835

49-
defpparse_args(match:[part,react],others:others),do:{:ok,part,react,others}
50-
defpparse_args(match:[part,react]),do:{:ok,part,react,[:owner]}
51-
52-
defpparse_args(match:part,others:others),do:{:ok,part,:self,others}
53-
defpparse_args(match:part),do:{:ok,part,:self,[:owner]}
36+
defpparse_args(match:[part,react]),do:{:ok,part,react}
37+
defpparse_args(match:part),do:{:ok,part,:self}
5438
end
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# ---
2+
# Absinthe.Middleware behaviour
3+
# see https://hexdocs.pm/absinthe/Absinthe.Middleware.html#content
4+
# ---
5+
# RBAC vs CBAC
6+
# https://stackoverflow.com/questions/22814023/role-based-access-control-rbac-vs-claims-based-access-control-cbac-in-asp-n
7+
8+
# 本中间件会隐式的加载 community 的 rules 信息,并应用该 rules 信息
9+
defmoduleMastaniServerWeb.Middleware.Passportdo
10+
@behaviourAbsinthe.Middleware
11+
12+
importHelper.Utils
13+
14+
defcall(%{errors:errors}=resolution,_)whenlength(errors)>0,do:resolution
15+
16+
defcall(%{arguments:%{passport_is_owner:true}}=resolution,claim:"owner"),do:resolution
17+
18+
defcall(%{arguments:%{passport_is_owner:true}}=resolution,claim:"owner;"<>_rest),
19+
do:resolution
20+
21+
defcall(
22+
%{
23+
context:%{cur_user:%{cur_passport:_}},
24+
arguments:%{community:_,part:_}
25+
}=resolution,
26+
claim:"cms->c?->p?."<>_rest=claim
27+
)do
28+
IO.inspect("catch me cms->c?->p?",label:"[passport]")
29+
resolution|>check_passport_stamp(claim)
30+
end
31+
32+
defcall(
33+
%{
34+
context:%{cur_user:%{cur_passport:_}},
35+
arguments:%{passport_communities:_}
36+
}=resolution,
37+
claim:"cms->c?->"<>_rest=claim
38+
)do
39+
# IO.inspect("catch me cms->c?->", label: "[passport]")
40+
resolution|>check_passport_stamp(claim)
41+
end
42+
43+
defcall(
44+
%{
45+
context:%{cur_user:%{cur_passport:_}},
46+
arguments:%{passport_communities:_}
47+
}=resolution,
48+
claim:"owner;"<>claim
49+
)do
50+
resolution|>check_passport_stamp(claim)
51+
end
52+
53+
defcall(resolution,_)do
54+
resolution|>handle_absinthe_error("PassportError: your passport not qualified.")
55+
end
56+
57+
defpcheck_passport_stamp(resolution,claim)do
58+
conddo
59+
claim|>String.starts_with?("cms->c?->p?.")->
60+
resolution|>two_step_check(claim)
61+
62+
claim|>String.starts_with?("cms->c?->")->
63+
resolution|>one_step_check(claim)
64+
65+
true->
66+
resolution|>handle_absinthe_error("PassportError: Passport not qualified.")
67+
end
68+
end
69+
70+
defptwo_step_check(resolution,claim)do
71+
cur_passport=resolution.context.cur_user.cur_passport
72+
community=resolution.arguments.community
73+
part=resolution.arguments.part|>to_string
74+
75+
path=
76+
claim
77+
|>String.replace("c?",community)
78+
|>String.replace("p?",part)
79+
|>String.split("->")
80+
81+
caseget_in(cur_passport,path)do
82+
true->resolution
83+
nil->resolution|>handle_absinthe_error("PassportError: Passport not qualified.")
84+
end
85+
end
86+
87+
defpone_step_check(resolution,claim)do
88+
cur_passport=resolution.context.cur_user.cur_passport
89+
communities=resolution.arguments.passport_communities
90+
91+
result=
92+
communities
93+
|>Enum.filter(fncommunity->
94+
path=claim|>String.replace("c?",community.title)|>String.split("->")
95+
get_in(cur_passport,path)==true
96+
end)
97+
|>length
98+
99+
caseresult>0do
100+
true->resolution
101+
false->resolution|>handle_absinthe_error("PassportError: Passport not qualified.")
102+
end
103+
end
104+
end
105+
106+
# 可以编辑某个社区 post 版块的文章, 支持 owner
107+
# middleware(M.Passport, claim: "cms->c?->posts.articles.edit")
108+
# middleware(M.Passport, claim: "owner;cms->c?->posts.articles.edit")
109+
110+
# 可以添加某个社区 posts 版块的 tag 标签, 同时可支持 owner
111+
# middleware(M.Passport, claim: "cms->c?->posts.tag.add")
112+
# middleware(M.Passport, claim: "cms->c?->posts.tag.edit")
113+
# middleware(M.Passport, claim: "cms->c?->posts.tag.delete")
114+
# middleware(M.Passport, claim: "cms->c?->posts.tag.trash")
115+
# middleware(M.Passport, claim: "owner;cms->c?->posts.tag.delete")
116+
117+
# 可以给某个社区 posts 版块的 posts 设置标签(setTag), 同时可支持 owner?
118+
# middleware(M.Passport, claim: "c?->posts.setTag")
119+
120+
# 可以某个社区的 posts 版块置顶
121+
# middleware(M.Passport, claim: "cms->c?->posts.setTop")
122+
123+
# 可以编辑某个社区所有版块的文章
124+
# middleware(M.Passport, claim: "cms->c?->posts.articles.edit")
125+
# middleware(M.Passport, claim: "cms->c?->job.articles.edit")
126+
# ....全部显示声明....
127+
# middleware(M.Passport, claim: "cms->c?->radar.articles.edit")
128+
129+
# 可以给某个社区的某个版块添加/删除管理员, 实际上就是在给其他成员分配上面的权限,同时该用户会被添加到相应的管理员中
130+
# middleware(M.Passport, claim: "cms->c?->posts.managers.add")
131+
# middleware(M.Passport, claim: "cms->c?->jobs.managers.add")
132+
# middleware(M.Passport, claim: "cms->c?->videos.managers.add")
133+
# middleware(M.Passport, claim: "cms->c?->videos.managers.delete")
134+
135+
# 可以给社区的版块设置审核后发布
136+
# middleware(M.Passport, claim: "cms->c?->settings.posts.needReview")
137+
# middleware(M.Passport, claim: "cms->c?->posts.reviewer") # 审核员 (一开始没必要加)
138+
139+
# 在某个社区的某个版块屏蔽某个用户
140+
# middleware(M.Passport, claim: "cms->c?->viewer->block")
141+
142+
# 查看某个社区的总访问量
143+
# middleware(M.Passport, claim: "statistics->c?->click")
144+
# middleware(M.Passport, claim: "logs->c?->posts ...")
145+
146+
# defguard the_fuck(value) when String.contains?(value, "->?")
147+
# classify the require of this gateway

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp