From 7cccba91c934257acd97e29c75c7efa86bd10d23 Mon Sep 17 00:00:00 2001 From: b1ackd0t Date: Fri, 28 Jul 2023 15:39:13 +0300 Subject: [PATCH] NOISSUE - Reformat Things and Users Policies Endpoint (#1831) * Reformat Policies Enpoint to Take Sub Obj Signed-off-by: rodneyosodo * Add Redirect to `policies` Signed-off-by: rodneyosodo * Make Delete Endpoint not to Contain Body Signed-off-by: rodneyosodo * Remove gRPC unused functions Signed-off-by: rodneyosodo * Remove Redirect Signed-off-by: rodneyosodo * Update CLI Signed-off-by: rodneyosodo * Use Switch Statement Signed-off-by: rodneyosodo * Uncomment Commented Parts Signed-off-by: rodneyosodo * Add Empty Line Signed-off-by: rodneyosodo * Remove Unused gRPC Req and Resp Signed-off-by: rodneyosodo * Fix Listing of Policies Signed-off-by: rodneyosodo * Rename Authorize Functions For Users and Things Service Signed-off-by: rodneyosodo * Add Authorize To CLI Signed-off-by: rodneyosodo --------- Signed-off-by: rodneyosodo --- bootstrap/api/endpoint_test.go | 1 + bootstrap/mocks/channels.go | 6 +- bootstrap/mocks/policies.go | 4 +- bootstrap/mocks/things.go | 12 +- bootstrap/mocks/users.go | 23 +- bootstrap/service.go | 2 +- bootstrap/service_test.go | 1 + certs/mocks/channels.go | 6 +- certs/mocks/policies.go | 4 +- certs/mocks/things.go | 12 +- certs/service.go | 10 +- cli/policies.go | 160 ++++-- cmd/cli/main.go | 16 +- cmd/http/main.go | 2 +- cmd/things/main.go | 2 +- cmd/ws/main.go | 2 +- coap/adapter.go | 22 +- consumers/notifiers/mocks/auth.go | 25 +- consumers/notifiers/service.go | 8 +- docker/nginx/nginx-key.conf | 14 +- docker/nginx/nginx-x509.conf | 12 + http/adapter.go | 10 +- http/api/endpoint_test.go | 2 +- http/mocks/things.go | 8 +- internal/clients/grpc/things/client.go | 2 +- mqtt/handler.go | 16 +- mqtt/handler_test.go | 4 +- mqtt/mocks/auth.go | 20 +- pkg/clients/page.go | 31 +- pkg/sdk/go/message_test.go | 2 +- pkg/sdk/go/policies.go | 170 +++--- pkg/sdk/go/policies_test.go | 55 +- pkg/sdk/go/requests.go | 11 +- pkg/sdk/go/responses.go | 6 +- pkg/sdk/go/sdk.go | 146 +++-- pkg/sdk/go/things.go | 1 - readers/api/endpoint.go | 2 +- readers/api/endpoint_test.go | 2 +- readers/api/transport.go | 10 +- readers/mocks/things.go | 16 +- things/clients/mocks/auth.go | 40 +- things/clients/service.go | 10 +- things/clients/standalone/standalone.go | 32 +- things/groups/service.go | 8 +- things/policies/api/grpc/client.go | 30 +- things/policies/api/grpc/endpoint.go | 12 +- things/policies/api/grpc/requests.go | 14 +- things/policies/api/grpc/transport.go | 20 +- things/policies/api/http/endpoints.go | 80 ++- things/policies/api/http/requests.go | 36 +- things/policies/api/http/responses.go | 118 +++- things/policies/api/http/transport.go | 78 ++- things/policies/auth.pb.go | 142 ++--- things/policies/auth.proto | 28 +- things/policies/auth_grpc.pb.go | 94 +-- things/policies/policies.go | 2 +- things/policies/postgres/policies.go | 49 +- things/policies/service.go | 8 +- twins/mocks/auth.go | 22 +- twins/service.go | 12 +- users/clients/api/logging.go | 2 +- users/clients/mocks/authn.go | 42 +- users/policies/api/grpc/client.go | 183 +----- users/policies/api/grpc/endpoint.go | 73 +-- users/policies/api/grpc/requests.go | 91 +-- users/policies/api/grpc/responses.go | 18 +- users/policies/api/grpc/transport.go | 114 +--- users/policies/api/http/endpoints.go | 30 +- users/policies/api/http/responses.go | 33 +- users/policies/api/http/transport.go | 4 +- users/policies/auth.pb.go | 721 +++--------------------- users/policies/auth.proto | 61 +- users/policies/auth_grpc.pb.go | 194 +------ users/policies/policies.go | 2 +- ws/adapter.go | 10 +- ws/adapter_test.go | 2 +- ws/api/endpoint_test.go | 2 +- 77 files changed, 1118 insertions(+), 2157 deletions(-) diff --git a/bootstrap/api/endpoint_test.go b/bootstrap/api/endpoint_test.go index e6ec027b69..6a2647fb16 100644 --- a/bootstrap/api/endpoint_test.go +++ b/bootstrap/api/endpoint_test.go @@ -205,6 +205,7 @@ func newThingsServer(csvc clients.Service, gsvc groups.Service, psvc tpolicies.S capi.MakeHandler(csvc, mux, logger, instanceID) gapi.MakeHandler(gsvc, mux, logger) papi.MakeHandler(csvc, psvc, mux, logger) + return httptest.NewServer(mux) } diff --git a/bootstrap/mocks/channels.go b/bootstrap/mocks/channels.go index fb2439da6e..584696e141 100644 --- a/bootstrap/mocks/channels.go +++ b/bootstrap/mocks/channels.go @@ -37,7 +37,7 @@ func (svc *mainfluxChannels) CreateGroups(ctx context.Context, token string, chs svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return []mfgroups.Group{}, errors.ErrAuthentication } @@ -74,7 +74,7 @@ func (svc *mainfluxChannels) EnableGroup(ctx context.Context, token, id string) svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfgroups.Group{}, errors.ErrAuthentication } @@ -93,7 +93,7 @@ func (svc *mainfluxChannels) DisableGroup(ctx context.Context, token, id string) svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfgroups.Group{}, errors.ErrAuthentication } diff --git a/bootstrap/mocks/policies.go b/bootstrap/mocks/policies.go index 14f345465f..bf9c85a696 100644 --- a/bootstrap/mocks/policies.go +++ b/bootstrap/mocks/policies.go @@ -34,7 +34,7 @@ func (svc *mainfluxPolicies) AddPolicy(ctx context.Context, token string, p tpol svc.mu.Lock() defer svc.mu.Unlock() - if _, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}); err != nil { + if _, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}); err != nil { return tpolicies.Policy{}, errors.ErrAuthentication } svc.connections[fmt.Sprintf("%s:%s", p.Subject, p.Object)] = p @@ -46,7 +46,7 @@ func (svc *mainfluxPolicies) DeletePolicy(ctx context.Context, token string, p t svc.mu.Lock() defer svc.mu.Unlock() - if _, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}); err != nil { + if _, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}); err != nil { return errors.ErrAuthentication } diff --git a/bootstrap/mocks/things.go b/bootstrap/mocks/things.go index 4a22ef53e4..f5b3763e5d 100644 --- a/bootstrap/mocks/things.go +++ b/bootstrap/mocks/things.go @@ -32,11 +32,11 @@ func NewThingsService(things map[string]mfclients.Client, auth upolicies.AuthSer } } -func (svc *mainfluxThings) CreateThings(ctx context.Context, owner string, ths ...mfclients.Client) ([]mfclients.Client, error) { +func (svc *mainfluxThings) CreateThings(ctx context.Context, token string, ths ...mfclients.Client) ([]mfclients.Client, error) { svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: owner}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return []mfclients.Client{}, errors.ErrAuthentication } @@ -51,11 +51,11 @@ func (svc *mainfluxThings) CreateThings(ctx context.Context, owner string, ths . return ths, nil } -func (svc *mainfluxThings) ViewClient(ctx context.Context, owner, id string) (mfclients.Client, error) { +func (svc *mainfluxThings) ViewClient(ctx context.Context, token, id string) (mfclients.Client, error) { svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: owner}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfclients.Client{}, errors.ErrAuthentication } @@ -72,7 +72,7 @@ func (svc *mainfluxThings) EnableClient(ctx context.Context, token, id string) ( svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfclients.Client{}, errors.ErrAuthentication } @@ -91,7 +91,7 @@ func (svc *mainfluxThings) DisableClient(ctx context.Context, token, id string) svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfclients.Client{}, errors.ErrAuthentication } diff --git a/bootstrap/mocks/users.go b/bootstrap/mocks/users.go index 588f21db7b..fb1049cc69 100644 --- a/bootstrap/mocks/users.go +++ b/bootstrap/mocks/users.go @@ -22,16 +22,9 @@ func NewAuthClient(users map[string]string) policies.AuthServiceClient { return &serviceMock{users} } -func (svc serviceMock) Identify(ctx context.Context, in *policies.Token, opts ...grpc.CallOption) (*policies.UserIdentity, error) { - if id, ok := svc.users[in.GetValue()]; ok { - return &policies.UserIdentity{Id: id}, nil - } - return nil, errors.ErrAuthentication -} - -func (svc serviceMock) Issue(ctx context.Context, in *policies.IssueReq, opts ...grpc.CallOption) (*policies.Token, error) { - if id, ok := svc.users[in.GetEmail()]; ok { - return &policies.Token{Value: id}, nil +func (svc serviceMock) Identify(ctx context.Context, req *policies.IdentifyReq, opts ...grpc.CallOption) (*policies.IdentifyRes, error) { + if id, ok := svc.users[req.GetToken()]; ok { + return &policies.IdentifyRes{Id: id}, nil } return nil, errors.ErrAuthentication } @@ -39,13 +32,3 @@ func (svc serviceMock) Issue(ctx context.Context, in *policies.IssueReq, opts .. func (svc serviceMock) Authorize(ctx context.Context, req *policies.AuthorizeReq, _ ...grpc.CallOption) (r *policies.AuthorizeRes, err error) { panic("not implemented") } - -func (svc serviceMock) AddPolicy(ctx context.Context, req *policies.AddPolicyReq, _ ...grpc.CallOption) (r *policies.AddPolicyRes, err error) { - panic("not implemented") -} -func (svc serviceMock) DeletePolicy(ctx context.Context, req *policies.DeletePolicyReq, _ ...grpc.CallOption) (r *policies.DeletePolicyRes, err error) { - panic("not implemented") -} -func (svc serviceMock) ListPolicies(ctx context.Context, req *policies.ListPoliciesReq, _ ...grpc.CallOption) (r *policies.ListPoliciesRes, err error) { - panic("not implemented") -} diff --git a/bootstrap/service.go b/bootstrap/service.go index 1e2553545d..23e372d6fe 100644 --- a/bootstrap/service.go +++ b/bootstrap/service.go @@ -364,7 +364,7 @@ func (bs bootstrapService) identify(ctx context.Context, token string) (string, ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() - res, err := bs.auth.Identify(ctx, &policies.Token{Value: token}) + res, err := bs.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return "", errors.ErrAuthentication } diff --git a/bootstrap/service_test.go b/bootstrap/service_test.go index 1ca1e915cb..b916330024 100644 --- a/bootstrap/service_test.go +++ b/bootstrap/service_test.go @@ -96,6 +96,7 @@ func newThingsServer(csvc clients.Service, gsvc groups.Service, psvc tpolicies.S capi.MakeHandler(csvc, mux, logger, instanceID) gapi.MakeHandler(gsvc, mux, logger) papi.MakeHandler(csvc, psvc, mux, logger) + return httptest.NewServer(mux) } diff --git a/certs/mocks/channels.go b/certs/mocks/channels.go index fb2439da6e..584696e141 100644 --- a/certs/mocks/channels.go +++ b/certs/mocks/channels.go @@ -37,7 +37,7 @@ func (svc *mainfluxChannels) CreateGroups(ctx context.Context, token string, chs svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return []mfgroups.Group{}, errors.ErrAuthentication } @@ -74,7 +74,7 @@ func (svc *mainfluxChannels) EnableGroup(ctx context.Context, token, id string) svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfgroups.Group{}, errors.ErrAuthentication } @@ -93,7 +93,7 @@ func (svc *mainfluxChannels) DisableGroup(ctx context.Context, token, id string) svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfgroups.Group{}, errors.ErrAuthentication } diff --git a/certs/mocks/policies.go b/certs/mocks/policies.go index 14f345465f..bf9c85a696 100644 --- a/certs/mocks/policies.go +++ b/certs/mocks/policies.go @@ -34,7 +34,7 @@ func (svc *mainfluxPolicies) AddPolicy(ctx context.Context, token string, p tpol svc.mu.Lock() defer svc.mu.Unlock() - if _, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}); err != nil { + if _, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}); err != nil { return tpolicies.Policy{}, errors.ErrAuthentication } svc.connections[fmt.Sprintf("%s:%s", p.Subject, p.Object)] = p @@ -46,7 +46,7 @@ func (svc *mainfluxPolicies) DeletePolicy(ctx context.Context, token string, p t svc.mu.Lock() defer svc.mu.Unlock() - if _, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}); err != nil { + if _, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}); err != nil { return errors.ErrAuthentication } diff --git a/certs/mocks/things.go b/certs/mocks/things.go index 4a22ef53e4..f5b3763e5d 100644 --- a/certs/mocks/things.go +++ b/certs/mocks/things.go @@ -32,11 +32,11 @@ func NewThingsService(things map[string]mfclients.Client, auth upolicies.AuthSer } } -func (svc *mainfluxThings) CreateThings(ctx context.Context, owner string, ths ...mfclients.Client) ([]mfclients.Client, error) { +func (svc *mainfluxThings) CreateThings(ctx context.Context, token string, ths ...mfclients.Client) ([]mfclients.Client, error) { svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: owner}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return []mfclients.Client{}, errors.ErrAuthentication } @@ -51,11 +51,11 @@ func (svc *mainfluxThings) CreateThings(ctx context.Context, owner string, ths . return ths, nil } -func (svc *mainfluxThings) ViewClient(ctx context.Context, owner, id string) (mfclients.Client, error) { +func (svc *mainfluxThings) ViewClient(ctx context.Context, token, id string) (mfclients.Client, error) { svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: owner}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfclients.Client{}, errors.ErrAuthentication } @@ -72,7 +72,7 @@ func (svc *mainfluxThings) EnableClient(ctx context.Context, token, id string) ( svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfclients.Client{}, errors.ErrAuthentication } @@ -91,7 +91,7 @@ func (svc *mainfluxThings) DisableClient(ctx context.Context, token, id string) svc.mu.Lock() defer svc.mu.Unlock() - userID, err := svc.auth.Identify(ctx, &upolicies.Token{Value: token}) + userID, err := svc.auth.Identify(ctx, &upolicies.IdentifyReq{Token: token}) if err != nil { return mfclients.Client{}, errors.ErrAuthentication } diff --git a/certs/service.go b/certs/service.go index 0a46187c43..a32c547275 100644 --- a/certs/service.go +++ b/certs/service.go @@ -80,7 +80,7 @@ type Cert struct { } func (cs *certsService) IssueCert(ctx context.Context, token, thingID string, ttl string) (Cert, error) { - owner, err := cs.auth.Identify(ctx, &policies.Token{Value: token}) + owner, err := cs.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return Cert{}, err } @@ -113,7 +113,7 @@ func (cs *certsService) IssueCert(ctx context.Context, token, thingID string, tt func (cs *certsService) RevokeCert(ctx context.Context, token, thingID string) (Revoke, error) { var revoke Revoke - u, err := cs.auth.Identify(ctx, &policies.Token{Value: token}) + u, err := cs.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return revoke, err } @@ -144,7 +144,7 @@ func (cs *certsService) RevokeCert(ctx context.Context, token, thingID string) ( } func (cs *certsService) ListCerts(ctx context.Context, token, thingID string, offset, limit uint64) (Page, error) { - u, err := cs.auth.Identify(ctx, &policies.Token{Value: token}) + u, err := cs.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return Page{}, err } @@ -167,7 +167,7 @@ func (cs *certsService) ListCerts(ctx context.Context, token, thingID string, of } func (cs *certsService) ListSerials(ctx context.Context, token, thingID string, offset, limit uint64) (Page, error) { - u, err := cs.auth.Identify(ctx, &policies.Token{Value: token}) + u, err := cs.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return Page{}, err } @@ -176,7 +176,7 @@ func (cs *certsService) ListSerials(ctx context.Context, token, thingID string, } func (cs *certsService) ViewCert(ctx context.Context, token, serialID string) (Cert, error) { - u, err := cs.auth.Identify(ctx, &policies.Token{Value: token}) + u, err := cs.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return Cert{}, err } diff --git a/cli/policies.go b/cli/policies.go index f542043f0a..efd309cf4a 100644 --- a/cli/policies.go +++ b/cli/policies.go @@ -10,62 +10,92 @@ import ( "github.com/spf13/cobra" ) +const ( + users = "users" + things = "things" +) + var cmdPolicies = []cobra.Command{ { - Use: "create ", + Use: "create [ users | things ] ", Short: "Create policy", Long: "Create a new policy\n" + "Usage:\n" + - "\tmainflux-cli policies create '{\"object\":\"\", \"subject\":\"\",\"actions\":[\"c_list\"]}' $USERTOKEN\n", + "\tmainflux-cli policies create users '[\"c_list\"]' $USERTOKEN\n" + + "\tmainflux-cli policies create things '[\"m_write\"]' $USERTOKEN\n", Run: func(cmd *cobra.Command, args []string) { - if len(args) != 2 { + if len(args) != 5 { logUsage(cmd.Use) return } - var policy mfxsdk.Policy - if err := json.Unmarshal([]byte(args[0]), &policy); err != nil { + var actions []string + if err := json.Unmarshal([]byte(args[3]), &actions); err != nil { logError(err) return } - if err := sdk.CreatePolicy(policy, args[1]); err != nil { - logError(err) - return + + var policy = mfxsdk.Policy{ + Subject: args[1], + Object: args[2], + Actions: actions, } - logOK() + switch args[0] { + case things: + if err := sdk.CreateThingPolicy(policy, args[4]); err != nil { + logError(err) + return + } + case users: + if err := sdk.CreateUserPolicy(policy, args[4]); err != nil { + logError(err) + return + } + default: + logUsage(cmd.Use) + } }, }, { - Use: "update [ | things ] ", + Use: "update [ users | things ] ", Short: "Update policy", Long: "Update policy\n" + "Usage:\n" + - "\tmainflux-cli policies update '{\"object\":\"\", \"subject\":\"\",\"actions\":[\"c_list\"]}' $USERTOKEN\n" + - "\tmainflux-cli policies update things '{\"object\":\"\", \"subject\":\"\",\"actions\":[\"m_write\"]}' $USERTOKEN\n", + "\tmainflux-cli policies update users '[\"c_list\"]' $USERTOKEN\n" + + "\tmainflux-cli policies update things '[\"m_write\"]' $USERTOKEN\n", Run: func(cmd *cobra.Command, args []string) { - if len(args) != 2 && len(args) != 3 { + if len(args) != 5 { logUsage(cmd.Use) return } - var policy mfxsdk.Policy - if err := json.Unmarshal([]byte(args[0]), &policy); err != nil { + var actions []string + if err := json.Unmarshal([]byte(args[3]), &actions); err != nil { logError(err) return } - if args[0] == "things" { - if err := sdk.UpdateThingsPolicy(policy, args[2]); err != nil { + + var policy = mfxsdk.Policy{ + Subject: args[1], + Object: args[2], + Actions: actions, + } + + switch args[0] { + case things: + if err := sdk.UpdateThingPolicy(policy, args[4]); err != nil { logError(err) return } + case users: + if err := sdk.UpdateUserPolicy(policy, args[4]); err != nil { + logError(err) + return + } + default: + logUsage(cmd.Use) } - if err := sdk.UpdatePolicy(policy, args[1]); err != nil { - logError(err) - return - } - - logOK() }, }, { @@ -84,17 +114,17 @@ var cmdPolicies = []cobra.Command{ Offset: uint64(Offset), Limit: uint64(Limit), } - if args[0] == "things" { - policies, err := sdk.ListThingsPolicies(pm, args[1]) + switch args[0] { + case things: + policies, err := sdk.ListThingPolicies(pm, args[1]) if err != nil { logError(err) return } logJSON(policies) return - } - if args[0] == "users" { - policies, err := sdk.ListPolicies(pm, args[0]) + case users: + policies, err := sdk.ListUserPolicies(pm, args[1]) if err != nil { logError(err) return @@ -102,32 +132,82 @@ var cmdPolicies = []cobra.Command{ logJSON(policies) return + default: + logUsage(cmd.Use) } }, }, { - Use: "remove ", + Use: "remove [ users | things ] ", Short: "Remove policy", Long: "Removes a policy with the provided object and subject\n" + "Usage:\n" + - "\tmainflux-cli policies remove '{\"object\":\"\", \"subject\":\"\"}' $USERTOKEN\n", + "\tmainflux-cli policies remove users $USERTOKEN\n" + + "\tmainflux-cli policies remove things $USERTOKEN\n", Run: func(cmd *cobra.Command, args []string) { - if len(args) != 2 { + if len(args) != 4 { logUsage(cmd.Use) return } - var policy mfxsdk.Policy - if err := json.Unmarshal([]byte(args[0]), &policy); err != nil { - logError(err) - return + var policy = mfxsdk.Policy{ + Subject: args[1], + Object: args[2], } - if err := sdk.DeletePolicy(policy, args[1]); err != nil { - logError(err) + switch args[0] { + case things: + if err := sdk.DeleteThingPolicy(policy, args[3]); err != nil { + logError(err) + return + } + case users: + if err := sdk.DeleteUserPolicy(policy, args[3]); err != nil { + logError(err) + return + } + default: + logUsage(cmd.Use) + } + }, + }, + { + Use: "authorize [ users | things ] ", + Short: "Authorize access request", + Long: "Authorize subject over object with provided actions\n" + + "Usage:\n" + + "\tmainflux-cli policies authorize users \"c_list\" $USERTOKEN\n" + + "\tmainflux-cli policies authorize things \"m_read\" $USERTOKEN\n", + Run: func(cmd *cobra.Command, args []string) { + if len(args) != 6 { + logUsage(cmd.Use) return } - logOK() + var areq = mfxsdk.AccessRequest{ + Subject: args[1], + Object: args[2], + Action: args[3], + EntityType: args[4], + } + + switch args[0] { + case users: + ok, err := sdk.AuthorizeUser(areq, args[5]) + if err != nil { + logError(err) + return + } + logJSON(ok) + case things: + ok, _, err := sdk.AuthorizeThing(areq, args[5]) + if err != nil { + logError(err) + return + } + logJSON(ok) + default: + logUsage(cmd.Use) + } }, }, } @@ -135,9 +215,9 @@ var cmdPolicies = []cobra.Command{ // NewPolicyCmd returns policies command. func NewPolicyCmd() *cobra.Command { cmd := cobra.Command{ - Use: "policies [create | update | list | remove ]", + Use: "policies [create | update | list | remove | authorize ]", Short: "Policies management", - Long: `Policies management: create or update or list or delete policies`, + Long: `Policies management: create or update or list or delete or check policies`, } for i := range cmdPolicies { diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 8ef57aa7f1..b44cec1fad 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -13,17 +13,23 @@ import ( "github.com/spf13/cobra" ) -const defURL string = "http://localhost" +const ( + defURL string = "http://localhost" + defUsersURL string = defURL + ":9002" + defThingsURL string = defURL + ":9000" + defBootstrapURL string = defURL + ":9013" + defCertsURL string = defURL + ":9019" +) func main() { msgContentType := string(sdk.CTJSONSenML) sdkConf := sdk.Config{ - ThingsURL: defURL, - UsersURL: defURL, + ThingsURL: defThingsURL, + UsersURL: defUsersURL, ReaderURL: defURL, HTTPAdapterURL: fmt.Sprintf("%s/http", defURL), - BootstrapURL: defURL, - CertsURL: defURL, + BootstrapURL: defBootstrapURL, + CertsURL: defCertsURL, MsgContentType: sdk.ContentType(msgContentType), TLSVerification: false, } diff --git a/cmd/http/main.go b/cmd/http/main.go index 5cb35d55b7..6b3dac9dbc 100644 --- a/cmd/http/main.go +++ b/cmd/http/main.go @@ -126,7 +126,7 @@ func main() { } } -func newService(pub messaging.Publisher, tc policies.ThingsServiceClient, logger mflog.Logger, tracer trace.Tracer) adapter.Service { +func newService(pub messaging.Publisher, tc policies.AuthServiceClient, logger mflog.Logger, tracer trace.Tracer) adapter.Service { svc := adapter.New(pub, tc) svc = tracing.New(tracer, svc) svc = api.LoggingMiddleware(svc, logger) diff --git a/cmd/things/main.go b/cmd/things/main.go index c42977655e..0d4258f7c7 100644 --- a/cmd/things/main.go +++ b/cmd/things/main.go @@ -170,7 +170,7 @@ func main() { registerThingsServiceServer := func(srv *grpc.Server) { reflection.Register(srv) - tpolicies.RegisterThingsServiceServer(srv, grpcapi.NewServer(csvc, psvc)) + tpolicies.RegisterAuthServiceServer(srv, grpcapi.NewServer(csvc, psvc)) } grpcServerConfig := server.Config{Port: defSvcAuthGrpcPort} if err := env.Parse(&grpcServerConfig, env.Options{Prefix: envPrefixAuthGrpc, AltPrefix: envPrefix}); err != nil { diff --git a/cmd/ws/main.go b/cmd/ws/main.go index fdf1256744..58946ab96e 100644 --- a/cmd/ws/main.go +++ b/cmd/ws/main.go @@ -128,7 +128,7 @@ func main() { } } -func newService(tc policies.ThingsServiceClient, nps messaging.PubSub, logger mflog.Logger, tracer trace.Tracer) adapter.Service { +func newService(tc policies.AuthServiceClient, nps messaging.PubSub, logger mflog.Logger, tracer trace.Tracer) adapter.Service { svc := adapter.New(tc, nps) svc = tracing.New(tracer, svc) svc = api.LoggingMiddleware(svc, logger) diff --git a/coap/adapter.go b/coap/adapter.go index 8f81a1bd29..bb54cdeb09 100644 --- a/coap/adapter.go +++ b/coap/adapter.go @@ -40,13 +40,13 @@ var _ Service = (*adapterService)(nil) // Observers is a map of maps,. type adapterService struct { - auth policies.ThingsServiceClient + auth policies.AuthServiceClient pubsub messaging.PubSub obsLock sync.Mutex } // New instantiates the CoAP adapter implementation. -func New(auth policies.ThingsServiceClient, pubsub messaging.PubSub) Service { +func New(auth policies.AuthServiceClient, pubsub messaging.PubSub) Service { as := &adapterService{ auth: auth, pubsub: pubsub, @@ -58,9 +58,9 @@ func New(auth policies.ThingsServiceClient, pubsub messaging.PubSub) Service { func (svc *adapterService) Publish(ctx context.Context, key string, msg *messaging.Message) error { ar := &policies.AuthorizeReq{ - Sub: key, - Obj: msg.Channel, - Act: policies.WriteAction, + Subject: key, + Object: msg.Channel, + Action: policies.WriteAction, EntityType: policies.ThingEntityType, } res, err := svc.auth.Authorize(ctx, ar) @@ -77,9 +77,9 @@ func (svc *adapterService) Publish(ctx context.Context, key string, msg *messagi func (svc *adapterService) Subscribe(ctx context.Context, key, chanID, subtopic string, c Client) error { ar := &policies.AuthorizeReq{ - Sub: key, - Obj: chanID, - Act: policies.ReadAction, + Subject: key, + Object: chanID, + Action: policies.ReadAction, EntityType: policies.GroupEntityType, } res, err := svc.auth.Authorize(ctx, ar) @@ -98,9 +98,9 @@ func (svc *adapterService) Subscribe(ctx context.Context, key, chanID, subtopic func (svc *adapterService) Unsubscribe(ctx context.Context, key, chanID, subtopic, token string) error { ar := &policies.AuthorizeReq{ - Sub: key, - Obj: chanID, - Act: policies.ReadAction, + Subject: key, + Object: chanID, + Action: policies.ReadAction, EntityType: policies.GroupEntityType, } res, err := svc.auth.Authorize(ctx, ar) diff --git a/consumers/notifiers/mocks/auth.go b/consumers/notifiers/mocks/auth.go index c0c3fd7c3d..9fb06b3e9b 100644 --- a/consumers/notifiers/mocks/auth.go +++ b/consumers/notifiers/mocks/auth.go @@ -22,16 +22,9 @@ func NewAuth(users map[string]string) policies.AuthServiceClient { return &authServiceMock{users} } -func (svc authServiceMock) Identify(ctx context.Context, in *policies.Token, opts ...grpc.CallOption) (*policies.UserIdentity, error) { - if id, ok := svc.users[in.Value]; ok { - return &policies.UserIdentity{Id: id}, nil - } - return nil, errors.ErrAuthentication -} - -func (svc authServiceMock) Issue(ctx context.Context, in *policies.IssueReq, opts ...grpc.CallOption) (*policies.Token, error) { - if id, ok := svc.users[in.GetEmail()]; ok { - return &policies.Token{Value: id}, nil +func (svc authServiceMock) Identify(ctx context.Context, req *policies.IdentifyReq, opts ...grpc.CallOption) (*policies.IdentifyRes, error) { + if id, ok := svc.users[req.GetToken()]; ok { + return &policies.IdentifyRes{Id: id}, nil } return nil, errors.ErrAuthentication } @@ -39,15 +32,3 @@ func (svc authServiceMock) Issue(ctx context.Context, in *policies.IssueReq, opt func (svc authServiceMock) Authorize(ctx context.Context, req *policies.AuthorizeReq, _ ...grpc.CallOption) (r *policies.AuthorizeRes, err error) { panic("not implemented") } - -func (svc authServiceMock) AddPolicy(ctx context.Context, in *policies.AddPolicyReq, opts ...grpc.CallOption) (*policies.AddPolicyRes, error) { - panic("not implemented") -} - -func (svc authServiceMock) DeletePolicy(ctx context.Context, in *policies.DeletePolicyReq, opts ...grpc.CallOption) (*policies.DeletePolicyRes, error) { - panic("not implemented") -} - -func (svc authServiceMock) ListPolicies(ctx context.Context, in *policies.ListPoliciesReq, opts ...grpc.CallOption) (*policies.ListPoliciesRes, error) { - panic("not implemented") -} diff --git a/consumers/notifiers/service.go b/consumers/notifiers/service.go index ce2511d3e9..b2bcafc47e 100644 --- a/consumers/notifiers/service.go +++ b/consumers/notifiers/service.go @@ -63,7 +63,7 @@ func New(auth policies.AuthServiceClient, subs SubscriptionsRepository, idp main } func (ns *notifierService) CreateSubscription(ctx context.Context, token string, sub Subscription) (string, error) { - res, err := ns.auth.Identify(ctx, &policies.Token{Value: token}) + res, err := ns.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return "", err } @@ -77,7 +77,7 @@ func (ns *notifierService) CreateSubscription(ctx context.Context, token string, } func (ns *notifierService) ViewSubscription(ctx context.Context, token, id string) (Subscription, error) { - if _, err := ns.auth.Identify(ctx, &policies.Token{Value: token}); err != nil { + if _, err := ns.auth.Identify(ctx, &policies.IdentifyReq{Token: token}); err != nil { return Subscription{}, err } @@ -85,7 +85,7 @@ func (ns *notifierService) ViewSubscription(ctx context.Context, token, id strin } func (ns *notifierService) ListSubscriptions(ctx context.Context, token string, pm PageMetadata) (Page, error) { - if _, err := ns.auth.Identify(ctx, &policies.Token{Value: token}); err != nil { + if _, err := ns.auth.Identify(ctx, &policies.IdentifyReq{Token: token}); err != nil { return Page{}, err } @@ -93,7 +93,7 @@ func (ns *notifierService) ListSubscriptions(ctx context.Context, token string, } func (ns *notifierService) RemoveSubscription(ctx context.Context, token, id string) error { - if _, err := ns.auth.Identify(ctx, &policies.Token{Value: token}); err != nil { + if _, err := ns.auth.Identify(ctx, &policies.IdentifyReq{Token: token}); err != nil { return err } diff --git a/docker/nginx/nginx-key.conf b/docker/nginx/nginx-key.conf index 40d8279a6e..ecfec164b5 100644 --- a/docker/nginx/nginx-key.conf +++ b/docker/nginx/nginx-key.conf @@ -51,12 +51,18 @@ http { server_name localhost; # Proxy pass to users service - location ~ ^/(users|groups|password|policies|authorize) { + location ~ ^/(users|groups|password|authorize) { include snippets/proxy-headers.conf; add_header Access-Control-Expose-Headers Location; proxy_pass http://users:${MF_USERS_HTTP_PORT}; } + location ^~ /users/policies { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://users:${MF_USERS_HTTP_PORT}/policies; + } + # Proxy pass to things service location ~ ^/(things|channels|connect|disconnect|identify) { include snippets/proxy-headers.conf; @@ -64,6 +70,12 @@ http { proxy_pass http://things:${MF_THINGS_HTTP_PORT}; } + location ^~ /things/policies { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}/policies; + } + location /health { include snippets/proxy-headers.conf; proxy_pass http://things:${MF_THINGS_HTTP_PORT}; diff --git a/docker/nginx/nginx-x509.conf b/docker/nginx/nginx-x509.conf index 06e2bcb316..c3b5f5d552 100644 --- a/docker/nginx/nginx-x509.conf +++ b/docker/nginx/nginx-x509.conf @@ -65,6 +65,12 @@ http { proxy_pass http://users:${MF_USERS_HTTP_PORT}; } + location ^~ /users/policies { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://users:${MF_USERS_HTTP_PORT}/policies; + } + # Proxy pass to things service location ~ ^/(things|channels|connect|disconnect|identify) { include snippets/proxy-headers.conf; @@ -72,6 +78,12 @@ http { proxy_pass http://things:${MF_THINGS_HTTP_PORT}; } + location ^~ /things/policies { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}/policies; + } + location /health { include snippets/proxy-headers.conf; proxy_pass http://things:${MF_THINGS_HTTP_PORT}; diff --git a/http/adapter.go b/http/adapter.go index 1be25e9e35..dadf8b235f 100644 --- a/http/adapter.go +++ b/http/adapter.go @@ -23,11 +23,11 @@ var _ Service = (*adapterService)(nil) type adapterService struct { publisher messaging.Publisher - things policies.ThingsServiceClient + things policies.AuthServiceClient } // New instantiates the HTTP adapter implementation. -func New(publisher messaging.Publisher, things policies.ThingsServiceClient) Service { +func New(publisher messaging.Publisher, things policies.AuthServiceClient) Service { return &adapterService{ publisher: publisher, things: things, @@ -36,9 +36,9 @@ func New(publisher messaging.Publisher, things policies.ThingsServiceClient) Ser func (as *adapterService) Publish(ctx context.Context, token string, msg *messaging.Message) error { ar := &policies.AuthorizeReq{ - Sub: token, - Obj: msg.Channel, - Act: policies.WriteAction, + Subject: token, + Object: msg.Channel, + Action: policies.WriteAction, EntityType: policies.ThingEntityType, } res, err := as.things.Authorize(ctx, ar) diff --git a/http/api/endpoint_test.go b/http/api/endpoint_test.go index 36e7738aed..07bc2ddf16 100644 --- a/http/api/endpoint_test.go +++ b/http/api/endpoint_test.go @@ -21,7 +21,7 @@ import ( const instanceID = "5de9b29a-feb9-11ed-be56-0242ac120002" -func newService(cc policies.ThingsServiceClient) adapter.Service { +func newService(cc policies.AuthServiceClient) adapter.Service { pub := mocks.NewPublisher() return adapter.New(pub, cc) } diff --git a/http/mocks/things.go b/http/mocks/things.go index 76971f6fd4..57e1761680 100644 --- a/http/mocks/things.go +++ b/http/mocks/things.go @@ -13,7 +13,7 @@ import ( "google.golang.org/grpc/status" ) -var _ policies.ThingsServiceClient = (*thingsClient)(nil) +var _ policies.AuthServiceClient = (*thingsClient)(nil) // ServiceErrToken is used to simulate internal server error. const ServiceErrToken = "unavailable" @@ -23,12 +23,12 @@ type thingsClient struct { } // NewThingsClient returns mock implementation of things service client. -func NewThingsClient(data map[string]string) policies.ThingsServiceClient { +func NewThingsClient(data map[string]string) policies.AuthServiceClient { return &thingsClient{data} } func (tc thingsClient) Authorize(ctx context.Context, req *policies.AuthorizeReq, opts ...grpc.CallOption) (*policies.AuthorizeRes, error) { - secret := req.GetSub() + secret := req.GetSubject() // Since there is no appropriate way to simulate internal server error, // we had to use this obscure approach. ErrorToken simulates gRPC @@ -48,6 +48,6 @@ func (tc thingsClient) Authorize(ctx context.Context, req *policies.AuthorizeReq return &policies.AuthorizeRes{ThingID: id, Authorized: true}, nil } -func (tc thingsClient) Identify(ctx context.Context, req *policies.Key, opts ...grpc.CallOption) (*policies.ClientID, error) { +func (tc thingsClient) Identify(ctx context.Context, req *policies.IdentifyReq, opts ...grpc.CallOption) (*policies.IdentifyRes, error) { panic("not implemented") } diff --git a/internal/clients/grpc/things/client.go b/internal/clients/grpc/things/client.go index 795901f2ea..2c4c85c8ba 100644 --- a/internal/clients/grpc/things/client.go +++ b/internal/clients/grpc/things/client.go @@ -16,7 +16,7 @@ const envThingsAuthGrpcPrefix = "MF_THINGS_AUTH_GRPC_" var errGrpcConfig = errors.New("failed to load grpc configuration") // Setup loads Things gRPC configuration from environment variable and creates new Things gRPC API. -func Setup(envPrefix string) (policies.ThingsServiceClient, grpcClient.ClientHandler, error) { +func Setup(envPrefix string) (policies.AuthServiceClient, grpcClient.ClientHandler, error) { config := grpcClient.Config{} if err := env.Parse(&config, env.Options{Prefix: envThingsAuthGrpcPrefix, AltPrefix: envPrefix}); err != nil { return nil, nil, errors.Wrap(errGrpcConfig, err) diff --git a/mqtt/handler.go b/mqtt/handler.go index 530533c7e7..82bbb2657d 100644 --- a/mqtt/handler.go +++ b/mqtt/handler.go @@ -57,14 +57,14 @@ var channelRegExp = regexp.MustCompile(`^\/?channels\/([\w\-]+)\/messages(\/[^?] // Event implements events.Event interface. type handler struct { publishers []messaging.Publisher - auth policies.ThingsServiceClient + auth policies.AuthServiceClient logger logger.Logger es redis.EventStore } // NewHandler creates new Handler entity. func NewHandler(publishers []messaging.Publisher, es redis.EventStore, - logger logger.Logger, auth policies.ThingsServiceClient) session.Handler { + logger logger.Logger, auth policies.AuthServiceClient) session.Handler { return &handler{ es: es, logger: logger, @@ -87,15 +87,15 @@ func (h *handler) AuthConnect(ctx context.Context) error { pwd := string(s.Password) - t := &policies.Key{ - Value: pwd, + t := &policies.IdentifyReq{ + Secret: pwd, } thid, err := h.auth.Identify(ctx, t) if err != nil { return err } - if thid.GetValue() != s.Username { + if thid.GetId() != s.Username { return errors.ErrAuthentication } @@ -241,9 +241,9 @@ func (h *handler) authAccess(ctx context.Context, password, topic, action string chanID := channelParts[1] ar := &policies.AuthorizeReq{ - Sub: password, - Obj: chanID, - Act: action, + Subject: password, + Object: chanID, + Action: action, EntityType: policies.ThingEntityType, } res, err := h.auth.Authorize(ctx, ar) diff --git a/mqtt/handler_test.go b/mqtt/handler_test.go index 355d7e1994..b71fd030dc 100644 --- a/mqtt/handler_test.go +++ b/mqtt/handler_test.go @@ -441,9 +441,9 @@ func newHandler() session.Handler { if err != nil { log.Fatalf("failed to create logger: %s", err) } - k := mocks.Key(&policies.AuthorizeReq{Sub: password, Obj: chanID}) + k := mocks.Key(&policies.AuthorizeReq{Subject: password, Object: chanID}) elems := map[string][]string{k: {policies.WriteAction}} - k = mocks.Key(&policies.AuthorizeReq{Sub: password1, Obj: chanID}) + k = mocks.Key(&policies.AuthorizeReq{Subject: password1, Object: chanID}) elems[k] = []string{policies.ReadAction} authClient := mocks.NewClient(map[string]string{password: thingID, password1: thingID1}, elems) eventStore := mocks.NewEventStore() diff --git a/mqtt/mocks/auth.go b/mqtt/mocks/auth.go index 782d2a30d4..6f7494edb8 100644 --- a/mqtt/mocks/auth.go +++ b/mqtt/mocks/auth.go @@ -17,31 +17,31 @@ type mockClient struct { } // NewClient returns a new mock Things gRPC client. -func NewClient(ids map[string]string, elems map[string][]string) policies.ThingsServiceClient { +func NewClient(ids map[string]string, elems map[string][]string) policies.AuthServiceClient { return mockClient{elems: elems, ids: ids} } -func (cli mockClient) Authorize(ctx context.Context, ar *policies.AuthorizeReq, opts ...grpc.CallOption) (*policies.AuthorizeRes, error) { - actions, ok := cli.elems[Key(ar)] +func (cli mockClient) Authorize(ctx context.Context, req *policies.AuthorizeReq, opts ...grpc.CallOption) (*policies.AuthorizeRes, error) { + actions, ok := cli.elems[Key(req)] if !ok { return &policies.AuthorizeRes{Authorized: false}, nil } for _, a := range actions { - if a == ar.Act { - return &policies.AuthorizeRes{ThingID: ar.Sub, Authorized: true}, nil + if a == req.GetAction() { + return &policies.AuthorizeRes{ThingID: req.GetSubject(), Authorized: true}, nil } } return &policies.AuthorizeRes{Authorized: false}, nil } -func (cli mockClient) Identify(ctx context.Context, in *policies.Key, opts ...grpc.CallOption) (*policies.ClientID, error) { - if id, ok := cli.ids[in.GetValue()]; ok { - return &policies.ClientID{Value: id}, nil +func (cli mockClient) Identify(ctx context.Context, req *policies.IdentifyReq, opts ...grpc.CallOption) (*policies.IdentifyRes, error) { + if id, ok := cli.ids[req.GetSecret()]; ok { + return &policies.IdentifyRes{Id: id}, nil } - return &policies.ClientID{}, errors.ErrAuthentication + return &policies.IdentifyRes{}, errors.ErrAuthentication } // Key generates key for internal auth map. func Key(ar *policies.AuthorizeReq) string { - return fmt.Sprintf("%s%s%s", ar.Sub, separator, ar.Obj) + return fmt.Sprintf("%s%s%s", ar.GetSubject(), separator, ar.GetObject()) } diff --git a/pkg/clients/page.go b/pkg/clients/page.go index 91767f3895..24f1d4f19d 100644 --- a/pkg/clients/page.go +++ b/pkg/clients/page.go @@ -5,20 +5,19 @@ package clients // Page contains page metadata that helps navigation. type Page struct { - Total uint64 `json:"total"` - Offset uint64 `json:"offset"` - Limit uint64 `json:"limit"` - Name string `json:"name,omitempty"` - Order string `json:"order,omitempty"` - Dir string `json:"dir,omitempty"` - Metadata Metadata `json:"metadata,omitempty"` - Disconnected bool `json:"disconnected,omitempty"` // Used for connected or disconnected lists - Owner string `json:"owner,omitempty"` - Tag string `json:"tag,omitempty"` - SharedBy string `json:"shared_by,omitempty"` - Status Status `json:"status,omitempty"` - Action string `json:"action,omitempty"` - Subject string `json:"subject,omitempty"` - IDs []string `json:"ids,omitempty"` - Identity string `json:"identity,omitempty"` + Total uint64 `json:"total"` + Offset uint64 `json:"offset"` + Limit uint64 `json:"limit"` + Name string `json:"name,omitempty"` + Order string `json:"order,omitempty"` + Dir string `json:"dir,omitempty"` + Metadata Metadata `json:"metadata,omitempty"` + Owner string `json:"owner,omitempty"` + Tag string `json:"tag,omitempty"` + SharedBy string `json:"shared_by,omitempty"` + Status Status `json:"status,omitempty"` + Action string `json:"action,omitempty"` + Subject string `json:"subject,omitempty"` + IDs []string `json:"ids,omitempty"` + Identity string `json:"identity,omitempty"` } diff --git a/pkg/sdk/go/message_test.go b/pkg/sdk/go/message_test.go index 3cad9c6207..3111f6f077 100644 --- a/pkg/sdk/go/message_test.go +++ b/pkg/sdk/go/message_test.go @@ -21,7 +21,7 @@ import ( const eof = "EOF" -func newMessageService(cc policies.ThingsServiceClient) adapter.Service { +func newMessageService(cc policies.AuthServiceClient) adapter.Service { pub := mocks.NewPublisher() return adapter.New(pub, cc) diff --git a/pkg/sdk/go/policies.go b/pkg/sdk/go/policies.go index 258bef789c..23305b9d4a 100644 --- a/pkg/sdk/go/policies.go +++ b/pkg/sdk/go/policies.go @@ -10,7 +10,7 @@ import ( ) const ( - policiesEndpoint = "policies" + policyEndpoint = "policies" authorizeEndpoint = "authorize" accessEndpoint = "access" ) @@ -26,38 +26,34 @@ type Policy struct { } type AccessRequest struct { - Subject string `json:"subject"` - Object string `json:"object"` - Action string `json:"action"` - EntityType string `json:"entity_type"` + Subject string `json:"subject,omitempty"` + Object string `json:"object,omitempty"` + Action string `json:"action,omitempty"` + EntityType string `json:"entity_type,omitempty"` } -func (sdk mfSDK) Authorize(accessReq AccessRequest, token string) (bool, errors.SDKError) { +func (sdk mfSDK) AuthorizeUser(accessReq AccessRequest, token string) (bool, errors.SDKError) { data, err := json.Marshal(accessReq) if err != nil { return false, errors.NewSDKError(err) } url := fmt.Sprintf("%s/%s", sdk.usersURL, authorizeEndpoint) - _, body, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusOK) + _, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusOK) if sdkerr != nil { return false, sdkerr } - resp := authorizeRes{} - if err := json.Unmarshal(body, &resp); err != nil { - return false, errors.NewSDKError(err) - } - return resp.Authorized, nil + return true, nil } -func (sdk mfSDK) CreatePolicy(p Policy, token string) errors.SDKError { +func (sdk mfSDK) CreateUserPolicy(p Policy, token string) errors.SDKError { data, err := json.Marshal(p) if err != nil { return errors.NewSDKError(err) } - url := fmt.Sprintf("%s/%s", sdk.usersURL, policiesEndpoint) + url := fmt.Sprintf("%s/%s", sdk.usersURL, policyEndpoint) _, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusCreated) if sdkerr != nil { return sdkerr @@ -66,13 +62,13 @@ func (sdk mfSDK) CreatePolicy(p Policy, token string) errors.SDKError { return nil } -func (sdk mfSDK) UpdatePolicy(p Policy, token string) errors.SDKError { +func (sdk mfSDK) UpdateUserPolicy(p Policy, token string) errors.SDKError { data, err := json.Marshal(p) if err != nil { return errors.NewSDKError(err) } - url := fmt.Sprintf("%s/%s", sdk.usersURL, policiesEndpoint) + url := fmt.Sprintf("%s/%s", sdk.usersURL, policyEndpoint) _, _, sdkerr := sdk.processRequest(http.MethodPut, url, token, string(CTJSON), data, http.StatusNoContent) if sdkerr != nil { @@ -82,8 +78,8 @@ func (sdk mfSDK) UpdatePolicy(p Policy, token string) errors.SDKError { return nil } -func (sdk mfSDK) ListPolicies(pm PageMetadata, token string) (PolicyPage, errors.SDKError) { - url, err := sdk.withQueryParams(sdk.usersURL, policiesEndpoint, pm) +func (sdk mfSDK) ListUserPolicies(pm PageMetadata, token string) (PolicyPage, errors.SDKError) { + url, err := sdk.withQueryParams(sdk.usersURL, policyEndpoint, pm) if err != nil { return PolicyPage{}, errors.NewSDKError(err) } @@ -101,117 +97,133 @@ func (sdk mfSDK) ListPolicies(pm PageMetadata, token string) (PolicyPage, errors return pp, nil } -func (sdk mfSDK) DeletePolicy(p Policy, token string) errors.SDKError { - url := fmt.Sprintf("%s/%s/%s/%s", sdk.usersURL, policiesEndpoint, p.Subject, p.Object) - +func (sdk mfSDK) DeleteUserPolicy(p Policy, token string) errors.SDKError { + url := fmt.Sprintf("%s/%s/%s/%s", sdk.usersURL, policyEndpoint, p.Subject, p.Object) _, _, sdkerr := sdk.processRequest(http.MethodDelete, url, token, string(CTJSON), nil, http.StatusNoContent) return sdkerr } -func (sdk mfSDK) Assign(memberType []string, memberID, groupID, token string) errors.SDKError { - var policy = Policy{ - Subject: memberID, - Object: groupID, - Actions: memberType, - } - data, err := json.Marshal(policy) +func (sdk mfSDK) CreateThingPolicy(p Policy, token string) errors.SDKError { + data, err := json.Marshal(p) if err != nil { return errors.NewSDKError(err) } - url := fmt.Sprintf("%s/%s", sdk.usersURL, policiesEndpoint) - _, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusCreated) - return sdkerr -} - -func (sdk mfSDK) Unassign(memberID, groupID, token string) errors.SDKError { - url := fmt.Sprintf("%s/%s/%s/%s", sdk.usersURL, policiesEndpoint, memberID, groupID) - - _, _, sdkerr := sdk.processRequest(http.MethodDelete, url, token, string(CTJSON), nil, http.StatusNoContent) + url := fmt.Sprintf("%s/%s", sdk.thingsURL, policyEndpoint) + _, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusCreated) + if sdkerr != nil { + return sdkerr + } - return sdkerr + return nil } -func (sdk mfSDK) Connect(connIDs ConnectionIDs, token string) errors.SDKError { - data, err := json.Marshal(connIDs) +func (sdk mfSDK) UpdateThingPolicy(p Policy, token string) errors.SDKError { + data, err := json.Marshal(p) if err != nil { return errors.NewSDKError(err) } - url := fmt.Sprintf("%s/%s", sdk.thingsURL, connectEndpoint) + url := fmt.Sprintf("%s/%s", sdk.thingsURL, policyEndpoint) - _, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusCreated) + _, _, sdkerr := sdk.processRequest(http.MethodPut, url, token, string(CTJSON), data, http.StatusNoContent) + if sdkerr != nil { + return sdkerr + } - return sdkerr + return nil } -func (sdk mfSDK) Disconnect(connIDs ConnectionIDs, token string) errors.SDKError { - data, err := json.Marshal(connIDs) +func (sdk mfSDK) ListThingPolicies(pm PageMetadata, token string) (PolicyPage, errors.SDKError) { + url, err := sdk.withQueryParams(sdk.thingsURL, policyEndpoint, pm) if err != nil { - return errors.NewSDKError(err) + return PolicyPage{}, errors.NewSDKError(err) } - url := fmt.Sprintf("%s/%s", sdk.thingsURL, disconnectEndpoint) - _, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusNoContent) + _, body, sdkerr := sdk.processRequest(http.MethodGet, url, token, string(CTJSON), nil, http.StatusOK) + if sdkerr != nil { + return PolicyPage{}, sdkerr + } - return sdkerr -} + var pp PolicyPage + if err := json.Unmarshal(body, &pp); err != nil { + return PolicyPage{}, errors.NewSDKError(err) + } -func (sdk mfSDK) ConnectThing(thingID, chanID, token string) errors.SDKError { - url := fmt.Sprintf("%s/%s/%s/%s/%s", sdk.thingsURL, channelsEndpoint, chanID, thingsEndpoint, thingID) + return pp, nil +} - _, _, err := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), nil, http.StatusCreated) +func (sdk mfSDK) DeleteThingPolicy(p Policy, token string) errors.SDKError { + url := fmt.Sprintf("%s/%s/%s/%s", sdk.thingsURL, policyEndpoint, p.Subject, p.Object) + _, _, sdkerr := sdk.processRequest(http.MethodDelete, url, token, string(CTJSON), nil, http.StatusNoContent) - return err + return sdkerr } -func (sdk mfSDK) DisconnectThing(thingID, chanID, token string) errors.SDKError { - url := fmt.Sprintf("%s/%s/%s/%s/%s", sdk.thingsURL, channelsEndpoint, chanID, thingsEndpoint, thingID) +func (sdk mfSDK) Assign(actions []string, userID, groupID, token string) errors.SDKError { + var policy = Policy{ + Subject: userID, + Object: groupID, + Actions: actions, + } + return sdk.CreateUserPolicy(policy, token) +} - _, _, err := sdk.processRequest(http.MethodDelete, url, token, string(CTJSON), nil, http.StatusNoContent) +func (sdk mfSDK) Unassign(userID, groupID, token string) errors.SDKError { + var policy = Policy{ + Subject: userID, + Object: groupID, + } - return err + return sdk.DeleteUserPolicy(policy, token) } -func (sdk mfSDK) UpdateThingsPolicy(p Policy, token string) errors.SDKError { - data, err := json.Marshal(p) +func (sdk mfSDK) Connect(connIDs ConnectionIDs, token string) errors.SDKError { + data, err := json.Marshal(connIDs) if err != nil { return errors.NewSDKError(err) } - url := fmt.Sprintf("%s/%s/%s", sdk.thingsURL, thingsEndpoint, policiesEndpoint) + url := fmt.Sprintf("%s/%s", sdk.thingsURL, connectEndpoint) - _, _, sdkerr := sdk.processRequest(http.MethodPut, url, token, string(CTJSON), data, http.StatusOK) - if sdkerr != nil { - return sdkerr - } + _, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusOK) - return nil + return sdkerr } -func (sdk mfSDK) ListThingsPolicies(pm PageMetadata, token string) (PolicyPage, errors.SDKError) { - url, err := sdk.withQueryParams(fmt.Sprintf("%s/%s", sdk.thingsURL, thingsEndpoint), policiesEndpoint, pm) +func (sdk mfSDK) Disconnect(connIDs ConnectionIDs, token string) errors.SDKError { + data, err := json.Marshal(connIDs) if err != nil { - return PolicyPage{}, errors.NewSDKError(err) + return errors.NewSDKError(err) } - _, body, sdkerr := sdk.processRequest(http.MethodGet, url, token, string(CTJSON), nil, http.StatusOK) - if sdkerr != nil { - return PolicyPage{}, sdkerr + url := fmt.Sprintf("%s/%s", sdk.thingsURL, disconnectEndpoint) + _, _, sdkerr := sdk.processRequest(http.MethodPost, url, token, string(CTJSON), data, http.StatusNoContent) + + return sdkerr +} + +func (sdk mfSDK) ConnectThing(thingID, channelID, token string) errors.SDKError { + var policy = Policy{ + Subject: thingID, + Object: channelID, } - var pp PolicyPage - if err := json.Unmarshal(body, &pp); err != nil { - return PolicyPage{}, errors.NewSDKError(err) + return sdk.CreateThingPolicy(policy, token) +} + +func (sdk mfSDK) DisconnectThing(thingID, channelID, token string) errors.SDKError { + var policy = Policy{ + Subject: thingID, + Object: channelID, } - return pp, nil + return sdk.DeleteThingPolicy(policy, token) } -func (sdk mfSDK) ThingCanAccess(accessReq AccessRequest, token string) (bool, string, errors.SDKError) { - creq := canAccessReq{ClientSecret: accessReq.Subject, GroupID: accessReq.Object, Action: accessReq.Action, EntityType: accessReq.EntityType} - data, err := json.Marshal(creq) +func (sdk mfSDK) AuthorizeThing(accessReq AccessRequest, token string) (bool, string, errors.SDKError) { + data, err := json.Marshal(accessReq) if err != nil { return false, "", errors.NewSDKError(err) } diff --git a/pkg/sdk/go/policies_test.go b/pkg/sdk/go/policies_test.go index 2dc7cd3186..31d60571cf 100644 --- a/pkg/sdk/go/policies_test.go +++ b/pkg/sdk/go/policies_test.go @@ -10,13 +10,16 @@ import ( "github.com/go-zoo/bone" "github.com/mainflux/mainflux/internal/apiutil" "github.com/mainflux/mainflux/logger" + mflog "github.com/mainflux/mainflux/logger" "github.com/mainflux/mainflux/pkg/errors" sdk "github.com/mainflux/mainflux/pkg/sdk/go" + "github.com/mainflux/mainflux/things/clients" tclients "github.com/mainflux/mainflux/things/clients" tmocks "github.com/mainflux/mainflux/things/clients/mocks" tgmocks "github.com/mainflux/mainflux/things/groups/mocks" "github.com/mainflux/mainflux/things/policies" tpolicies "github.com/mainflux/mainflux/things/policies" + tapi "github.com/mainflux/mainflux/things/policies/api/http" tpmocks "github.com/mainflux/mainflux/things/policies/mocks" uclients "github.com/mainflux/mainflux/users/clients" umocks "github.com/mainflux/mainflux/users/clients/mocks" @@ -30,7 +33,7 @@ import ( var utadminPolicy = umocks.SubjectSet{Subject: "things", Relation: []string{"g_add"}} -func newPolicyServer(svc upolicies.Service) *httptest.Server { +func newUsersPolicyServer(svc upolicies.Service) *httptest.Server { logger := logger.NewMock() mux := bone.New() uapi.MakeHandler(svc, mux, logger) @@ -38,14 +41,22 @@ func newPolicyServer(svc upolicies.Service) *httptest.Server { return httptest.NewServer(mux) } -func TestCreatePolicy(t *testing.T) { +func newThingsPolicyServer(svc clients.Service, psvc policies.Service) *httptest.Server { + logger := mflog.NewMock() + mux := bone.New() + tapi.MakeHandler(svc, psvc, mux, logger) + + return httptest.NewServer(mux) +} + +func TestCreatePolicyUser(t *testing.T) { cRepo := new(umocks.Repository) pRepo := new(upmocks.Repository) tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration) csvc := uclients.NewService(cRepo, pRepo, tokenizer, emailer, phasher, idProvider, passRegex) svc := upolicies.NewService(pRepo, tokenizer, idProvider) - ts := newPolicyServer(svc) + ts := newUsersPolicyServer(svc) defer ts.Close() conf := sdk.Config{ UsersURL: ts.URL, @@ -152,7 +163,7 @@ func TestCreatePolicy(t *testing.T) { for _, tc := range cases { repoCall := pRepo.On("CheckAdmin", mock.Anything, mock.Anything).Return(nil) repoCall1 := pRepo.On("Save", mock.Anything, mock.Anything).Return(tc.err) - err := mfsdk.CreatePolicy(tc.policy, tc.token) + err := mfsdk.CreateUserPolicy(tc.policy, tc.token) assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err)) if tc.err == nil { ok := repoCall1.Parent.AssertCalled(t, "Save", mock.Anything, mock.Anything) @@ -163,14 +174,14 @@ func TestCreatePolicy(t *testing.T) { } } -func TestAuthorize(t *testing.T) { +func TestAuthorizeUser(t *testing.T) { cRepo := new(umocks.Repository) pRepo := new(upmocks.Repository) tokenizer := jwt.NewRepository([]byte(secret), accessDuration, refreshDuration) csvc := uclients.NewService(cRepo, pRepo, tokenizer, emailer, phasher, idProvider, passRegex) svc := upolicies.NewService(pRepo, tokenizer, idProvider) - ts := newPolicyServer(svc) + ts := newUsersPolicyServer(svc) defer ts.Close() conf := sdk.Config{ UsersURL: ts.URL, @@ -257,7 +268,7 @@ func TestAuthorize(t *testing.T) { for _, tc := range cases { repoCall := pRepo.On("CheckAdmin", mock.Anything, mock.Anything).Return(nil) - ok, err := mfsdk.Authorize(tc.policy, tc.token) + ok, err := mfsdk.AuthorizeUser(tc.policy, tc.token) assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err)) if tc.err == nil { assert.True(t, ok, fmt.Sprintf("%s: expected true, got false", tc.desc)) @@ -275,7 +286,7 @@ func TestAssign(t *testing.T) { csvc := uclients.NewService(cRepo, pRepo, tokenizer, emailer, phasher, idProvider, passRegex) svc := upolicies.NewService(pRepo, tokenizer, idProvider) - ts := newPolicyServer(svc) + ts := newUsersPolicyServer(svc) defer ts.Close() conf := sdk.Config{ UsersURL: ts.URL, @@ -399,7 +410,7 @@ func TestUpdatePolicy(t *testing.T) { csvc := uclients.NewService(cRepo, pRepo, tokenizer, emailer, phasher, idProvider, passRegex) svc := upolicies.NewService(pRepo, tokenizer, idProvider) - ts := newPolicyServer(svc) + ts := newUsersPolicyServer(svc) defer ts.Close() conf := sdk.Config{ @@ -445,7 +456,7 @@ func TestUpdatePolicy(t *testing.T) { repoCall := pRepo.On("CheckAdmin", mock.Anything, mock.Anything).Return(nil) repoCall1 := pRepo.On("RetrieveAll", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(upolicies.PolicyPage{}, nil) repoCall2 := pRepo.On("Update", mock.Anything, mock.Anything).Return(tc.err) - err := mfsdk.UpdatePolicy(policy, tc.token) + err := mfsdk.UpdateUserPolicy(policy, tc.token) assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err)) ok := repoCall1.Parent.AssertCalled(t, "Update", mock.Anything, mock.Anything) assert.True(t, ok, fmt.Sprintf("Update was not called on %s", tc.desc)) @@ -466,7 +477,7 @@ func TestUpdateThingsPolicy(t *testing.T) { psvc := tpolicies.NewService(uauth, pRepo, policiesCache, idProvider) svc := tclients.NewService(uauth, psvc, cRepo, gRepo, thingCache, idProvider) - ts := newThingsServer(svc, psvc) + ts := newThingsPolicyServer(svc, psvc) defer ts.Close() conf := sdk.Config{ @@ -511,7 +522,7 @@ func TestUpdateThingsPolicy(t *testing.T) { policy.CreatedAt = time.Now() repoCall := pRepo.On("RetrieveAll", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tpolicies.PolicyPage{}, nil) repoCall1 := pRepo.On("Update", mock.Anything, mock.Anything).Return(policies.Policy{}, tc.err) - err := mfsdk.UpdateThingsPolicy(policy, tc.token) + err := mfsdk.UpdateThingPolicy(policy, tc.token) assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err)) ok := repoCall.Parent.AssertCalled(t, "Update", mock.Anything, mock.Anything) assert.True(t, ok, fmt.Sprintf("Update was not called on %s", tc.desc)) @@ -527,7 +538,7 @@ func TestListPolicies(t *testing.T) { csvc := uclients.NewService(cRepo, pRepo, tokenizer, emailer, phasher, idProvider, passRegex) svc := upolicies.NewService(pRepo, tokenizer, idProvider) - ts := newPolicyServer(svc) + ts := newUsersPolicyServer(svc) defer ts.Close() conf := sdk.Config{ @@ -644,7 +655,7 @@ func TestListPolicies(t *testing.T) { for _, tc := range cases { repoCall := pRepo.On("CheckAdmin", mock.Anything, mock.Anything).Return(nil) repoCall1 := pRepo.On("RetrieveAll", mock.Anything, mock.Anything).Return(convertUserPolicyPage(sdk.PolicyPage{Policies: tc.response}), tc.err) - pp, err := mfsdk.ListPolicies(tc.page, tc.token) + pp, err := mfsdk.ListUserPolicies(tc.page, tc.token) assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected error %s, got %s", tc.desc, tc.err, err)) assert.Equal(t, tc.response, pp.Policies, fmt.Sprintf("%s: expected %v, got %v", tc.desc, tc.response, pp)) ok := repoCall.Parent.AssertCalled(t, "RetrieveAll", mock.Anything, mock.Anything) @@ -661,7 +672,7 @@ func TestDeletePolicy(t *testing.T) { csvc := uclients.NewService(cRepo, pRepo, tokenizer, emailer, phasher, idProvider, passRegex) svc := upolicies.NewService(pRepo, tokenizer, idProvider) - ts := newPolicyServer(svc) + ts := newUsersPolicyServer(svc) defer ts.Close() conf := sdk.Config{ @@ -676,7 +687,7 @@ func TestDeletePolicy(t *testing.T) { repoCall := pRepo.On("CheckAdmin", mock.Anything, mock.Anything).Return(nil) repoCall1 := pRepo.On("RetrieveAll", mock.Anything, mock.Anything).Return(convertUserPolicyPage(sdk.PolicyPage{Policies: []sdk.Policy{cpr}}), nil) repoCall2 := pRepo.On("Delete", mock.Anything, mock.Anything).Return(nil) - err := mfsdk.DeletePolicy(pr, generateValidToken(t, csvc, cRepo)) + err := mfsdk.DeleteUserPolicy(pr, generateValidToken(t, csvc, cRepo)) assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err)) ok := repoCall1.Parent.AssertCalled(t, "Delete", mock.Anything, mock.Anything) assert.True(t, ok, "Delete was not called on valid policy") @@ -687,7 +698,7 @@ func TestDeletePolicy(t *testing.T) { repoCall = pRepo.On("CheckAdmin", mock.Anything, mock.Anything).Return(nil) repoCall1 = pRepo.On("RetrieveAll", mock.Anything, mock.Anything).Return(convertUserPolicyPage(sdk.PolicyPage{Policies: []sdk.Policy{cpr}}), nil) repoCall2 = pRepo.On("Delete", mock.Anything, mock.Anything).Return(sdk.ErrFailedRemoval) - err = mfsdk.DeletePolicy(pr, invalidToken) + err = mfsdk.DeleteUserPolicy(pr, invalidToken) assert.Equal(t, err, errors.NewSDKErrorWithStatus(errors.ErrAuthentication, http.StatusUnauthorized), fmt.Sprintf("expected %s got %s", pr, err)) ok = repoCall.Parent.AssertCalled(t, "Delete", mock.Anything, mock.Anything) assert.True(t, ok, "Delete was not called on invalid policy") @@ -703,7 +714,7 @@ func TestUnassign(t *testing.T) { csvc := uclients.NewService(cRepo, pRepo, tokenizer, emailer, phasher, idProvider, passRegex) svc := upolicies.NewService(pRepo, tokenizer, idProvider) - ts := newPolicyServer(svc) + ts := newUsersPolicyServer(svc) defer ts.Close() conf := sdk.Config{ @@ -749,7 +760,7 @@ func TestConnect(t *testing.T) { psvc := tpolicies.NewService(uauth, pRepo, policiesCache, idProvider) svc := tclients.NewService(uauth, psvc, cRepo, gRepo, thingCache, idProvider) - ts := newThingsServer(svc, psvc) + ts := newThingsPolicyServer(svc, psvc) defer ts.Close() conf := sdk.Config{ @@ -878,7 +889,7 @@ func TestConnectThing(t *testing.T) { psvc := tpolicies.NewService(uauth, pRepo, policiesCache, idProvider) svc := tclients.NewService(uauth, psvc, cRepo, gRepo, thingCache, idProvider) - ts := newThingsServer(svc, psvc) + ts := newThingsPolicyServer(svc, psvc) defer ts.Close() conf := sdk.Config{ @@ -1006,7 +1017,7 @@ func TestDisconnectThing(t *testing.T) { psvc := tpolicies.NewService(uauth, pRepo, policiesCache, idProvider) svc := tclients.NewService(uauth, psvc, cRepo, gRepo, thingCache, idProvider) - ts := newThingsServer(svc, psvc) + ts := newThingsPolicyServer(svc, psvc) defer ts.Close() conf := sdk.Config{ @@ -1043,7 +1054,7 @@ func TestDisconnect(t *testing.T) { psvc := tpolicies.NewService(uauth, pRepo, policiesCache, idProvider) svc := tclients.NewService(uauth, psvc, cRepo, gRepo, thingCache, idProvider) - ts := newThingsServer(svc, psvc) + ts := newThingsPolicyServer(svc, psvc) defer ts.Close() conf := sdk.Config{ diff --git a/pkg/sdk/go/requests.go b/pkg/sdk/go/requests.go index e03daa5ee0..befa5a7fc4 100644 --- a/pkg/sdk/go/requests.go +++ b/pkg/sdk/go/requests.go @@ -28,8 +28,8 @@ type UserPasswordReq struct { // ConnectionIDs contains ID lists of things and channels to be connected. type ConnectionIDs struct { - ChannelIDs []string `json:"group_ids"` - ThingIDs []string `json:"client_ids"` + ThingIDs []string `json:"subjects"` + ChannelIDs []string `json:"objects"` Actions []string `json:"actions,omitempty"` } @@ -37,10 +37,3 @@ type tokenReq struct { Identity string `json:"identity"` Secret string `json:"secret"` } - -type canAccessReq struct { - ClientSecret string `json:"secret"` - GroupID string `json:"group_id"` - Action string `json:"action"` - EntityType string `json:"entity_type"` -} diff --git a/pkg/sdk/go/responses.go b/pkg/sdk/go/responses.go index 3ed6f269d1..ae06d6f645 100644 --- a/pkg/sdk/go/responses.go +++ b/pkg/sdk/go/responses.go @@ -67,7 +67,7 @@ type MembershipsPage struct { // of Policies that belong to the page. type PolicyPage struct { PageMetadata - Policies []Policy + Policies []Policy `json:"policies"` } type revokeCertsRes struct { @@ -94,10 +94,6 @@ type identifyThingResp struct { ID string `json:"id,omitempty"` } -type authorizeRes struct { - Authorized bool `json:"authorized"` -} - type canAccessRes struct { ThingID string `json:"thing_id"` Authorized bool `json:"authorized"` diff --git a/pkg/sdk/go/sdk.go b/pkg/sdk/go/sdk.go index 8484442b08..9666de2ccd 100644 --- a/pkg/sdk/go/sdk.go +++ b/pkg/sdk/go/sdk.go @@ -571,57 +571,119 @@ type SDK interface { // fmt.Println(channel) DisableChannel(id, token string) (Channel, errors.SDKError) - // CreatePolicy creates a policy for the given subject, so that, after - // CreatePolicy, `subject` has a `relation` on `object`. Returns a non-nil + // CreateUserPolicy creates a policy for the given subject, so that, after + // CreateUserPolicy, `subject` has a `relation` on `object`. Returns a non-nil // error in case of failures. // + // The subject in this case is the `userID` and the object is the `groupID`. + // // example: // policy := sdk.Policy{ // Subject: "userID:1", // Object: "groupID:1", // Actions: []string{"g_add"}, // } - // err := sdk.CreatePolicy(policy, "token") + // err := sdk.CreateUserPolicy(policy, "token") // fmt.Println(err) - CreatePolicy(policy Policy, token string) errors.SDKError + CreateUserPolicy(policy Policy, token string) errors.SDKError - // DeletePolicy deletes policies. + // UpdateUserPolicy updates policies based on the given policy structure. // + // The subject in this case is the `userID` and the object is the `groupID`. + // example: // policy := sdk.Policy{ // Subject: "userID:1", // Object: "groupID:1", // Actions: []string{"g_add"}, // } - // err := sdk.DeletePolicy(policy, "token") + // err := sdk.UpdateUserPolicy(policy, "token") // fmt.Println(err) - DeletePolicy(policy Policy, token string) errors.SDKError + UpdateUserPolicy(p Policy, token string) errors.SDKError - // UpdatePolicy updates policies based on the given policy structure. + // ListUserPolicies lists policies based on the given policy structure. + // + // example: + // pm := sdk.PageMetadata{ + // Offset: 0, + // Limit: 10, + // Subject: "userID:1", + // } + // policies, _ := sdk.ListUserPolicies(pm, "token") + // fmt.Println(policies) + ListUserPolicies(pm PageMetadata, token string) (PolicyPage, errors.SDKError) + + // DeleteUserPolicy deletes policies. + // + // The subject in this case is the `userID` and the object is the `groupID`. // // example: // policy := sdk.Policy{ // Subject: "userID:1", // Object: "groupID:1", - // Actions: []string{"g_add"}, // } - // err := sdk.UpdatePolicy(policy, "token") + // err := sdk.DeleteUserPolicy(policy, "token") + // fmt.Println(err) + DeleteUserPolicy(policy Policy, token string) errors.SDKError + + // CreateThingPolicy creates a policy for the given subject, so that, after + // CreateThingPolicy, `subject` has a `relation` on `object`. Returns a non-nil + // error in case of failures. + // + // The subject in this case can be a `thingID` or a `userID` and the object is the `channelID`. + // + // example: + // policy := sdk.Policy{ + // Subject: "thingID:1", + // Object: "channelID:1", + // Actions: []string{"m_write"}, + // } + // err := sdk.CreateThingPolicy(policy, "token") + // fmt.Println(err) + CreateThingPolicy(policy Policy, token string) errors.SDKError + + // UpdateThingPolicy updates policies based on the given policy structure. + // + // The subject in this case can be a `thingID` or a `userID` and the object is the `channelID`. + // + // example: + // policy := sdk.Policy{ + // Subject: "thingID:1", + // Object: "channelID:1", + // Actions: []string{"m_write"}, + // } + // err := sdk.UpdateThingPolicy(policy, "token") // fmt.Println(err) - UpdatePolicy(p Policy, token string) errors.SDKError + UpdateThingPolicy(p Policy, token string) errors.SDKError - // ListPolicies lists policies based on the given policy structure. + // ListThingPolicies lists policies based on the given policy structure. // // example: // pm := sdk.PageMetadata{ // Offset: 0, // Limit: 10, - // Subject: "userID:1", + // Subject: "thingID:1", // } - // policies, _ := sdk.ListPolicies(pm, "token") + // policies, _ := sdk.ListThingPolicies(pm, "token") // fmt.Println(policies) - ListPolicies(pm PageMetadata, token string) (PolicyPage, errors.SDKError) + ListThingPolicies(pm PageMetadata, token string) (PolicyPage, errors.SDKError) - // Authorize returns true if the given policy structure allows the action. + // DeleteThingPolicy deletes policies. + // + // The subject in this case can be a `thingID` or a `userID` and the object is the `channelID`. + // + // example: + // policy := sdk.Policy{ + // Subject: "thingID:1", + // Object: "channelID:1", + // } + // err := sdk.DeleteThingPolicy(policy, "token") + // fmt.Println(err) + DeleteThingPolicy(policy Policy, token string) errors.SDKError + + // AuthorizeUser returns true if the given policy structure allows the action. + // + // The subject in this case is the `userID` and the object is the `groupID`. // // example: // aReq := sdk.AccessRequest{ @@ -630,23 +692,27 @@ type SDK interface { // Actions: "g_add", // EntityType: "clients", // } - // ok, _ := sdk.Authorize(aReq, "token") + // ok, _ := sdk.AuthorizeUser(aReq, "token") // fmt.Println(ok) - Authorize(accessReq AccessRequest, token string) (bool, errors.SDKError) + AuthorizeUser(accessReq AccessRequest, token string) (bool, errors.SDKError) - // Assign assigns member of member type (thing or user) to a group. + // Assign assigns users to a group with the given actions. + // + // The `Assign` method calls the `CreateUserPolicy` method under the hood. // // example: // err := sdk.Assign([]string{"g_add"}, "userID:1", "groupID:1", "token") // fmt.Println(err) - Assign(memberType []string, memberID, groupID, token string) errors.SDKError + Assign(action []string, userID, groupID, token string) errors.SDKError - // Unassign removes member from a group. + // Unassign removes a user from a group. + // + // The `Unassign` method calls the `DeleteUserPolicy` method under the hood. // // example: // err := sdk.Unassign("userID:1", "groupID:1", "token") // fmt.Println(err) - Unassign(memberID, groupID, token string) errors.SDKError + Unassign(userID, groupID, token string) errors.SDKError // Connect bulk connects things to channels specified by id. // @@ -671,7 +737,9 @@ type SDK interface { // fmt.Println(err) Disconnect(connIDs ConnectionIDs, token string) errors.SDKError - // ConnectThing + // ConnectThing connects thing to specified channel by id. + // + // The `ConnectThing` method calls the `CreateThingPolicy` method under the hood. // // example: // err := sdk.ConnectThing("thingID", "channelID", "token") @@ -680,36 +748,14 @@ type SDK interface { // DisconnectThing disconnect thing from specified channel by id. // + // The `DisconnectThing` method calls the `DeleteThingPolicy` method under the hood. + // // example: // err := sdk.DisconnectThing("thingID", "channelID", "token") // fmt.Println(err) DisconnectThing(thingID, chanID, token string) errors.SDKError - // UpdateThingsPolicy updates policies based on the given policy structure. - // - // example: - // policy := sdk.Policy{ - // Subject: "thingID", - // Object: "channelID", - // Actions: []string{"m_read"}, - // } - // err := sdk.UpdateThingsPolicy(policy, "token") - // fmt.Println(err) - UpdateThingsPolicy(p Policy, token string) errors.SDKError - - // ListThingsPolicies lists policies based on the given policy structure. - // - // example: - // pm := sdk.PageMetadata{ - // Offset: 0, - // Limit: 10, - // Subject: "thingID:1", - // } - // policies, _ := sdk.ListThingsPolicies(pm, "token") - // fmt.Println(policies) - ListThingsPolicies(pm PageMetadata, token string) (PolicyPage, errors.SDKError) - - // ThingCanAccess returns true if the given policy structure allows the action. + // AuthorizeThing returns true if the given policy structure allows the action. // // example: // aReq := sdk.AccessRequest{ @@ -718,9 +764,9 @@ type SDK interface { // Actions: "m_read", // EntityType: "things", // } - // ok, _ := sdk.ThingCanAccess(aReq "token") + // ok, _ := sdk.AuthorizeThing(aReq "token") // fmt.Println(ok) - ThingCanAccess(accessReq AccessRequest, token string) (bool, string, errors.SDKError) + AuthorizeThing(accessReq AccessRequest, token string) (bool, string, errors.SDKError) // SendMessage send message to specified channel. // diff --git a/pkg/sdk/go/things.go b/pkg/sdk/go/things.go index b819c1d868..7bf7a062ce 100644 --- a/pkg/sdk/go/things.go +++ b/pkg/sdk/go/things.go @@ -14,7 +14,6 @@ const ( connectEndpoint = "connect" disconnectEndpoint = "disconnect" identifyEndpoint = "identify" - shareEndpoint = "share" ) // Thing represents mainflux thing. diff --git a/readers/api/endpoint.go b/readers/api/endpoint.go index 629bbc27ef..fae1a70da5 100644 --- a/readers/api/endpoint.go +++ b/readers/api/endpoint.go @@ -13,7 +13,7 @@ import ( upolicies "github.com/mainflux/mainflux/users/policies" ) -func listMessagesEndpoint(svc readers.MessageRepository, tc tpolicies.ThingsServiceClient, ac upolicies.AuthServiceClient) endpoint.Endpoint { +func listMessagesEndpoint(svc readers.MessageRepository, tc tpolicies.AuthServiceClient, ac upolicies.AuthServiceClient) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { req := request.(listMessagesReq) diff --git a/readers/api/endpoint_test.go b/readers/api/endpoint_test.go index d66b95b78b..1c50cbb6e2 100644 --- a/readers/api/endpoint_test.go +++ b/readers/api/endpoint_test.go @@ -49,7 +49,7 @@ var ( idProvider = uuid.New() ) -func newServer(repo readers.MessageRepository, tc tpolicies.ThingsServiceClient, ac upolicies.AuthServiceClient) *httptest.Server { +func newServer(repo readers.MessageRepository, tc tpolicies.AuthServiceClient, ac upolicies.AuthServiceClient) *httptest.Server { mux := api.MakeHandler(repo, tc, ac, svcName, instanceID) return httptest.NewServer(mux) } diff --git a/readers/api/transport.go b/readers/api/transport.go index f2b07570ea..a4e649bde4 100644 --- a/readers/api/transport.go +++ b/readers/api/transport.go @@ -48,7 +48,7 @@ var ( ) // MakeHandler returns a HTTP handler for API endpoints. -func MakeHandler(svc readers.MessageRepository, tc tpolicies.ThingsServiceClient, ac upolicies.AuthServiceClient, svcName, instanceID string) http.Handler { +func MakeHandler(svc readers.MessageRepository, tc tpolicies.AuthServiceClient, ac upolicies.AuthServiceClient, svcName, instanceID string) http.Handler { opts := []kithttp.ServerOption{ kithttp.ServerErrorEncoder(encodeError), @@ -210,10 +210,10 @@ func encodeError(_ context.Context, err error, w http.ResponseWriter) { } } -func authorize(ctx context.Context, req listMessagesReq, tc tpolicies.ThingsServiceClient, ac upolicies.AuthServiceClient) (err error) { +func authorize(ctx context.Context, req listMessagesReq, tc tpolicies.AuthServiceClient, ac upolicies.AuthServiceClient) (err error) { switch { case req.token != "": - user, err := ac.Identify(ctx, &upolicies.Token{Value: req.token}) + user, err := ac.Identify(ctx, &upolicies.IdentifyReq{Token: req.token}) if err != nil { e, ok := status.FromError(err) if ok && e.Code() == codes.PermissionDenied { @@ -221,7 +221,7 @@ func authorize(ctx context.Context, req listMessagesReq, tc tpolicies.ThingsServ } return err } - if _, err = tc.Authorize(ctx, &tpolicies.AuthorizeReq{Sub: user.GetId(), Obj: req.chanID, Act: tpolicies.ReadAction, EntityType: tpolicies.GroupEntityType}); err != nil { + if _, err = tc.Authorize(ctx, &tpolicies.AuthorizeReq{Subject: user.GetId(), Object: req.chanID, Action: tpolicies.ReadAction, EntityType: tpolicies.GroupEntityType}); err != nil { e, ok := status.FromError(err) if ok && e.Code() == codes.PermissionDenied { return errors.Wrap(errUserAccess, err) @@ -230,7 +230,7 @@ func authorize(ctx context.Context, req listMessagesReq, tc tpolicies.ThingsServ } return nil default: - if _, err := tc.Authorize(ctx, &tpolicies.AuthorizeReq{Sub: req.key, Obj: req.chanID, Act: tpolicies.ReadAction, EntityType: tpolicies.GroupEntityType}); err != nil { + if _, err := tc.Authorize(ctx, &tpolicies.AuthorizeReq{Subject: req.key, Object: req.chanID, Action: tpolicies.ReadAction, EntityType: tpolicies.GroupEntityType}); err != nil { return errors.Wrap(errThingAccess, err) } return nil diff --git a/readers/mocks/things.go b/readers/mocks/things.go index 639dd4e47a..0419846e30 100644 --- a/readers/mocks/things.go +++ b/readers/mocks/things.go @@ -6,35 +6,25 @@ package mocks import ( "context" - "github.com/mainflux/mainflux/pkg/errors" "github.com/mainflux/mainflux/things/policies" "google.golang.org/grpc" ) -var _ policies.ThingsServiceClient = (*thingsServiceMock)(nil) +var _ policies.AuthServiceClient = (*thingsServiceMock)(nil) type thingsServiceMock struct { channels map[string]string } // NewThingsService returns mock implementation of things service. -func NewThingsService(channels map[string]string) policies.ThingsServiceClient { +func NewThingsService(channels map[string]string) policies.AuthServiceClient { return &thingsServiceMock{channels} } -func (svc thingsServiceMock) AuthorizeByKey(ctx context.Context, in *policies.AuthorizeReq, opts ...grpc.CallOption) (*policies.ClientID, error) { - token := in.GetSub() - if token == "invalid" || token == "" { - return nil, errors.ErrAuthentication - } - - return &policies.ClientID{Value: token}, nil -} - func (svc thingsServiceMock) Authorize(context.Context, *policies.AuthorizeReq, ...grpc.CallOption) (*policies.AuthorizeRes, error) { return &policies.AuthorizeRes{Authorized: true}, nil } -func (svc thingsServiceMock) Identify(context.Context, *policies.Key, ...grpc.CallOption) (*policies.ClientID, error) { +func (svc thingsServiceMock) Identify(context.Context, *policies.IdentifyReq, ...grpc.CallOption) (*policies.IdentifyRes, error) { panic("not implemented") } diff --git a/things/clients/mocks/auth.go b/things/clients/mocks/auth.go index 29753ef1ff..89ac4a363c 100644 --- a/things/clients/mocks/auth.go +++ b/things/clients/mocks/auth.go @@ -28,24 +28,17 @@ func NewAuthService(users map[string]string, policies map[string][]MockSubjectSe return &authServiceMock{users, policies} } -func (svc authServiceMock) Identify(ctx context.Context, in *policies.Token, opts ...grpc.CallOption) (*policies.UserIdentity, error) { - if id, ok := svc.users[in.Value]; ok { - return &policies.UserIdentity{Id: id}, nil - } - return nil, errors.ErrAuthentication -} - -func (svc authServiceMock) Issue(ctx context.Context, in *policies.IssueReq, opts ...grpc.CallOption) (*policies.Token, error) { - if id, ok := svc.users[in.GetEmail()]; ok { - return &policies.Token{Value: id}, nil +func (svc authServiceMock) Identify(ctx context.Context, req *policies.IdentifyReq, opts ...grpc.CallOption) (*policies.IdentifyRes, error) { + if id, ok := svc.users[req.GetToken()]; ok { + return &policies.IdentifyRes{Id: id}, nil } return nil, errors.ErrAuthentication } func (svc authServiceMock) Authorize(ctx context.Context, req *policies.AuthorizeReq, _ ...grpc.CallOption) (r *policies.AuthorizeRes, err error) { - for _, policy := range svc.policies[req.GetSub()] { + for _, policy := range svc.policies[req.GetSubject()] { for _, r := range policy.Relation { - if r == req.GetAct() && policy.Object == req.GetObj() { + if r == req.GetAction() && policy.Object == req.GetObject() { return &policies.AuthorizeRes{Authorized: true}, nil } } @@ -53,26 +46,3 @@ func (svc authServiceMock) Authorize(ctx context.Context, req *policies.Authoriz } return nil, errors.ErrAuthorization } - -func (svc authServiceMock) AddPolicy(ctx context.Context, in *policies.AddPolicyReq, opts ...grpc.CallOption) (*policies.AddPolicyRes, error) { - if len(in.GetAct()) == 0 || in.GetObj() == "" || in.GetSub() == "" { - return &policies.AddPolicyRes{}, errors.ErrMalformedEntity - } - - obj := in.GetObj() - svc.policies[in.GetSub()] = append(svc.policies[in.GetSub()], MockSubjectSet{Object: obj, Relation: in.GetAct()}) - return &policies.AddPolicyRes{Authorized: true}, nil -} - -func (svc authServiceMock) ListPolicies(ctx context.Context, in *policies.ListPoliciesReq, opts ...grpc.CallOption) (*policies.ListPoliciesRes, error) { - res := policies.ListPoliciesRes{} - for key := range svc.policies { - res.Objects = append(res.Objects, key) - } - return &res, nil -} - -func (svc authServiceMock) DeletePolicy(ctx context.Context, in *policies.DeletePolicyReq, opts ...grpc.CallOption) (*policies.DeletePolicyRes, error) { - // Not implemented yet - return &policies.DeletePolicyRes{Deleted: true}, nil -} diff --git a/things/clients/service.go b/things/clients/service.go index 8d99dd06cc..cf541b4961 100644 --- a/things/clients/service.go +++ b/things/clients/service.go @@ -18,11 +18,9 @@ import ( const ( MyKey = "mine" thingsObjectKey = "things" - addRelationKey = "g_add" updateRelationKey = "c_update" listRelationKey = "c_list" deleteRelationKey = "c_delete" - groupEntityType = "group" clientEntityType = "client" ) @@ -294,7 +292,7 @@ func (svc service) Identify(ctx context.Context, key string) (string, error) { } func (svc service) identify(ctx context.Context, token string) (string, error) { - req := &upolicies.Token{Value: token} + req := &upolicies.IdentifyReq{Token: token} res, err := svc.uauth.Identify(ctx, req) if err != nil { return "", errors.Wrap(errors.ErrAuthorization, err) @@ -317,9 +315,9 @@ func (svc service) authorize(ctx context.Context, subject, object, action string // TODO : Only accept token as parameter since object and action are irrelevant. func (svc service) checkAdmin(ctx context.Context, subject, object, action string) error { req := &upolicies.AuthorizeReq{ - Sub: subject, - Obj: object, - Act: action, + Subject: subject, + Object: object, + Action: action, EntityType: clientEntityType, } res, err := svc.uauth.Authorize(ctx, req) diff --git a/things/clients/standalone/standalone.go b/things/clients/standalone/standalone.go index 1e762239cf..abf557ad2a 100644 --- a/things/clients/standalone/standalone.go +++ b/things/clients/standalone/standalone.go @@ -11,8 +11,6 @@ import ( "google.golang.org/grpc" ) -var errUnsupported = errors.New("not supported in standalone mode") - var _ policies.AuthServiceClient = (*singleUserRepo)(nil) type singleUserRepo struct { @@ -28,39 +26,17 @@ func NewAuthService(id, token string) policies.AuthServiceClient { } } -func (repo singleUserRepo) Issue(ctx context.Context, req *policies.IssueReq, opts ...grpc.CallOption) (*policies.Token, error) { - return &policies.Token{}, errUnsupported -} - -func (repo singleUserRepo) Identify(ctx context.Context, token *policies.Token, opts ...grpc.CallOption) (*policies.UserIdentity, error) { - if repo.token != token.GetValue() { +func (repo singleUserRepo) Identify(ctx context.Context, req *policies.IdentifyReq, opts ...grpc.CallOption) (*policies.IdentifyRes, error) { + if repo.token != req.GetToken() { return nil, errors.ErrAuthentication } - return &policies.UserIdentity{Id: repo.id}, nil + return &policies.IdentifyRes{Id: repo.id}, nil } func (repo singleUserRepo) Authorize(ctx context.Context, req *policies.AuthorizeReq, _ ...grpc.CallOption) (r *policies.AuthorizeRes, err error) { - if repo.id != req.GetSub() { + if repo.id != req.GetSubject() { return &policies.AuthorizeRes{}, errors.ErrAuthorization } return &policies.AuthorizeRes{Authorized: true}, nil } - -func (repo singleUserRepo) AddPolicy(ctx context.Context, req *policies.AddPolicyReq, opts ...grpc.CallOption) (*policies.AddPolicyRes, error) { - if repo.token != req.GetToken() { - return &policies.AddPolicyRes{}, errors.ErrAuthorization - } - return &policies.AddPolicyRes{Authorized: true}, nil -} - -func (repo singleUserRepo) DeletePolicy(ctx context.Context, req *policies.DeletePolicyReq, opts ...grpc.CallOption) (*policies.DeletePolicyRes, error) { - if repo.token != req.GetToken() { - return &policies.DeletePolicyRes{}, errors.ErrAuthorization - } - return &policies.DeletePolicyRes{Deleted: true}, nil -} - -func (repo singleUserRepo) ListPolicies(ctx context.Context, in *policies.ListPoliciesReq, opts ...grpc.CallOption) (*policies.ListPoliciesRes, error) { - return &policies.ListPoliciesRes{}, errUnsupported -} diff --git a/things/groups/service.go b/things/groups/service.go index 57989ade36..572b136d23 100644 --- a/things/groups/service.go +++ b/things/groups/service.go @@ -182,7 +182,7 @@ func (svc service) changeGroupStatus(ctx context.Context, token string, group gr } func (svc service) identify(ctx context.Context, token string) (string, error) { - req := &upolicies.Token{Value: token} + req := &upolicies.IdentifyReq{Token: token} res, err := svc.uauth.Identify(ctx, req) if err != nil { return "", errors.Wrap(errors.ErrAuthorization, err) @@ -205,9 +205,9 @@ func (svc service) authorize(ctx context.Context, subject, object, action string func (svc service) checkAdmin(ctx context.Context, subject, object, action string) error { // for checking admin rights policy object, action and entity type are not important req := &upolicies.AuthorizeReq{ - Sub: subject, - Obj: object, - Act: action, + Subject: subject, + Object: object, + Action: action, EntityType: entityType, } res, err := svc.uauth.Authorize(ctx, req) diff --git a/things/policies/api/grpc/client.go b/things/policies/api/grpc/client.go index 7c96374afb..b9aa3b9dc2 100644 --- a/things/policies/api/grpc/client.go +++ b/things/policies/api/grpc/client.go @@ -14,9 +14,9 @@ import ( "google.golang.org/grpc" ) -const svcName = "mainflux.things.policies.ThingsService" +const svcName = "mainflux.things.policies.AuthService" -var _ policies.ThingsServiceClient = (*grpcClient)(nil) +var _ policies.AuthServiceClient = (*grpcClient)(nil) type grpcClient struct { authorize endpoint.Endpoint @@ -25,7 +25,7 @@ type grpcClient struct { } // NewClient returns new gRPC client instance. -func NewClient(conn *grpc.ClientConn, timeout time.Duration) policies.ThingsServiceClient { +func NewClient(conn *grpc.ClientConn, timeout time.Duration) policies.AuthServiceClient { return &grpcClient{ authorize: otelkit.EndpointMiddleware(otelkit.WithOperation("authorize"))(kitgrpc.NewClient( conn, @@ -41,7 +41,7 @@ func NewClient(conn *grpc.ClientConn, timeout time.Duration) policies.ThingsServ "Identify", encodeIdentifyRequest, decodeIdentityResponse, - policies.ClientID{}, + policies.IdentifyRes{}, ).Endpoint()), timeout: timeout, @@ -53,10 +53,10 @@ func (client grpcClient) Authorize(ctx context.Context, req *policies.AuthorizeR defer cancel() areq := authorizeReq{ + subject: req.GetSubject(), + object: req.GetObject(), + action: req.GetAction(), entityType: req.GetEntityType(), - clientID: req.GetSub(), - groupID: req.GetObj(), - action: req.GetAct(), } res, err := client.authorize(ctx, areq) if err != nil { @@ -67,32 +67,32 @@ func (client grpcClient) Authorize(ctx context.Context, req *policies.AuthorizeR return &policies.AuthorizeRes{ThingID: ares.thingID, Authorized: ares.authorized}, nil } -func (client grpcClient) Identify(ctx context.Context, req *policies.Key, _ ...grpc.CallOption) (*policies.ClientID, error) { +func (client grpcClient) Identify(ctx context.Context, req *policies.IdentifyReq, _ ...grpc.CallOption) (*policies.IdentifyRes, error) { ctx, cancel := context.WithTimeout(ctx, client.timeout) defer cancel() - res, err := client.identify(ctx, identifyReq{key: req.GetValue()}) + res, err := client.identify(ctx, identifyReq{secret: req.GetSecret()}) if err != nil { return nil, err } - ir := res.(identityRes) - return &policies.ClientID{Value: ir.id}, nil + ires := res.(identityRes) + return &policies.IdentifyRes{Id: ires.id}, nil } func encodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { req := grpcReq.(authorizeReq) - return &policies.AuthorizeReq{Sub: req.clientID, Obj: req.groupID, Act: req.action, EntityType: req.entityType}, nil + return &policies.AuthorizeReq{Subject: req.subject, Object: req.object, Action: req.action, EntityType: req.entityType}, nil } func encodeIdentifyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { req := grpcReq.(identifyReq) - return &policies.Key{Value: req.key}, nil + return &policies.IdentifyReq{Secret: req.secret}, nil } func decodeIdentityResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*policies.ClientID) - return identityRes{id: res.GetValue()}, nil + res := grpcRes.(*policies.IdentifyRes) + return identityRes{id: res.GetId()}, nil } func decodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { diff --git a/things/policies/api/grpc/endpoint.go b/things/policies/api/grpc/endpoint.go index 7737fb3b3d..9ea47be8eb 100644 --- a/things/policies/api/grpc/endpoint.go +++ b/things/policies/api/grpc/endpoint.go @@ -15,17 +15,17 @@ func authorizeEndpoint(svc policies.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { req := request.(authorizeReq) if err := req.validate(); err != nil { - return nil, err + return authorizeRes{}, err } ar := policies.AccessRequest{ - Subject: req.clientID, - Object: req.groupID, + Subject: req.subject, + Object: req.object, Action: req.action, Entity: req.entityType, } policy, err := svc.Authorize(ctx, ar) if err != nil { - return authorizeRes{authorized: false}, err + return authorizeRes{}, err } return authorizeRes{authorized: true, thingID: policy.Subject}, nil @@ -35,10 +35,10 @@ func authorizeEndpoint(svc policies.Service) endpoint.Endpoint { func identifyEndpoint(svc clients.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { req := request.(identifyReq) - id, err := svc.Identify(ctx, req.key) if err := req.validate(); err != nil { - return nil, err + return identityRes{}, err } + id, err := svc.Identify(ctx, req.secret) if err != nil { return identityRes{}, err } diff --git a/things/policies/api/grpc/requests.go b/things/policies/api/grpc/requests.go index 70aee29fd4..a2d4c00601 100644 --- a/things/policies/api/grpc/requests.go +++ b/things/policies/api/grpc/requests.go @@ -9,17 +9,17 @@ import ( ) type authorizeReq struct { - entityType string - clientID string - groupID string + subject string + object string action string + entityType string } func (req authorizeReq) validate() error { - if req.clientID == "" { + if req.subject == "" { return apiutil.ErrMissingPolicySub } - if req.groupID == "" { + if req.object == "" { return apiutil.ErrMissingPolicyObj } if ok := policies.ValidateAction(req.action); !ok { @@ -30,11 +30,11 @@ func (req authorizeReq) validate() error { } type identifyReq struct { - key string + secret string } func (req identifyReq) validate() error { - if req.key == "" { + if req.secret == "" { return apiutil.ErrBearerKey } diff --git a/things/policies/api/grpc/transport.go b/things/policies/api/grpc/transport.go index df7de0f98c..ee2d32c341 100644 --- a/things/policies/api/grpc/transport.go +++ b/things/policies/api/grpc/transport.go @@ -16,19 +16,19 @@ import ( "google.golang.org/grpc/status" ) -var _ policies.ThingsServiceServer = (*grpcServer)(nil) +var _ policies.AuthServiceServer = (*grpcServer)(nil) type grpcServer struct { authorize kitgrpc.Handler identify kitgrpc.Handler - policies.UnimplementedThingsServiceServer + policies.UnimplementedAuthServiceServer } // NewServer returns new ThingsServiceServer instance. -func NewServer(csvc clients.Service, psvc policies.Service) policies.ThingsServiceServer { +func NewServer(csvc clients.Service, psvc policies.Service) policies.AuthServiceServer { return &grpcServer{ authorize: kitgrpc.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("can_access_by_id"))(authorizeEndpoint(psvc)), + otelkit.EndpointMiddleware(otelkit.WithOperation("authorize"))(authorizeEndpoint(psvc)), decodeAuthorizeRequest, encodeAuthorizeResponse, ), @@ -49,28 +49,28 @@ func (gs *grpcServer) Authorize(ctx context.Context, req *policies.AuthorizeReq) return res.(*policies.AuthorizeRes), nil } -func (gs *grpcServer) Identify(ctx context.Context, req *policies.Key) (*policies.ClientID, error) { +func (gs *grpcServer) Identify(ctx context.Context, req *policies.IdentifyReq) (*policies.IdentifyRes, error) { _, res, err := gs.identify.ServeGRPC(ctx, req) if err != nil { return nil, encodeError(err) } - return res.(*policies.ClientID), nil + return res.(*policies.IdentifyRes), nil } func decodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { req := grpcReq.(*policies.AuthorizeReq) - return authorizeReq{entityType: req.GetEntityType(), clientID: req.GetSub(), groupID: req.GetObj(), action: req.GetAct()}, nil + return authorizeReq{subject: req.GetSubject(), object: req.GetObject(), action: req.GetAction(), entityType: req.GetEntityType()}, nil } func decodeIdentifyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*policies.Key) - return identifyReq{key: req.GetValue()}, nil + req := grpcReq.(*policies.IdentifyReq) + return identifyReq{secret: req.GetSecret()}, nil } func encodeIdentityResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { res := grpcRes.(identityRes) - return &policies.ClientID{Value: res.id}, nil + return &policies.IdentifyRes{Id: res.id}, nil } func encodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { diff --git a/things/policies/api/http/endpoints.go b/things/policies/api/http/endpoints.go index db773c4d8c..943075c667 100644 --- a/things/policies/api/http/endpoints.go +++ b/things/policies/api/http/endpoints.go @@ -18,7 +18,7 @@ func identifyEndpoint(svc clients.Service) endpoint.Endpoint { return nil, err } - id, err := svc.Identify(ctx, req.Secret) + id, err := svc.Identify(ctx, req.secret) if err != nil { return nil, err } @@ -31,7 +31,7 @@ func authorizeEndpoint(svc policies.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { req := request.(authorizeReq) if err := req.validate(); err != nil { - return nil, err + return authorizeRes{}, err } ar := policies.AccessRequest{ Subject: req.Subject, @@ -41,7 +41,7 @@ func authorizeEndpoint(svc policies.Service) endpoint.Endpoint { } policy, err := svc.Authorize(ctx, ar) if err != nil { - return authorizeRes{Authorized: false}, err + return authorizeRes{}, err } return authorizeRes{ThingID: policy.Subject, Authorized: true}, nil @@ -53,14 +53,14 @@ func connectEndpoint(svc policies.Service) endpoint.Endpoint { cr := request.(createPolicyReq) if err := cr.validate(); err != nil { - return nil, err + return addPolicyRes{}, err } if len(cr.Actions) == 0 { cr.Actions = policies.PolicyTypes } policy := policies.Policy{ - Subject: cr.ClientID, - Object: cr.GroupID, + Subject: cr.Subject, + Object: cr.Object, Actions: cr.Actions, } policy, err := svc.AddPolicy(ctx, cr.token, policy) @@ -68,7 +68,7 @@ func connectEndpoint(svc policies.Service) endpoint.Endpoint { return nil, err } - return policyRes{[]policies.Policy{policy}, true}, nil + return addPolicyRes{created: true, Policy: policy}, nil } } @@ -77,27 +77,28 @@ func connectThingsEndpoint(svc policies.Service) endpoint.Endpoint { cr := request.(createPoliciesReq) if err := cr.validate(); err != nil { - return nil, err + return listPolicyRes{}, err } if len(cr.Actions) == 0 { cr.Actions = policies.PolicyTypes } - ps := []policies.Policy{} - for _, tid := range cr.ClientIDs { - for _, cid := range cr.GroupIDs { + var pols policies.PolicyPage + for _, tid := range cr.Subjects { + for _, cid := range cr.Objects { policy := policies.Policy{ Subject: tid, Object: cid, Actions: cr.Actions, } - if _, err := svc.AddPolicy(ctx, cr.token, policy); err != nil { - return nil, err + p, err := svc.AddPolicy(ctx, cr.token, policy) + if err != nil { + return listPolicyRes{}, err } - ps = append(ps, policy) + pols.Policies = append(pols.Policies, p) } } - return policyRes{created: true, Policies: ps}, nil + return buildPoliciesResponse(pols), nil } } @@ -106,7 +107,7 @@ func updatePolicyEndpoint(svc policies.Service) endpoint.Endpoint { cr := request.(policyReq) if err := cr.validate(); err != nil { - return nil, err + return updatePolicyRes{}, err } policy := policies.Policy{ Subject: cr.Subject, @@ -115,10 +116,10 @@ func updatePolicyEndpoint(svc policies.Service) endpoint.Endpoint { } policy, err := svc.UpdatePolicy(ctx, cr.token, policy) if err != nil { - return nil, err + return updatePolicyRes{}, err } - return policyRes{[]policies.Policy{policy}, false}, nil + return updatePolicyRes{updated: true, Policy: policy}, nil } } @@ -129,7 +130,7 @@ func listPoliciesEndpoint(svc policies.Service) endpoint.Endpoint { if err := lpr.validate(); err != nil { return nil, err } - policy := policies.Page{ + pm := policies.Page{ Limit: lpr.limit, Offset: lpr.offset, Subject: lpr.client, @@ -137,12 +138,12 @@ func listPoliciesEndpoint(svc policies.Service) endpoint.Endpoint { Action: lpr.action, OwnerID: lpr.owner, } - policyPage, err := svc.ListPolicies(ctx, lpr.token, policy) + policyPage, err := svc.ListPolicies(ctx, lpr.token, pm) if err != nil { return nil, err } - return listPolicyRes{policyPage}, nil + return buildPoliciesResponse(policyPage), nil } } @@ -150,22 +151,22 @@ func disconnectEndpoint(svc policies.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { cr := request.(createPolicyReq) if err := cr.validate(); err != nil { - return nil, err + return deletePolicyRes{}, err } if len(cr.Actions) == 0 { cr.Actions = policies.PolicyTypes } policy := policies.Policy{ - Subject: cr.ClientID, - Object: cr.GroupID, + Subject: cr.Subject, + Object: cr.Object, Actions: cr.Actions, } if err := svc.DeletePolicy(ctx, cr.token, policy); err != nil { - return nil, err + return deletePolicyRes{}, err } - return deletePolicyRes{}, nil + return deletePolicyRes{deleted: true}, nil } } @@ -173,20 +174,37 @@ func disconnectThingsEndpoint(svc policies.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { req := request.(createPoliciesReq) if err := req.validate(); err != nil { - return nil, err + return deletePolicyRes{}, err } - for _, tid := range req.ClientIDs { - for _, cid := range req.GroupIDs { + for _, tid := range req.Subjects { + for _, cid := range req.Objects { policy := policies.Policy{ Subject: tid, Object: cid, } if err := svc.DeletePolicy(ctx, req.token, policy); err != nil { - return nil, err + return deletePolicyRes{}, err } } } - return deletePolicyRes{}, nil + return deletePolicyRes{deleted: true}, nil } } + +func buildPoliciesResponse(page policies.PolicyPage) listPolicyRes { + res := listPolicyRes{ + pageRes: pageRes{ + Limit: page.Limit, + Offset: page.Offset, + Total: page.Total, + }, + Policies: []viewPolicyRes{}, + } + + for _, policy := range page.Policies { + res.Policies = append(res.Policies, viewPolicyRes{policy}) + } + + return res +} diff --git a/things/policies/api/http/requests.go b/things/policies/api/http/requests.go index 2b7c31e8b7..b469bef183 100644 --- a/things/policies/api/http/requests.go +++ b/things/policies/api/http/requests.go @@ -9,29 +9,27 @@ import ( ) type createPolicyReq struct { - token string - Owner string `json:"owner,omitempty"` - ClientID string `json:"client,omitempty"` - GroupID string `json:"group,omitempty"` - Actions []string `json:"actions,omitempty"` + token string + Subject string `json:"subject,omitempty"` + Object string `json:"object,omitempty"` + Actions []string `json:"actions,omitempty"` } func (req createPolicyReq) validate() error { if req.token == "" { return apiutil.ErrBearerToken } - if req.GroupID == "" || req.ClientID == "" { + if req.Object == "" || req.Subject == "" { return apiutil.ErrMissingID } return nil } type createPoliciesReq struct { - token string - Owner string `json:"owner,omitempty"` - ClientIDs []string `json:"client_ids,omitempty"` - GroupIDs []string `json:"group_ids,omitempty"` - Actions []string `json:"actions,omitempty"` + token string + Subjects []string `json:"subjects,omitempty"` + Objects []string `json:"objects,omitempty"` + Actions []string `json:"actions,omitempty"` } func (req createPoliciesReq) validate() error { @@ -39,16 +37,16 @@ func (req createPoliciesReq) validate() error { return apiutil.ErrBearerToken } - if len(req.GroupIDs) == 0 || len(req.ClientIDs) == 0 { + if len(req.Objects) == 0 || len(req.Subjects) == 0 { return apiutil.ErrEmptyList } - for _, chID := range req.GroupIDs { - if chID == "" { + for _, channelID := range req.Objects { + if channelID == "" { return apiutil.ErrMissingID } } - for _, thingID := range req.ClientIDs { + for _, thingID := range req.Subjects { if thingID == "" { return apiutil.ErrMissingID } @@ -57,11 +55,11 @@ func (req createPoliciesReq) validate() error { } type identifyReq struct { - Secret string `json:"token"` + secret string } func (req identifyReq) validate() error { - if req.Secret == "" { + if req.secret == "" { return apiutil.ErrMissingSecret } @@ -69,8 +67,8 @@ func (req identifyReq) validate() error { } type authorizeReq struct { - Subject string `json:"secret"` - Object string + Subject string `json:"subject"` + Object string `json:"object"` Action string `json:"action"` EntityType string `json:"entity_type"` } diff --git a/things/policies/api/http/responses.go b/things/policies/api/http/responses.go index c580d26632..cca9d422e8 100644 --- a/things/policies/api/http/responses.go +++ b/things/policies/api/http/responses.go @@ -11,93 +11,149 @@ import ( ) var ( - _ mainflux.Response = (*policyRes)(nil) - _ mainflux.Response = (*listPolicyRes)(nil) _ mainflux.Response = (*identityRes)(nil) _ mainflux.Response = (*authorizeRes)(nil) + _ mainflux.Response = (*addPolicyRes)(nil) + _ mainflux.Response = (*viewPolicyRes)(nil) + _ mainflux.Response = (*listPolicyRes)(nil) + _ mainflux.Response = (*updatePolicyRes)(nil) _ mainflux.Response = (*deletePolicyRes)(nil) ) -type policyRes struct { - Policies []policies.Policy `json:"policies"` - created bool +type pageRes struct { + Limit uint64 `json:"limit"` + Offset uint64 `json:"offset"` + Total uint64 `json:"total"` } -func (res policyRes) Code() int { - if res.created { - return http.StatusCreated +type authorizeRes struct { + ThingID string `json:"thing_id"` + Authorized bool `json:"authorized"` +} + +func (res authorizeRes) Code() int { + if !res.Authorized { + return http.StatusForbidden } return http.StatusOK } -func (res policyRes) Headers() map[string]string { +func (res authorizeRes) Headers() map[string]string { return map[string]string{} } -func (res policyRes) Empty() bool { +func (res authorizeRes) Empty() bool { return false } -type listPolicyRes struct { - policies.PolicyPage +type identityRes struct { + ID string `json:"id"` } -func (res listPolicyRes) Code() int { +func (res identityRes) Code() int { return http.StatusOK } -func (res listPolicyRes) Headers() map[string]string { +func (res identityRes) Headers() map[string]string { return map[string]string{} } -func (res listPolicyRes) Empty() bool { +func (res identityRes) Empty() bool { return false } -type deletePolicyRes struct{} +type addPolicyRes struct { + created bool + policies.Policy `json:",inline"` +} -func (res deletePolicyRes) Code() int { - return http.StatusNoContent +func (res addPolicyRes) Code() int { + if res.created { + return http.StatusCreated + } + + return http.StatusBadRequest } -func (res deletePolicyRes) Headers() map[string]string { +func (res addPolicyRes) Headers() map[string]string { return map[string]string{} } -func (res deletePolicyRes) Empty() bool { +func (res addPolicyRes) Empty() bool { return true } -type identityRes struct { - ID string `json:"id"` +type viewPolicyRes struct { + policies.Policy `json:",inline"` } -func (res identityRes) Code() int { +func (res viewPolicyRes) Code() int { return http.StatusOK } -func (res identityRes) Headers() map[string]string { +func (res viewPolicyRes) Headers() map[string]string { return map[string]string{} } -func (res identityRes) Empty() bool { +func (res viewPolicyRes) Empty() bool { return false } -type authorizeRes struct { - ThingID string `json:"thing_id"` - Authorized bool `json:"authorized"` +type updatePolicyRes struct { + updated bool + policies.Policy `json:",inline"` } -func (res authorizeRes) Code() int { +func (res updatePolicyRes) Code() int { + if res.updated { + return http.StatusNoContent + } + + return http.StatusBadRequest +} + +func (res updatePolicyRes) Headers() map[string]string { + return map[string]string{} +} + +func (res updatePolicyRes) Empty() bool { + return true +} + +type listPolicyRes struct { + pageRes + Policies []viewPolicyRes `json:"policies"` +} + +func (res listPolicyRes) Code() int { return http.StatusOK } -func (res authorizeRes) Headers() map[string]string { +func (res listPolicyRes) Headers() map[string]string { return map[string]string{} } -func (res authorizeRes) Empty() bool { +func (res listPolicyRes) Empty() bool { + return false +} + +type deletePolicyRes struct { + deleted bool +} + +func (res deletePolicyRes) Code() int { + if res.deleted { + return http.StatusNoContent + } + + return http.StatusBadRequest +} + +func (res deletePolicyRes) Headers() map[string]string { + return map[string]string{} +} + +func (res deletePolicyRes) Empty() bool { return true } diff --git a/things/policies/api/http/transport.go b/things/policies/api/http/transport.go index cb1817fafc..4c9b31c34b 100644 --- a/things/policies/api/http/transport.go +++ b/things/policies/api/http/transport.go @@ -25,75 +25,74 @@ func MakeHandler(csvc clients.Service, psvc policies.Service, mux *bone.Mux, log opts := []kithttp.ServerOption{ kithttp.ServerErrorEncoder(apiutil.LoggingErrorEncoder(logger, api.EncodeError)), } - mux.Post("/connect", kithttp.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("connect"))(connectThingsEndpoint(psvc)), - decodeConnectList, + mux.Post("/channels/:chanID/access", kithttp.NewServer( + otelkit.EndpointMiddleware(otelkit.WithOperation("authorize"))(authorizeEndpoint(psvc)), + decodeCanAccess, api.EncodeResponse, opts..., )) - mux.Post("/disconnect", kithttp.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("disconnect"))(disconnectThingsEndpoint(psvc)), - decodeConnectList, + mux.Post("/identify", kithttp.NewServer( + otelkit.EndpointMiddleware(otelkit.WithOperation("identify"))(identifyEndpoint(csvc)), + decodeIdentify, api.EncodeResponse, opts..., )) - mux.Post("/channels/:chanID/things/:thingID", kithttp.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("connect_thing"))(connectEndpoint(psvc)), + mux.Post("/policies", kithttp.NewServer( + otelkit.EndpointMiddleware(otelkit.WithOperation("connect"))(connectEndpoint(psvc)), decodeConnectThing, api.EncodeResponse, opts..., )) - mux.Delete("/channels/:chanID/things/:thingID", kithttp.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("disconnect_thing"))(disconnectEndpoint(psvc)), - decodeDisconnectThing, + mux.Put("/policies", kithttp.NewServer( + otelkit.EndpointMiddleware(otelkit.WithOperation("update_policy"))(updatePolicyEndpoint(psvc)), + decodeUpdatePolicy, api.EncodeResponse, opts..., )) - mux.Post("/identify", kithttp.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("identify"))(identifyEndpoint(csvc)), - decodeIdentify, + mux.Get("/policies", kithttp.NewServer( + otelkit.EndpointMiddleware(otelkit.WithOperation("list_policies"))(listPoliciesEndpoint(psvc)), + decodeListPolicies, api.EncodeResponse, opts..., )) - mux.Put("/things/policies", kithttp.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("update_policy"))(updatePolicyEndpoint(psvc)), - decodeUpdatePolicy, + mux.Delete("/policies/:subject/:object", kithttp.NewServer( + otelkit.EndpointMiddleware(otelkit.WithOperation("disconnect"))(disconnectEndpoint(psvc)), + decodeDisconnectThing, api.EncodeResponse, opts..., )) - mux.Get("/things/policies", kithttp.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("list_policies"))(listPoliciesEndpoint(psvc)), - decodeListPolicies, + mux.Post("/connect", kithttp.NewServer( + otelkit.EndpointMiddleware(otelkit.WithOperation("bulk_connect"))(connectThingsEndpoint(psvc)), + decodeConnectList, api.EncodeResponse, opts..., )) - mux.Post("/channels/:chanID/access", kithttp.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("authorize"))(authorizeEndpoint(psvc)), - decodeCanAccess, + mux.Post("/disconnect", kithttp.NewServer( + otelkit.EndpointMiddleware(otelkit.WithOperation("bulk_disconnect"))(disconnectThingsEndpoint(psvc)), + decodeConnectList, api.EncodeResponse, opts..., )) + return mux } func decodeConnectThing(_ context.Context, r *http.Request) (interface{}, error) { - req := createPolicyReq{ - token: apiutil.ExtractBearerToken(r), - GroupID: bone.GetValue(r, "chanID"), - ClientID: bone.GetValue(r, "thingID"), + if !strings.Contains(r.Header.Get("Content-Type"), api.ContentType) { + return nil, errors.ErrUnsupportedContentType } - if r.Body != http.NoBody { - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - return nil, errors.Wrap(errors.ErrMalformedEntity, err) - } + + req := createPolicyReq{token: apiutil.ExtractBearerToken(r)} + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + return nil, errors.Wrap(errors.ErrMalformedEntity, err) } return req, nil @@ -101,14 +100,9 @@ func decodeConnectThing(_ context.Context, r *http.Request) (interface{}, error) func decodeDisconnectThing(_ context.Context, r *http.Request) (interface{}, error) { req := createPolicyReq{ - token: apiutil.ExtractBearerToken(r), - GroupID: bone.GetValue(r, "chanID"), - ClientID: bone.GetValue(r, "thingID"), - } - if r.Body != http.NoBody { - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - return nil, errors.Wrap(errors.ErrMalformedEntity, err) - } + token: apiutil.ExtractBearerToken(r), + Subject: bone.GetValue(r, api.SubjectKey), + Object: bone.GetValue(r, api.ObjectKey), } return req, nil @@ -131,7 +125,7 @@ func decodeIdentify(_ context.Context, r *http.Request) (interface{}, error) { return nil, errors.ErrUnsupportedContentType } - req := identifyReq{Secret: apiutil.ExtractThingKey(r)} + req := identifyReq{secret: apiutil.ExtractThingKey(r)} return req, nil } @@ -141,9 +135,7 @@ func decodeCanAccess(_ context.Context, r *http.Request) (interface{}, error) { return nil, errors.ErrUnsupportedContentType } - req := authorizeReq{ - Object: bone.GetValue(r, "chanID"), - } + req := authorizeReq{Object: bone.GetValue(r, "chanID")} if err := json.NewDecoder(r.Body).Decode(&req); err != nil { return nil, errors.Wrap(errors.ErrMalformedEntity, err) } diff --git a/things/policies/auth.pb.go b/things/policies/auth.pb.go index 0c744a152d..d6df052eba 100644 --- a/things/policies/auth.pb.go +++ b/things/policies/auth.pb.go @@ -28,9 +28,9 @@ type AuthorizeReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Sub string `protobuf:"bytes,1,opt,name=sub,proto3" json:"sub,omitempty"` - Obj string `protobuf:"bytes,2,opt,name=obj,proto3" json:"obj,omitempty"` - Act string `protobuf:"bytes,3,opt,name=act,proto3" json:"act,omitempty"` + Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"` + Object string `protobuf:"bytes,2,opt,name=object,proto3" json:"object,omitempty"` + Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"` EntityType string `protobuf:"bytes,4,opt,name=entityType,proto3" json:"entityType,omitempty"` } @@ -66,23 +66,23 @@ func (*AuthorizeReq) Descriptor() ([]byte, []int) { return file_things_policies_auth_proto_rawDescGZIP(), []int{0} } -func (x *AuthorizeReq) GetSub() string { +func (x *AuthorizeReq) GetSubject() string { if x != nil { - return x.Sub + return x.Subject } return "" } -func (x *AuthorizeReq) GetObj() string { +func (x *AuthorizeReq) GetObject() string { if x != nil { - return x.Obj + return x.Object } return "" } -func (x *AuthorizeReq) GetAct() string { +func (x *AuthorizeReq) GetAction() string { if x != nil { - return x.Act + return x.Action } return "" } @@ -149,19 +149,16 @@ func (x *AuthorizeRes) GetAuthorized() bool { return false } -// If a key is not carrying any information itself, the type -// field can be used to determine how to validate the token. -// Also, different tokens can be encoded in different ways. -type Key struct { +type IdentifyReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret,omitempty"` } -func (x *Key) Reset() { - *x = Key{} +func (x *IdentifyReq) Reset() { + *x = IdentifyReq{} if protoimpl.UnsafeEnabled { mi := &file_things_policies_auth_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -169,13 +166,13 @@ func (x *Key) Reset() { } } -func (x *Key) String() string { +func (x *IdentifyReq) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Key) ProtoMessage() {} +func (*IdentifyReq) ProtoMessage() {} -func (x *Key) ProtoReflect() protoreflect.Message { +func (x *IdentifyReq) ProtoReflect() protoreflect.Message { mi := &file_things_policies_auth_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -187,28 +184,28 @@ func (x *Key) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Key.ProtoReflect.Descriptor instead. -func (*Key) Descriptor() ([]byte, []int) { +// Deprecated: Use IdentifyReq.ProtoReflect.Descriptor instead. +func (*IdentifyReq) Descriptor() ([]byte, []int) { return file_things_policies_auth_proto_rawDescGZIP(), []int{2} } -func (x *Key) GetValue() string { +func (x *IdentifyReq) GetSecret() string { if x != nil { - return x.Value + return x.Secret } return "" } -type ClientID struct { +type IdentifyRes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` } -func (x *ClientID) Reset() { - *x = ClientID{} +func (x *IdentifyRes) Reset() { + *x = IdentifyRes{} if protoimpl.UnsafeEnabled { mi := &file_things_policies_auth_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -216,13 +213,13 @@ func (x *ClientID) Reset() { } } -func (x *ClientID) String() string { +func (x *IdentifyRes) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ClientID) ProtoMessage() {} +func (*IdentifyRes) ProtoMessage() {} -func (x *ClientID) ProtoReflect() protoreflect.Message { +func (x *IdentifyRes) ProtoReflect() protoreflect.Message { mi := &file_things_policies_auth_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -234,14 +231,14 @@ func (x *ClientID) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ClientID.ProtoReflect.Descriptor instead. -func (*ClientID) Descriptor() ([]byte, []int) { +// Deprecated: Use IdentifyRes.ProtoReflect.Descriptor instead. +func (*IdentifyRes) Descriptor() ([]byte, []int) { return file_things_policies_auth_proto_rawDescGZIP(), []int{3} } -func (x *ClientID) GetValue() string { +func (x *IdentifyRes) GetId() string { if x != nil { - return x.Value + return x.Id } return "" } @@ -252,35 +249,38 @@ var file_things_policies_auth_proto_rawDesc = []byte{ 0x0a, 0x1a, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x75, 0x62, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x62, 0x6a, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x62, 0x6a, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1e, 0x0a, 0x0a, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x22, 0x48, 0x0a, 0x0c, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x74, 0x68, 0x69, 0x6e, 0x67, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, - 0x68, 0x69, 0x6e, 0x67, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x1b, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x20, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x32, 0xbf, 0x01, 0x0a, 0x0d, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x65, 0x12, 0x26, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, - 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x26, 0x2e, 0x6d, - 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x65, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x79, 0x12, 0x1d, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x74, 0x68, - 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x4b, 0x65, - 0x79, 0x1a, 0x22, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x74, 0x68, 0x69, - 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x49, 0x44, 0x22, 0x00, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x69, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0x78, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, + 0x22, 0x48, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x25, 0x0a, 0x0b, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x22, 0x1d, 0x0a, 0x0b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x32, 0xc8, 0x01, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x5d, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x12, 0x26, 0x2e, + 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x26, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, + 0x2e, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, + 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, + 0x5a, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x25, 0x2e, 0x6d, 0x61, + 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, + 0x65, 0x71, 0x1a, 0x25, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x74, 0x68, + 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, + 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -299,14 +299,14 @@ var file_things_policies_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_things_policies_auth_proto_goTypes = []interface{}{ (*AuthorizeReq)(nil), // 0: mainflux.things.policies.AuthorizeReq (*AuthorizeRes)(nil), // 1: mainflux.things.policies.AuthorizeRes - (*Key)(nil), // 2: mainflux.things.policies.Key - (*ClientID)(nil), // 3: mainflux.things.policies.ClientID + (*IdentifyReq)(nil), // 2: mainflux.things.policies.IdentifyReq + (*IdentifyRes)(nil), // 3: mainflux.things.policies.IdentifyRes } var file_things_policies_auth_proto_depIdxs = []int32{ - 0, // 0: mainflux.things.policies.ThingsService.Authorize:input_type -> mainflux.things.policies.AuthorizeReq - 2, // 1: mainflux.things.policies.ThingsService.Identify:input_type -> mainflux.things.policies.Key - 1, // 2: mainflux.things.policies.ThingsService.Authorize:output_type -> mainflux.things.policies.AuthorizeRes - 3, // 3: mainflux.things.policies.ThingsService.Identify:output_type -> mainflux.things.policies.ClientID + 0, // 0: mainflux.things.policies.AuthService.Authorize:input_type -> mainflux.things.policies.AuthorizeReq + 2, // 1: mainflux.things.policies.AuthService.Identify:input_type -> mainflux.things.policies.IdentifyReq + 1, // 2: mainflux.things.policies.AuthService.Authorize:output_type -> mainflux.things.policies.AuthorizeRes + 3, // 3: mainflux.things.policies.AuthService.Identify:output_type -> mainflux.things.policies.IdentifyRes 2, // [2:4] is the sub-list for method output_type 0, // [0:2] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name @@ -345,7 +345,7 @@ func file_things_policies_auth_proto_init() { } } file_things_policies_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Key); i { + switch v := v.(*IdentifyReq); i { case 0: return &v.state case 1: @@ -357,7 +357,7 @@ func file_things_policies_auth_proto_init() { } } file_things_policies_auth_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClientID); i { + switch v := v.(*IdentifyRes); i { case 0: return &v.state case 1: diff --git a/things/policies/auth.proto b/things/policies/auth.proto index 0af03a731d..76f900a822 100644 --- a/things/policies/auth.proto +++ b/things/policies/auth.proto @@ -7,15 +7,20 @@ package mainflux.things.policies; option go_package = "./policies"; -service ThingsService { +// AuthService is a service that provides authentication and authorization +// functionalities for the things service. +service AuthService { + // Authorize checks if the subject is authorized to perform + // the action on the object. rpc Authorize(AuthorizeReq) returns (AuthorizeRes) {} - rpc Identify(Key) returns (ClientID) {} + // Identify returns the ID of the thing has the given secret. + rpc Identify(IdentifyReq) returns (IdentifyRes) {} } message AuthorizeReq { - string sub = 1; - string obj = 2; - string act = 3; + string subject = 1; + string object = 2; + string action = 3; string entityType = 4; } @@ -24,13 +29,10 @@ message AuthorizeRes { bool authorized = 2; } -// If a key is not carrying any information itself, the type -// field can be used to determine how to validate the token. -// Also, different tokens can be encoded in different ways. -message Key { - string value = 1; +message IdentifyReq { + string secret = 1; } -message ClientID { - string value = 1; -} \ No newline at end of file +message IdentifyRes { + string id = 1; +} diff --git a/things/policies/auth_grpc.pb.go b/things/policies/auth_grpc.pb.go index 0d62bb6adc..80e32336a8 100644 --- a/things/policies/auth_grpc.pb.go +++ b/things/policies/auth_grpc.pb.go @@ -22,126 +22,132 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - ThingsService_Authorize_FullMethodName = "/mainflux.things.policies.ThingsService/Authorize" - ThingsService_Identify_FullMethodName = "/mainflux.things.policies.ThingsService/Identify" + AuthService_Authorize_FullMethodName = "/mainflux.things.policies.AuthService/Authorize" + AuthService_Identify_FullMethodName = "/mainflux.things.policies.AuthService/Identify" ) -// ThingsServiceClient is the client API for ThingsService service. +// AuthServiceClient is the client API for AuthService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type ThingsServiceClient interface { +type AuthServiceClient interface { + // Authorize checks if the subject is authorized to perform + // the action on the object. Authorize(ctx context.Context, in *AuthorizeReq, opts ...grpc.CallOption) (*AuthorizeRes, error) - Identify(ctx context.Context, in *Key, opts ...grpc.CallOption) (*ClientID, error) + // Identify returns the ID of the thing has the given secret. + Identify(ctx context.Context, in *IdentifyReq, opts ...grpc.CallOption) (*IdentifyRes, error) } -type thingsServiceClient struct { +type authServiceClient struct { cc grpc.ClientConnInterface } -func NewThingsServiceClient(cc grpc.ClientConnInterface) ThingsServiceClient { - return &thingsServiceClient{cc} +func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient { + return &authServiceClient{cc} } -func (c *thingsServiceClient) Authorize(ctx context.Context, in *AuthorizeReq, opts ...grpc.CallOption) (*AuthorizeRes, error) { +func (c *authServiceClient) Authorize(ctx context.Context, in *AuthorizeReq, opts ...grpc.CallOption) (*AuthorizeRes, error) { out := new(AuthorizeRes) - err := c.cc.Invoke(ctx, ThingsService_Authorize_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, AuthService_Authorize_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *thingsServiceClient) Identify(ctx context.Context, in *Key, opts ...grpc.CallOption) (*ClientID, error) { - out := new(ClientID) - err := c.cc.Invoke(ctx, ThingsService_Identify_FullMethodName, in, out, opts...) +func (c *authServiceClient) Identify(ctx context.Context, in *IdentifyReq, opts ...grpc.CallOption) (*IdentifyRes, error) { + out := new(IdentifyRes) + err := c.cc.Invoke(ctx, AuthService_Identify_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -// ThingsServiceServer is the server API for ThingsService service. -// All implementations must embed UnimplementedThingsServiceServer +// AuthServiceServer is the server API for AuthService service. +// All implementations must embed UnimplementedAuthServiceServer // for forward compatibility -type ThingsServiceServer interface { +type AuthServiceServer interface { + // Authorize checks if the subject is authorized to perform + // the action on the object. Authorize(context.Context, *AuthorizeReq) (*AuthorizeRes, error) - Identify(context.Context, *Key) (*ClientID, error) - mustEmbedUnimplementedThingsServiceServer() + // Identify returns the ID of the thing has the given secret. + Identify(context.Context, *IdentifyReq) (*IdentifyRes, error) + mustEmbedUnimplementedAuthServiceServer() } -// UnimplementedThingsServiceServer must be embedded to have forward compatible implementations. -type UnimplementedThingsServiceServer struct { +// UnimplementedAuthServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAuthServiceServer struct { } -func (UnimplementedThingsServiceServer) Authorize(context.Context, *AuthorizeReq) (*AuthorizeRes, error) { +func (UnimplementedAuthServiceServer) Authorize(context.Context, *AuthorizeReq) (*AuthorizeRes, error) { return nil, status.Errorf(codes.Unimplemented, "method Authorize not implemented") } -func (UnimplementedThingsServiceServer) Identify(context.Context, *Key) (*ClientID, error) { +func (UnimplementedAuthServiceServer) Identify(context.Context, *IdentifyReq) (*IdentifyRes, error) { return nil, status.Errorf(codes.Unimplemented, "method Identify not implemented") } -func (UnimplementedThingsServiceServer) mustEmbedUnimplementedThingsServiceServer() {} +func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {} -// UnsafeThingsServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ThingsServiceServer will +// UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AuthServiceServer will // result in compilation errors. -type UnsafeThingsServiceServer interface { - mustEmbedUnimplementedThingsServiceServer() +type UnsafeAuthServiceServer interface { + mustEmbedUnimplementedAuthServiceServer() } -func RegisterThingsServiceServer(s grpc.ServiceRegistrar, srv ThingsServiceServer) { - s.RegisterService(&ThingsService_ServiceDesc, srv) +func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) { + s.RegisterService(&AuthService_ServiceDesc, srv) } -func _ThingsService_Authorize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _AuthService_Authorize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthorizeReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ThingsServiceServer).Authorize(ctx, in) + return srv.(AuthServiceServer).Authorize(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ThingsService_Authorize_FullMethodName, + FullMethod: AuthService_Authorize_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ThingsServiceServer).Authorize(ctx, req.(*AuthorizeReq)) + return srv.(AuthServiceServer).Authorize(ctx, req.(*AuthorizeReq)) } return interceptor(ctx, in, info, handler) } -func _ThingsService_Identify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Key) +func _AuthService_Identify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(IdentifyReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ThingsServiceServer).Identify(ctx, in) + return srv.(AuthServiceServer).Identify(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ThingsService_Identify_FullMethodName, + FullMethod: AuthService_Identify_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ThingsServiceServer).Identify(ctx, req.(*Key)) + return srv.(AuthServiceServer).Identify(ctx, req.(*IdentifyReq)) } return interceptor(ctx, in, info, handler) } -// ThingsService_ServiceDesc is the grpc.ServiceDesc for ThingsService service. +// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) -var ThingsService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "mainflux.things.policies.ThingsService", - HandlerType: (*ThingsServiceServer)(nil), +var AuthService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "mainflux.things.policies.AuthService", + HandlerType: (*AuthServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Authorize", - Handler: _ThingsService_Authorize_Handler, + Handler: _AuthService_Authorize_Handler, }, { MethodName: "Identify", - Handler: _ThingsService_Identify_Handler, + Handler: _AuthService_Identify_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/things/policies/policies.go b/things/policies/policies.go index ffce4ad211..eee7eacc34 100644 --- a/things/policies/policies.go +++ b/things/policies/policies.go @@ -36,7 +36,7 @@ type AccessRequest struct { // PolicyPage contains a page of policies. type PolicyPage struct { Page - Policies []Policy + Policies []Policy `json:"policies"` } // Repository specifies an account persistence API. diff --git a/things/policies/postgres/policies.go b/things/policies/postgres/policies.go index 82d5c0c650..4746f79571 100644 --- a/things/policies/postgres/policies.go +++ b/things/policies/postgres/policies.go @@ -5,6 +5,7 @@ package postgres import ( "context" + "database/sql" "fmt" "strings" "time" @@ -29,8 +30,8 @@ func NewRepository(db postgres.Database) policies.Repository { } func (pr prepo) Save(ctx context.Context, policy policies.Policy) (policies.Policy, error) { - q := `INSERT INTO policies (owner_id, subject, object, actions, created_at, updated_at, updated_by) - VALUES (:owner_id, :subject, :object, :actions, :created_at, :updated_at, :updated_by) + q := `INSERT INTO policies (owner_id, subject, object, actions, created_at) + VALUES (:owner_id, :subject, :object, :actions, :created_at) ON CONFLICT (subject, object) DO UPDATE SET actions = :actions, updated_at = :updated_at, updated_by = :updated_by RETURNING owner_id, subject, object, actions, created_at, updated_at, updated_by;` @@ -159,7 +160,7 @@ func (pr prepo) Retrieve(ctx context.Context, pm policies.Page) (policies.Policy emq = fmt.Sprintf(" WHERE %s", strings.Join(query, " AND ")) } - q := fmt.Sprintf(`SELECT owner_id, subject, object, actions + q := fmt.Sprintf(`SELECT owner_id, subject, object, actions, created_at, updated_at, updated_by FROM policies %s ORDER BY updated_at LIMIT :limit OFFSET :offset;`, emq) dbPage, err := toDBPoliciesPage(pm) @@ -225,41 +226,55 @@ type dbPolicy struct { Object string `db:"object"` Actions pgtype.TextArray `db:"actions"` CreatedAt time.Time `db:"created_at"` - UpdatedAt time.Time `db:"updated_at"` - UpdatedBy string `db:"updated_by"` + UpdatedAt sql.NullTime `db:"updated_at,omitempty"` + UpdatedBy *string `db:"updated_by,omitempty"` } func toDBPolicy(p policies.Policy) (dbPolicy, error) { - var ps pgtype.TextArray - if err := ps.Set(p.Actions); err != nil { + var actions pgtype.TextArray + if err := actions.Set(p.Actions); err != nil { return dbPolicy{}, err } - + var updatedAt sql.NullTime + if !p.UpdatedAt.IsZero() { + updatedAt = sql.NullTime{Time: p.UpdatedAt, Valid: true} + } + var updatedBy *string + if p.UpdatedBy != "" { + updatedBy = &p.UpdatedBy + } return dbPolicy{ OwnerID: p.OwnerID, Subject: p.Subject, Object: p.Object, - Actions: ps, + Actions: actions, CreatedAt: p.CreatedAt, - UpdatedAt: p.UpdatedAt, - UpdatedBy: p.UpdatedBy, + UpdatedAt: updatedAt, + UpdatedBy: updatedBy, }, nil } func toPolicy(dbp dbPolicy) (policies.Policy, error) { - var ps []string + var actions []string for _, e := range dbp.Actions.Elements { - ps = append(ps, e.String) + actions = append(actions, e.String) + } + var updatedAt time.Time + if dbp.UpdatedAt.Valid { + updatedAt = dbp.UpdatedAt.Time + } + var updatedBy string + if dbp.UpdatedBy != nil { + updatedBy = *dbp.UpdatedBy } - return policies.Policy{ OwnerID: dbp.OwnerID, Subject: dbp.Subject, Object: dbp.Object, - Actions: ps, + Actions: actions, CreatedAt: dbp.CreatedAt, - UpdatedAt: dbp.UpdatedAt, - UpdatedBy: dbp.UpdatedBy, + UpdatedAt: updatedAt, + UpdatedBy: updatedBy, }, nil } diff --git a/things/policies/service.go b/things/policies/service.go index 15d6d0d873..6cdc6b9245 100644 --- a/things/policies/service.go +++ b/things/policies/service.go @@ -213,7 +213,7 @@ func (svc service) checkPolicy(ctx context.Context, clientID string, p Policy) e } func (svc service) identify(ctx context.Context, token string) (string, error) { - req := &upolicies.Token{Value: token} + req := &upolicies.IdentifyReq{Token: token} res, err := svc.auth.Identify(ctx, req) if err != nil { return "", errors.Wrap(errors.ErrAuthorization, err) @@ -224,9 +224,9 @@ func (svc service) identify(ctx context.Context, token string) (string, error) { func (svc service) checkAdmin(ctx context.Context, id string) error { // for checking admin rights policy object, action and entity type are not important req := &upolicies.AuthorizeReq{ - Sub: id, - Obj: thingsObjectKey, - Act: addPolicyAction, + Subject: id, + Object: thingsObjectKey, + Action: addPolicyAction, EntityType: GroupEntityType, } res, err := svc.auth.Authorize(ctx, req) diff --git a/twins/mocks/auth.go b/twins/mocks/auth.go index 2d2e7684b6..4ff43ef0d1 100644 --- a/twins/mocks/auth.go +++ b/twins/mocks/auth.go @@ -17,34 +17,18 @@ type authServiceClient struct { users map[string]string } -func (svc authServiceClient) ListPolicies(ctx context.Context, in *policies.ListPoliciesReq, opts ...grpc.CallOption) (*policies.ListPoliciesRes, error) { - panic("not implemented") -} - // NewAuthServiceClient creates mock of auth service. func NewAuthServiceClient(users map[string]string) policies.AuthServiceClient { return &authServiceClient{users} } -func (svc authServiceClient) Identify(ctx context.Context, in *policies.Token, opts ...grpc.CallOption) (*policies.UserIdentity, error) { - if id, ok := svc.users[in.Value]; ok { - return &policies.UserIdentity{Id: id}, nil +func (svc authServiceClient) Identify(ctx context.Context, req *policies.IdentifyReq, opts ...grpc.CallOption) (*policies.IdentifyRes, error) { + if id, ok := svc.users[req.GetToken()]; ok { + return &policies.IdentifyRes{Id: id}, nil } return nil, errors.ErrAuthentication } -func (svc *authServiceClient) Issue(ctx context.Context, in *policies.IssueReq, opts ...grpc.CallOption) (*policies.Token, error) { - return new(policies.Token), nil -} - func (svc *authServiceClient) Authorize(ctx context.Context, req *policies.AuthorizeReq, _ ...grpc.CallOption) (r *policies.AuthorizeRes, err error) { panic("not implemented") } - -func (svc authServiceClient) AddPolicy(ctx context.Context, in *policies.AddPolicyReq, opts ...grpc.CallOption) (*policies.AddPolicyRes, error) { - panic("not implemented") -} - -func (svc authServiceClient) DeletePolicy(ctx context.Context, in *policies.DeletePolicyReq, opts ...grpc.CallOption) (*policies.DeletePolicyRes, error) { - panic("not implemented") -} diff --git a/twins/service.go b/twins/service.go index 42200ca29d..acec271873 100644 --- a/twins/service.go +++ b/twins/service.go @@ -105,7 +105,7 @@ func (ts *twinsService) AddTwin(ctx context.Context, token string, twin Twin, de var b []byte defer ts.publish(ctx, &id, &err, crudOp["createSucc"], crudOp["createFail"], &b) - res, err := ts.auth.Identify(ctx, &policies.Token{Value: token}) + res, err := ts.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return Twin{}, err } @@ -148,7 +148,7 @@ func (ts *twinsService) UpdateTwin(ctx context.Context, token string, twin Twin, var id string defer ts.publish(ctx, &id, &err, crudOp["updateSucc"], crudOp["updateFail"], &b) - _, err = ts.auth.Identify(ctx, &policies.Token{Value: token}) + _, err = ts.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return errors.ErrAuthentication } @@ -198,7 +198,7 @@ func (ts *twinsService) ViewTwin(ctx context.Context, token, twinID string) (tw var b []byte defer ts.publish(ctx, &twinID, &err, crudOp["getSucc"], crudOp["getFail"], &b) - _, err = ts.auth.Identify(ctx, &policies.Token{Value: token}) + _, err = ts.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return Twin{}, err } @@ -217,7 +217,7 @@ func (ts *twinsService) RemoveTwin(ctx context.Context, token, twinID string) (e var b []byte defer ts.publish(ctx, &twinID, &err, crudOp["removeSucc"], crudOp["removeFail"], &b) - _, err = ts.auth.Identify(ctx, &policies.Token{Value: token}) + _, err = ts.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return errors.ErrAuthentication } @@ -230,7 +230,7 @@ func (ts *twinsService) RemoveTwin(ctx context.Context, token, twinID string) (e } func (ts *twinsService) ListTwins(ctx context.Context, token string, offset uint64, limit uint64, name string, metadata Metadata) (Page, error) { - res, err := ts.auth.Identify(ctx, &policies.Token{Value: token}) + res, err := ts.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return Page{}, errors.ErrAuthentication } @@ -239,7 +239,7 @@ func (ts *twinsService) ListTwins(ctx context.Context, token string, offset uint } func (ts *twinsService) ListStates(ctx context.Context, token string, offset uint64, limit uint64, twinID string) (StatesPage, error) { - _, err := ts.auth.Identify(ctx, &policies.Token{Value: token}) + _, err := ts.auth.Identify(ctx, &policies.IdentifyReq{Token: token}) if err != nil { return StatesPage{}, errors.ErrAuthentication } diff --git a/users/clients/api/logging.go b/users/clients/api/logging.go index 7bf7b517e1..9605e9564a 100644 --- a/users/clients/api/logging.go +++ b/users/clients/api/logging.go @@ -58,7 +58,7 @@ func (lm *loggingMiddleware) IssueToken(ctx context.Context, identity, secret st // If the request fails, it logs the error. func (lm *loggingMiddleware) RefreshToken(ctx context.Context, refreshToken string) (t jwt.Token, err error) { defer func(begin time.Time) { - message := fmt.Sprintf("Method refresh_token of type %s for token %s took %s to complete", t.AccessType, refreshToken, time.Since(begin)) + message := fmt.Sprintf("Method refresh_token of type %s for refresh token %s took %s to complete", t.AccessType, refreshToken, time.Since(begin)) if err != nil { lm.logger.Warn(fmt.Sprintf("%s with error: %s.", message, err)) return diff --git a/users/clients/mocks/authn.go b/users/clients/mocks/authn.go index 6675953337..f29a495adb 100644 --- a/users/clients/mocks/authn.go +++ b/users/clients/mocks/authn.go @@ -23,57 +23,25 @@ type authServiceMock struct { authz map[string][]SubjectSet } -func (svc authServiceMock) ListPolicies(ctx context.Context, in *policies.ListPoliciesReq, opts ...grpc.CallOption) (*policies.ListPoliciesRes, error) { - res := policies.ListPoliciesRes{} - for key := range svc.authz { - res.Objects = append(res.Objects, key) - } - return &res, nil -} - // NewAuthService creates mock of users service. func NewAuthService(users map[string]string, authzDB map[string][]SubjectSet) policies.AuthServiceClient { return &authServiceMock{users, authzDB} } -func (svc authServiceMock) Identify(ctx context.Context, in *policies.Token, opts ...grpc.CallOption) (*policies.UserIdentity, error) { - if id, ok := svc.users[in.Value]; ok { - return &policies.UserIdentity{Id: id}, nil - } - return nil, errors.ErrAuthentication -} - -func (svc authServiceMock) Issue(ctx context.Context, in *policies.IssueReq, opts ...grpc.CallOption) (*policies.Token, error) { - if id, ok := svc.users[in.GetEmail()]; ok { - return &policies.Token{Value: id}, nil +func (svc authServiceMock) Identify(ctx context.Context, req *policies.IdentifyReq, opts ...grpc.CallOption) (*policies.IdentifyRes, error) { + if id, ok := svc.users[req.GetToken()]; ok { + return &policies.IdentifyRes{Id: id}, nil } return nil, errors.ErrAuthentication } func (svc authServiceMock) Authorize(ctx context.Context, req *policies.AuthorizeReq, _ ...grpc.CallOption) (r *policies.AuthorizeRes, err error) { - for _, policy := range svc.authz[req.GetSub()] { + for _, policy := range svc.authz[req.GetSubject()] { for _, r := range policy.Relation { - if r == req.GetAct() && policy.Subject == req.GetObj() { + if r == req.GetAction() && policy.Subject == req.GetObject() { return &policies.AuthorizeRes{Authorized: true}, nil } } } return &policies.AuthorizeRes{Authorized: false}, nil } - -func (svc authServiceMock) AddPolicy(ctx context.Context, in *policies.AddPolicyReq, opts ...grpc.CallOption) (*policies.AddPolicyRes, error) { - if len(in.GetAct()) == 0 || in.GetObj() == "" || in.GetSub() == "" { - return &policies.AddPolicyRes{}, errors.ErrMalformedEntity - } - - svc.authz[in.GetSub()] = append(svc.authz[in.GetSub()], SubjectSet{Subject: in.GetSub(), Relation: in.GetAct()}) - return &policies.AddPolicyRes{Authorized: true}, nil -} - -func (svc authServiceMock) DeletePolicy(ctx context.Context, in *policies.DeletePolicyReq, opts ...grpc.CallOption) (*policies.DeletePolicyRes, error) { - if in.GetObj() == "" || in.GetSub() == "" { - return &policies.DeletePolicyRes{}, errors.ErrMalformedEntity - } - delete(svc.authz, in.GetSub()) - return &policies.DeletePolicyRes{Deleted: true}, nil -} diff --git a/users/policies/api/grpc/client.go b/users/policies/api/grpc/client.go index 788554245b..7659b45323 100644 --- a/users/policies/api/grpc/client.go +++ b/users/policies/api/grpc/client.go @@ -19,13 +19,9 @@ const svcName = "mainflux.users.policies.AuthService" var _ policies.AuthServiceClient = (*grpcClient)(nil) type grpcClient struct { - authorize endpoint.Endpoint - issue endpoint.Endpoint - identify endpoint.Endpoint - addPolicy endpoint.Endpoint - deletePolicy endpoint.Endpoint - listPolicies endpoint.Endpoint - timeout time.Duration + authorize endpoint.Endpoint + identify endpoint.Endpoint + timeout time.Duration } // NewClient returns new gRPC client instance. @@ -39,45 +35,13 @@ func NewClient(conn *grpc.ClientConn, timeout time.Duration) policies.AuthServic decodeAuthorizeResponse, policies.AuthorizeRes{}, ).Endpoint()), - issue: otelkit.EndpointMiddleware(otelkit.WithOperation("issue"))(kitgrpc.NewClient( - conn, - svcName, - "Issue", - encodeIssueRequest, - decodeIssueResponse, - policies.UserIdentity{}, - ).Endpoint()), identify: otelkit.EndpointMiddleware(otelkit.WithOperation("identify"))(kitgrpc.NewClient( conn, svcName, "Identify", encodeIdentifyRequest, decodeIdentifyResponse, - policies.UserIdentity{}, - ).Endpoint()), - addPolicy: otelkit.EndpointMiddleware(otelkit.WithOperation("add_policy"))(kitgrpc.NewClient( - conn, - svcName, - "AddPolicy", - encodeAddPolicyRequest, - decodeAddPolicyResponse, - policies.AddPolicyRes{}, - ).Endpoint()), - deletePolicy: otelkit.EndpointMiddleware(otelkit.WithOperation("delete_policy"))(kitgrpc.NewClient( - conn, - svcName, - "DeletePolicy", - encodeDeletePolicyRequest, - decodeDeletePolicyResponse, - policies.DeletePolicyRes{}, - ).Endpoint()), - listPolicies: otelkit.EndpointMiddleware(otelkit.WithOperation("list_policies"))(kitgrpc.NewClient( - conn, - svcName, - "ListPolicies", - encodeListPoliciesRequest, - decodeListPoliciesResponse, - policies.ListPoliciesRes{}, + policies.IdentifyRes{}, ).Endpoint()), timeout: timeout, @@ -87,157 +51,50 @@ func NewClient(conn *grpc.ClientConn, timeout time.Duration) policies.AuthServic func (client grpcClient) Authorize(ctx context.Context, req *policies.AuthorizeReq, _ ...grpc.CallOption) (r *policies.AuthorizeRes, err error) { ctx, close := context.WithTimeout(ctx, client.timeout) defer close() - areq := authReq{Act: req.GetAct(), Obj: req.GetObj(), Sub: req.GetSub(), EntityType: req.GetEntityType()} + areq := authReq{subject: req.GetSubject(), object: req.GetObject(), action: req.GetAction(), entityType: req.GetEntityType()} res, err := client.authorize(ctx, areq) if err != nil { return &policies.AuthorizeRes{}, err } - ar := res.(authorizeRes) - return &policies.AuthorizeRes{Authorized: ar.authorized}, err + ares := res.(authorizeRes) + return &policies.AuthorizeRes{Authorized: ares.authorized}, err } func decodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { res := grpcRes.(*policies.AuthorizeRes) - return authorizeRes{authorized: res.Authorized}, nil + return authorizeRes{authorized: res.GetAuthorized()}, nil } func encodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { req := grpcReq.(authReq) return &policies.AuthorizeReq{ - Sub: req.Sub, - Obj: req.Obj, - Act: req.Act, - EntityType: req.EntityType, + Subject: req.subject, + Object: req.object, + Action: req.action, + EntityType: req.entityType, }, nil } -func (client grpcClient) Issue(ctx context.Context, req *policies.IssueReq, _ ...grpc.CallOption) (*policies.Token, error) { - ctx, close := context.WithTimeout(ctx, client.timeout) - defer close() - ireq := issueReq{email: req.GetEmail(), password: req.GetPassword()} - res, err := client.issue(ctx, ireq) - if err != nil { - return nil, err - } - - ir := res.(identityRes) - return &policies.Token{Value: ir.id}, nil -} - -func encodeIssueRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(issueReq) - return &policies.IssueReq{Email: req.email, Password: req.password}, nil -} - -func decodeIssueResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*policies.UserIdentity) - return identityRes{id: res.GetId()}, nil -} - -func (client grpcClient) Identify(ctx context.Context, token *policies.Token, _ ...grpc.CallOption) (*policies.UserIdentity, error) { +func (client grpcClient) Identify(ctx context.Context, req *policies.IdentifyReq, _ ...grpc.CallOption) (*policies.IdentifyRes, error) { ctx, close := context.WithTimeout(ctx, client.timeout) defer close() - res, err := client.identify(ctx, identityReq{token: token.GetValue()}) + ireq, err := client.identify(ctx, identifyReq{token: req.GetToken()}) if err != nil { return nil, err } - ir := res.(identityRes) - return &policies.UserIdentity{Id: ir.id}, nil + ires := ireq.(identifyRes) + return &policies.IdentifyRes{Id: ires.id}, nil } func encodeIdentifyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(identityReq) - return &policies.Token{Value: req.token}, nil + req := grpcReq.(identifyReq) + return &policies.IdentifyReq{Token: req.token}, nil } func decodeIdentifyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*policies.UserIdentity) - return identityRes{id: res.GetId()}, nil -} - -func (client grpcClient) AddPolicy(ctx context.Context, in *policies.AddPolicyReq, opts ...grpc.CallOption) (*policies.AddPolicyRes, error) { - ctx, close := context.WithTimeout(ctx, client.timeout) - defer close() - areq := addPolicyReq{Token: in.GetToken(), Act: in.GetAct(), Obj: in.GetObj(), Sub: in.GetSub()} - res, err := client.addPolicy(ctx, areq) - if err != nil { - return &policies.AddPolicyRes{}, err - } - - apr := res.(addPolicyRes) - return &policies.AddPolicyRes{Authorized: apr.authorized}, err -} - -func decodeAddPolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*policies.AddPolicyRes) - return addPolicyRes{authorized: res.Authorized}, nil -} - -func encodeAddPolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(addPolicyReq) - return &policies.AddPolicyReq{ - Token: req.Token, - Sub: req.Sub, - Obj: req.Obj, - Act: req.Act, - }, nil -} - -func (client grpcClient) DeletePolicy(ctx context.Context, in *policies.DeletePolicyReq, opts ...grpc.CallOption) (*policies.DeletePolicyRes, error) { - ctx, close := context.WithTimeout(ctx, client.timeout) - defer close() - preq := policyReq{Token: in.GetToken(), Act: in.GetAct(), Obj: in.GetObj(), Sub: in.GetSub()} - res, err := client.deletePolicy(ctx, preq) - if err != nil { - return &policies.DeletePolicyRes{}, err - } - - dpr := res.(deletePolicyRes) - return &policies.DeletePolicyRes{Deleted: dpr.deleted}, err -} - -func decodeDeletePolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*policies.DeletePolicyRes) - return deletePolicyRes{deleted: res.GetDeleted()}, nil -} - -func encodeDeletePolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(policyReq) - return &policies.DeletePolicyReq{ - Token: req.Token, - Sub: req.Sub, - Obj: req.Obj, - Act: req.Act, - }, nil -} - -func (client grpcClient) ListPolicies(ctx context.Context, in *policies.ListPoliciesReq, opts ...grpc.CallOption) (*policies.ListPoliciesRes, error) { - ctx, close := context.WithTimeout(ctx, client.timeout) - defer close() - lreq := listPoliciesReq{Token: in.GetToken(), Obj: in.GetObj(), Act: in.GetAct(), Sub: in.GetSub()} - res, err := client.listPolicies(ctx, lreq) - if err != nil { - return &policies.ListPoliciesRes{}, err - } - - lpr := res.(listPoliciesRes) - return &policies.ListPoliciesRes{Objects: lpr.objects}, err -} - -func decodeListPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*policies.ListPoliciesRes) - return listPoliciesRes{objects: res.GetObjects()}, nil -} - -func encodeListPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(listPoliciesReq) - return &policies.ListPoliciesReq{ - Token: req.Token, - Sub: req.Sub, - Obj: req.Obj, - Act: req.Act, - }, nil + res := grpcRes.(*policies.IdentifyRes) + return identifyRes{id: res.GetId()}, nil } diff --git a/users/policies/api/grpc/endpoint.go b/users/policies/api/grpc/endpoint.go index aaf4a04a67..324b430cc2 100644 --- a/users/policies/api/grpc/endpoint.go +++ b/users/policies/api/grpc/endpoint.go @@ -18,7 +18,7 @@ func authorizeEndpoint(svc policies.Service) endpoint.Endpoint { if err := req.validate(); err != nil { return authorizeRes{}, err } - aReq := policies.AccessRequest{Subject: req.Sub, Object: req.Obj, Action: req.Act, Entity: req.EntityType} + aReq := policies.AccessRequest{Subject: req.subject, Object: req.object, Action: req.action, Entity: req.entityType} err := svc.Authorize(ctx, aReq) if err != nil { return authorizeRes{}, err @@ -27,84 +27,21 @@ func authorizeEndpoint(svc policies.Service) endpoint.Endpoint { } } -func issueEndpoint(svc clients.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(issueReq) - if err := req.validate(); err != nil { - return issueRes{}, err - } - - tkn, err := svc.IssueToken(ctx, req.email, req.password) - if err != nil { - return issueRes{}, err - } - - return issueRes{value: tkn.AccessToken}, nil - } -} - func identifyEndpoint(svc clients.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(identityReq) + req := request.(identifyReq) if err := req.validate(); err != nil { - return identityRes{}, err + return identifyRes{}, err } id, err := svc.Identify(ctx, req.token) if err != nil { - return identityRes{}, err + return identifyRes{}, err } - ret := identityRes{ + ret := identifyRes{ id: id, } return ret, nil } } - -func addPolicyEndpoint(svc policies.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(addPolicyReq) - if err := req.validate(); err != nil { - return addPolicyRes{}, err - } - policy := policies.Policy{Subject: req.Sub, Object: req.Obj, Actions: req.Act} - err := svc.AddPolicy(ctx, req.Token, policy) - if err != nil { - return addPolicyRes{}, err - } - return addPolicyRes{authorized: true}, err - } -} - -func deletePolicyEndpoint(svc policies.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(policyReq) - if err := req.validate(); err != nil { - return deletePolicyRes{}, err - } - - policy := policies.Policy{Subject: req.Sub, Object: req.Obj, Actions: []string{req.Act}} - err := svc.DeletePolicy(ctx, req.Token, policy) - if err != nil { - return deletePolicyRes{}, err - } - return deletePolicyRes{deleted: true}, nil - } -} - -func listPoliciesEndpoint(svc policies.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(listPoliciesReq) - pp := policies.Page{Subject: req.Sub, Object: req.Obj, Action: req.Act, Limit: 10} - page, err := svc.ListPolicies(ctx, req.Token, pp) - if err != nil { - return listPoliciesRes{}, err - } - var objects []string - for _, p := range page.Policies { - objects = append(objects, p.Object) - } - return listPoliciesRes{objects: objects}, nil - } -} diff --git a/users/policies/api/grpc/requests.go b/users/policies/api/grpc/requests.go index 25d4b63e01..e3a7287e10 100644 --- a/users/policies/api/grpc/requests.go +++ b/users/policies/api/grpc/requests.go @@ -13,108 +13,37 @@ import ( // 3. action - type of action that will be executed (read/write) // 4. entity_type - type of entity (client, group, computation, dataset). type authReq struct { - Sub string - Obj string - Act string - EntityType string + subject string + object string + action string + entityType string } func (req authReq) validate() error { - if req.Sub == "" { + if req.subject == "" { return apiutil.ErrMissingPolicySub } - if req.Obj == "" { + if req.object == "" { return apiutil.ErrMissingPolicyObj } - if req.Act == "" { + if req.action == "" { return apiutil.ErrMalformedPolicyAct } - if req.EntityType == "" { + if req.entityType == "" { return apiutil.ErrMissingPolicyEntityType } return nil } -type identityReq struct { +type identifyReq struct { token string } -func (req identityReq) validate() error { +func (req identifyReq) validate() error { if req.token == "" { return apiutil.ErrBearerToken } return nil } - -type issueReq struct { - email string - password string -} - -func (req issueReq) validate() error { - if req.email == "" { - return apiutil.ErrMissingEmail - } - if req.password == "" { - return apiutil.ErrMissingPass - } - return nil -} - -type addPolicyReq struct { - Token string - Sub string - Obj string - Act []string -} - -func (req addPolicyReq) validate() error { - if req.Token == "" { - return apiutil.ErrBearerToken - } - if req.Sub == "" { - return apiutil.ErrMissingPolicySub - } - - if req.Obj == "" { - return apiutil.ErrMissingPolicyObj - } - - if len(req.Act) == 0 { - return apiutil.ErrMalformedPolicyAct - } - - return nil -} - -type policyReq struct { - Token string - Sub string - Obj string - Act string -} - -func (req policyReq) validate() error { - if req.Sub == "" { - return apiutil.ErrMissingPolicySub - } - - if req.Obj == "" { - return apiutil.ErrMissingPolicyObj - } - - if req.Act == "" { - return apiutil.ErrMalformedPolicyAct - } - - return nil -} - -type listPoliciesReq struct { - Token string - Sub string - Obj string - Act string -} diff --git a/users/policies/api/grpc/responses.go b/users/policies/api/grpc/responses.go index 3cff801379..806d797ce7 100644 --- a/users/policies/api/grpc/responses.go +++ b/users/policies/api/grpc/responses.go @@ -7,22 +7,6 @@ type authorizeRes struct { authorized bool } -type identityRes struct { +type identifyRes struct { id string } - -type issueRes struct { - value string -} - -type addPolicyRes struct { - authorized bool -} - -type deletePolicyRes struct { - deleted bool -} - -type listPoliciesRes struct { - objects []string -} diff --git a/users/policies/api/grpc/transport.go b/users/policies/api/grpc/transport.go index 424214d082..4c20e39119 100644 --- a/users/policies/api/grpc/transport.go +++ b/users/policies/api/grpc/transport.go @@ -19,12 +19,8 @@ import ( var _ policies.AuthServiceServer = (*grpcServer)(nil) type grpcServer struct { - authorize kitgrpc.Handler - issue kitgrpc.Handler - identify kitgrpc.Handler - addPolicy kitgrpc.Handler - deletePolicy kitgrpc.Handler - listPolicies kitgrpc.Handler + authorize kitgrpc.Handler + identify kitgrpc.Handler policies.UnimplementedAuthServiceServer } @@ -36,31 +32,11 @@ func NewServer(csvc clients.Service, psvc policies.Service) policies.AuthService decodeAuthorizeRequest, encodeAuthorizeResponse, ), - issue: kitgrpc.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("issue"))(issueEndpoint(csvc)), - decodeIssueRequest, - encodeIssueResponse, - ), identify: kitgrpc.NewServer( otelkit.EndpointMiddleware(otelkit.WithOperation("identify"))(identifyEndpoint(csvc)), decodeIdentifyRequest, encodeIdentifyResponse, ), - addPolicy: kitgrpc.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("add_policy"))(addPolicyEndpoint(psvc)), - decodeAddPolicyRequest, - encodeAddPolicyResponse, - ), - deletePolicy: kitgrpc.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("delete_policy"))(deletePolicyEndpoint(psvc)), - decodeDeletePolicyRequest, - encodeDeletePolicyResponse, - ), - listPolicies: kitgrpc.NewServer( - otelkit.EndpointMiddleware(otelkit.WithOperation("list_policies"))(listPoliciesEndpoint(psvc)), - decodeListPoliciesRequest, - encodeListPoliciesResponse, - ), } } @@ -72,49 +48,17 @@ func (s *grpcServer) Authorize(ctx context.Context, req *policies.AuthorizeReq) return res.(*policies.AuthorizeRes), nil } -func (s *grpcServer) Issue(ctx context.Context, req *policies.IssueReq) (*policies.Token, error) { - _, res, err := s.issue.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*policies.Token), nil -} - -func (s *grpcServer) Identify(ctx context.Context, token *policies.Token) (*policies.UserIdentity, error) { +func (s *grpcServer) Identify(ctx context.Context, token *policies.IdentifyReq) (*policies.IdentifyRes, error) { _, res, err := s.identify.ServeGRPC(ctx, token) if err != nil { return nil, encodeError(err) } - return res.(*policies.UserIdentity), nil -} - -func (s *grpcServer) AddPolicy(ctx context.Context, req *policies.AddPolicyReq) (*policies.AddPolicyRes, error) { - _, res, err := s.addPolicy.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*policies.AddPolicyRes), nil -} - -func (s *grpcServer) DeletePolicy(ctx context.Context, req *policies.DeletePolicyReq) (*policies.DeletePolicyRes, error) { - _, res, err := s.deletePolicy.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*policies.DeletePolicyRes), nil -} - -func (s *grpcServer) ListPolicies(ctx context.Context, req *policies.ListPoliciesReq) (*policies.ListPoliciesRes, error) { - _, res, err := s.listPolicies.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*policies.ListPoliciesRes), nil + return res.(*policies.IdentifyRes), nil } func decodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { req := grpcReq.(*policies.AuthorizeReq) - return authReq{Act: req.GetAct(), Obj: req.GetObj(), Sub: req.GetSub(), EntityType: req.GetEntityType()}, nil + return authReq{subject: req.GetSubject(), object: req.GetObject(), action: req.GetAction(), entityType: req.GetEntityType()}, nil } func encodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { @@ -122,54 +66,14 @@ func encodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{ return &policies.AuthorizeRes{Authorized: res.authorized}, nil } -func decodeIssueRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*policies.IssueReq) - return issueReq{email: req.GetEmail(), password: req.GetPassword()}, nil -} - -func encodeIssueResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(issueRes) - return &policies.Token{Value: res.value}, nil -} - func decodeIdentifyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*policies.Token) - return identityReq{token: req.GetValue()}, nil + req := grpcReq.(*policies.IdentifyReq) + return identifyReq{token: req.GetToken()}, nil } func encodeIdentifyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(identityRes) - return &policies.UserIdentity{Id: res.id}, nil -} - -func decodeAddPolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*policies.AddPolicyReq) - return addPolicyReq{Token: req.GetToken(), Sub: req.GetSub(), Obj: req.GetObj(), Act: req.GetAct()}, nil -} - -func encodeAddPolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(addPolicyRes) - return &policies.AddPolicyRes{Authorized: res.authorized}, nil -} - -func decodeDeletePolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*policies.DeletePolicyReq) - return policyReq{Token: req.GetToken(), Sub: req.GetSub(), Obj: req.GetObj(), Act: req.GetAct()}, nil -} - -func encodeDeletePolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(deletePolicyRes) - return &policies.DeletePolicyRes{Deleted: res.deleted}, nil -} - -func decodeListPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*policies.ListPoliciesReq) - return listPoliciesReq{Token: req.GetToken(), Sub: req.GetSub(), Obj: req.GetObj(), Act: req.GetAct()}, nil -} - -func encodeListPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(listPoliciesRes) - return &policies.ListPoliciesRes{Objects: res.objects}, nil + res := grpcRes.(identifyRes) + return &policies.IdentifyRes{Id: res.id}, nil } func encodeError(err error) error { diff --git a/users/policies/api/http/endpoints.go b/users/policies/api/http/endpoints.go index 755e43b5fc..424c70f303 100644 --- a/users/policies/api/http/endpoints.go +++ b/users/policies/api/http/endpoints.go @@ -14,7 +14,7 @@ func authorizeEndpoint(svc policies.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { req := request.(authorizeReq) if err := req.validate(); err != nil { - return authorizeRes{Authorized: false}, err + return authorizeRes{}, err } aReq := policies.AccessRequest{ Subject: req.Subject, @@ -24,10 +24,10 @@ func authorizeEndpoint(svc policies.Service) endpoint.Endpoint { } err := svc.Authorize(ctx, aReq) if err != nil { - return authorizeRes{Authorized: false}, err + return authorizeRes{}, err } - return authorizeRes{Authorized: true}, nil + return authorizeRes{authorized: true}, nil } } @@ -70,8 +70,7 @@ func updatePolicyEndpoint(svc policies.Service) endpoint.Endpoint { return updatePolicyRes{}, err } - res := updatePolicyRes{updated: false} - return res, nil + return updatePolicyRes{updated: true}, nil } } @@ -94,7 +93,7 @@ func listPolicyEndpoint(svc policies.Service) endpoint.Endpoint { if err != nil { return listPolicyRes{}, err } - return buildGroupsResponse(page), nil + return buildPoliciesResponse(page), nil } } @@ -112,22 +111,11 @@ func deletePolicyEndpoint(svc policies.Service) endpoint.Endpoint { return deletePolicyRes{}, err } - return deletePolicyRes{}, nil + return deletePolicyRes{deleted: true}, nil } } -func toViewPolicyRes(group policies.Policy) viewPolicyRes { - return viewPolicyRes{ - OwnerID: group.OwnerID, - Subject: group.Subject, - Object: group.Object, - Actions: group.Actions, - CreatedAt: group.CreatedAt, - UpdatedAt: group.UpdatedAt, - } -} - -func buildGroupsResponse(page policies.PolicyPage) listPolicyRes { +func buildPoliciesResponse(page policies.PolicyPage) listPolicyRes { res := listPolicyRes{ pageRes: pageRes{ Limit: page.Limit, @@ -137,8 +125,8 @@ func buildGroupsResponse(page policies.PolicyPage) listPolicyRes { Policies: []viewPolicyRes{}, } - for _, group := range page.Policies { - res.Policies = append(res.Policies, toViewPolicyRes(group)) + for _, policy := range page.Policies { + res.Policies = append(res.Policies, viewPolicyRes{policy}) } return res diff --git a/users/policies/api/http/responses.go b/users/policies/api/http/responses.go index 65bda7bb85..4eaee07427 100644 --- a/users/policies/api/http/responses.go +++ b/users/policies/api/http/responses.go @@ -5,9 +5,9 @@ package http import ( "net/http" - "time" "github.com/mainflux/mainflux" + "github.com/mainflux/mainflux/users/policies" ) var ( @@ -26,10 +26,14 @@ type pageRes struct { } type authorizeRes struct { - Authorized bool `json:"authorized"` + authorized bool } func (res authorizeRes) Code() int { + if !res.authorized { + return http.StatusForbidden + } + return http.StatusOK } @@ -50,7 +54,7 @@ func (res addPolicyRes) Code() int { return http.StatusCreated } - return http.StatusOK + return http.StatusBadRequest } func (res addPolicyRes) Headers() map[string]string { @@ -62,12 +66,7 @@ func (res addPolicyRes) Empty() bool { } type viewPolicyRes struct { - OwnerID string `json:"owner_id"` - Subject string `json:"subject"` - Object string `json:"object"` - Actions []string `json:"actions"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + policies.Policy `json:",inline"` } func (res viewPolicyRes) Code() int { @@ -87,7 +86,11 @@ type updatePolicyRes struct { } func (res updatePolicyRes) Code() int { - return http.StatusNoContent + if res.updated { + return http.StatusNoContent + } + + return http.StatusBadRequest } func (res updatePolicyRes) Headers() map[string]string { @@ -115,10 +118,16 @@ func (res listPolicyRes) Empty() bool { return false } -type deletePolicyRes struct{} +type deletePolicyRes struct { + deleted bool +} func (res deletePolicyRes) Code() int { - return http.StatusNoContent + if res.deleted { + return http.StatusNoContent + } + + return http.StatusBadRequest } func (res deletePolicyRes) Headers() map[string]string { diff --git a/users/policies/api/http/transport.go b/users/policies/api/http/transport.go index efb4981a66..e5da506401 100644 --- a/users/policies/api/http/transport.go +++ b/users/policies/api/http/transport.go @@ -159,8 +159,8 @@ func decodeListPoliciesRequest(_ context.Context, r *http.Request) (interface{}, func deletePolicyRequest(_ context.Context, r *http.Request) (interface{}, error) { req := deletePolicyReq{ token: apiutil.ExtractBearerToken(r), - Subject: bone.GetValue(r, "subject"), - Object: bone.GetValue(r, "object"), + Subject: bone.GetValue(r, api.SubjectKey), + Object: bone.GetValue(r, api.ObjectKey), } return req, nil diff --git a/users/policies/auth.pb.go b/users/policies/auth.pb.go index a2b3e87950..a0c5c24d9b 100644 --- a/users/policies/auth.pb.go +++ b/users/policies/auth.pb.go @@ -28,9 +28,9 @@ type AuthorizeReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Sub string `protobuf:"bytes,1,opt,name=sub,proto3" json:"sub,omitempty"` - Obj string `protobuf:"bytes,2,opt,name=obj,proto3" json:"obj,omitempty"` - Act string `protobuf:"bytes,3,opt,name=act,proto3" json:"act,omitempty"` + Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"` + Object string `protobuf:"bytes,2,opt,name=object,proto3" json:"object,omitempty"` + Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"` EntityType string `protobuf:"bytes,4,opt,name=entityType,proto3" json:"entityType,omitempty"` } @@ -66,23 +66,23 @@ func (*AuthorizeReq) Descriptor() ([]byte, []int) { return file_users_policies_auth_proto_rawDescGZIP(), []int{0} } -func (x *AuthorizeReq) GetSub() string { +func (x *AuthorizeReq) GetSubject() string { if x != nil { - return x.Sub + return x.Subject } return "" } -func (x *AuthorizeReq) GetObj() string { +func (x *AuthorizeReq) GetObject() string { if x != nil { - return x.Obj + return x.Object } return "" } -func (x *AuthorizeReq) GetAct() string { +func (x *AuthorizeReq) GetAction() string { if x != nil { - return x.Act + return x.Action } return "" } @@ -141,18 +141,16 @@ func (x *AuthorizeRes) GetAuthorized() bool { return false } -type IssueReq struct { +type IdentifyReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` - Type uint32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` } -func (x *IssueReq) Reset() { - *x = IssueReq{} +func (x *IdentifyReq) Reset() { + *x = IdentifyReq{} if protoimpl.UnsafeEnabled { mi := &file_users_policies_auth_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -160,13 +158,13 @@ func (x *IssueReq) Reset() { } } -func (x *IssueReq) String() string { +func (x *IdentifyReq) String() string { return protoimpl.X.MessageStringOf(x) } -func (*IssueReq) ProtoMessage() {} +func (*IdentifyReq) ProtoMessage() {} -func (x *IssueReq) ProtoReflect() protoreflect.Message { +func (x *IdentifyReq) ProtoReflect() protoreflect.Message { mi := &file_users_policies_auth_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -178,42 +176,28 @@ func (x *IssueReq) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use IssueReq.ProtoReflect.Descriptor instead. -func (*IssueReq) Descriptor() ([]byte, []int) { +// Deprecated: Use IdentifyReq.ProtoReflect.Descriptor instead. +func (*IdentifyReq) Descriptor() ([]byte, []int) { return file_users_policies_auth_proto_rawDescGZIP(), []int{2} } -func (x *IssueReq) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *IssueReq) GetPassword() string { +func (x *IdentifyReq) GetToken() string { if x != nil { - return x.Password + return x.Token } return "" } -func (x *IssueReq) GetType() uint32 { - if x != nil { - return x.Type - } - return 0 -} - -type Token struct { +type IdentifyRes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` } -func (x *Token) Reset() { - *x = Token{} +func (x *IdentifyRes) Reset() { + *x = IdentifyRes{} if protoimpl.UnsafeEnabled { mi := &file_users_policies_auth_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -221,13 +205,13 @@ func (x *Token) Reset() { } } -func (x *Token) String() string { +func (x *IdentifyRes) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Token) ProtoMessage() {} +func (*IdentifyRes) ProtoMessage() {} -func (x *Token) ProtoReflect() protoreflect.Message { +func (x *IdentifyRes) ProtoReflect() protoreflect.Message { mi := &file_users_policies_auth_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -239,507 +223,53 @@ func (x *Token) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Token.ProtoReflect.Descriptor instead. -func (*Token) Descriptor() ([]byte, []int) { +// Deprecated: Use IdentifyRes.ProtoReflect.Descriptor instead. +func (*IdentifyRes) Descriptor() ([]byte, []int) { return file_users_policies_auth_proto_rawDescGZIP(), []int{3} } -func (x *Token) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -type UserIdentity struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *UserIdentity) Reset() { - *x = UserIdentity{} - if protoimpl.UnsafeEnabled { - mi := &file_users_policies_auth_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UserIdentity) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserIdentity) ProtoMessage() {} - -func (x *UserIdentity) ProtoReflect() protoreflect.Message { - mi := &file_users_policies_auth_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UserIdentity.ProtoReflect.Descriptor instead. -func (*UserIdentity) Descriptor() ([]byte, []int) { - return file_users_policies_auth_proto_rawDescGZIP(), []int{4} -} - -func (x *UserIdentity) GetId() string { +func (x *IdentifyRes) GetId() string { if x != nil { return x.Id } return "" } -type AddPolicyReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` - Sub string `protobuf:"bytes,2,opt,name=sub,proto3" json:"sub,omitempty"` - Obj string `protobuf:"bytes,3,opt,name=obj,proto3" json:"obj,omitempty"` - Act []string `protobuf:"bytes,4,rep,name=act,proto3" json:"act,omitempty"` -} - -func (x *AddPolicyReq) Reset() { - *x = AddPolicyReq{} - if protoimpl.UnsafeEnabled { - mi := &file_users_policies_auth_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddPolicyReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddPolicyReq) ProtoMessage() {} - -func (x *AddPolicyReq) ProtoReflect() protoreflect.Message { - mi := &file_users_policies_auth_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddPolicyReq.ProtoReflect.Descriptor instead. -func (*AddPolicyReq) Descriptor() ([]byte, []int) { - return file_users_policies_auth_proto_rawDescGZIP(), []int{5} -} - -func (x *AddPolicyReq) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -func (x *AddPolicyReq) GetSub() string { - if x != nil { - return x.Sub - } - return "" -} - -func (x *AddPolicyReq) GetObj() string { - if x != nil { - return x.Obj - } - return "" -} - -func (x *AddPolicyReq) GetAct() []string { - if x != nil { - return x.Act - } - return nil -} - -type AddPolicyRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Authorized bool `protobuf:"varint,1,opt,name=authorized,proto3" json:"authorized,omitempty"` -} - -func (x *AddPolicyRes) Reset() { - *x = AddPolicyRes{} - if protoimpl.UnsafeEnabled { - mi := &file_users_policies_auth_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddPolicyRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddPolicyRes) ProtoMessage() {} - -func (x *AddPolicyRes) ProtoReflect() protoreflect.Message { - mi := &file_users_policies_auth_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddPolicyRes.ProtoReflect.Descriptor instead. -func (*AddPolicyRes) Descriptor() ([]byte, []int) { - return file_users_policies_auth_proto_rawDescGZIP(), []int{6} -} - -func (x *AddPolicyRes) GetAuthorized() bool { - if x != nil { - return x.Authorized - } - return false -} - -type DeletePolicyReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` - Sub string `protobuf:"bytes,2,opt,name=sub,proto3" json:"sub,omitempty"` - Obj string `protobuf:"bytes,3,opt,name=obj,proto3" json:"obj,omitempty"` - Act string `protobuf:"bytes,4,opt,name=act,proto3" json:"act,omitempty"` -} - -func (x *DeletePolicyReq) Reset() { - *x = DeletePolicyReq{} - if protoimpl.UnsafeEnabled { - mi := &file_users_policies_auth_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeletePolicyReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeletePolicyReq) ProtoMessage() {} - -func (x *DeletePolicyReq) ProtoReflect() protoreflect.Message { - mi := &file_users_policies_auth_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeletePolicyReq.ProtoReflect.Descriptor instead. -func (*DeletePolicyReq) Descriptor() ([]byte, []int) { - return file_users_policies_auth_proto_rawDescGZIP(), []int{7} -} - -func (x *DeletePolicyReq) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -func (x *DeletePolicyReq) GetSub() string { - if x != nil { - return x.Sub - } - return "" -} - -func (x *DeletePolicyReq) GetObj() string { - if x != nil { - return x.Obj - } - return "" -} - -func (x *DeletePolicyReq) GetAct() string { - if x != nil { - return x.Act - } - return "" -} - -type DeletePolicyRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Deleted bool `protobuf:"varint,1,opt,name=deleted,proto3" json:"deleted,omitempty"` -} - -func (x *DeletePolicyRes) Reset() { - *x = DeletePolicyRes{} - if protoimpl.UnsafeEnabled { - mi := &file_users_policies_auth_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeletePolicyRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeletePolicyRes) ProtoMessage() {} - -func (x *DeletePolicyRes) ProtoReflect() protoreflect.Message { - mi := &file_users_policies_auth_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeletePolicyRes.ProtoReflect.Descriptor instead. -func (*DeletePolicyRes) Descriptor() ([]byte, []int) { - return file_users_policies_auth_proto_rawDescGZIP(), []int{8} -} - -func (x *DeletePolicyRes) GetDeleted() bool { - if x != nil { - return x.Deleted - } - return false -} - -type ListPoliciesReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` - Sub string `protobuf:"bytes,2,opt,name=sub,proto3" json:"sub,omitempty"` - Obj string `protobuf:"bytes,3,opt,name=obj,proto3" json:"obj,omitempty"` - Act string `protobuf:"bytes,4,opt,name=act,proto3" json:"act,omitempty"` -} - -func (x *ListPoliciesReq) Reset() { - *x = ListPoliciesReq{} - if protoimpl.UnsafeEnabled { - mi := &file_users_policies_auth_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListPoliciesReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListPoliciesReq) ProtoMessage() {} - -func (x *ListPoliciesReq) ProtoReflect() protoreflect.Message { - mi := &file_users_policies_auth_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListPoliciesReq.ProtoReflect.Descriptor instead. -func (*ListPoliciesReq) Descriptor() ([]byte, []int) { - return file_users_policies_auth_proto_rawDescGZIP(), []int{9} -} - -func (x *ListPoliciesReq) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -func (x *ListPoliciesReq) GetSub() string { - if x != nil { - return x.Sub - } - return "" -} - -func (x *ListPoliciesReq) GetObj() string { - if x != nil { - return x.Obj - } - return "" -} - -func (x *ListPoliciesReq) GetAct() string { - if x != nil { - return x.Act - } - return "" -} - -type ListPoliciesRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Objects []string `protobuf:"bytes,1,rep,name=objects,proto3" json:"objects,omitempty"` -} - -func (x *ListPoliciesRes) Reset() { - *x = ListPoliciesRes{} - if protoimpl.UnsafeEnabled { - mi := &file_users_policies_auth_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListPoliciesRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListPoliciesRes) ProtoMessage() {} - -func (x *ListPoliciesRes) ProtoReflect() protoreflect.Message { - mi := &file_users_policies_auth_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListPoliciesRes.ProtoReflect.Descriptor instead. -func (*ListPoliciesRes) Descriptor() ([]byte, []int) { - return file_users_policies_auth_proto_rawDescGZIP(), []int{10} -} - -func (x *ListPoliciesRes) GetObjects() []string { - if x != nil { - return x.Objects - } - return nil -} - var File_users_policies_auth_proto protoreflect.FileDescriptor var file_users_policies_auth_proto_rawDesc = []byte{ 0x0a, 0x19, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x69, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x65, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x73, 0x75, 0x62, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x62, 0x6a, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x62, 0x6a, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2e, 0x0a, 0x0c, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x50, 0x0a, 0x08, 0x49, 0x73, - 0x73, 0x75, 0x65, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x1d, 0x0a, 0x05, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1e, 0x0a, 0x0c, 0x55, - 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5a, 0x0a, 0x0c, 0x41, - 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x73, 0x75, 0x62, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x62, 0x6a, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6f, 0x62, 0x6a, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x03, 0x61, 0x63, 0x74, 0x22, 0x2e, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x5d, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, - 0x75, 0x62, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x62, 0x6a, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6f, 0x62, 0x6a, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x61, 0x63, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x22, 0x5d, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, - 0x73, 0x75, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x75, 0x62, 0x12, 0x10, - 0x0a, 0x03, 0x6f, 0x62, 0x6a, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x62, 0x6a, - 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, - 0x63, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x32, - 0xb6, 0x04, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x5b, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x12, 0x25, 0x2e, 0x6d, - 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, - 0x52, 0x65, 0x71, 0x1a, 0x25, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x05, - 0x49, 0x73, 0x73, 0x75, 0x65, 0x12, 0x21, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, - 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, - 0x49, 0x73, 0x73, 0x75, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1e, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, - 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x08, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x1e, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, - 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x25, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, - 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x00, 0x12, - 0x5b, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x25, 0x2e, 0x6d, - 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x52, 0x65, 0x71, 0x1a, 0x25, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x41, 0x64, - 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x0c, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x28, 0x2e, 0x6d, - 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x28, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, - 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, - 0x22, 0x00, 0x12, 0x64, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x12, 0x28, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, - 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x28, 0x2e, 0x6d, - 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x69, 0x65, 0x73, 0x22, 0x78, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, + 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2e, + 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x12, 0x1e, + 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x23, + 0x0a, 0x0b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x1d, 0x0a, 0x0b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, + 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x32, 0xc4, 0x01, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x58, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x24, + 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x79, 0x52, 0x65, 0x71, 0x1a, 0x24, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x09, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x12, 0x25, 0x2e, 0x6d, 0x61, 0x69, 0x6e, + 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, + 0x1a, 0x25, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -754,38 +284,23 @@ func file_users_policies_auth_proto_rawDescGZIP() []byte { return file_users_policies_auth_proto_rawDescData } -var file_users_policies_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_users_policies_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_users_policies_auth_proto_goTypes = []interface{}{ - (*AuthorizeReq)(nil), // 0: mainflux.users.policies.AuthorizeReq - (*AuthorizeRes)(nil), // 1: mainflux.users.policies.AuthorizeRes - (*IssueReq)(nil), // 2: mainflux.users.policies.IssueReq - (*Token)(nil), // 3: mainflux.users.policies.Token - (*UserIdentity)(nil), // 4: mainflux.users.policies.UserIdentity - (*AddPolicyReq)(nil), // 5: mainflux.users.policies.AddPolicyReq - (*AddPolicyRes)(nil), // 6: mainflux.users.policies.AddPolicyRes - (*DeletePolicyReq)(nil), // 7: mainflux.users.policies.DeletePolicyReq - (*DeletePolicyRes)(nil), // 8: mainflux.users.policies.DeletePolicyRes - (*ListPoliciesReq)(nil), // 9: mainflux.users.policies.ListPoliciesReq - (*ListPoliciesRes)(nil), // 10: mainflux.users.policies.ListPoliciesRes + (*AuthorizeReq)(nil), // 0: mainflux.users.policies.AuthorizeReq + (*AuthorizeRes)(nil), // 1: mainflux.users.policies.AuthorizeRes + (*IdentifyReq)(nil), // 2: mainflux.users.policies.IdentifyReq + (*IdentifyRes)(nil), // 3: mainflux.users.policies.IdentifyRes } var file_users_policies_auth_proto_depIdxs = []int32{ - 0, // 0: mainflux.users.policies.AuthService.Authorize:input_type -> mainflux.users.policies.AuthorizeReq - 2, // 1: mainflux.users.policies.AuthService.Issue:input_type -> mainflux.users.policies.IssueReq - 3, // 2: mainflux.users.policies.AuthService.Identify:input_type -> mainflux.users.policies.Token - 5, // 3: mainflux.users.policies.AuthService.AddPolicy:input_type -> mainflux.users.policies.AddPolicyReq - 7, // 4: mainflux.users.policies.AuthService.DeletePolicy:input_type -> mainflux.users.policies.DeletePolicyReq - 9, // 5: mainflux.users.policies.AuthService.ListPolicies:input_type -> mainflux.users.policies.ListPoliciesReq - 1, // 6: mainflux.users.policies.AuthService.Authorize:output_type -> mainflux.users.policies.AuthorizeRes - 3, // 7: mainflux.users.policies.AuthService.Issue:output_type -> mainflux.users.policies.Token - 4, // 8: mainflux.users.policies.AuthService.Identify:output_type -> mainflux.users.policies.UserIdentity - 6, // 9: mainflux.users.policies.AuthService.AddPolicy:output_type -> mainflux.users.policies.AddPolicyRes - 8, // 10: mainflux.users.policies.AuthService.DeletePolicy:output_type -> mainflux.users.policies.DeletePolicyRes - 10, // 11: mainflux.users.policies.AuthService.ListPolicies:output_type -> mainflux.users.policies.ListPoliciesRes - 6, // [6:12] is the sub-list for method output_type - 0, // [0:6] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 2, // 0: mainflux.users.policies.AuthService.Identify:input_type -> mainflux.users.policies.IdentifyReq + 0, // 1: mainflux.users.policies.AuthService.Authorize:input_type -> mainflux.users.policies.AuthorizeReq + 3, // 2: mainflux.users.policies.AuthService.Identify:output_type -> mainflux.users.policies.IdentifyRes + 1, // 3: mainflux.users.policies.AuthService.Authorize:output_type -> mainflux.users.policies.AuthorizeRes + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_users_policies_auth_proto_init() } @@ -819,7 +334,7 @@ func file_users_policies_auth_proto_init() { } } file_users_policies_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IssueReq); i { + switch v := v.(*IdentifyReq); i { case 0: return &v.state case 1: @@ -831,91 +346,7 @@ func file_users_policies_auth_proto_init() { } } file_users_policies_auth_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Token); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_users_policies_auth_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserIdentity); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_users_policies_auth_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddPolicyReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_users_policies_auth_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddPolicyRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_users_policies_auth_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletePolicyReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_users_policies_auth_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletePolicyRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_users_policies_auth_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPoliciesReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_users_policies_auth_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPoliciesRes); i { + switch v := v.(*IdentifyRes); i { case 0: return &v.state case 1: @@ -933,7 +364,7 @@ func file_users_policies_auth_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_users_policies_auth_proto_rawDesc, NumEnums: 0, - NumMessages: 11, + NumMessages: 4, NumExtensions: 0, NumServices: 1, }, diff --git a/users/policies/auth.proto b/users/policies/auth.proto index 9e6668f51f..fbe31b4b49 100644 --- a/users/policies/auth.proto +++ b/users/policies/auth.proto @@ -7,19 +7,19 @@ package mainflux.users.policies; option go_package = "./policies"; +// AuthService is a service that provides authentication and authorization +// functionalities for the users service. service AuthService { + rpc Identify(IdentifyReq) returns (IdentifyRes) {} + // Authorize authorizes the given subject to perform the given action on the + // given object. rpc Authorize(AuthorizeReq) returns (AuthorizeRes) {} - rpc Issue(IssueReq) returns (Token) {} - rpc Identify(Token) returns (UserIdentity) {} - rpc AddPolicy(AddPolicyReq) returns (AddPolicyRes) {} - rpc DeletePolicy(DeletePolicyReq) returns (DeletePolicyRes) {} - rpc ListPolicies(ListPoliciesReq) returns (ListPoliciesRes) {} } message AuthorizeReq { - string sub = 1; - string obj = 2; - string act = 3; + string subject = 1; + string object = 2; + string action = 3; string entityType = 4; } @@ -27,49 +27,10 @@ message AuthorizeRes { bool authorized = 1; } -message IssueReq { - string email = 1; - string password = 2; - uint32 type = 3; -} - -message Token { - string value = 1; -} - -message UserIdentity { - string id = 1; -} - -message AddPolicyReq { - string token = 1; - string sub = 2; - string obj = 3; - repeated string act = 4; -} - -message AddPolicyRes { - bool authorized = 1; -} - -message DeletePolicyReq { - string token = 1; - string sub = 2; - string obj = 3; - string act = 4; -} - -message DeletePolicyRes { - bool deleted = 1; -} - -message ListPoliciesReq { +message IdentifyReq { string token = 1; - string sub = 2; - string obj = 3; - string act = 4; } -message ListPoliciesRes { - repeated string objects = 1; +message IdentifyRes { + string id = 1; } diff --git a/users/policies/auth_grpc.pb.go b/users/policies/auth_grpc.pb.go index 6ed001f6ba..cb8cb6778f 100644 --- a/users/policies/auth_grpc.pb.go +++ b/users/policies/auth_grpc.pb.go @@ -22,24 +22,18 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - AuthService_Authorize_FullMethodName = "/mainflux.users.policies.AuthService/Authorize" - AuthService_Issue_FullMethodName = "/mainflux.users.policies.AuthService/Issue" - AuthService_Identify_FullMethodName = "/mainflux.users.policies.AuthService/Identify" - AuthService_AddPolicy_FullMethodName = "/mainflux.users.policies.AuthService/AddPolicy" - AuthService_DeletePolicy_FullMethodName = "/mainflux.users.policies.AuthService/DeletePolicy" - AuthService_ListPolicies_FullMethodName = "/mainflux.users.policies.AuthService/ListPolicies" + AuthService_Identify_FullMethodName = "/mainflux.users.policies.AuthService/Identify" + AuthService_Authorize_FullMethodName = "/mainflux.users.policies.AuthService/Authorize" ) // AuthServiceClient is the client API for AuthService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type AuthServiceClient interface { + Identify(ctx context.Context, in *IdentifyReq, opts ...grpc.CallOption) (*IdentifyRes, error) + // Authorize authorizes the given subject to perform the given action on the + // given object. Authorize(ctx context.Context, in *AuthorizeReq, opts ...grpc.CallOption) (*AuthorizeRes, error) - Issue(ctx context.Context, in *IssueReq, opts ...grpc.CallOption) (*Token, error) - Identify(ctx context.Context, in *Token, opts ...grpc.CallOption) (*UserIdentity, error) - AddPolicy(ctx context.Context, in *AddPolicyReq, opts ...grpc.CallOption) (*AddPolicyRes, error) - DeletePolicy(ctx context.Context, in *DeletePolicyReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) - ListPolicies(ctx context.Context, in *ListPoliciesReq, opts ...grpc.CallOption) (*ListPoliciesRes, error) } type authServiceClient struct { @@ -50,26 +44,8 @@ func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient { return &authServiceClient{cc} } -func (c *authServiceClient) Authorize(ctx context.Context, in *AuthorizeReq, opts ...grpc.CallOption) (*AuthorizeRes, error) { - out := new(AuthorizeRes) - err := c.cc.Invoke(ctx, AuthService_Authorize_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *authServiceClient) Issue(ctx context.Context, in *IssueReq, opts ...grpc.CallOption) (*Token, error) { - out := new(Token) - err := c.cc.Invoke(ctx, AuthService_Issue_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *authServiceClient) Identify(ctx context.Context, in *Token, opts ...grpc.CallOption) (*UserIdentity, error) { - out := new(UserIdentity) +func (c *authServiceClient) Identify(ctx context.Context, in *IdentifyReq, opts ...grpc.CallOption) (*IdentifyRes, error) { + out := new(IdentifyRes) err := c.cc.Invoke(ctx, AuthService_Identify_FullMethodName, in, out, opts...) if err != nil { return nil, err @@ -77,27 +53,9 @@ func (c *authServiceClient) Identify(ctx context.Context, in *Token, opts ...grp return out, nil } -func (c *authServiceClient) AddPolicy(ctx context.Context, in *AddPolicyReq, opts ...grpc.CallOption) (*AddPolicyRes, error) { - out := new(AddPolicyRes) - err := c.cc.Invoke(ctx, AuthService_AddPolicy_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *authServiceClient) DeletePolicy(ctx context.Context, in *DeletePolicyReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) { - out := new(DeletePolicyRes) - err := c.cc.Invoke(ctx, AuthService_DeletePolicy_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *authServiceClient) ListPolicies(ctx context.Context, in *ListPoliciesReq, opts ...grpc.CallOption) (*ListPoliciesRes, error) { - out := new(ListPoliciesRes) - err := c.cc.Invoke(ctx, AuthService_ListPolicies_FullMethodName, in, out, opts...) +func (c *authServiceClient) Authorize(ctx context.Context, in *AuthorizeReq, opts ...grpc.CallOption) (*AuthorizeRes, error) { + out := new(AuthorizeRes) + err := c.cc.Invoke(ctx, AuthService_Authorize_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -108,12 +66,10 @@ func (c *authServiceClient) ListPolicies(ctx context.Context, in *ListPoliciesRe // All implementations must embed UnimplementedAuthServiceServer // for forward compatibility type AuthServiceServer interface { + Identify(context.Context, *IdentifyReq) (*IdentifyRes, error) + // Authorize authorizes the given subject to perform the given action on the + // given object. Authorize(context.Context, *AuthorizeReq) (*AuthorizeRes, error) - Issue(context.Context, *IssueReq) (*Token, error) - Identify(context.Context, *Token) (*UserIdentity, error) - AddPolicy(context.Context, *AddPolicyReq) (*AddPolicyRes, error) - DeletePolicy(context.Context, *DeletePolicyReq) (*DeletePolicyRes, error) - ListPolicies(context.Context, *ListPoliciesReq) (*ListPoliciesRes, error) mustEmbedUnimplementedAuthServiceServer() } @@ -121,23 +77,11 @@ type AuthServiceServer interface { type UnimplementedAuthServiceServer struct { } -func (UnimplementedAuthServiceServer) Authorize(context.Context, *AuthorizeReq) (*AuthorizeRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method Authorize not implemented") -} -func (UnimplementedAuthServiceServer) Issue(context.Context, *IssueReq) (*Token, error) { - return nil, status.Errorf(codes.Unimplemented, "method Issue not implemented") -} -func (UnimplementedAuthServiceServer) Identify(context.Context, *Token) (*UserIdentity, error) { +func (UnimplementedAuthServiceServer) Identify(context.Context, *IdentifyReq) (*IdentifyRes, error) { return nil, status.Errorf(codes.Unimplemented, "method Identify not implemented") } -func (UnimplementedAuthServiceServer) AddPolicy(context.Context, *AddPolicyReq) (*AddPolicyRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddPolicy not implemented") -} -func (UnimplementedAuthServiceServer) DeletePolicy(context.Context, *DeletePolicyReq) (*DeletePolicyRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeletePolicy not implemented") -} -func (UnimplementedAuthServiceServer) ListPolicies(context.Context, *ListPoliciesReq) (*ListPoliciesRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListPolicies not implemented") +func (UnimplementedAuthServiceServer) Authorize(context.Context, *AuthorizeReq) (*AuthorizeRes, error) { + return nil, status.Errorf(codes.Unimplemented, "method Authorize not implemented") } func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {} @@ -152,44 +96,8 @@ func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) { s.RegisterService(&AuthService_ServiceDesc, srv) } -func _AuthService_Authorize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AuthorizeReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(AuthServiceServer).Authorize(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: AuthService_Authorize_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AuthServiceServer).Authorize(ctx, req.(*AuthorizeReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _AuthService_Issue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(IssueReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(AuthServiceServer).Issue(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: AuthService_Issue_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AuthServiceServer).Issue(ctx, req.(*IssueReq)) - } - return interceptor(ctx, in, info, handler) -} - func _AuthService_Identify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Token) + in := new(IdentifyReq) if err := dec(in); err != nil { return nil, err } @@ -201,61 +109,25 @@ func _AuthService_Identify_Handler(srv interface{}, ctx context.Context, dec fun FullMethod: AuthService_Identify_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AuthServiceServer).Identify(ctx, req.(*Token)) - } - return interceptor(ctx, in, info, handler) -} - -func _AuthService_AddPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddPolicyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(AuthServiceServer).AddPolicy(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: AuthService_AddPolicy_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AuthServiceServer).AddPolicy(ctx, req.(*AddPolicyReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _AuthService_DeletePolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeletePolicyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(AuthServiceServer).DeletePolicy(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: AuthService_DeletePolicy_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AuthServiceServer).DeletePolicy(ctx, req.(*DeletePolicyReq)) + return srv.(AuthServiceServer).Identify(ctx, req.(*IdentifyReq)) } return interceptor(ctx, in, info, handler) } -func _AuthService_ListPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListPoliciesReq) +func _AuthService_Authorize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthorizeReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(AuthServiceServer).ListPolicies(ctx, in) + return srv.(AuthServiceServer).Authorize(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: AuthService_ListPolicies_FullMethodName, + FullMethod: AuthService_Authorize_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AuthServiceServer).ListPolicies(ctx, req.(*ListPoliciesReq)) + return srv.(AuthServiceServer).Authorize(ctx, req.(*AuthorizeReq)) } return interceptor(ctx, in, info, handler) } @@ -267,29 +139,13 @@ var AuthService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "mainflux.users.policies.AuthService", HandlerType: (*AuthServiceServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "Authorize", - Handler: _AuthService_Authorize_Handler, - }, - { - MethodName: "Issue", - Handler: _AuthService_Issue_Handler, - }, { MethodName: "Identify", Handler: _AuthService_Identify_Handler, }, { - MethodName: "AddPolicy", - Handler: _AuthService_AddPolicy_Handler, - }, - { - MethodName: "DeletePolicy", - Handler: _AuthService_DeletePolicy_Handler, - }, - { - MethodName: "ListPolicies", - Handler: _AuthService_ListPolicies_Handler, + MethodName: "Authorize", + Handler: _AuthService_Authorize_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/users/policies/policies.go b/users/policies/policies.go index a866275cba..fde22fd9ca 100644 --- a/users/policies/policies.go +++ b/users/policies/policies.go @@ -52,7 +52,7 @@ type AccessRequest struct { // PolicyPage contains a page of policies. type PolicyPage struct { Page - Policies []Policy + Policies []Policy `json:"policies"` } // Repository specifies a policy persistence API. diff --git a/ws/adapter.go b/ws/adapter.go index 493bd5b6e7..ab6aa89425 100644 --- a/ws/adapter.go +++ b/ws/adapter.go @@ -62,12 +62,12 @@ type Service interface { var _ Service = (*adapterService)(nil) type adapterService struct { - auth policies.ThingsServiceClient + auth policies.AuthServiceClient pubsub messaging.PubSub } // New instantiates the WS adapter implementation. -func New(auth policies.ThingsServiceClient, pubsub messaging.PubSub) Service { +func New(auth policies.AuthServiceClient, pubsub messaging.PubSub) Service { return &adapterService{ auth: auth, pubsub: pubsub, @@ -139,9 +139,9 @@ func (svc *adapterService) Unsubscribe(ctx context.Context, thingKey, chanID, su // and returns the thingID if it is. func (svc *adapterService) authorize(ctx context.Context, thingKey, chanID string) (string, error) { ar := &policies.AuthorizeReq{ - Sub: thingKey, - Obj: chanID, - Act: policies.ReadAction, + Subject: thingKey, + Object: chanID, + Action: policies.ReadAction, EntityType: policies.ThingEntityType, } res, err := svc.auth.Authorize(ctx, ar) diff --git a/ws/adapter_test.go b/ws/adapter_test.go index 0b4ac779e6..ee01cdac0c 100644 --- a/ws/adapter_test.go +++ b/ws/adapter_test.go @@ -32,7 +32,7 @@ var msg = messaging.Message{ Payload: []byte(`[{"n":"current","t":-5,"v":1.2}]`), } -func newService(cc policies.ThingsServiceClient) (ws.Service, mocks.MockPubSub) { +func newService(cc policies.AuthServiceClient) (ws.Service, mocks.MockPubSub) { pubsub := mocks.NewPubSub() return ws.New(cc, pubsub), pubsub } diff --git a/ws/api/endpoint_test.go b/ws/api/endpoint_test.go index f51125e720..ac7656a186 100644 --- a/ws/api/endpoint_test.go +++ b/ws/api/endpoint_test.go @@ -32,7 +32,7 @@ const ( var msg = []byte(`[{"n":"current","t":-1,"v":1.6}]`) -func newService(cc policies.ThingsServiceClient) (ws.Service, mocks.MockPubSub) { +func newService(cc policies.AuthServiceClient) (ws.Service, mocks.MockPubSub) { pubsub := mocks.NewPubSub() return ws.New(cc, pubsub), pubsub }