@@ -48,131 +48,143 @@ func (h *ActionHandler) IsUserLoggedOrAdmin(ctx context.Context) bool {
4848 return h .IsUserLogged (ctx ) || h .IsUserAdmin (ctx )
4949}
5050
51- func (h * ActionHandler ) IsOrgOwner (ctx context.Context , orgID string ) (bool , error ) {
52- isAdmin := h .IsUserAdmin (ctx )
53- if isAdmin {
54- return true , nil
55- }
51+ func (h * ActionHandler ) userActionsForUser (ctx context.Context , userRef string ) ([]cstypes.ActionType , error ) {
52+ actions := []cstypes.ActionType {}
5653
5754 userID := h .CurrentUserID (ctx )
5855 if userID == "" {
59- return false , nil
56+ return actions , nil
57+ }
58+
59+ // By default any logged user can get an user
60+ actions = append (actions , cstypes .ActionTypeGetUser )
61+
62+ // no existing user
63+ if userRef == "" {
64+ return actions , nil
6065 }
6166
62- userOrgs , resp , err := h .configstoreClient .GetUserOrgs (ctx , userID )
67+ user , resp , err := h .configstoreClient .GetUser (ctx , userRef )
6368 if err != nil {
64- return false , errors . Errorf ( "failed to get user orgs: %w" , ErrFromRemote (resp , err ) )
69+ return nil , ErrFromRemote (resp , err )
6570 }
6671
67- for _ , userOrg := range userOrgs {
68- if userOrg .Organization .ID != orgID {
69- continue
70- }
71- if userOrg .Role == cstypes .OrgMemberRoleOwner {
72- return true , nil
73- }
72+ ownerActions , err := h .userActionsForOwner (ctx , cstypes .ConfigTypeUser , user .ID )
73+ if err != nil {
74+ return nil , err
7475 }
76+ actions = append (actions , ownerActions ... )
7577
76- return false , nil
78+ return actions , nil
7779}
7880
79- func (h * ActionHandler ) IsProjectOwner (ctx context.Context , ownerType cstypes.ConfigType , ownerID string ) (bool , error ) {
80- isAdmin := h .IsUserAdmin (ctx )
81- if isAdmin {
82- return true , nil
83- }
81+ func (h * ActionHandler ) userActionsForOrg (ctx context.Context , orgRef string ) ([]cstypes.ActionType , error ) {
82+ actions := []cstypes.ActionType {}
8483
8584 userID := h .CurrentUserID (ctx )
8685 if userID == "" {
87- return false , nil
86+ return actions , nil
8887 }
8988
90- if ownerType == cstypes .ConfigTypeUser {
91- if userID == ownerID {
92- return true , nil
93- }
89+ // By default any logged user can create an org
90+ actions = append (actions , cstypes .ActionTypeCreateOrg )
91+
92+ // no existing org
93+ if orgRef == "" {
94+ return actions , nil
9495 }
9596
96- if ownerType == cstypes .ConfigTypeOrg {
97- userOrgs , resp , err := h .configstoreClient .GetUserOrgs (ctx , userID )
98- if err != nil {
99- return false , errors .Errorf ("failed to get user orgs: %w" , ErrFromRemote (resp , err ))
100- }
97+ org , resp , err := h .configstoreClient .GetOrg (ctx , orgRef )
98+ if err != nil {
99+ return nil , ErrFromRemote (resp , err )
100+ }
101101
102- for _ , userOrg := range userOrgs {
103- if userOrg .Organization .ID != ownerID {
104- continue
105- }
106- if userOrg .Role == cstypes .OrgMemberRoleOwner {
107- return true , nil
108- }
109- }
102+ if org .Visibility == cstypes .VisibilityPublic {
103+ actions = append (actions , cstypes .OrgMemberActions ... )
110104 }
111105
112- return false , nil
106+ ownerRoles , err := h .userActionsForOwner (ctx , cstypes .ConfigTypeOrg , org .ID )
107+ if err != nil {
108+ return nil , err
109+ }
110+ actions = append (actions , ownerRoles ... )
111+
112+ return actions , nil
113113}
114114
115- func (h * ActionHandler ) IsProjectMember (ctx context.Context , ownerType cstypes.ConfigType , ownerID string ) (bool , error ) {
116- isAdmin := h .IsUserAdmin (ctx )
117- if isAdmin {
118- return true , nil
119- }
115+ func (h * ActionHandler ) userActionsForProjectGroup (ctx context.Context , projectGroupRef string ) ([]cstypes.ActionType , error ) {
116+ actions := []cstypes.ActionType {}
120117
121118 userID := h .CurrentUserID (ctx )
122119 if userID == "" {
123- return false , nil
120+ return actions , nil
124121 }
125122
126- if ownerType == cstypes .ConfigTypeUser {
127- if userID == ownerID {
128- return true , nil
129- }
123+ p , resp , err := h .configstoreClient .GetProjectGroup (ctx , projectGroupRef )
124+ if err != nil {
125+ return nil , ErrFromRemote (resp , err )
130126 }
131127
132- if ownerType == cstypes .ConfigTypeOrg {
133- userOrgs , resp , err := h .configstoreClient .GetUserOrgs (ctx , userID )
134- if err != nil {
135- return false , errors .Errorf ("failed to get user orgs: %w" , ErrFromRemote (resp , err ))
136- }
128+ if p .GlobalVisibility == cstypes .VisibilityPublic {
129+ actions = append (actions , cstypes .ProjectReadActions ... )
130+ }
137131
138- for _ , userOrg := range userOrgs {
139- if userOrg .Organization .ID != ownerID {
140- continue
141- }
142- return true , nil
143- }
132+ ownerRoles , err := h .userActionsForOwner (ctx , p .OwnerType , p .OwnerID )
133+ if err != nil {
134+ return nil , err
144135 }
136+ actions = append (actions , ownerRoles ... )
145137
146- return false , nil
138+ return actions , nil
147139}
148140
149- func (h * ActionHandler ) IsVariableOwner (ctx context.Context , parentType cstypes.ConfigType , parentRef string ) (bool , error ) {
150- var ownerType cstypes.ConfigType
151- var ownerID string
141+ func (h * ActionHandler ) userActionsForProject (ctx context.Context , projectRef string ) ([]cstypes.ActionType , error ) {
142+ actions := []cstypes.ActionType {}
143+
144+ userID := h .CurrentUserID (ctx )
145+ if userID == "" {
146+ return actions , nil
147+ }
148+
149+ p , resp , err := h .configstoreClient .GetProject (ctx , projectRef )
150+ if err != nil {
151+ return nil , ErrFromRemote (resp , err )
152+ }
153+
154+ if p .GlobalVisibility == cstypes .VisibilityPublic {
155+ actions = append (actions , cstypes .ProjectReadActions ... )
156+ }
157+ ownerRoles , err := h .userActionsForOwner (ctx , p .OwnerType , p .OwnerID )
158+ if err != nil {
159+ return nil , err
160+ }
161+ actions = append (actions , ownerRoles ... )
162+
163+ return actions , nil
164+ }
165+
166+ func (h * ActionHandler ) userActionsForVariable (ctx context.Context , parentType cstypes.ConfigType , parentRef string ) ([]cstypes.ActionType , error ) {
152167 switch parentType {
153168 case cstypes .ConfigTypeProjectGroup :
154- pg , resp , err := h .configstoreClient .GetProjectGroup (ctx , parentRef )
155- if err != nil {
156- return false , errors .Errorf ("failed to get project group %q: %w" , parentRef , ErrFromRemote (resp , err ))
157- }
158- ownerType = pg .OwnerType
159- ownerID = pg .OwnerID
169+ return h .userActionsForProjectGroup (ctx , parentRef )
160170 case cstypes .ConfigTypeProject :
161- p , resp , err := h .configstoreClient .GetProject (ctx , parentRef )
162- if err != nil {
163- return false , errors .Errorf ("failed to get project %q: %w" , parentRef , ErrFromRemote (resp , err ))
164- }
165- ownerType = p .OwnerType
166- ownerID = p .OwnerID
171+ return h .userActionsForProject (ctx , parentRef )
172+ default :
173+ return nil , errors .Errorf ("wrong parent type: %q" , parentType )
167174 }
168-
169- return h .IsProjectOwner (ctx , ownerType , ownerID )
170175}
171176
172- func (h * ActionHandler ) CanGetRun (ctx context.Context , runGroup string ) (bool , error ) {
177+ func (h * ActionHandler ) userActionsForRun (ctx context.Context , runGroup string ) ([]cstypes.ActionType , error ) {
178+ actions := []cstypes.ActionType {}
179+
180+ userID := h .CurrentUserID (ctx )
181+ if userID == "" {
182+ return actions , nil
183+ }
184+
173185 groupType , groupID , err := common .GroupTypeIDFromRunGroup (runGroup )
174186 if err != nil {
175- return false , err
187+ return nil , err
176188 }
177189
178190 var visibility cstypes.Visibility
@@ -182,59 +194,137 @@ func (h *ActionHandler) CanGetRun(ctx context.Context, runGroup string) (bool, e
182194 case common .GroupTypeProject :
183195 p , resp , err := h .configstoreClient .GetProject (ctx , groupID )
184196 if err != nil {
185- return false , ErrFromRemote (resp , err )
197+ return nil , ErrFromRemote (resp , err )
186198 }
187199 ownerType = p .OwnerType
188200 ownerID = p .OwnerID
189201 visibility = p .GlobalVisibility
202+
190203 case common .GroupTypeUser :
191204 // user direct runs
192205 ownerType = cstypes .ConfigTypeUser
193206 ownerID = groupID
194207 visibility = cstypes .VisibilityPrivate
208+ default :
209+ return nil , errors .Errorf ("wrong run group type: %q" , runGroup )
195210 }
196211
197212 if visibility == cstypes .VisibilityPublic {
198- return true , nil
213+ actions = append ( actions , cstypes . ProjectReadActions ... )
199214 }
200- isProjectMember , err := h .IsProjectMember (ctx , ownerType , ownerID )
215+ ownerRoles , err := h .userActionsForOwner (ctx , ownerType , ownerID )
201216 if err != nil {
202- return false , errors .Errorf ("failed to determine ownership: %w" , err )
217+ return nil , err
218+ }
219+ actions = append (actions , ownerRoles ... )
220+
221+ return actions , nil
222+ }
223+
224+ func (h * ActionHandler ) userActionsForOwner (ctx context.Context , ownerType cstypes.ConfigType , ownerID string ) ([]cstypes.ActionType , error ) {
225+ actions := []cstypes.ActionType {}
226+
227+ userID := h .CurrentUserID (ctx )
228+ if userID == "" {
229+ return actions , nil
203230 }
204- if ! isProjectMember {
205- return false , nil
231+
232+ switch ownerType {
233+ case cstypes .ConfigTypeUser :
234+ if userID == ownerID {
235+ actions = append (actions , cstypes .UserOwnerActions ... )
236+ }
237+ case cstypes .ConfigTypeOrg :
238+ userOrgs , resp , err := h .configstoreClient .GetUserOrgs (ctx , userID )
239+ if err != nil {
240+ return nil , errors .Errorf ("failed to get user orgs: %w" , ErrFromRemote (resp , err ))
241+ }
242+
243+ for _ , userOrg := range userOrgs {
244+ if userOrg .Organization .ID != ownerID {
245+ continue
246+ }
247+ if userOrg .Role == cstypes .OrgMemberRoleOwner {
248+ actions = append (actions , cstypes .OrgOwnerActions ... )
249+ }
250+ if userOrg .Role == cstypes .OrgMemberRoleMember {
251+ actions = append (actions , cstypes .OrgMemberActions ... )
252+ }
253+ }
206254 }
207- return true , nil
255+
256+ return actions , nil
208257}
209258
210- func (h * ActionHandler ) CanDoRunActions (ctx context.Context , runGroup string ) (bool , error ) {
211- groupType , groupID , err := common . GroupTypeIDFromRunGroup ( runGroup )
259+ func (h * ActionHandler ) CanDoUserAction (ctx context.Context , action cstypes. ActionType , userRef string ) (bool , error ) {
260+ actions , err := h . userActionsForUser ( ctx , userRef )
212261 if err != nil {
213262 return false , err
214263 }
215264
216- var ownerType cstypes.ConfigType
217- var ownerID string
218- switch groupType {
219- case common .GroupTypeProject :
220- p , resp , err := h .configstoreClient .GetProject (ctx , groupID )
221- if err != nil {
222- return false , ErrFromRemote (resp , err )
223- }
224- ownerType = p .OwnerType
225- ownerID = p .OwnerID
226- case common .GroupTypeUser :
227- // user direct runs
228- ownerType = cstypes .ConfigTypeUser
229- ownerID = groupID
265+ return h .CanDoAction (ctx , actions , action )
266+ }
267+
268+ func (h * ActionHandler ) CanDoOrgAction (ctx context.Context , action cstypes.ActionType , orgRef string ) (bool , error ) {
269+ actions , err := h .userActionsForOrg (ctx , orgRef )
270+ if err != nil {
271+ return false , err
272+ }
273+
274+ return h .CanDoAction (ctx , actions , action )
275+ }
276+
277+ func (h * ActionHandler ) CanDoProjectGroupAction (ctx context.Context , action cstypes.ActionType , projectGroupRef string ) (bool , error ) {
278+ actions , err := h .userActionsForProjectGroup (ctx , projectGroupRef )
279+ if err != nil {
280+ return false , err
230281 }
231282
232- isProjectOwner , err := h .IsProjectOwner (ctx , ownerType , ownerID )
283+ return h .CanDoAction (ctx , actions , action )
284+ }
285+
286+ func (h * ActionHandler ) CanDoProjectAction (ctx context.Context , action cstypes.ActionType , projectRef string ) (bool , error ) {
287+ actions , err := h .userActionsForProject (ctx , projectRef )
233288 if err != nil {
234- return false , errors . Errorf ( "failed to determine ownership: %w" , err )
289+ return false , err
235290 }
236- if ! isProjectOwner {
237- return false , nil
291+
292+ return h .CanDoAction (ctx , actions , action )
293+ }
294+
295+ func (h * ActionHandler ) CanDoVariableAction (ctx context.Context , action cstypes.ActionType , parentType cstypes.ConfigType , parentRef string ) (bool , error ) {
296+ actions , err := h .userActionsForVariable (ctx , parentType , parentRef )
297+ if err != nil {
298+ return false , err
238299 }
239- return true , nil
300+
301+ return h .CanDoAction (ctx , actions , action )
302+ }
303+ func (h * ActionHandler ) CanDoSecretAction (ctx context.Context , action cstypes.ActionType , parentType cstypes.ConfigType , parentRef string ) (bool , error ) {
304+ return h .CanDoVariableAction (ctx , action , parentType , parentRef )
305+ }
306+
307+ func (h * ActionHandler ) CanDoRunAction (ctx context.Context , action cstypes.ActionType , runGroup string ) (bool , error ) {
308+ actions , err := h .userActionsForRun (ctx , runGroup )
309+ if err != nil {
310+ return false , err
311+ }
312+
313+ return h .CanDoAction (ctx , actions , action )
314+ }
315+
316+ func (h * ActionHandler ) CanDoAction (ctx context.Context , actions []cstypes.ActionType , action cstypes.ActionType ) (bool , error ) {
317+ isAdmin := h .IsUserAdmin (ctx )
318+ if isAdmin {
319+ actions = append (actions , cstypes .AdminActions ... )
320+ }
321+
322+ for _ , a := range actions {
323+ if a != action {
324+ continue
325+ }
326+ return true , nil
327+ }
328+
329+ return false , nil
240330}
0 commit comments