go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/rpc/batch_check_permissions.go (about) 1 // Copyright 2022 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package rpc 16 17 import ( 18 "context" 19 20 "go.chromium.org/luci/common/errors" 21 "go.chromium.org/luci/grpc/appstatus" 22 milopb "go.chromium.org/luci/milo/proto/v1" 23 "go.chromium.org/luci/server/auth" 24 "go.chromium.org/luci/server/auth/realms" 25 26 // Ensure those permissions are registered in memory. 27 _ "go.chromium.org/luci/buildbucket/bbperms" 28 _ "go.chromium.org/luci/resultdb/rdbperms" 29 ) 30 31 // The maximum number of permissions allowed in the BatchCheckPermissions RPC. 32 const maxPermissions = 100 33 34 // BatchCheckPermissions implements milopb.MiloInternal service 35 func (s *MiloInternalService) BatchCheckPermissions(ctx context.Context, req *milopb.BatchCheckPermissionsRequest) (_ *milopb.BatchCheckPermissionsResponse, err error) { 36 // Validate request. 37 err = validateBatchCheckPermissionsRequest(req) 38 if err != nil { 39 return nil, appstatus.BadRequest(err) 40 } 41 42 // Convert the permission names to permissions and check whether they exist. 43 perms, err := realms.GetPermissions(req.Permissions...) 44 if err != nil { 45 return nil, appstatus.BadRequest(err) 46 } 47 48 // Check whether the user has each permission. 49 results := make(map[string]bool, len(perms)) 50 for _, perm := range perms { 51 allowed, err := auth.HasPermission(ctx, perm, req.GetRealm(), nil) 52 if err != nil { 53 return nil, err 54 } 55 results[perm.Name()] = allowed 56 } 57 58 return &milopb.BatchCheckPermissionsResponse{Results: results}, nil 59 } 60 61 func validateBatchCheckPermissionsRequest(req *milopb.BatchCheckPermissionsRequest) error { 62 if req.GetRealm() == "" { 63 return errors.Reason("realm: must be specified").Err() 64 } 65 if err := realms.ValidateRealmName(req.Realm, realms.GlobalScope); err != nil { 66 return errors.Annotate(err, "realm").Err() 67 } 68 69 if len(req.GetPermissions()) > maxPermissions { 70 return errors.Reason("permissions: at most %d permissions can be specified", maxPermissions).Err() 71 } 72 73 return nil 74 }