2019-12-16 16:22:09 +01:00
|
|
|
// Copyright (c) Mainflux
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
2020-12-29 23:02:35 +01:00
|
|
|
package auth_test
|
2019-12-16 16:22:09 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2020-12-29 23:02:35 +01:00
|
|
|
"github.com/mainflux/mainflux/auth"
|
|
|
|
"github.com/mainflux/mainflux/auth/jwt"
|
|
|
|
"github.com/mainflux/mainflux/auth/mocks"
|
2020-06-03 15:16:19 +02:00
|
|
|
"github.com/mainflux/mainflux/pkg/errors"
|
2020-06-03 18:49:44 +02:00
|
|
|
"github.com/mainflux/mainflux/pkg/uuid"
|
2019-12-16 16:22:09 +01:00
|
|
|
"github.com/stretchr/testify/assert"
|
2021-03-04 10:29:03 +01:00
|
|
|
"github.com/stretchr/testify/require"
|
2019-12-16 16:22:09 +01:00
|
|
|
)
|
|
|
|
|
2021-03-04 10:29:03 +01:00
|
|
|
var idProvider = uuid.New()
|
|
|
|
|
2019-12-16 16:22:09 +01:00
|
|
|
const (
|
2021-03-04 10:29:03 +01:00
|
|
|
secret = "secret"
|
|
|
|
email = "test@example.com"
|
|
|
|
id = "testID"
|
|
|
|
groupName = "mfx"
|
|
|
|
description = "Description"
|
2021-10-27 00:38:28 +02:00
|
|
|
|
2021-11-08 14:55:18 +03:00
|
|
|
memberRelation = "member"
|
2021-10-27 00:38:28 +02:00
|
|
|
authoritiesObj = "authorities"
|
2022-01-25 21:42:41 +03:00
|
|
|
loginDuration = 30 * time.Minute
|
2019-12-16 16:22:09 +01:00
|
|
|
)
|
|
|
|
|
2020-12-29 23:02:35 +01:00
|
|
|
func newService() auth.Service {
|
2019-12-16 16:22:09 +01:00
|
|
|
repo := mocks.NewKeyRepository()
|
2020-12-29 23:02:35 +01:00
|
|
|
groupRepo := mocks.NewGroupRepository()
|
2021-01-17 23:12:45 +01:00
|
|
|
idProvider := uuid.NewMock()
|
2021-10-27 00:38:28 +02:00
|
|
|
|
|
|
|
mockAuthzDB := map[string][]mocks.MockSubjectSet{}
|
2021-11-08 14:55:18 +03:00
|
|
|
mockAuthzDB[id] = append(mockAuthzDB[id], mocks.MockSubjectSet{Object: authoritiesObj, Relation: memberRelation})
|
2021-10-27 00:38:28 +02:00
|
|
|
ketoMock := mocks.NewKetoMock(mockAuthzDB)
|
|
|
|
|
2019-12-16 16:22:09 +01:00
|
|
|
t := jwt.New(secret)
|
2022-01-25 21:42:41 +03:00
|
|
|
return auth.New(repo, groupRepo, idProvider, t, ketoMock, loginDuration)
|
2019-12-16 16:22:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestIssue(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2019-12-16 16:22:09 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
cases := []struct {
|
2020-10-27 19:42:53 +01:00
|
|
|
desc string
|
2020-12-29 23:02:35 +01:00
|
|
|
key auth.Key
|
2020-10-27 19:42:53 +01:00
|
|
|
token string
|
|
|
|
err error
|
2019-12-16 16:22:09 +01:00
|
|
|
}{
|
|
|
|
{
|
2021-12-24 14:53:06 +01:00
|
|
|
desc: "issue login key",
|
2020-12-29 23:02:35 +01:00
|
|
|
key: auth.Key{
|
2021-12-24 14:53:06 +01:00
|
|
|
Type: auth.LoginKey,
|
2019-12-16 16:22:09 +01:00
|
|
|
IssuedAt: time.Now(),
|
|
|
|
},
|
2020-10-27 19:42:53 +01:00
|
|
|
token: secret,
|
|
|
|
err: nil,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2021-12-24 14:53:06 +01:00
|
|
|
desc: "issue login key with no time",
|
2020-12-29 23:02:35 +01:00
|
|
|
key: auth.Key{
|
2021-12-24 14:53:06 +01:00
|
|
|
Type: auth.LoginKey,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
2020-10-27 19:42:53 +01:00
|
|
|
token: secret,
|
2020-12-29 23:02:35 +01:00
|
|
|
err: auth.ErrInvalidKeyIssuedAt,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2020-01-16 18:43:06 +01:00
|
|
|
desc: "issue API key",
|
2020-12-29 23:02:35 +01:00
|
|
|
key: auth.Key{
|
|
|
|
Type: auth.APIKey,
|
2019-12-16 16:22:09 +01:00
|
|
|
IssuedAt: time.Now(),
|
|
|
|
},
|
2020-10-27 19:42:53 +01:00
|
|
|
token: secret,
|
|
|
|
err: nil,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2022-02-01 17:33:23 +01:00
|
|
|
desc: "issue API key with an invalid token",
|
2020-12-29 23:02:35 +01:00
|
|
|
key: auth.Key{
|
|
|
|
Type: auth.APIKey,
|
2019-12-16 16:22:09 +01:00
|
|
|
IssuedAt: time.Now(),
|
|
|
|
},
|
2020-10-27 19:42:53 +01:00
|
|
|
token: "invalid",
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2020-10-27 19:42:53 +01:00
|
|
|
desc: "issue API key with no time",
|
2020-12-29 23:02:35 +01:00
|
|
|
key: auth.Key{
|
|
|
|
Type: auth.APIKey,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
2020-10-27 19:42:53 +01:00
|
|
|
token: secret,
|
2020-12-29 23:02:35 +01:00
|
|
|
err: auth.ErrInvalidKeyIssuedAt,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2020-01-16 18:43:06 +01:00
|
|
|
desc: "issue recovery key",
|
2020-12-29 23:02:35 +01:00
|
|
|
key: auth.Key{
|
|
|
|
Type: auth.RecoveryKey,
|
2019-12-16 16:22:09 +01:00
|
|
|
IssuedAt: time.Now(),
|
|
|
|
},
|
2020-10-27 19:42:53 +01:00
|
|
|
token: "",
|
|
|
|
err: nil,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2020-10-27 19:42:53 +01:00
|
|
|
desc: "issue recovery with no issue time",
|
2020-12-29 23:02:35 +01:00
|
|
|
key: auth.Key{
|
|
|
|
Type: auth.RecoveryKey,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
2020-10-27 19:42:53 +01:00
|
|
|
token: secret,
|
2020-12-29 23:02:35 +01:00
|
|
|
err: auth.ErrInvalidKeyIssuedAt,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
2020-10-27 19:42:53 +01:00
|
|
|
_, _, err := svc.Issue(context.Background(), tc.token, tc.key)
|
2020-04-10 17:43:42 +02:00
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err))
|
2019-12-16 16:22:09 +01:00
|
|
|
}
|
|
|
|
}
|
2020-10-27 19:42:53 +01:00
|
|
|
|
2019-12-16 16:22:09 +01:00
|
|
|
func TestRevoke(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2019-12-16 16:22:09 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
2020-12-29 23:02:35 +01:00
|
|
|
key := auth.Key{
|
|
|
|
Type: auth.APIKey,
|
2019-12-16 16:22:09 +01:00
|
|
|
IssuedAt: time.Now(),
|
2020-10-27 19:42:53 +01:00
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
2019-12-16 16:22:09 +01:00
|
|
|
}
|
2020-10-27 19:42:53 +01:00
|
|
|
newKey, _, err := svc.Issue(context.Background(), secret, key)
|
2019-12-16 16:22:09 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
cases := []struct {
|
2020-10-27 19:42:53 +01:00
|
|
|
desc string
|
|
|
|
id string
|
|
|
|
token string
|
|
|
|
err error
|
2019-12-16 16:22:09 +01:00
|
|
|
}{
|
|
|
|
{
|
2021-12-24 14:53:06 +01:00
|
|
|
desc: "revoke login key",
|
2020-10-27 19:42:53 +01:00
|
|
|
id: newKey.ID,
|
|
|
|
token: secret,
|
|
|
|
err: nil,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2021-12-24 14:53:06 +01:00
|
|
|
desc: "revoke non-existing login key",
|
2020-10-27 19:42:53 +01:00
|
|
|
id: newKey.ID,
|
|
|
|
token: secret,
|
|
|
|
err: nil,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2022-02-01 17:33:23 +01:00
|
|
|
desc: "revoke with empty login key",
|
2020-10-27 19:42:53 +01:00
|
|
|
id: newKey.ID,
|
|
|
|
token: "",
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
2020-10-27 19:42:53 +01:00
|
|
|
err := svc.Revoke(context.Background(), tc.token, tc.id)
|
2020-04-10 17:43:42 +02:00
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err))
|
2019-12-16 16:22:09 +01:00
|
|
|
}
|
|
|
|
}
|
2020-10-27 19:42:53 +01:00
|
|
|
|
2019-12-16 16:22:09 +01:00
|
|
|
func TestRetrieve(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), Subject: email, IssuerID: id})
|
2019-12-16 16:22:09 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
2020-12-29 23:02:35 +01:00
|
|
|
key := auth.Key{
|
2019-12-16 16:22:09 +01:00
|
|
|
ID: "id",
|
2020-12-29 23:02:35 +01:00
|
|
|
Type: auth.APIKey,
|
2020-10-27 19:42:53 +01:00
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
2019-12-16 16:22:09 +01:00
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
2020-10-27 19:42:53 +01:00
|
|
|
|
2021-12-24 14:53:06 +01:00
|
|
|
_, userToken, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
2020-10-27 19:42:53 +01:00
|
|
|
|
|
|
|
apiKey, apiToken, err := svc.Issue(context.Background(), secret, key)
|
2021-12-24 14:53:06 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login's key expected to succeed: %s", err))
|
2019-12-16 16:22:09 +01:00
|
|
|
|
2020-12-29 23:02:35 +01:00
|
|
|
_, resetToken, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.RecoveryKey, IssuedAt: time.Now()})
|
2019-12-16 16:22:09 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing reset key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
cases := []struct {
|
2020-10-27 19:42:53 +01:00
|
|
|
desc string
|
|
|
|
id string
|
|
|
|
token string
|
|
|
|
err error
|
2019-12-16 16:22:09 +01:00
|
|
|
}{
|
|
|
|
{
|
2021-12-24 14:53:06 +01:00
|
|
|
desc: "retrieve login key",
|
2020-10-27 19:42:53 +01:00
|
|
|
id: apiKey.ID,
|
|
|
|
token: userToken,
|
|
|
|
err: nil,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2021-12-24 14:53:06 +01:00
|
|
|
desc: "retrieve non-existing login key",
|
2020-10-27 19:42:53 +01:00
|
|
|
id: "invalid",
|
|
|
|
token: userToken,
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrNotFound,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2022-02-01 17:33:23 +01:00
|
|
|
desc: "retrieve with wrong login key",
|
2020-10-27 19:42:53 +01:00
|
|
|
id: apiKey.ID,
|
|
|
|
token: "wrong",
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2020-10-27 19:42:53 +01:00
|
|
|
desc: "retrieve with API token",
|
|
|
|
id: apiKey.ID,
|
|
|
|
token: apiToken,
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
2020-10-27 19:42:53 +01:00
|
|
|
desc: "retrieve with reset token",
|
|
|
|
id: apiKey.ID,
|
|
|
|
token: resetToken,
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
2020-12-29 23:02:35 +01:00
|
|
|
_, err := svc.RetrieveKey(context.Background(), tc.token, tc.id)
|
2020-04-10 17:43:42 +02:00
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err))
|
2019-12-16 16:22:09 +01:00
|
|
|
}
|
|
|
|
}
|
2020-10-27 19:42:53 +01:00
|
|
|
|
2019-12-16 16:22:09 +01:00
|
|
|
func TestIdentify(t *testing.T) {
|
|
|
|
svc := newService()
|
2020-10-27 19:42:53 +01:00
|
|
|
|
2021-12-24 14:53:06 +01:00
|
|
|
_, loginSecret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2019-12-16 16:22:09 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
2020-12-29 23:02:35 +01:00
|
|
|
_, recoverySecret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.RecoveryKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2019-12-16 16:22:09 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing reset key expected to succeed: %s", err))
|
|
|
|
|
2020-12-29 23:02:35 +01:00
|
|
|
_, apiSecret, err := svc.Issue(context.Background(), loginSecret, auth.Key{Type: auth.APIKey, IssuerID: id, Subject: email, IssuedAt: time.Now(), ExpiresAt: time.Now().Add(time.Minute)})
|
2021-12-24 14:53:06 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
2019-12-16 16:22:09 +01:00
|
|
|
|
|
|
|
exp1 := time.Now().Add(-2 * time.Second)
|
2020-12-29 23:02:35 +01:00
|
|
|
_, expSecret, err := svc.Issue(context.Background(), loginSecret, auth.Key{Type: auth.APIKey, IssuedAt: time.Now(), ExpiresAt: exp1})
|
2021-12-24 14:53:06 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing expired login key expected to succeed: %s", err))
|
2019-12-16 16:22:09 +01:00
|
|
|
|
2020-12-29 23:02:35 +01:00
|
|
|
_, invalidSecret, err := svc.Issue(context.Background(), loginSecret, auth.Key{Type: 22, IssuedAt: time.Now()})
|
2021-12-24 14:53:06 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
2019-12-16 16:22:09 +01:00
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
desc string
|
|
|
|
key string
|
2020-12-29 23:02:35 +01:00
|
|
|
idt auth.Identity
|
2019-12-16 16:22:09 +01:00
|
|
|
err error
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "identify login key",
|
2020-10-27 19:42:53 +01:00
|
|
|
key: loginSecret,
|
2020-12-29 23:02:35 +01:00
|
|
|
idt: auth.Identity{id, email},
|
2019-12-16 16:22:09 +01:00
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
2020-01-16 18:43:06 +01:00
|
|
|
desc: "identify recovery key",
|
2020-10-27 19:42:53 +01:00
|
|
|
key: recoverySecret,
|
2020-12-29 23:02:35 +01:00
|
|
|
idt: auth.Identity{id, email},
|
2019-12-16 16:22:09 +01:00
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
2020-10-27 19:42:53 +01:00
|
|
|
desc: "identify API key",
|
|
|
|
key: apiSecret,
|
2020-12-29 23:02:35 +01:00
|
|
|
idt: auth.Identity{id, email},
|
2019-12-16 16:22:09 +01:00
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
2020-10-27 19:42:53 +01:00
|
|
|
desc: "identify expired API key",
|
|
|
|
key: expSecret,
|
2020-12-29 23:02:35 +01:00
|
|
|
idt: auth.Identity{},
|
|
|
|
err: auth.ErrAPIKeyExpired,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "identify expired key",
|
2020-10-27 19:42:53 +01:00
|
|
|
key: invalidSecret,
|
2020-12-29 23:02:35 +01:00
|
|
|
idt: auth.Identity{},
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "identify invalid key",
|
|
|
|
key: "invalid",
|
2020-12-29 23:02:35 +01:00
|
|
|
idt: auth.Identity{},
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2019-12-16 16:22:09 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
2020-10-27 19:42:53 +01:00
|
|
|
idt, err := svc.Identify(context.Background(), tc.key)
|
2020-04-10 17:43:42 +02:00
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err))
|
2020-10-27 19:42:53 +01:00
|
|
|
assert.Equal(t, tc.idt, idt, fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.idt, idt))
|
2019-12-16 16:22:09 +01:00
|
|
|
}
|
|
|
|
}
|
2021-03-04 10:29:03 +01:00
|
|
|
|
|
|
|
func TestCreateGroup(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
group := auth.Group{
|
|
|
|
Name: "Group",
|
|
|
|
Description: description,
|
|
|
|
}
|
|
|
|
|
|
|
|
parentGroup := auth.Group{
|
|
|
|
Name: "ParentGroup",
|
|
|
|
Description: description,
|
|
|
|
}
|
|
|
|
|
|
|
|
parent, err := svc.CreateGroup(context.Background(), apiToken, parentGroup)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Creating parent group expected to succeed: %s", err))
|
|
|
|
|
2021-11-08 14:55:18 +03:00
|
|
|
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: parent.ID, Relation: memberRelation, Subject: id})
|
2021-10-27 00:38:28 +02:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Checking parent group owner's policy expected to succeed: %s", err))
|
|
|
|
|
2021-03-04 10:29:03 +01:00
|
|
|
cases := []struct {
|
|
|
|
desc string
|
|
|
|
group auth.Group
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "create new group",
|
|
|
|
group: group,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "create group with existing name",
|
|
|
|
group: group,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "create group with parent",
|
|
|
|
group: auth.Group{
|
|
|
|
Name: groupName,
|
|
|
|
ParentID: parent.ID,
|
|
|
|
},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "create group with invalid parent",
|
|
|
|
group: auth.Group{
|
|
|
|
Name: groupName,
|
|
|
|
ParentID: "xxxxxxxxxx",
|
|
|
|
},
|
2022-02-14 22:49:23 +01:00
|
|
|
err: errors.ErrCreateEntity,
|
2021-03-04 10:29:03 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
2021-10-27 00:38:28 +02:00
|
|
|
g, err := svc.CreateGroup(context.Background(), apiToken, tc.group)
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
2021-10-27 00:38:28 +02:00
|
|
|
|
|
|
|
if err == nil {
|
2021-11-08 14:55:18 +03:00
|
|
|
authzErr := svc.Authorize(context.Background(), auth.PolicyReq{Object: g.ID, Relation: memberRelation, Subject: g.OwnerID})
|
2021-10-27 00:38:28 +02:00
|
|
|
assert.Nil(t, authzErr, fmt.Sprintf("%s - Checking group owner's policy expected to succeed: %s", tc.desc, authzErr))
|
|
|
|
}
|
2021-03-04 10:29:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUpdateGroup(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
group := auth.Group{
|
|
|
|
Name: "Group",
|
|
|
|
Description: description,
|
|
|
|
Metadata: auth.GroupMetadata{
|
|
|
|
"field": "value",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
group, err = svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Creating parent group failed: %s", err))
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
desc string
|
|
|
|
group auth.Group
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "update group",
|
|
|
|
group: auth.Group{
|
|
|
|
ID: group.ID,
|
|
|
|
Name: "NewName",
|
|
|
|
Description: "NewDescription",
|
|
|
|
Metadata: auth.GroupMetadata{
|
|
|
|
"field": "value2",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
g, err := svc.UpdateGroup(context.Background(), apiToken, tc.group)
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
|
|
|
assert.Equal(t, g.ID, tc.group.ID, fmt.Sprintf("ID: expected %s got %s\n", g.ID, tc.group.ID))
|
|
|
|
assert.Equal(t, g.Name, tc.group.Name, fmt.Sprintf("Name: expected %s got %s\n", g.Name, tc.group.Name))
|
|
|
|
assert.Equal(t, g.Description, tc.group.Description, fmt.Sprintf("Description: expected %s got %s\n", g.Description, tc.group.Description))
|
|
|
|
assert.Equal(t, g.Metadata["field"], g.Metadata["field"], fmt.Sprintf("Metadata: expected %s got %s\n", g.Metadata, tc.group.Metadata))
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestViewGroup(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
group := auth.Group{
|
|
|
|
Name: "Group",
|
|
|
|
Description: description,
|
|
|
|
Metadata: auth.GroupMetadata{
|
|
|
|
"field": "value",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
group, err = svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Creating parent group failed: %s", err))
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
desc string
|
|
|
|
token string
|
|
|
|
groupID string
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
|
|
|
|
desc: "view group",
|
|
|
|
token: apiToken,
|
|
|
|
groupID: group.ID,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
2022-02-01 17:33:23 +01:00
|
|
|
desc: "view group with invalid token",
|
2021-03-04 10:29:03 +01:00
|
|
|
token: "wrongtoken",
|
|
|
|
groupID: group.ID,
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2021-03-04 10:29:03 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "view group for wrong id",
|
|
|
|
token: apiToken,
|
|
|
|
groupID: "wrong",
|
2022-02-14 22:49:23 +01:00
|
|
|
err: errors.ErrNotFound,
|
2021-03-04 10:29:03 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
_, err := svc.ViewGroup(context.Background(), tc.token, tc.groupID)
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListGroups(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
group := auth.Group{
|
|
|
|
Description: description,
|
|
|
|
Metadata: auth.GroupMetadata{
|
|
|
|
"field": "value",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
n := uint64(10)
|
|
|
|
parentID := ""
|
|
|
|
for i := uint64(0); i < n; i++ {
|
|
|
|
group.Name = fmt.Sprintf("Group%d", i)
|
|
|
|
group.ParentID = parentID
|
|
|
|
g, err := svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
|
|
parentID = g.ID
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := map[string]struct {
|
|
|
|
token string
|
|
|
|
level uint64
|
|
|
|
size uint64
|
|
|
|
metadata auth.GroupMetadata
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
"list all groups": {
|
|
|
|
token: apiToken,
|
|
|
|
level: 5,
|
|
|
|
size: n,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
"list groups for level 1": {
|
|
|
|
token: apiToken,
|
|
|
|
level: 1,
|
|
|
|
size: n,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
"list all groups with wrong token": {
|
|
|
|
token: "wrongToken",
|
|
|
|
level: 5,
|
|
|
|
size: 0,
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2021-03-04 10:29:03 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for desc, tc := range cases {
|
|
|
|
page, err := svc.ListGroups(context.Background(), tc.token, auth.PageMetadata{Level: tc.level, Metadata: tc.metadata})
|
|
|
|
size := uint64(len(page.Groups))
|
|
|
|
assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected %d got %d\n", desc, tc.size, size))
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", desc, tc.err, err))
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListChildren(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
group := auth.Group{
|
|
|
|
Description: description,
|
|
|
|
Metadata: auth.GroupMetadata{
|
|
|
|
"field": "value",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
n := uint64(10)
|
|
|
|
parentID := ""
|
|
|
|
groupIDs := make([]string, n)
|
|
|
|
for i := uint64(0); i < n; i++ {
|
|
|
|
group.Name = fmt.Sprintf("Group%d", i)
|
|
|
|
group.ParentID = parentID
|
|
|
|
g, err := svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
|
|
parentID = g.ID
|
|
|
|
groupIDs[i] = g.ID
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := map[string]struct {
|
|
|
|
token string
|
|
|
|
level uint64
|
|
|
|
size uint64
|
|
|
|
id string
|
|
|
|
metadata auth.GroupMetadata
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
"list all children": {
|
|
|
|
token: apiToken,
|
|
|
|
level: 5,
|
|
|
|
id: groupIDs[0],
|
|
|
|
size: n,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
"list all groups with wrong token": {
|
|
|
|
token: "wrongToken",
|
|
|
|
level: 5,
|
|
|
|
size: 0,
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2021-03-04 10:29:03 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for desc, tc := range cases {
|
|
|
|
page, err := svc.ListChildren(context.Background(), tc.token, tc.id, auth.PageMetadata{Level: tc.level, Metadata: tc.metadata})
|
|
|
|
size := uint64(len(page.Groups))
|
|
|
|
assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected %d got %d\n", desc, tc.size, size))
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", desc, tc.err, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListParents(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
group := auth.Group{
|
|
|
|
Description: description,
|
|
|
|
Metadata: auth.GroupMetadata{
|
|
|
|
"field": "value",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
n := uint64(10)
|
|
|
|
parentID := ""
|
|
|
|
groupIDs := make([]string, n)
|
|
|
|
for i := uint64(0); i < n; i++ {
|
|
|
|
group.Name = fmt.Sprintf("Group%d", i)
|
|
|
|
group.ParentID = parentID
|
|
|
|
g, err := svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
|
|
parentID = g.ID
|
|
|
|
groupIDs[i] = g.ID
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := map[string]struct {
|
|
|
|
token string
|
|
|
|
level uint64
|
|
|
|
size uint64
|
|
|
|
id string
|
|
|
|
metadata auth.GroupMetadata
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
"list all parents": {
|
|
|
|
token: apiToken,
|
|
|
|
level: 5,
|
|
|
|
id: groupIDs[n-1],
|
|
|
|
size: n,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
"list all parents with wrong token": {
|
|
|
|
token: "wrongToken",
|
|
|
|
level: 5,
|
|
|
|
size: 0,
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2021-03-04 10:29:03 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for desc, tc := range cases {
|
|
|
|
page, err := svc.ListParents(context.Background(), tc.token, tc.id, auth.PageMetadata{Level: tc.level, Metadata: tc.metadata})
|
|
|
|
size := uint64(len(page.Groups))
|
|
|
|
assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected %d got %d\n", desc, tc.size, size))
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", desc, tc.err, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListMembers(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
group := auth.Group{
|
|
|
|
Description: description,
|
|
|
|
Metadata: auth.GroupMetadata{
|
|
|
|
"field": "value",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
g, err := svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Creating group expected to succeed: %s", err))
|
|
|
|
group.ID = g.ID
|
|
|
|
|
|
|
|
n := uint64(10)
|
|
|
|
for i := uint64(0); i < n; i++ {
|
|
|
|
uid, err := idProvider.ID()
|
|
|
|
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
|
|
|
|
|
|
err = svc.Assign(context.Background(), apiToken, group.ID, "things", uid)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("Assign member expected to succeed: %s\n", err))
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := map[string]struct {
|
|
|
|
token string
|
|
|
|
size uint64
|
|
|
|
offset uint64
|
|
|
|
limit uint64
|
|
|
|
group auth.Group
|
|
|
|
metadata auth.GroupMetadata
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
"list all members": {
|
|
|
|
token: apiToken,
|
|
|
|
offset: 0,
|
|
|
|
limit: n,
|
|
|
|
group: group,
|
|
|
|
size: n,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
"list half members": {
|
|
|
|
token: apiToken,
|
|
|
|
offset: n / 2,
|
|
|
|
limit: n,
|
|
|
|
group: group,
|
|
|
|
size: n / 2,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
"list all members with wrong token": {
|
|
|
|
token: "wrongToken",
|
|
|
|
offset: 0,
|
|
|
|
limit: n,
|
|
|
|
size: 0,
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2021-03-04 10:29:03 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for desc, tc := range cases {
|
|
|
|
page, err := svc.ListMembers(context.Background(), tc.token, tc.group.ID, "things", auth.PageMetadata{Offset: tc.offset, Limit: tc.limit, Metadata: tc.metadata})
|
|
|
|
size := uint64(len(page.Members))
|
|
|
|
assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected %d got %d\n", desc, tc.size, size))
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", desc, tc.err, err))
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListMemberships(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
group := auth.Group{
|
|
|
|
Description: description,
|
|
|
|
Metadata: auth.GroupMetadata{
|
|
|
|
"field": "value",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
memberID, err := idProvider.ID()
|
|
|
|
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
|
|
|
|
|
|
n := uint64(10)
|
|
|
|
for i := uint64(0); i < n; i++ {
|
|
|
|
group.Name = fmt.Sprintf("Group%d", i)
|
|
|
|
g, err := svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
|
|
|
2021-10-27 00:38:28 +02:00
|
|
|
_ = svc.AddPolicy(context.Background(), auth.PolicyReq{Subject: id, Object: memberID, Relation: "owner"})
|
2021-03-04 10:29:03 +01:00
|
|
|
err = svc.Assign(context.Background(), apiToken, g.ID, "things", memberID)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("Assign member expected to succeed: %s\n", err))
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := map[string]struct {
|
|
|
|
token string
|
|
|
|
size uint64
|
|
|
|
offset uint64
|
|
|
|
limit uint64
|
|
|
|
group auth.Group
|
|
|
|
metadata auth.GroupMetadata
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
"list all members": {
|
|
|
|
token: apiToken,
|
|
|
|
offset: 0,
|
|
|
|
limit: n,
|
|
|
|
group: group,
|
|
|
|
size: n,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
"list half members": {
|
|
|
|
token: apiToken,
|
|
|
|
offset: n / 2,
|
|
|
|
limit: n,
|
|
|
|
group: group,
|
|
|
|
size: n / 2,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
"list all members with wrong token": {
|
|
|
|
token: "wrongToken",
|
|
|
|
offset: 0,
|
|
|
|
limit: n,
|
|
|
|
size: 0,
|
2022-02-01 17:33:23 +01:00
|
|
|
err: errors.ErrAuthentication,
|
2021-03-04 10:29:03 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for desc, tc := range cases {
|
|
|
|
page, err := svc.ListMemberships(context.Background(), tc.token, memberID, auth.PageMetadata{Limit: tc.limit, Offset: tc.offset, Metadata: tc.metadata})
|
|
|
|
size := uint64(len(page.Groups))
|
|
|
|
assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected %d got %d\n", desc, tc.size, size))
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", desc, tc.err, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRemoveGroup(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
uid, err := idProvider.ID()
|
|
|
|
require.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
|
|
|
|
|
|
creationTime := time.Now().UTC()
|
|
|
|
group := auth.Group{
|
|
|
|
Name: groupName,
|
|
|
|
OwnerID: uid,
|
|
|
|
CreatedAt: creationTime,
|
|
|
|
UpdatedAt: creationTime,
|
|
|
|
}
|
|
|
|
|
|
|
|
group, err = svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("group save got unexpected error: %s", err))
|
|
|
|
|
|
|
|
err = svc.RemoveGroup(context.Background(), "wrongToken", group.ID)
|
2022-02-01 17:33:23 +01:00
|
|
|
assert.True(t, errors.Contains(err, errors.ErrAuthentication), fmt.Sprintf("Unauthorized access: expected %v got %v", errors.ErrAuthentication, err))
|
2021-03-04 10:29:03 +01:00
|
|
|
|
|
|
|
err = svc.RemoveGroup(context.Background(), apiToken, "wrongID")
|
2022-02-14 22:49:23 +01:00
|
|
|
assert.True(t, errors.Contains(err, errors.ErrNotFound), fmt.Sprintf("Remove group with wrong id: expected %v got %v", errors.ErrNotFound, err))
|
2021-03-04 10:29:03 +01:00
|
|
|
|
|
|
|
gp, err := svc.ListGroups(context.Background(), apiToken, auth.PageMetadata{Level: auth.MaxLevel})
|
|
|
|
require.Nil(t, err, fmt.Sprintf("list groups unexpected error: %s", err))
|
|
|
|
assert.True(t, gp.Total == 1, fmt.Sprintf("retrieve members of a group: expected %d got %d\n", 1, gp.Total))
|
|
|
|
|
|
|
|
err = svc.RemoveGroup(context.Background(), apiToken, group.ID)
|
|
|
|
assert.True(t, errors.Contains(err, nil), fmt.Sprintf("Unauthorized access: expected %v got %v", nil, err))
|
|
|
|
|
|
|
|
gp, err = svc.ListGroups(context.Background(), apiToken, auth.PageMetadata{Level: auth.MaxLevel})
|
|
|
|
require.Nil(t, err, fmt.Sprintf("list groups save unexpected error: %s", err))
|
|
|
|
assert.True(t, gp.Total == 0, fmt.Sprintf("retrieve members of a group: expected %d got %d\n", 0, gp.Total))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAssign(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
uid, err := idProvider.ID()
|
|
|
|
require.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
|
|
|
|
|
|
creationTime := time.Now().UTC()
|
|
|
|
group := auth.Group{
|
|
|
|
Name: groupName + "Updated",
|
|
|
|
OwnerID: uid,
|
|
|
|
CreatedAt: creationTime,
|
|
|
|
UpdatedAt: creationTime,
|
|
|
|
}
|
|
|
|
|
|
|
|
group, err = svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("group save got unexpected error: %s", err))
|
|
|
|
|
|
|
|
mid, err := idProvider.ID()
|
|
|
|
require.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
|
|
|
|
|
|
err = svc.Assign(context.Background(), apiToken, group.ID, "things", mid)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("member assign save unexpected error: %s", err))
|
|
|
|
|
2021-10-27 00:38:28 +02:00
|
|
|
// check access control policies things members.
|
2021-11-08 14:55:18 +03:00
|
|
|
subjectSet := fmt.Sprintf("%s:%s#%s", "members", group.ID, memberRelation)
|
2021-10-27 00:38:28 +02:00
|
|
|
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: mid, Relation: "read", Subject: subjectSet})
|
|
|
|
require.Nil(t, err, fmt.Sprintf("entites having an access to group %s must have %s policy on %s: %s", group.ID, "read", mid, err))
|
|
|
|
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: mid, Relation: "write", Subject: subjectSet})
|
|
|
|
require.Nil(t, err, fmt.Sprintf("entites having an access to group %s must have %s policy on %s: %s", group.ID, "write", mid, err))
|
|
|
|
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: mid, Relation: "delete", Subject: subjectSet})
|
|
|
|
require.Nil(t, err, fmt.Sprintf("entites having an access to group %s must have %s policy on %s: %s", group.ID, "delete", mid, err))
|
|
|
|
|
2021-03-04 10:29:03 +01:00
|
|
|
mp, err := svc.ListMembers(context.Background(), apiToken, group.ID, "things", auth.PageMetadata{Offset: 0, Limit: 10})
|
|
|
|
require.Nil(t, err, fmt.Sprintf("member assign save unexpected error: %s", err))
|
|
|
|
assert.True(t, mp.Total == 1, fmt.Sprintf("retrieve members of a group: expected %d got %d\n", 1, mp.Total))
|
|
|
|
|
|
|
|
err = svc.Assign(context.Background(), "wrongToken", group.ID, "things", mid)
|
2022-02-01 17:33:23 +01:00
|
|
|
assert.True(t, errors.Contains(err, errors.ErrAuthentication), fmt.Sprintf("Unauthorized access: expected %v got %v", errors.ErrAuthentication, err))
|
2021-03-04 10:29:03 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnassign(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-03-04 10:29:03 +01:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
uid, err := idProvider.ID()
|
|
|
|
require.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
|
|
|
|
|
|
creationTime := time.Now().UTC()
|
|
|
|
group := auth.Group{
|
|
|
|
Name: groupName + "Updated",
|
|
|
|
OwnerID: uid,
|
|
|
|
CreatedAt: creationTime,
|
|
|
|
UpdatedAt: creationTime,
|
|
|
|
}
|
|
|
|
|
|
|
|
group, err = svc.CreateGroup(context.Background(), apiToken, group)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("group save got unexpected error: %s", err))
|
|
|
|
|
|
|
|
mid, err := idProvider.ID()
|
|
|
|
require.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
|
|
|
|
|
|
err = svc.Assign(context.Background(), apiToken, group.ID, "things", mid)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("member assign save unexpected error: %s", err))
|
|
|
|
|
|
|
|
mp, err := svc.ListMembers(context.Background(), apiToken, group.ID, "things", auth.PageMetadata{Limit: 10, Offset: 0})
|
|
|
|
require.Nil(t, err, fmt.Sprintf("member assign save unexpected error: %s", err))
|
|
|
|
assert.True(t, mp.Total == 1, fmt.Sprintf("retrieve members of a group: expected %d got %d\n", 1, mp.Total))
|
|
|
|
|
|
|
|
err = svc.Unassign(context.Background(), apiToken, group.ID, mid)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("member unassign save unexpected error: %s", err))
|
|
|
|
|
|
|
|
mp, err = svc.ListMembers(context.Background(), apiToken, group.ID, "things", auth.PageMetadata{Limit: 10, Offset: 0})
|
|
|
|
require.Nil(t, err, fmt.Sprintf("member assign save unexpected error: %s", err))
|
|
|
|
assert.True(t, mp.Total == 0, fmt.Sprintf("retrieve members of a group: expected %d got %d\n", 0, mp.Total))
|
|
|
|
|
|
|
|
err = svc.Unassign(context.Background(), "wrongToken", group.ID, mid)
|
2022-02-01 17:33:23 +01:00
|
|
|
assert.True(t, errors.Contains(err, errors.ErrAuthentication), fmt.Sprintf("Unauthorized access: expected %v got %v", errors.ErrAuthentication, err))
|
2021-03-04 10:29:03 +01:00
|
|
|
|
|
|
|
err = svc.Unassign(context.Background(), apiToken, group.ID, mid)
|
2022-02-14 22:49:23 +01:00
|
|
|
assert.True(t, errors.Contains(err, errors.ErrNotFound), fmt.Sprintf("Unauthorized access: expected %v got %v", nil, err))
|
2021-03-04 10:29:03 +01:00
|
|
|
}
|
2021-10-27 00:38:28 +02:00
|
|
|
|
|
|
|
func TestAuthorize(t *testing.T) {
|
|
|
|
svc := newService()
|
|
|
|
|
2021-11-08 14:55:18 +03:00
|
|
|
pr := auth.PolicyReq{Object: authoritiesObj, Relation: memberRelation, Subject: id}
|
2021-10-27 00:38:28 +02:00
|
|
|
err := svc.Authorize(context.Background(), pr)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("authorizing initial %v policy expected to succeed: %s", pr, err))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddPolicy(t *testing.T) {
|
|
|
|
svc := newService()
|
|
|
|
|
|
|
|
pr := auth.PolicyReq{Object: "obj", Relation: "rel", Subject: "sub"}
|
|
|
|
err := svc.AddPolicy(context.Background(), pr)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("adding %v policy expected to succeed: %v", pr, err))
|
|
|
|
|
|
|
|
err = svc.Authorize(context.Background(), pr)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("checking shared %v policy expected to be succeed: %#v", pr, err))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeletePolicy(t *testing.T) {
|
|
|
|
svc := newService()
|
|
|
|
|
2021-11-08 14:55:18 +03:00
|
|
|
pr := auth.PolicyReq{Object: authoritiesObj, Relation: memberRelation, Subject: id}
|
2021-10-27 00:38:28 +02:00
|
|
|
err := svc.DeletePolicy(context.Background(), pr)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("deleting %v policy expected to succeed: %s", pr, err))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAssignAccessRights(t *testing.T) {
|
|
|
|
svc := newService()
|
|
|
|
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-10-27 00:38:28 +02:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
userGroupID := "user-group"
|
|
|
|
thingGroupID := "thing-group"
|
|
|
|
err = svc.AssignGroupAccessRights(context.Background(), apiToken, thingGroupID, userGroupID)
|
|
|
|
require.Nil(t, err, fmt.Sprintf("sharing the user group with thing group expected to succeed: %v", err))
|
|
|
|
|
2021-11-08 14:55:18 +03:00
|
|
|
err = svc.Authorize(context.Background(), auth.PolicyReq{Object: thingGroupID, Relation: memberRelation, Subject: fmt.Sprintf("%s:%s#%s", "members", userGroupID, memberRelation)})
|
2021-10-27 00:38:28 +02:00
|
|
|
require.Nil(t, err, fmt.Sprintf("checking shared group access policy expected to be succeed: %#v", err))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddPolicies(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-10-27 00:38:28 +02:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
thingID, err := idProvider.ID()
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
|
|
|
|
|
|
tmpID := "tmpid"
|
|
|
|
readPolicy := "read"
|
|
|
|
writePolicy := "write"
|
|
|
|
deletePolicy := "delete"
|
|
|
|
|
|
|
|
// Add read policy to users.
|
|
|
|
err = svc.AddPolicies(context.Background(), apiToken, thingID, []string{id, tmpID}, []string{readPolicy})
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("adding policies expected to succeed: %s", err))
|
|
|
|
|
|
|
|
// Add write and delete policies to users.
|
|
|
|
err = svc.AddPolicies(context.Background(), apiToken, thingID, []string{id, tmpID}, []string{writePolicy, deletePolicy})
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("adding multiple policies expected to succeed: %s", err))
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
desc string
|
|
|
|
policy auth.PolicyReq
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "check valid 'read' policy of user with id",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: readPolicy, Subject: id},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check valid 'write' policy of user with id",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: writePolicy, Subject: id},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check valid 'delete' policy of user with id",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: deletePolicy, Subject: id},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check valid 'read' policy of user with tmpid",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: readPolicy, Subject: tmpID},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check valid 'write' policy of user with tmpid",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: writePolicy, Subject: tmpID},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check valid 'delete' policy of user with tmpid",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: deletePolicy, Subject: tmpID},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check invalid 'access' policy of user with id",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: "access", Subject: id},
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrAuthorization,
|
2021-10-27 00:38:28 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check invalid 'access' policy of user with tmpid",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: "access", Subject: tmpID},
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrAuthorization,
|
2021-10-27 00:38:28 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
err := svc.Authorize(context.Background(), tc.policy)
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %v, got %v", tc.desc, tc.err, err))
|
|
|
|
}
|
|
|
|
}
|
2021-11-08 16:45:38 +03:00
|
|
|
|
|
|
|
func TestDeletePolicies(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-11-08 16:45:38 +03:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
thingID, err := idProvider.ID()
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
|
|
|
|
|
|
tmpID := "tmpid"
|
|
|
|
readPolicy := "read"
|
|
|
|
writePolicy := "write"
|
|
|
|
deletePolicy := "delete"
|
|
|
|
memberPolicy := "member"
|
|
|
|
|
|
|
|
// Add read, write and delete policies to users.
|
|
|
|
err = svc.AddPolicies(context.Background(), apiToken, thingID, []string{id, tmpID}, []string{readPolicy, writePolicy, deletePolicy, memberPolicy})
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("adding policies expected to succeed: %s", err))
|
|
|
|
|
|
|
|
// Delete multiple policies from single user.
|
|
|
|
err = svc.DeletePolicies(context.Background(), apiToken, thingID, []string{id}, []string{readPolicy, writePolicy})
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("deleting policies from single user expected to succeed: %s", err))
|
|
|
|
|
|
|
|
// Delete multiple policies from multiple user.
|
|
|
|
err = svc.DeletePolicies(context.Background(), apiToken, thingID, []string{id, tmpID}, []string{deletePolicy, memberPolicy})
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("deleting policies from multiple user expected to succeed: %s", err))
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
desc string
|
|
|
|
policy auth.PolicyReq
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "check non-existing 'read' policy of user with id",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: readPolicy, Subject: id},
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrAuthorization,
|
2021-11-08 16:45:38 +03:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check non-existing 'write' policy of user with id",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: writePolicy, Subject: id},
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrAuthorization,
|
2021-11-08 16:45:38 +03:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check non-existing 'delete' policy of user with id",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: deletePolicy, Subject: id},
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrAuthorization,
|
2021-11-08 16:45:38 +03:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check non-existing 'member' policy of user with id",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: memberPolicy, Subject: id},
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrAuthorization,
|
2021-11-08 16:45:38 +03:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check non-existing 'delete' policy of user with tmpid",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: deletePolicy, Subject: tmpID},
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrAuthorization,
|
2021-11-08 16:45:38 +03:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check non-existing 'member' policy of user with tmpid",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: memberPolicy, Subject: tmpID},
|
2022-01-27 17:03:57 +01:00
|
|
|
err: errors.ErrAuthorization,
|
2021-11-08 16:45:38 +03:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check valid 'read' policy of user with tmpid",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: readPolicy, Subject: tmpID},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "check valid 'write' policy of user with tmpid",
|
|
|
|
policy: auth.PolicyReq{Object: thingID, Relation: writePolicy, Subject: tmpID},
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
err := svc.Authorize(context.Background(), tc.policy)
|
|
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %v, got %v", tc.desc, tc.err, err))
|
|
|
|
}
|
|
|
|
}
|
2021-11-19 16:32:38 +03:00
|
|
|
|
|
|
|
func TestListPolicies(t *testing.T) {
|
|
|
|
svc := newService()
|
2021-12-24 14:53:06 +01:00
|
|
|
_, secret, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.LoginKey, IssuedAt: time.Now(), IssuerID: id, Subject: email})
|
2021-11-19 16:32:38 +03:00
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
key := auth.Key{
|
|
|
|
ID: "id",
|
|
|
|
Type: auth.APIKey,
|
|
|
|
IssuerID: id,
|
|
|
|
Subject: email,
|
|
|
|
IssuedAt: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, apiToken, err := svc.Issue(context.Background(), secret, key)
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("Issuing user's key expected to succeed: %s", err))
|
|
|
|
|
|
|
|
readPolicy := "read"
|
|
|
|
pageLen := 15
|
|
|
|
|
|
|
|
// Add arbitrary policies to the user.
|
|
|
|
for i := 0; i < pageLen; i++ {
|
|
|
|
err = svc.AddPolicies(context.Background(), apiToken, fmt.Sprintf("thing-%d", i), []string{id}, []string{readPolicy})
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("adding policies expected to succeed: %s", err))
|
|
|
|
}
|
|
|
|
|
|
|
|
page, err := svc.ListPolicies(context.Background(), auth.PolicyReq{Subject: id, Relation: readPolicy})
|
|
|
|
assert.Nil(t, err, fmt.Sprintf("listing policies expected to succeed: %s", err))
|
|
|
|
assert.Equal(t, pageLen, len(page.Policies), fmt.Sprintf("unexpected listing page size, expected %d, got %d: %v", pageLen, len(page.Policies), err))
|
|
|
|
|
|
|
|
}
|