diff --git a/controller/northbound/server/auth_interceptor.go b/controller/northbound/server/auth_interceptor.go index 501893e6f70b7d081da7508c52607f7b49f5b760..428b5873b80ddcc9ee24d793bab40f36ed4b6020 100644 --- a/controller/northbound/server/auth_interceptor.go +++ b/controller/northbound/server/auth_interceptor.go @@ -25,7 +25,7 @@ func NewAuthInterceptor(jwtManager *rbac.JWTManager) *AuthInterceptor { } // Unary returns a unary interceptor function to authenticate and authorize unary RPC calls -func (auth AuthInterceptor) Unary() grpc.UnaryServerInterceptor { +func (auth *AuthInterceptor) Unary() grpc.UnaryServerInterceptor { return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { switch r := req.(type) { case *apb.LoginRequest: @@ -53,7 +53,7 @@ func (auth AuthInterceptor) Unary() grpc.UnaryServerInterceptor { } // Stream returns a server interceptor function to authorize stream RPC calls -func (auth AuthInterceptor) Stream() grpc.StreamServerInterceptor { +func (auth *AuthInterceptor) Stream() grpc.StreamServerInterceptor { return func( srv interface{}, stream grpc.ServerStream, @@ -69,7 +69,7 @@ func (auth AuthInterceptor) Stream() grpc.StreamServerInterceptor { } } -func (auth AuthInterceptor) authorize(ctx context.Context, method string) error { +func (auth *AuthInterceptor) authorize(ctx context.Context, method string) error { md, ok := metadata.FromIncomingContext(ctx) if !ok { return status.Errorf(codes.Unauthenticated, "metadata is not provided") @@ -94,7 +94,7 @@ func (auth AuthInterceptor) authorize(ctx context.Context, method string) error return status.Errorf(codes.PermissionDenied, "invalid token") } - err = verifyPermisisonForRequestedCall(user.GetRoles(), method) + err = auth.verifyPermisisonForRequestedCall(user.GetRoles(), method) if err != nil { return err } @@ -105,27 +105,41 @@ func (auth AuthInterceptor) authorize(ctx context.Context, method string) error return nil } -func verifyPermisisonForRequestedCall(userRoles map[string]string, requestedMethod string) error { +func (auth *AuthInterceptor) verifyPermisisonForRequestedCall(userRoles map[string]string, requestedMethod string) error { + for _, userRole := range userRoles { + err := auth.verifyUserRoleAndRequestedCall(userRole, requestedMethod) + if err != nil { + return err + } + } + + return nil +} + +func (auth *AuthInterceptor) verifyUserRoleAndRequestedCall(userRole, requestedMethod string) error { storedRoles, err := rolec.GetAll() if err != nil { return err } - // authorization here - // first loop through map with roles associated to user - // second loop check if name of user role exists in roles - // third loop check if role associated to current user has permission for call - for _, userRole := range userRoles { - for _, storedRole := range storedRoles { - if userRole == storedRole.Name() { - for _, permission := range storedRole.GetPermissions() { - if permission == requestedMethod { - return nil - } - } + for _, storedRole := range storedRoles { + if userRole == storedRole.Name() { + err := auth.compareRequestedPermissionWithRolePermissions(requestedMethod, storedRole.GetPermissions()) + if err != nil { + return err } } } + return nil +} + +func (auth *AuthInterceptor) compareRequestedPermissionWithRolePermissions(requestedMethod string, storedRolePermissions []string) error { + for _, permission := range storedRolePermissions { + if permission == requestedMethod { + return nil + } + } + return status.Errorf(codes.PermissionDenied, "user not authorized for this call") }