From 6b6728356aa258ba8c2dab8156db7724c6e66550 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Tue, 17 Dec 2019 15:35:38 +0300 Subject: [PATCH 1/3] Container access control type definitions --- container/service.pb.go | Bin 59764 -> 61029 bytes container/service.proto | 3 +++ container/types.go | 13 +++++++++++++ container/types.pb.go | Bin 11990 -> 23152 bytes container/types.proto | 14 ++++++++++++++ 5 files changed, 30 insertions(+) diff --git a/container/service.pb.go b/container/service.pb.go index d9febc0e85a9d343fc30293765ae6c0f77e2f52d..cac8764ceb0852ab8a131580f2bb9ec3f847dcc5 100644 GIT binary patch delta 3700 zcmYk9J&Rpc6oyHn!5LF%VMNFz<5UJmIrpA(&qs)0Op(S$5NvZkA)+&JW&&4G5BUQY zUKD?Za0?3y|AU2>C`raoOH(%Vpvia`DtJ|MmxcJ=W^!_VX?~P|1zj5=tiOq{w z_O7wNyYuDl&dGT8=;Y|U!1l*0mv3IIv(3+|v$;Fm&(`G_*CCHtWa~u{e~d$1 zbHAJTy+mlJI9+kdTDI|f#abd$E6?3&$z4vD8YtPCYaCc*@jT;3UdHdDj;of{q(@8b zEaK_Hm0QYWdejj@iIWu<7Pz$Rr#rLwa3en2*d420M-^2m5D~h3Ynlfa<$~Lgc{K;OLcYBc_5LQ1>ao^d0uDWCSn;{ zC#d5gCK& zlSCtyd!p^(stw=fzra%~Q-1>@F$B@h%lR4H-nJcB>B2n{k1;rd9344;HQ0AH^q?AQ z7z@B1+IUQZLU6URtoR->>`NINZYx1SRf>oD4Jy)jL0zbfXH*hBhlc&V$AS$)6}c){ z8`HygJ7B*f#VxDHttjb|+#k_u-%m{zO|}EaZ|cg#mZl#dslmZMflEFRLNoJAzIDKt zvD2bEy-Nt%ggQrU6H+V#+ZFK)_-K2dCer`|oB;)jWYto`vr`7p7uK7ZF$TQwv9ki6 zfz_E6=4ecVufjW47e%LY` zxfM|rfUZX&lYu?T3%v}ti8OO+djOZJ5;q)wmELojn2A2?T{5JkBO^)Dgdp0Kh6ylI zZZXi&?`E5$4cw;ba1zxP`)R%tn{BU^R@m&U23__2H3&VNFssgY0h1p-Ip+nM99^M- z2CR%nlx+TKf*O|X%}OiJ@g}hm6;4^7lS(G2V3@@40WqfzX`-Desm74C(o#zWda0BH zOmY~TdMEXgW$505b7)zSN%kq(z^i3mhv6OD3*d^0jarCpvITWuo5+dT)!2L;2Gv*~ zxuTb2+PAH1gP9z4JPziyj~Z#}v&E!4s7%j9CWHNG;k>Ai3c>Inh!rSf0{22_X)F__ z59ahBh@QT?t|5Tvg&7nr^Z;${oz&?q2GH7+ZdtYY>%F}LcqqkvbB6ydQIUUN;?rjP z=G{MTJkP(f&65Y$Hd+7Gg?97gv#Z;e`hTvcgT2RZZU1|G`|5?&=Jl^Xd@B9TYun$y S{r5up`SP#r_V)Mn2mb?_7q~kB delta 3370 zcmYk9yN(@25Qe2SLfRE}f>ss*7ZYJ=gSk&n?!YMtvFDnS5KJ}_lHmbPOhib6bl!u2 zm;?#l03nf4{e8pYq&0iGs{g;L{;KZ%^S38|{rcqR`u*!yFV~yPPv3rUd42!<`qAyp zdq2K?`tqi$F5h?Ge7HP(R_xuH*QL&DGhd$d&yQ{3rz)>&m)B{`Yq{mMW*u=z?3U~{ zQ{Jtbybfhv+y3G1w%7~)DE$eegi(XrRAkeJ-2~*}87+T|aA|aCvuVe-Hf0CGI_Hg& zb?ftY1+g~e@1BD?c2{VZ99m$xa%e*?dh8E3M3_X_U|F!=Y70W*Byl8JVKai(zl#Iy zjW{=KD)7635E2_*CUfjFoMsRPvQ%@@ipN03YBFiG3uqHIrMn>XvaUcFsM~_uh*9Df zYc=CsXNO}KbHcR1)Dm})ERBS-6YFA%Nd|TWE?Gj=G_R4J~S_^FnH&X?2q%8xK;e3P~-Qf&4?LCY` zZ^5-z@7P!XQ(}2WY|L#>VLE@Y8&qaPdI~6&9?fxCLxEqDx6odowZxOa955~T-Ikr< z_*jx0Lrr>AN%9-Fg>QdpQJ7U#488IQ7J)B9iGyNPVzW}}DWzqVstGf>qnMmmL9ZiP zODt8>lQ^d$wCIBfcBmijj)-9<8?7nkBnQ!g)ns~zVPox#kX_HSS4Wa(e>zZ#g+lk_ z&`$TegLVk*2p*OAARCX3bK)p*&|26#GR^s-loG_O*g&8vP$ealp~Ou?r>a`;M+EKI zJ-LuW2E-mSGZ%UQp(6AZ_JxV&yMnyBsj+c#iZkJB!A?DcKW^Yhr)LCdn0gu8j-3J^ zxynsJJ7ZMrL}wb?CcX$3&u&=w!-n42F4K{PF!F~Z(wSlEdt)YhO37g*FQaOSJPMOT zXjBX-u|X}gR6Fn&vc2HeEa00f9cJRR_s^(si0djNI3Y*ERpV-+$LPE*pzR=PZC}tt zE(q2^*tg;n;i{BuN5_@2@~%6tNa)F4K{ue)l0?aRdCANm4|L{#T7~><&JT7Js{^zm zONk;nzw}ms4!I4qhO-O4j4m@dl zoK(G1kBvxX*srvY>2Bewv$fLAR*Ir$gmarRNJ)AN#c)hGQB8my=>3sz-(o*>3+=}r z_P7^iw9o$t9kwND9o`w{H6&HKedu^QrzpyFWZET$<{+Hr3~-z=Y$A}11_T>KGWNR# zI3F0;JMbJ9K9ar0A1|34g4c!Z>#N!aFzN|>#OmZa3r$oOBQD`cjI~mRip1Az+{L(IBCx@nR9;Zz6czwtG!HYkER)+ral|Q9I3XcnmGT5KtsNuEN+9n z7jlhm?GJB}Etm6)JtikHSX}z;>}4@oi}CW})yJPx7|S5CPjc;}ukUWJZ(jZJ>GhxG a?@umYfA{<4muF9}_ita{Umt!LzWf)C$53Pd diff --git a/container/service.proto b/container/service.proto index 8a3f56c..9bd02c9 100644 --- a/container/service.proto +++ b/container/service.proto @@ -41,6 +41,9 @@ message PutRequest { // Rules define storage policy for the object inside the container. netmap.PlacementRule rules = 4 [(gogoproto.nullable) = false]; + // Container ACL. + AccessGroup Group = 5 [(gogoproto.nullable) = false]; + // RequestMetaHeader contains information about request meta headers (should be embedded into message) service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) diff --git a/container/types.go b/container/types.go index 9269f30..d5d5a77 100644 --- a/container/types.go +++ b/container/types.go @@ -11,6 +11,19 @@ import ( "github.com/pkg/errors" ) +// AccessMode is a container access mode type. +type AccessMode uint32 + +const ( + // AccessModeRead is a read access mode. + AccessModeRead AccessMode = 1 << iota + // AccessModeWrite is a write access mode. + AccessModeWrite +) + +// AccessModeReadWrite is a read/write container access mode. +const AccessModeReadWrite = AccessModeRead | AccessModeWrite + var ( _ internal.Custom = (*Container)(nil) diff --git a/container/types.pb.go b/container/types.pb.go index 7bf9a03651924c5d814922abf4dc886e4ee45d13..6671670f05dd7cf29c9619232886f2f262d19410 100644 GIT binary patch literal 23152 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 UyL&wUeDY@L?8VLH_Umx%4_P^-rT_o{ diff --git a/container/types.proto b/container/types.proto index a601edd..a1429ce 100644 --- a/container/types.proto +++ b/container/types.proto @@ -17,4 +17,18 @@ message Container { uint64 Capacity = 3; // Rules define storage policy for the object inside the container. netmap.PlacementRule Rules = 4 [(gogoproto.nullable) = false]; + // Container ACL. + AccessControlList List = 5 [(gogoproto.nullable) = false]; +} + +message AccessGroup { + // Group access mode. + uint32 M = 1; + // Group members. + repeated bytes G = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; +} + +message AccessControlList { + // List of access groups. + repeated AccessGroup List = 1 [(gogoproto.nullable) = false]; } From 7e6e30b85024a669111f46dfa48da626d0802f5a Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Tue, 17 Dec 2019 16:15:51 +0300 Subject: [PATCH 2/3] Add unit tests for container access modes --- container/types_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/container/types_test.go b/container/types_test.go index c7dbbf8..cfd5f52 100644 --- a/container/types_test.go +++ b/container/types_test.go @@ -55,3 +55,23 @@ func TestCID(t *testing.T) { require.Equal(t, cid1, cid2) }) } + +func TestAccessMode(t *testing.T) { + t.Run("read access to read/write mode", func(t *testing.T) { + require.Equal(t, AccessModeRead, AccessModeReadWrite&AccessModeRead) + }) + + t.Run("write access to read/write mode", func(t *testing.T) { + require.Equal(t, AccessModeWrite, AccessModeReadWrite&AccessModeWrite) + }) + + t.Run("read(write) access to write(read) mode", func(t *testing.T) { + require.Zero(t, AccessModeRead&AccessModeWrite) + }) + + t.Run("access to same mode", func(t *testing.T) { + require.Equal(t, AccessModeWrite, AccessModeWrite&AccessModeWrite) + require.Equal(t, AccessModeRead, AccessModeRead&AccessModeRead) + require.Equal(t, AccessModeReadWrite, AccessModeReadWrite&AccessModeReadWrite) + }) +} From 6ad23612c99f2c1a84e3bbb0e28bf416746bf1e4 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Tue, 17 Dec 2019 19:48:44 +0300 Subject: [PATCH 3/3] Use expanded field naming in AccessGroup structure --- container/types.pb.go | Bin 23152 -> 23406 bytes container/types.proto | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/container/types.pb.go b/container/types.pb.go index 6671670f05dd7cf29c9619232886f2f262d19410..7a454de61c48e4bd35b25fa27d42cde5aaf6bbaa 100644 GIT binary patch delta 2640 zcmZ9OJC7Vi6os`|*qYgeH9`gv0K=}Zy?C@#Kc{< zYkq(u+&=(P5@e|XC;S02Acl;D1et`Gs_%^0l9N((^{so(J@?W5`1`HDf82Wb;r96L zrm@TA`}5ZJH@9EkKYN^>F6N)jlfB8E<^1Gm@9af?fBUu3&81!3Sj;~^?SI&ggQqXg z?FCQ&JiR|0?)-5sMA^A`Id~kBi$9&;D*DGSEZ1o_otRZx`?X_D%yc|5tElluP43rn z=GUq{GwRr9*d*9Qk$-Cv>{*kTTd7}Txn|8W04jfBz44k_Z`B!Y;I+jz<+cH#sQlXu zuWjk~Y3A1&`x%xQ=Z=vN!3a)NMU2ZCrnp$I5{x?7$M~~cumxzGCm^J(6$p6;g6NeH z%S8hhPD4*jjyRcdtpi{C((l(RO9CR+49o_#lT>NY4djXNDxqyCiNpZE#zmwAu*R^9 zIj`7T;-7hu)@Eg~n#nh4ML;9RR$}DXB>0#SRm|N8b~$^gP!LX25JD*(X?eGhXl;W7z zDkx9S)ldY2$W$EFsu*N2lAA;~(C!F5fkmU-5<;$+u`ChHxYgmivhpzqp%oc?Zz>b@ zHkHm^T~bSQrB!<*ah2(4D?KTUVs(Qgv6yz4W@fr}wo0xL8UzrF65UD(%{~IHQ~98R zB5{KG5R@xJh^j+5l9I}^3f&-29)n*Aha>fvw8-I-LAbIYw1}wki6J(FMyj+zPsr|q z3r%&S#HjXbz$~{43x1B;ZqoS}YCI{18If$-o_jH&M--YyP%ay#8?Pd)m?P{9u~P_) zy-meN*_vdLCcRJ}NizgO;l3S%@XIRL9h~$1dti< zHI+2pl^G2pH>mwJ6%qR?QKBJJ;Lm8qtNKmtqpWH`!~~+gX|Y#NwmJCv)M(N)LTF%L z0Igx>s@RcH7iqBO!sL8Lx+4JM%UsZLMrNgGm_PQGyLMxLBqES}KdqbK+d T4?ifL>K{G#;&A)D3(x)sI2OaV delta 2429 zcmYk8O^X~=6o%=EMtdeWqhrWINGhYF)7TETzN;b=+(?Vk64Z?Zm8!Z`FluIoiAbYJ z<62kN573q1MglD^#EnaL!M*+j(T(WNd!M(G%;s?W+4yu z?#Axp^XbXy@kht;PVoNi1i+<4;(c9n9`5krQVycPA{2a$xvt_j4&%X7a03YI{c8Fq#%?$ z%DFD_WYC9XRn3*bu0{??Qjf)?HG{C6W|*m;awP_*1tsy09DXDmSPZ-sn<7^kLJFV` zNYzkiVrUE`iLJtsieAGg<>e4Lj5_cuS96DNDheF~8Y&HV?Rcy1R{Nx)1Wt|*O+brn z1eztzlzxhNQ)?OuR6|yw)a28pYmgyV_>f&rge5E@WQBpDJO$?mF}M_3g+S<92LffxWst;2Cr6?0a?=^7aFlF7Xk^0iDXy}&{OF*Vo-~j1Egrw`fdz7 zLVXX;R}bGxwAP-%U|3U>%8C)qpuIknFaqCdH(};Bq({&SXvtNixgruhRnV3Mh?u%j zbM2ObpP_{k-d&r zLjlf8hvpFkDr@zG8+Aw0trRDtX7%rt-yXR#n*`Sb6MVWp9(Tv5!Qt!n;HSsY|d_?erNy9!%y11N&oru$;~c!ZyL0xr~a*f_rc!RkIsXu2i{j7?oQ6# z+Mlm(Oujqs{DpTV)2rLh&w_)XIyq^NtmifjK6XCG-sJ-#HwWUY@82laRyXFC GANwB>*=rsE diff --git a/container/types.proto b/container/types.proto index a1429ce..4600046 100644 --- a/container/types.proto +++ b/container/types.proto @@ -23,9 +23,9 @@ message Container { message AccessGroup { // Group access mode. - uint32 M = 1; + uint32 AccessMode = 1; // Group members. - repeated bytes G = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; + repeated bytes UserGroup = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; } message AccessControlList {