SMQ-3050 - Fix PAT redis connection (#3051)
Continuous Delivery / Build and Push (push) Has been cancelled
Check the consistency of generated files / check-generated-files (push) Has been cancelled
Check License Header / check-license (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
Steve Munene
2025-08-13 15:50:20 +03:00
committed by GitHub
parent 8188da16b3
commit 3dbd617ed0
8 changed files with 56 additions and 20 deletions
+2 -2
View File
@@ -97,12 +97,12 @@ func (client authGrpcClient) AuthenticatePAT(ctx context.Context, token *grpcAut
return &grpcAuthV1.AuthNRes{}, grpcapi.DecodeError(err)
}
ir := res.(authenticateRes)
return &grpcAuthV1.AuthNRes{Id: ir.id, UserId: ir.userID}, nil
return &grpcAuthV1.AuthNRes{Id: ir.id, UserId: ir.userID, UserRole: uint32(ir.userRole)}, nil
}
func decodeIdentifyPATResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
res := grpcRes.(*grpcAuthV1.AuthNRes)
return authenticateRes{id: res.GetId(), userID: res.GetUserId()}, nil
return authenticateRes{id: res.GetId(), userID: res.GetUserId(), userRole: auth.Role(res.UserRole)}, nil
}
func (client authGrpcClient) Authorize(ctx context.Context, req *grpcAuthV1.AuthZReq, _ ...grpc.CallOption) (r *grpcAuthV1.AuthZRes, err error) {
+1 -1
View File
@@ -39,7 +39,7 @@ func authenticatePATEndpoint(svc auth.Service) endpoint.Endpoint {
return authenticateRes{}, err
}
return authenticateRes{id: pat.ID, userID: pat.User}, nil
return authenticateRes{id: pat.ID, userID: pat.User, userRole: pat.Role}, nil
}
}
+1 -1
View File
@@ -87,7 +87,7 @@ func encodeAuthenticateResponse(_ context.Context, grpcRes interface{}) (interfa
func encodeAuthenticatePATResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
res := grpcRes.(authenticateRes)
return &grpcAuthV1.AuthNRes{Id: res.id, UserId: res.userID}, nil
return &grpcAuthV1.AuthNRes{Id: res.id, UserId: res.userID, UserRole: uint32(res.userRole)}, nil
}
func decodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
+15
View File
@@ -296,6 +296,7 @@ type PAT struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Secret string `json:"secret,omitempty"`
Role Role `json:"role,omitempty"`
IssuedAt time.Time `json:"issued_at,omitempty"`
ExpiresAt time.Time `json:"expires_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
@@ -341,6 +342,20 @@ func (pat *PAT) UnmarshalBinary(data []byte) error {
return json.Unmarshal(data, pat)
}
// Validate checks if the PAT has valid fields.
func (pat *PAT) Validate() error {
if pat == nil {
return errors.New("PAT cannot be nil")
}
if pat.Name == "" {
return errors.New("PAT name cannot be empty")
}
if pat.User == "" {
return errors.New("PAT user cannot be empty")
}
return nil
}
func (pat *PAT) String() string {
str, err := json.MarshalIndent(pat, "", " ")
if err != nil {
+21 -1
View File
@@ -369,6 +369,21 @@ func (svc service) checkUserRole(ctx context.Context, key Key) (err error) {
}
}
func (svc service) getUserRole(ctx context.Context, userID string) (role Role) {
rl := UserRole
if err := svc.Authorize(ctx, policies.Policy{
Subject: userID,
SubjectType: policies.UserType,
Permission: policies.AdminPermission,
Object: policies.SuperMQObject,
ObjectType: policies.PlatformType,
}); err == nil {
rl = AdminRole
}
return rl
}
func (svc service) userKey(ctx context.Context, token string, key Key) (Token, error) {
id, sub, err := svc.authenticate(token)
if err != nil {
@@ -485,6 +500,10 @@ func (svc service) CreatePAT(ctx context.Context, token, name, description strin
Revoked: false,
}
if err := pat.Validate(); err != nil {
return PAT{}, errors.Wrap(svcerr.ErrCreateEntity, err)
}
if err := svc.pats.Save(ctx, pat); err != nil {
return PAT{}, errors.Wrap(errCreatePAT, err)
}
@@ -682,7 +701,8 @@ func (svc service) IdentifyPAT(ctx context.Context, secret string) (PAT, error)
if err := svc.hasher.Compare(secret, secretHash); err != nil {
return PAT{}, errors.Wrap(svcerr.ErrAuthentication, err)
}
return PAT{ID: patID.String(), User: userID.String()}, nil
role := svc.getUserRole(ctx, userID.String())
return PAT{ID: patID.String(), User: userID.String(), Role: role}, nil
}
func (svc service) AuthorizePAT(ctx context.Context, userID, patID string, entityType EntityType, optionalDomainID string, operation Operation, entityID string) error {
+14 -14
View File
@@ -22,18 +22,18 @@ import (
)
var (
errView = errors.New("not authorized to view thing")
errUpdate = errors.New("not authorized to update thing")
errUpdateTags = errors.New("not authorized to update thing tags")
errUpdateSecret = errors.New("not authorized to update thing secret")
errEnable = errors.New("not authorized to enable thing")
errDisable = errors.New("not authorized to disable thing")
errDelete = errors.New("not authorized to delete thing")
errSetParentGroup = errors.New("not authorized to set parent group to thing")
errRemoveParentGroup = errors.New("not authorized to remove parent group from thing")
errDomainCreateClients = errors.New("not authorized to create thing in domain")
errGroupSetChildClients = errors.New("not authorized to set child thing for group")
errGroupRemoveChildClients = errors.New("not authorized to remove child thing for group")
errView = errors.New("not authorized to view client")
errUpdate = errors.New("not authorized to update client")
errUpdateTags = errors.New("not authorized to update client tags")
errUpdateSecret = errors.New("not authorized to update client secret")
errEnable = errors.New("not authorized to enable client")
errDisable = errors.New("not authorized to disable client")
errDelete = errors.New("not authorized to delete client")
errSetParentGroup = errors.New("not authorized to set parent group to client")
errRemoveParentGroup = errors.New("not authorized to remove parent group from client")
errDomainCreateClients = errors.New("not authorized to create client in domain")
errGroupSetChildClients = errors.New("not authorized to set child client for group")
errGroupRemoveChildClients = errors.New("not authorized to remove child client for group")
)
var _ clients.Service = (*authorizationMiddleware)(nil)
@@ -54,12 +54,12 @@ func AuthorizationMiddleware(
svc clients.Service,
authz smqauthz.Authorization,
repo clients.Repository,
thingsOpPerm, rolesOpPerm map[svcutil.Operation]svcutil.Permission,
clientsOpPerm, rolesOpPerm map[svcutil.Operation]svcutil.Permission,
extOpPerm map[svcutil.ExternalOperation]svcutil.Permission,
callout callout.Callout,
) (clients.Service, error) {
opp := clients.NewOperationPerm()
if err := opp.AddOperationPermissionMap(thingsOpPerm); err != nil {
if err := opp.AddOperationPermissionMap(clientsOpPerm); err != nil {
return nil, err
}
if err := opp.Validate(); err != nil {
+1
View File
@@ -141,6 +141,7 @@ services:
SMQ_SEND_TELEMETRY: ${SMQ_SEND_TELEMETRY}
SMQ_AUTH_ADAPTER_INSTANCE_ID: ${SMQ_AUTH_ADAPTER_INSTANCE_ID}
SMQ_ES_URL: ${SMQ_ES_URL}
SMQ_AUTH_CACHE_URL: ${SMQ_AUTH_CACHE_URL}
ports:
- ${SMQ_AUTH_HTTP_PORT}:${SMQ_AUTH_HTTP_PORT}
- ${SMQ_AUTH_GRPC_PORT}:${SMQ_AUTH_GRPC_PORT}
+1 -1
View File
@@ -47,7 +47,7 @@ func (a authentication) Authenticate(ctx context.Context, token string) (authn.S
return authn.Session{}, errors.Wrap(errors.ErrAuthentication, err)
}
return authn.Session{Type: authn.PersonalAccessToken, PatID: res.GetId(), UserID: res.GetUserId()}, nil
return authn.Session{Type: authn.PersonalAccessToken, PatID: res.GetId(), UserID: res.GetUserId(), Role: authn.Role(res.GetUserRole())}, nil
}
res, err := a.authSvcClient.Authenticate(ctx, &grpcAuthV1.AuthNReq{Token: token})
if err != nil {