mirror of
https://github.com/paralus/paralus.git
synced 2026-08-24 15:47:19 +00:00
Merge pull request #12 from paralus/imporove-coverage
Imporove coverage
This commit is contained in:
@@ -14,7 +14,7 @@ func GetProjectNamespaces(ctx context.Context, db bun.IDB, projectID uuid.UUID)
|
||||
|
||||
var panr []models.ProjectAccountNamespaceRole
|
||||
err := db.NewSelect().Model(&panr).Where("project_id = ?", projectID).Where("trash = ?", false).Scan(ctx)
|
||||
if err != sql.ErrNoRows {
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, err
|
||||
}
|
||||
for _, nr := range panr {
|
||||
@@ -23,7 +23,7 @@ func GetProjectNamespaces(ctx context.Context, db bun.IDB, projectID uuid.UUID)
|
||||
|
||||
var pgnr []models.ProjectGroupNamespaceRole
|
||||
err = db.NewSelect().Model(&pgnr).Where("project_id = ?", projectID).Where("trash = ?", false).Scan(ctx)
|
||||
if err != sql.ErrNoRows {
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, err
|
||||
}
|
||||
for _, nr := range pgnr {
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/google/uuid"
|
||||
userrpcv3 "github.com/paralus/paralus/proto/rpc/user"
|
||||
)
|
||||
|
||||
func TestApiKeyCreate(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ak := NewApiKeyService(db, getLogger())
|
||||
uuuid := uuid.NewString()
|
||||
auuid := uuid.NewString()
|
||||
req := &userrpcv3.ApiKeyRequest{Username: "user-" + uuuid, Id: uuuid}
|
||||
|
||||
// mocks
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_apikey"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(auuid, "apikey-"+auuid))
|
||||
|
||||
resp, err := ak.Create(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Error("unable to create apikey:", err)
|
||||
}
|
||||
if resp.ID != uuid.MustParse(auuid) {
|
||||
t.Errorf("incorrect id for apikey; expected '%v', got '%v'", uuid.MustParse(auuid), resp.ID)
|
||||
}
|
||||
if resp.Name != "apikey-"+auuid {
|
||||
t.Errorf("incorrect name for apikey; expected '%v', got '%v'", "apikey-"+auuid, resp.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApiKeyDelete(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ak := NewApiKeyService(db, getLogger())
|
||||
uuuid := uuid.NewString()
|
||||
req := &userrpcv3.ApiKeyRequest{Username: "user-" + uuuid, Id: uuuid}
|
||||
|
||||
// mocks
|
||||
mock.ExpectExec(`UPDATE "authsrv_apikey" AS "apikey" SET trash = TRUE WHERE \(account_id = 'user-` + uuuid + `'\) AND \(key = '` + uuuid + `'\)`).
|
||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
|
||||
_, err := ak.Delete(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Error("unable to delete apikey:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApiKeyGet(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ak := NewApiKeyService(db, getLogger())
|
||||
uuuid := uuid.NewString()
|
||||
req := &userrpcv3.ApiKeyRequest{Username: "user-" + uuuid, Id: uuuid}
|
||||
|
||||
// mocks
|
||||
mock.ExpectQuery(`SELECT "apikey"."id", "apikey"."name", .*FROM "authsrv_apikey" AS "apikey" WHERE \(name = 'user-` + uuuid + `'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(uuuid, "user-"+uuuid))
|
||||
|
||||
resp, err := ak.Get(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Error("unable to get apikey:", err)
|
||||
}
|
||||
if resp.ID != uuid.MustParse(uuuid) {
|
||||
t.Errorf("incorrect id for apikey; expected '%v', got '%v'", uuid.MustParse(uuuid), resp.ID)
|
||||
}
|
||||
if resp.Name != "user-"+uuuid {
|
||||
t.Errorf("incorrect name for apikey; expected '%v', got '%v'", "apikey-"+uuuid, resp.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApiKeyGetByKey(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ak := NewApiKeyService(db, getLogger())
|
||||
uuuid := uuid.NewString()
|
||||
req := &userrpcv3.ApiKeyRequest{Username: "user-" + uuuid, Id: uuuid}
|
||||
|
||||
// mocks
|
||||
mock.ExpectQuery(`SELECT "apikey"."id", "apikey"."name", .*FROM "authsrv_apikey" AS "apikey" WHERE \(key = '` + uuuid + `'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(uuuid, "user-"+uuuid))
|
||||
|
||||
resp, err := ak.GetByKey(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Error("unable to get apikey:", err)
|
||||
}
|
||||
if resp.ID != uuid.MustParse(uuuid) {
|
||||
t.Errorf("incorrect id for apikey; expected '%v', got '%v'", uuid.MustParse(uuuid), resp.ID)
|
||||
}
|
||||
if resp.Name != "user-"+uuuid {
|
||||
t.Errorf("incorrect name for apikey; expected '%v', got '%v'", "apikey-"+uuuid, resp.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApiKeyList(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ak := NewApiKeyService(db, getLogger())
|
||||
uuuid := uuid.NewString()
|
||||
req := &userrpcv3.ApiKeyRequest{Username: "user-" + uuuid, Id: uuuid}
|
||||
|
||||
// mocks
|
||||
mock.ExpectQuery(`SELECT "apikey"."id", "apikey"."name", .*FROM "authsrv_apikey" AS "apikey" WHERE \(account_id = 'user-` + uuuid + `'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(uuuid, "user-"+uuuid))
|
||||
|
||||
resp, err := ak.List(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Error("unable to list apikey:", err)
|
||||
}
|
||||
if resp.Items[0].Name != "user-"+uuuid {
|
||||
t.Errorf("incorrect name for apikey; expected '%v', got '%v'", "apikey-"+uuuid, resp.Items[0].Name)
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
type AuditLogService struct {
|
||||
auditQuery *ElasticSearchQuery
|
||||
auditQuery ElasticSearchQuery
|
||||
}
|
||||
|
||||
func NewAuditLogService(url string, auditPattern string, logPrefix string) (*AuditLogService, error) {
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
v1 "github.com/paralus/paralus/proto/rpc/audit"
|
||||
v3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
||||
)
|
||||
|
||||
type md struct {
|
||||
Source []string `json:"_source"`
|
||||
Aggs struct {
|
||||
GroupByProject struct {
|
||||
Aggs struct {
|
||||
GroupByType struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
Size int `json:"size"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_type"`
|
||||
GroupByUsername struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
Size int `json:"size"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_username"`
|
||||
} `json:"aggs"`
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
Size int `json:"size"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_project"`
|
||||
GroupByType struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_type"`
|
||||
GroupByUsername struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_username"`
|
||||
} `json:"aggs"`
|
||||
Query struct {
|
||||
Bool struct {
|
||||
Filter struct {
|
||||
Range struct {
|
||||
JSONTimestamp struct {
|
||||
Gte string `json:"gte"`
|
||||
Lt string `json:"lt"`
|
||||
} `json:"json.timestamp"`
|
||||
} `json:"range"`
|
||||
} `json:"filter"`
|
||||
Must []struct {
|
||||
Term struct {
|
||||
JSONCategory string `json:"json.category"`
|
||||
} `json:"term,omitempty"`
|
||||
Terms struct {
|
||||
JSONProject []string `json:"json.project"`
|
||||
} `json:"terms,omitempty"`
|
||||
QueryString struct {
|
||||
Query string `json:"query"`
|
||||
} `json:"query_string,omitempty"`
|
||||
} `json:"must"`
|
||||
} `json:"bool"`
|
||||
} `json:"query"`
|
||||
Size int `json:"size"`
|
||||
Sort struct {
|
||||
JSONTimestamp struct {
|
||||
Order string `json:"order"`
|
||||
} `json:"json.timestamp"`
|
||||
} `json:"sort"`
|
||||
}
|
||||
|
||||
type mockElasticSearchQuery struct {
|
||||
msg []bytes.Buffer
|
||||
}
|
||||
|
||||
func (m *mockElasticSearchQuery) Handle(msg bytes.Buffer) (map[string]interface{}, error) {
|
||||
m.msg = append(m.msg, msg)
|
||||
return map[string]interface{}{}, nil
|
||||
}
|
||||
|
||||
func TestGetAuditLogByProjectsSimple(t *testing.T) {
|
||||
esq := &mockElasticSearchQuery{}
|
||||
al := &AuditLogService{auditQuery: esq}
|
||||
req := v1.AuditLogSearchRequest{
|
||||
Filter: &v1.AuditLogQueryFilter{
|
||||
QueryString: "query-string",
|
||||
Projects: []string{"project-one", "project-two"},
|
||||
Timefrom: "now-1h",
|
||||
Type: "fake-type",
|
||||
User: "fake-user",
|
||||
Client: "fake-client",
|
||||
DashboardData: true,
|
||||
},
|
||||
}
|
||||
_, err := al.GetAuditLogByProjects(&req)
|
||||
if err != nil {
|
||||
t.Error("unable to get audit logs")
|
||||
}
|
||||
if len(esq.msg) != 1 {
|
||||
t.Fatalf("incorrect number of searches; expected '%v', got '%v'", 1, len(esq.msg))
|
||||
}
|
||||
m := &md{}
|
||||
err = json.Unmarshal(esq.msg[0].Bytes(), m)
|
||||
if err != nil {
|
||||
t.Fatal("unable to unmarshall es request")
|
||||
}
|
||||
expected := `{"_source":["json"],"aggs":{"group_by_project":{"aggs":{"group_by_type":{"terms":{"field":"json.type","size":1000}},"group_by_username":{"terms":{"field":"json.actor.account.username","size":1000}}},"terms":{"field":"json.project","size":1000}},"group_by_type":{"terms":{"field":"json.type"}},"group_by_username":{"terms":{"field":"json.actor.account.username"}}},"query":{"bool":{"filter":{"range":{"json.timestamp":{"gte":"now-1h","lt":"now"}}},"must":[{"term":{"json.category":"AUDIT"}},{"term":{"json.type":"fake-type"}},{"term":{"json.actor.account.username":"fake-user"}},{"term":{"json.client.type":"fake-client"}},{"terms":{"json.project":["project-one","project-two"]}},{"query_string":{"query":"query-string"}}]}},"size":0,"sort":{"json.timestamp":{"order":"desc"}}}`
|
||||
if strings.TrimSpace(esq.msg[0].String()) != expected {
|
||||
t.Errorf("incorrect es query; expected '%v', got '%v'", expected, strings.TrimSpace(esq.msg[0].String()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAuditLogByProjectsNoProject(t *testing.T) {
|
||||
esq := &mockElasticSearchQuery{}
|
||||
al := &AuditLogService{auditQuery: esq}
|
||||
req := v1.AuditLogSearchRequest{
|
||||
Metadata: &v3.Metadata{UrlScope: "url/project"},
|
||||
Filter: &v1.AuditLogQueryFilter{
|
||||
QueryString: "query-string",
|
||||
},
|
||||
}
|
||||
_, err := al.GetAuditLog(&req)
|
||||
if err != nil {
|
||||
t.Error("unable to get audit logs", err)
|
||||
}
|
||||
if len(esq.msg) != 1 {
|
||||
t.Fatalf("incorrect number of searches; expected '%v', got '%v'", 1, len(esq.msg))
|
||||
}
|
||||
m := &md{}
|
||||
err = json.Unmarshal(esq.msg[0].Bytes(), m)
|
||||
if err != nil {
|
||||
t.Fatal("unable to unmarshall es request")
|
||||
}
|
||||
|
||||
expected := `{"_source":["json"],"aggs":{"group_by_type":{"terms":{"field":"json.type"}},"group_by_username":{"terms":{"field":"json.actor.account.username"}}},"query":{"bool":{"must":[{"term":{"json.category":"AUDIT"}},{"terms":{"json.project":["project"]}},{"query_string":{"query":"query-string"}}]}},"size":500,"sort":{"json.timestamp":{"order":"desc"}}}`
|
||||
if strings.TrimSpace(esq.msg[0].String()) != expected {
|
||||
t.Errorf("incorrect es query; expected '%v', got '%v'", expected, strings.TrimSpace(esq.msg[0].String()))
|
||||
}
|
||||
}
|
||||
@@ -9,14 +9,18 @@ import (
|
||||
v6Client "github.com/elastic/go-elasticsearch"
|
||||
)
|
||||
|
||||
type ElasticSearchQuery struct {
|
||||
type elasticSearchQuery struct {
|
||||
url string
|
||||
indexPattern string
|
||||
logPrefix string
|
||||
esClient *v6Client.Client
|
||||
}
|
||||
|
||||
func NewElasticSearchQuery(url string, indexPattern string, logPrefix string) (*ElasticSearchQuery, error) {
|
||||
type ElasticSearchQuery interface {
|
||||
Handle(bytes.Buffer) (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
func NewElasticSearchQuery(url string, indexPattern string, logPrefix string) (ElasticSearchQuery, error) {
|
||||
cfg := v6Client.Config{
|
||||
Addresses: []string{
|
||||
url,
|
||||
@@ -33,7 +37,7 @@ func NewElasticSearchQuery(url string, indexPattern string, logPrefix string) (*
|
||||
// return nil, err
|
||||
// }
|
||||
// _log.Infow(logPrefix+":Connected to elastic search ", "cluster", res, "index", indexPattern)
|
||||
esQuery := &ElasticSearchQuery{
|
||||
esQuery := &elasticSearchQuery{
|
||||
url: url,
|
||||
indexPattern: indexPattern,
|
||||
logPrefix: logPrefix,
|
||||
@@ -43,7 +47,7 @@ func NewElasticSearchQuery(url string, indexPattern string, logPrefix string) (*
|
||||
}
|
||||
|
||||
//Handle Fires the search query
|
||||
func (q *ElasticSearchQuery) Handle(msg bytes.Buffer) (map[string]interface{}, error) {
|
||||
func (q *elasticSearchQuery) Handle(msg bytes.Buffer) (map[string]interface{}, error) {
|
||||
_log.Debugw("Searching elastic search: ", "index", q.indexPattern, "url", q.url, "q", q)
|
||||
res, err := q.esClient.Search(
|
||||
q.esClient.Search.WithContext(context.Background()),
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func TestGetProjectNamespaces(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
puuid := uuid.New()
|
||||
mock.ExpectQuery(`SELECT "projectaccountnamespacerole"."id", "projectaccountnamespacerole"."name", "projectaccountnamespacerole"."description", "projectaccountnamespacerole"."created_at", "projectaccountnamespacerole"."modified_at", "projectaccountnamespacerole"."trash", "projectaccountnamespacerole"."organization_id", "projectaccountnamespacerole"."partner_id", "projectaccountnamespacerole"."role_id", "projectaccountnamespacerole"."account_id", "projectaccountnamespacerole"."project_id", "projectaccountnamespacerole"."namespace", "projectaccountnamespacerole"."active" FROM "authsrv_projectaccountnamespacerole" AS "projectaccountnamespacerole" WHERE \(project_id = '` + puuid.String() + `'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"namespace"}).AddRow("namespace1"))
|
||||
mock.ExpectQuery(`SELECT "projectgroupnamespacerole"."id", "projectgroupnamespacerole"."name", "projectgroupnamespacerole"."description", "projectgroupnamespacerole"."created_at", "projectgroupnamespacerole"."modified_at", "projectgroupnamespacerole"."trash", "projectgroupnamespacerole"."organization_id", "projectgroupnamespacerole"."partner_id", "projectgroupnamespacerole"."role_id", "projectgroupnamespacerole"."group_id", "projectgroupnamespacerole"."project_id", "projectgroupnamespacerole"."namespace", "projectgroupnamespacerole"."active" FROM "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" WHERE \(project_id = '` + puuid.String() + `'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"namespace"}).AddRow("namespace2"))
|
||||
|
||||
ns := NewNamespaceService(db)
|
||||
nl, err := ns.GetProjectNamespaces(context.Background(), puuid)
|
||||
if err != nil {
|
||||
t.Fatal("unable to get namespaces", err)
|
||||
}
|
||||
if len(nl) != 2 {
|
||||
t.Errorf("incorrect number of namespaces; expected '%v', got '%v'", 2, len(nl))
|
||||
}
|
||||
if nl[0] != "namespace1" {
|
||||
t.Errorf("incorrect namespace name; expected '%v', got '%v'", "namespace1", nl[0])
|
||||
}
|
||||
if nl[1] != "namespace2" {
|
||||
t.Errorf("incorrect namespace name; expected '%v', got '%v'", "namespace2", nl[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountProjectNamespaces(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
puuid := uuid.New()
|
||||
uuuid := uuid.New()
|
||||
mock.ExpectQuery(`SELECT "projectaccountnamespacerole"."id", "projectaccountnamespacerole"."name", "projectaccountnamespacerole"."description", "projectaccountnamespacerole"."created_at", "projectaccountnamespacerole"."modified_at", "projectaccountnamespacerole"."trash", "projectaccountnamespacerole"."organization_id", "projectaccountnamespacerole"."partner_id", "projectaccountnamespacerole"."role_id", "projectaccountnamespacerole"."account_id", "projectaccountnamespacerole"."project_id", "projectaccountnamespacerole"."namespace", "projectaccountnamespacerole"."active" FROM "authsrv_projectaccountnamespacerole" AS "projectaccountnamespacerole" WHERE \(project_id = '` + puuid.String() + `'\) AND \(account_id = '` + uuuid.String() + `'\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"namespace"}).AddRow("namespace1"))
|
||||
|
||||
ns := NewNamespaceService(db)
|
||||
nl, err := ns.GetAccountProjectNamespaces(context.Background(), puuid, uuuid)
|
||||
if err != nil {
|
||||
t.Fatal("unable to get namespaces", err)
|
||||
}
|
||||
if len(nl) != 1 {
|
||||
t.Errorf("incorrect number of namespaces; expected '%v', got '%v'", 1, len(nl))
|
||||
}
|
||||
if nl[0] != "namespace1" {
|
||||
t.Errorf("incorrect namespace name; expected '%v', got '%v'", "namespace1", nl[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetGroupProjectNamespaces(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
puuid := uuid.New()
|
||||
uuuid := uuid.New()
|
||||
mock.ExpectQuery(`SELECT "projectgroupnamespacerole"."id", "projectgroupnamespacerole"."name", "projectgroupnamespacerole"."description", "projectgroupnamespacerole"."created_at", "projectgroupnamespacerole"."modified_at", "projectgroupnamespacerole"."trash", "projectgroupnamespacerole"."organization_id", "projectgroupnamespacerole"."partner_id", "projectgroupnamespacerole"."role_id", "projectgroupnamespacerole"."group_id", "projectgroupnamespacerole"."project_id", "projectgroupnamespacerole"."namespace", "projectgroupnamespacerole"."active" FROM "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" JOIN authsrv_groupaccount ON projectgroupnamespacerole.group_id=authsrv_groupaccount.group_id WHERE \(project_id = '+` + puuid.String() + `+'\) AND \(authsrv_groupaccount.account_id = '` + uuuid.String() + `'\) AND \(projectgroupnamespacerole.trash = FALSE\) AND \(authsrv_groupaccount.trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"namespace"}).AddRow("namespace1"))
|
||||
|
||||
ns := NewNamespaceService(db)
|
||||
nl, err := ns.GetGroupProjectNamespaces(context.Background(), puuid, uuuid)
|
||||
if err != nil {
|
||||
t.Fatal("unable to get namespaces", err)
|
||||
}
|
||||
if len(nl) != 1 {
|
||||
t.Errorf("incorrect number of namespaces; expected '%v', got '%v'", 1, len(nl))
|
||||
}
|
||||
if nl[0] != "namespace1" {
|
||||
t.Errorf("incorrect namespace name; expected '%v', got '%v'", "namespace1", nl[0])
|
||||
}
|
||||
}
|
||||
+168
-23
@@ -7,8 +7,10 @@ import (
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/google/uuid"
|
||||
"github.com/paralus/paralus/pkg/common"
|
||||
v3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
||||
systemv3 "github.com/paralus/paralus/proto/types/systempb/v3"
|
||||
userv3 "github.com/paralus/paralus/proto/types/userpb/v3"
|
||||
)
|
||||
|
||||
func performProjectBasicChecks(t *testing.T, project *systemv3.Project, puuid string) {
|
||||
@@ -25,10 +27,8 @@ func TestCreateProject(t *testing.T) {
|
||||
ps := NewProjectService(db, &mazc, getLogger(), true)
|
||||
|
||||
puuid := uuid.New().String()
|
||||
ouuid := uuid.New().String()
|
||||
|
||||
mock.ExpectQuery(`SELECT "organization"."id", "organization"."name"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid))
|
||||
addFetchExpectation(mock, "organization")
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_project"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid))
|
||||
@@ -68,6 +68,52 @@ func TestCreateProjectDuplicate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateProjectFull(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
mazc := mockAuthzClient{}
|
||||
ps := NewProjectService(db, &mazc, getLogger(), true)
|
||||
|
||||
puuid := uuid.New().String()
|
||||
|
||||
addFetchExpectation(mock, "organization")
|
||||
addFetchEmptyExpecteation(mock, "project") // not existing project
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_project"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid))
|
||||
mock.ExpectQuery(`SELECT "resourcerole"."id", "resourcerole"."name", "resourcerole"."description", "resourcerole"."created_at", "resourcerole"."modified_at", "resourcerole"."trash", "resourcerole"."organization_id", "resourcerole"."partner_id", "resourcerole"."is_global", "resourcerole"."builtin", "resourcerole"."scope" FROM "authsrv_resourcerole" AS "resourcerole" WHERE \(name = 'test-role'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name", "scope"}).AddRow(puuid, "resourcerole-"+puuid, "namespace"))
|
||||
addFetchExpectation(mock, "group")
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_projectgroupnamespacerole"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uuid.NewString()))
|
||||
mock.ExpectQuery(`SELECT "identities"."id".* FROM "identities" WHERE .*traits ->> 'email' = 'test-user'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "traits"}).AddRow(uuid.NewString(), []byte(`{"email":"test-user", "first_name": "John", "last_name": "Doe", "description": "The OG user."}`)))
|
||||
mock.ExpectQuery(`SELECT "resourcerole"."id", "resourcerole"."name", "resourcerole"."description", "resourcerole"."created_at", "resourcerole"."modified_at", "resourcerole"."trash", "resourcerole"."organization_id", "resourcerole"."partner_id", "resourcerole"."is_global", "resourcerole"."builtin", "resourcerole"."scope" FROM "authsrv_resourcerole" AS "resourcerole" WHERE \(name = 'test-role'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name", "scope"}).AddRow(puuid, "resourcerole-"+puuid, "namespace"))
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_projectaccountnamespacerole"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uuid.NewString()))
|
||||
mock.ExpectCommit()
|
||||
|
||||
te := []string{"test-project", "test-namespace", "test-group", "test-role", "test-user"}
|
||||
project := &systemv3.Project{
|
||||
Metadata: &v3.Metadata{Id: puuid, Name: "project-" + puuid, Organization: "orgname"},
|
||||
Spec: &systemv3.ProjectSpec{
|
||||
ProjectNamespaceRoles: []*userv3.ProjectNamespaceRole{
|
||||
{Project: &te[0], Namespace: &te[1], Group: &te[2], Role: te[3]},
|
||||
},
|
||||
UserRoles: []*userv3.UserRole{
|
||||
{User: te[4], Role: te[3]},
|
||||
},
|
||||
},
|
||||
}
|
||||
project, err := ps.Create(context.Background(), project)
|
||||
if err != nil {
|
||||
t.Fatal("could not create project:", err)
|
||||
}
|
||||
performProjectBasicChecks(t, project, puuid)
|
||||
}
|
||||
|
||||
func TestProjectDelete(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
@@ -109,8 +155,7 @@ func TestProjectDeleteNonExist(t *testing.T) {
|
||||
|
||||
puuid := uuid.New().String()
|
||||
|
||||
mock.ExpectQuery(`SELECT "project"."id", "project"."name", .* FROM "authsrv_project" AS "project" WHERE`).
|
||||
WithArgs().WillReturnError(fmt.Errorf("no data available"))
|
||||
addFailingFetchExpecteation(mock, "project")
|
||||
|
||||
project := &systemv3.Project{
|
||||
Metadata: &v3.Metadata{Id: puuid, Name: "project-" + puuid},
|
||||
@@ -128,18 +173,10 @@ func TestProjectGetByName(t *testing.T) {
|
||||
mazc := mockAuthzClient{}
|
||||
ps := NewProjectService(db, &mazc, getLogger(), true)
|
||||
|
||||
partuuid := uuid.New().String()
|
||||
ouuid := uuid.New().String()
|
||||
puuid := uuid.New().String()
|
||||
|
||||
mock.ExpectQuery(`SELECT "project"."id", "project"."name"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "organization_id", "partner_id"}).AddRow(puuid, ouuid, partuuid))
|
||||
|
||||
mock.ExpectQuery(`SELECT "organization"."id", "organization"."name"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid))
|
||||
|
||||
mock.ExpectQuery(`SELECT "partner"."id", "partner"."name"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(partuuid))
|
||||
addFetchExpectation(mock, "project")
|
||||
addFetchExpectation(mock, "organization")
|
||||
addFetchExpectation(mock, "partner")
|
||||
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group
|
||||
FROM "authsrv_projectgrouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgrouprole.role_id
|
||||
@@ -176,10 +213,9 @@ func TestProjectGetById(t *testing.T) {
|
||||
mazc := mockAuthzClient{}
|
||||
ps := NewProjectService(db, &mazc, getLogger(), true)
|
||||
|
||||
puuid := uuid.New().String()
|
||||
puuid := uuid.NewString()
|
||||
|
||||
mock.ExpectQuery(`SELECT "project"."id", "project"."name", .* FROM "authsrv_project" AS "project" WHERE .*id = '` + puuid + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(puuid, "project-"+puuid))
|
||||
addFetchByIdExpectation(mock, "project", puuid)
|
||||
|
||||
project := &systemv3.Project{
|
||||
Metadata: &v3.Metadata{Id: puuid, Name: "project-" + puuid},
|
||||
@@ -198,10 +234,7 @@ func TestProjectUpdate(t *testing.T) {
|
||||
mazc := mockAuthzClient{}
|
||||
ps := NewProjectService(db, &mazc, getLogger(), true)
|
||||
|
||||
puuid := uuid.New().String()
|
||||
|
||||
mock.ExpectQuery(`SELECT "project"."id", "project"."name", .* FROM "authsrv_project" AS "project" WHERE`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(puuid, "project-"+puuid))
|
||||
puuid := addFetchExpectation(mock, "project")
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectExec(`UPDATE "authsrv_projectgrouprole" AS "projectgrouprole" SET trash = TRUE WHERE`).WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
mock.ExpectQuery(`UPDATE "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" SET trash = TRUE WHERE ."project_id" = '` + puuid + `'. AND .trash = false. RETURNING *`).
|
||||
@@ -237,3 +270,115 @@ func TestProjectUpdate(t *testing.T) {
|
||||
t.Fatal("could not update project:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProjectList(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
mazc := mockAuthzClient{}
|
||||
ps := NewProjectService(db, &mazc, getLogger(), true)
|
||||
|
||||
uid := uuid.NewString()
|
||||
ouuid := addFetchExpectation(mock, "organization")
|
||||
puuid := addFetchExpectation(mock, "partner")
|
||||
mock.ExpectQuery(`SELECT "project"."id", "project"."name", .* FROM "authsrv_project" AS "project" WHERE \(partner_id = '` + puuid + `'\) AND \(organization_id = '` + ouuid + `'\) AND \(trash = false\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(uid, "project-"+uid))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group FROM "authsrv_projectgrouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgrouprole.role_id JOIN authsrv_group ON authsrv_group.id=authsrv_projectgrouprole.group_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectgrouprole.project_id WHERE \(authsrv_projectgrouprole.project_id = '` + uid + `'\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "group"}).AddRow("test-role1", "test-project1", "test-group1"))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group, namespace FROM "authsrv_projectgroupnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgroupnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectgroupnamespacerole.project_id JOIN authsrv_group ON authsrv_group.id=authsrv_projectgroupnamespacerole.group_id WHERE \(authsrv_projectgroupnamespacerole.project_id = '` + uid + `'\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "group", "namespace"}).AddRow("test-role2", "test-project2", "test-group2", "test-namespace2"))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user FROM "authsrv_projectaccountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id JOIN identities ON identities.id=authsrv_projectaccountresourcerole.account_id WHERE \(authsrv_projectaccountresourcerole.project_id = '` + uid + `'\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "user"}).AddRow("test-role3", "test-user3"))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user, namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN identities ON identities.id=authsrv_projectaccountnamespacerole.account_id WHERE \(authsrv_projectaccountnamespacerole.project_id = '` + uid + `'\) AND \(authsrv_projectaccountnamespacerole.trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "user", "namespace"}).AddRow("test-role4", "test-user4", "test-namespace4"))
|
||||
|
||||
project := &systemv3.Project{
|
||||
Metadata: &v3.Metadata{
|
||||
Organization: ouuid,
|
||||
},
|
||||
}
|
||||
pl, err := ps.List(context.Background(), project)
|
||||
if err != nil {
|
||||
t.Fatal("could not get project:", err)
|
||||
}
|
||||
if pl.Metadata.Count != 1 {
|
||||
t.Errorf("incorrect number of projects returned; expected '%v', got '%v'", 1, pl.Metadata.Count)
|
||||
}
|
||||
if pl.Items[0].Metadata.Name != "project-"+uid {
|
||||
t.Errorf("incorrect project name; expected '%v', got '%v'", "project-"+uid, pl.Items[0].Metadata.Name)
|
||||
}
|
||||
if *pl.Items[0].Spec.ProjectNamespaceRoles[0].Project != "test-project1" {
|
||||
t.Errorf("incorrect projectnamespacerole; expected '%v', got '%v'", "test-project1", *pl.Items[0].Spec.ProjectNamespaceRoles[0].Project)
|
||||
}
|
||||
if *pl.Items[0].Spec.ProjectNamespaceRoles[1].Namespace != "test-namespace2" {
|
||||
t.Errorf("incorrect projectnamespacerole; expected '%v', got '%v'", "test-namespace2", *pl.Items[0].Spec.ProjectNamespaceRoles[1].Namespace)
|
||||
}
|
||||
if pl.Items[0].Spec.UserRoles[0].User != "test-user3" {
|
||||
t.Errorf("incorrect userrole; expected '%v', got '%v'", "test-user3", pl.Items[0].Spec.UserRoles[0].User)
|
||||
}
|
||||
if pl.Items[0].Spec.UserRoles[1].Namespace != "test-namespace4" {
|
||||
t.Errorf("incorrect userrole; expected '%v', got '%v'", "test-namespace4", pl.Items[0].Spec.UserRoles[1].Namespace)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProjectListNonDev(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
mazc := mockAuthzClient{}
|
||||
ps := NewProjectService(db, &mazc, getLogger(), false)
|
||||
|
||||
uid := uuid.NewString()
|
||||
ouuid := addFetchExpectation(mock, "organization")
|
||||
puuid := addFetchExpectation(mock, "partner")
|
||||
uuuid := addUserFetchExpectation(mock)
|
||||
mock.ExpectQuery(`SELECT distinct account_id, project_id FROM "sentry_account_permission" AS "sap" WHERE \(sap.partner_id = '` + puuid + `'\) AND \(sap.organization_id = '` + ouuid + `'\) AND \(sap.account_id = '` + uuuid + `'\) AND \(sap.permission_name IN \('project.read', 'ops_star.all'\)\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"account_id", "project_id"}).AddRow(uuuid, uid))
|
||||
mock.ExpectQuery(`SELECT "project"."id", "project"."name", .* FROM "authsrv_project" AS "project" WHERE \(project.partner_id = '` + puuid + `'\) AND \(project.organization_id = '` + ouuid + `'\) AND \(project.trash = FALSE\) AND \(project.id IN \('` + uid + `'\)\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(uid, "project-"+uid))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group FROM "authsrv_projectgrouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgrouprole.role_id JOIN authsrv_group ON authsrv_group.id=authsrv_projectgrouprole.group_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectgrouprole.project_id WHERE \(authsrv_projectgrouprole.project_id = '` + uid + `'\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "group"}).AddRow("test-role1", "test-project1", "test-group1"))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group, namespace FROM "authsrv_projectgroupnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgroupnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectgroupnamespacerole.project_id JOIN authsrv_group ON authsrv_group.id=authsrv_projectgroupnamespacerole.group_id WHERE \(authsrv_projectgroupnamespacerole.project_id = '` + uid + `'\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "group", "namespace"}).AddRow("test-role2", "test-project2", "test-group2", "test-namespace2"))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user FROM "authsrv_projectaccountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id JOIN identities ON identities.id=authsrv_projectaccountresourcerole.account_id WHERE \(authsrv_projectaccountresourcerole.project_id = '` + uid + `'\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "user"}).AddRow("test-role3", "test-user3"))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user, namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN identities ON identities.id=authsrv_projectaccountnamespacerole.account_id WHERE \(authsrv_projectaccountnamespacerole.project_id = '` + uid + `'\) AND \(authsrv_projectaccountnamespacerole.trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "user", "namespace"}).AddRow("test-role4", "test-user4", "test-namespace4"))
|
||||
|
||||
project := &systemv3.Project{
|
||||
Metadata: &v3.Metadata{
|
||||
Organization: ouuid,
|
||||
},
|
||||
}
|
||||
|
||||
sd := v3.SessionData{Username: "user-" + uuuid}
|
||||
ctx := context.WithValue(context.Background(), common.SessionDataKey, &sd)
|
||||
pl, err := ps.List(ctx, project)
|
||||
if err != nil {
|
||||
t.Fatal("could not get project:", err)
|
||||
}
|
||||
|
||||
if pl.Metadata.Count != 1 {
|
||||
t.Errorf("incorrect number of projects returned; expected '%v', got '%v'", 1, pl.Metadata.Count)
|
||||
}
|
||||
|
||||
if pl.Items[0].Metadata.Name != "project-"+uid {
|
||||
t.Errorf("incorrect project name; expected '%v', got '%v'", "project-"+uid, pl.Items[0].Metadata.Name)
|
||||
}
|
||||
|
||||
if *pl.Items[0].Spec.ProjectNamespaceRoles[0].Project != "test-project1" {
|
||||
t.Errorf("incorrect projectnamespacerole; expected '%v', got '%v'", "test-project1", *pl.Items[0].Spec.ProjectNamespaceRoles[0].Project)
|
||||
}
|
||||
|
||||
if *pl.Items[0].Spec.ProjectNamespaceRoles[1].Namespace != "test-namespace2" {
|
||||
t.Errorf("incorrect projectnamespacerole; expected '%v', got '%v'", "test-namespace2", *pl.Items[0].Spec.ProjectNamespaceRoles[1].Namespace)
|
||||
}
|
||||
|
||||
if pl.Items[0].Spec.UserRoles[0].User != "test-user3" {
|
||||
t.Errorf("incorrect userrole; expected '%v', got '%v'", "test-user3", pl.Items[0].Spec.UserRoles[0].User)
|
||||
}
|
||||
|
||||
if pl.Items[0].Spec.UserRoles[1].Namespace != "test-namespace4" {
|
||||
t.Errorf("incorrect userrole; expected '%v', got '%v'", "test-namespace4", pl.Items[0].Spec.UserRoles[1].Namespace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
type RelayAuditService struct {
|
||||
relayQuery *ElasticSearchQuery
|
||||
relayQuery ElasticSearchQuery
|
||||
}
|
||||
|
||||
func NewRelayAuditService(url string, auditPattern string, logPrefix string) (*RelayAuditService, error) {
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
v1 "github.com/paralus/paralus/proto/rpc/audit"
|
||||
v3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
||||
)
|
||||
|
||||
type rmd struct {
|
||||
Source []string `json:"_source"`
|
||||
Aggs struct {
|
||||
GroupByCluster struct {
|
||||
Aggs struct {
|
||||
GroupByNamespace struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
Size int `json:"size"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_namespace"`
|
||||
GroupByUsername struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
Size int `json:"size"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_username"`
|
||||
} `json:"aggs"`
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
Size int `json:"size"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_cluster"`
|
||||
GroupByKind struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_kind"`
|
||||
GroupByMethod struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_method"`
|
||||
GroupByNamespace struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_namespace"`
|
||||
GroupByUsername struct {
|
||||
Terms struct {
|
||||
Field string `json:"field"`
|
||||
} `json:"terms"`
|
||||
} `json:"group_by_username"`
|
||||
} `json:"aggs"`
|
||||
Query struct {
|
||||
Bool struct {
|
||||
Filter struct {
|
||||
Range struct {
|
||||
JSONTs struct {
|
||||
Gte string `json:"gte"`
|
||||
Lt string `json:"lt"`
|
||||
} `json:"json.ts"`
|
||||
} `json:"range"`
|
||||
} `json:"filter"`
|
||||
Must []struct {
|
||||
Term struct {
|
||||
JSONUn string `json:"json.un"`
|
||||
} `json:"term,omitempty"`
|
||||
Terms struct {
|
||||
JSONProject []string `json:"json.project"`
|
||||
} `json:"terms,omitempty"`
|
||||
QueryString struct {
|
||||
Query string `json:"query"`
|
||||
} `json:"query_string,omitempty"`
|
||||
} `json:"must"`
|
||||
} `json:"bool"`
|
||||
} `json:"query"`
|
||||
Size int `json:"size"`
|
||||
Sort struct {
|
||||
JSONTs struct {
|
||||
Order string `json:"order"`
|
||||
} `json:"json.ts"`
|
||||
} `json:"sort"`
|
||||
}
|
||||
|
||||
func TestGetRelayAuditLogByProjectsSimple(t *testing.T) {
|
||||
esq := &mockElasticSearchQuery{}
|
||||
al := &RelayAuditService{relayQuery: esq}
|
||||
req := v1.RelayAuditSearchRequest{
|
||||
Filter: &v1.RelayAuditQueryFilter{
|
||||
QueryString: "query-string",
|
||||
Projects: []string{"project-one", "project-two"},
|
||||
Timefrom: "now-1h",
|
||||
Type: "test-type",
|
||||
User: "test-user",
|
||||
Client: "test-client",
|
||||
Cluster: "test-cluster",
|
||||
Namespace: "test-namespace",
|
||||
Kind: "test-kind",
|
||||
Method: "test-method",
|
||||
DashboardData: true,
|
||||
},
|
||||
}
|
||||
_, err := al.GetRelayAuditByProjects(&req)
|
||||
if err != nil {
|
||||
t.Error("unable to get audit logs")
|
||||
}
|
||||
if len(esq.msg) != 1 {
|
||||
t.Fatalf("incorrect number of searches; expected '%v', got '%v'", 1, len(esq.msg))
|
||||
}
|
||||
m := &rmd{}
|
||||
err = json.Unmarshal(esq.msg[0].Bytes(), m)
|
||||
if err != nil {
|
||||
t.Fatal("unable to unmarshall es request")
|
||||
}
|
||||
expected := `{"_source":["json"],"aggs":{"group_by_cluster":{"aggs":{"group_by_namespace":{"terms":{"field":"json.ns","size":1000}},"group_by_username":{"terms":{"field":"json.un","size":1000}}},"terms":{"field":"json.cn","size":1000}},"group_by_kind":{"terms":{"field":"json.k"}},"group_by_method":{"terms":{"field":"json.m"}},"group_by_namespace":{"terms":{"field":"json.ns"}},"group_by_username":{"terms":{"field":"json.un"}}},"query":{"bool":{"filter":{"range":{"json.ts":{"gte":"now-1h","lt":"now"}}},"must":[{"term":{"json.un":"test-user"}},{"term":{"json.cn":"test-cluster"}},{"term":{"json.ns":"test-namespace"}},{"term":{"json.k":"test-kind"}},{"term":{"json.m":"test-method"}},{"terms":{"json.project":["project-one","project-two"]}},{"query_string":{"query":"query-string"}}]}},"size":0,"sort":{"json.ts":{"order":"desc"}}}`
|
||||
if strings.TrimSpace(esq.msg[0].String()) != expected {
|
||||
t.Errorf("incorrect es query; expected '%v', got '%v'", expected, strings.TrimSpace(esq.msg[0].String()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRelayAuditLogByProjectsNoProject(t *testing.T) {
|
||||
esq := &mockElasticSearchQuery{}
|
||||
al := &RelayAuditService{relayQuery: esq}
|
||||
req := v1.RelayAuditSearchRequest{
|
||||
Metadata: &v3.Metadata{UrlScope: "url/project"},
|
||||
Filter: &v1.RelayAuditQueryFilter{
|
||||
QueryString: "query-string",
|
||||
},
|
||||
}
|
||||
_, err := al.GetRelayAudit(&req)
|
||||
if err != nil {
|
||||
t.Error("unable to get audit logs", err)
|
||||
}
|
||||
if len(esq.msg) != 1 {
|
||||
t.Fatalf("incorrect number of searches; expected '%v', got '%v'", 1, len(esq.msg))
|
||||
}
|
||||
m := &rmd{}
|
||||
err = json.Unmarshal(esq.msg[0].Bytes(), m)
|
||||
if err != nil {
|
||||
t.Fatal("unable to unmarshall es request")
|
||||
}
|
||||
|
||||
expected := `{"_source":["json"],"aggs":{"group_by_cluster":{"terms":{"field":"json.cn"}},"group_by_kind":{"terms":{"field":"json.k"}},"group_by_method":{"terms":{"field":"json.m"}},"group_by_namespace":{"terms":{"field":"json.ns"}},"group_by_username":{"terms":{"field":"json.un"}}},"query":{"bool":{"must":[{"terms":{"json.project":["project"]}},{"query_string":{"query":"query-string"}}]}},"size":500,"sort":{"json.ts":{"order":"desc"}}}`
|
||||
if strings.TrimSpace(esq.msg[0].String()) != expected {
|
||||
t.Errorf("incorrect es query; expected '%v', got '%v'", expected, strings.TrimSpace(esq.msg[0].String()))
|
||||
}
|
||||
}
|
||||
@@ -49,21 +49,6 @@ func (s *rolepermissionService) toV3Rolepermission(rolepermission *rolev3.RolePe
|
||||
return rolepermission
|
||||
}
|
||||
|
||||
func (s *rolepermissionService) getPartnerOrganization(ctx context.Context, rolepermission *rolev3.RolePermission) (uuid.UUID, uuid.UUID, error) {
|
||||
partner := rolepermission.GetMetadata().GetPartner()
|
||||
org := rolepermission.GetMetadata().GetOrganization()
|
||||
partnerId, err := dao.GetPartnerId(ctx, s.db, partner)
|
||||
if err != nil {
|
||||
return uuid.Nil, uuid.Nil, err
|
||||
}
|
||||
organizationId, err := dao.GetOrganizationId(ctx, s.db, org)
|
||||
if err != nil {
|
||||
return partnerId, uuid.Nil, err
|
||||
}
|
||||
return partnerId, organizationId, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *rolepermissionService) GetByName(ctx context.Context, rolepermission *rolev3.RolePermission) (*rolev3.RolePermission, error) {
|
||||
name := rolepermission.GetMetadata().GetName()
|
||||
entity, err := dao.GetByName(ctx, s.db, name, &models.ResourcePermission{})
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/paralus/paralus/pkg/query"
|
||||
commonv3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
||||
v3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
||||
rolev3 "github.com/paralus/paralus/proto/types/rolepb/v3"
|
||||
)
|
||||
|
||||
@@ -55,3 +56,63 @@ func TestRolePermissionList(t *testing.T) {
|
||||
t.Errorf("incorrect role ids returned when listing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRolePermissionListWithSelectors(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
rs := NewRolepermissionService(db)
|
||||
|
||||
ruuid1 := uuid.New().String()
|
||||
ruuid2 := uuid.New().String()
|
||||
puuid := uuid.New().String()
|
||||
ouuid := uuid.New().String()
|
||||
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcepermission.name as name, authsrv_resourcepermission.scope as scope FROM "authsrv_resourcepermission" WHERE \(scope = 'NAMESPACE'\) AND \(authsrv_resourcepermission.trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).
|
||||
AddRow(ruuid1, "role-"+ruuid1))
|
||||
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcepermission.name as name, authsrv_resourcepermission.scope as scope FROM "authsrv_resourcepermission" WHERE \(scope = 'PROJECT'\) AND \(authsrv_resourcepermission.trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).
|
||||
AddRow(ruuid2, "role-"+ruuid2))
|
||||
|
||||
req := &commonv3.QueryOptions{
|
||||
Partner: "partner-" + puuid,
|
||||
Organization: "org-" + ouuid,
|
||||
Selector: "namespace",
|
||||
}
|
||||
rolelist, err := rs.List(context.Background(), query.WithOptions(req))
|
||||
if err != nil {
|
||||
t.Fatal("could not list rolepermissions:", err)
|
||||
}
|
||||
if rolelist.Metadata.Count != 2 {
|
||||
t.Errorf("incorrect number of rolepermissions returned, expected 2; got %v", rolelist.Metadata.Count)
|
||||
}
|
||||
if rolelist.Items[0].Metadata.Name != "role-"+ruuid1 || rolelist.Items[1].Metadata.Name != "role-"+ruuid2 {
|
||||
t.Errorf("incorrect role ids returned when listing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRolePermissionGetByName(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
rs := NewRolepermissionService(db)
|
||||
|
||||
ruuid := uuid.New().String()
|
||||
|
||||
mock.ExpectQuery(`SELECT "resourcepermission"."id", "resourcepermission"."name".* FROM "authsrv_resourcepermission" AS "resourcepermission"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).
|
||||
AddRow(ruuid, "role-"+ruuid))
|
||||
|
||||
req := &rolev3.RolePermission{
|
||||
Metadata: &v3.Metadata{},
|
||||
}
|
||||
role, err := rs.GetByName(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Fatal("could not list rolepermissions:", err)
|
||||
}
|
||||
if role.Metadata.Name != "role-"+ruuid {
|
||||
t.Errorf("incorrect role name; expected '%v', got '%v'", "role-"+ruuid, role.Metadata.Name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
func getLogger() *zap.Logger {
|
||||
ao := audit.AuditOptions{
|
||||
LogPath: "stdout",
|
||||
LogPath: "/dev/stdout",
|
||||
MaxSizeMB: 1,
|
||||
MaxBackups: 10, // Should we let sidecar do rotation?
|
||||
MaxAgeDays: 10, // Make these configurable via env
|
||||
@@ -65,6 +65,16 @@ func idnamea(uid string, resource string) *string {
|
||||
return &name
|
||||
}
|
||||
|
||||
func addFetchEmptyExpecteation(mock sqlmock.Sqlmock, resource string) {
|
||||
mock.ExpectQuery(`SELECT "` + resource + `"."id" FROM "authsrv_` + resource + `" AS "` + resource + `"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}))
|
||||
}
|
||||
|
||||
func addFailingFetchExpecteation(mock sqlmock.Sqlmock, resource string) {
|
||||
mock.ExpectQuery(`SELECT "` + resource + `"."id" FROM "authsrv_` + resource + `" AS "` + resource + `"`).
|
||||
WithArgs().WillReturnError(fmt.Errorf("no data available"))
|
||||
}
|
||||
|
||||
func addFetchIdExpectation(mock sqlmock.Sqlmock, resource string) string {
|
||||
uid := uuid.New().String()
|
||||
mock.ExpectQuery(`SELECT "` + resource + `"."id" FROM "authsrv_` + resource + `" AS "` + resource + `"`).
|
||||
@@ -72,10 +82,22 @@ func addFetchIdExpectation(mock sqlmock.Sqlmock, resource string) string {
|
||||
return uid
|
||||
}
|
||||
|
||||
func addFetchByIdExpectation(mock sqlmock.Sqlmock, resource, uid string) {
|
||||
mock.ExpectQuery(`SELECT "` + resource + `"."id".* FROM "authsrv_` + resource + `" AS "` + resource + `" WHERE .id = '` + uid + `'.`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(uid, resource+"-"+uid))
|
||||
}
|
||||
|
||||
func addFetchIdByNameExpectation(mock sqlmock.Sqlmock, resource, name string) string {
|
||||
uid := uuid.NewString()
|
||||
mock.ExpectQuery(`SELECT "` + resource + `"."id" FROM "authsrv_` + resource + `" AS "` + resource + `" WHERE .name = '` + name + `'.`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uid))
|
||||
return uid
|
||||
}
|
||||
|
||||
func addFetchExpectation(mock sqlmock.Sqlmock, resource string) string {
|
||||
uid := uuid.New().String()
|
||||
mock.ExpectQuery(`SELECT "` + resource + `"."id".* FROM "authsrv_` + resource + `" AS "` + resource + `"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(uid, "role-name"))
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(uid, resource+"-name"))
|
||||
return uid
|
||||
}
|
||||
|
||||
@@ -152,6 +174,13 @@ func addUserFullFetchExpectation(mock sqlmock.Sqlmock) string {
|
||||
return uid
|
||||
}
|
||||
|
||||
func addUserFullFetchExpectationWithIdpGroups(mock sqlmock.Sqlmock) string {
|
||||
uid := uuid.New().String()
|
||||
mock.ExpectQuery(`SELECT "identities"."id", "identities"."schema_id", "identities"."traits", "identities"."created_at", "identities"."updated_at", "identities"."state", "identities"."state_changed_at", "identities"."nid", "identity_credential"."id" AS "identity_credential__id", "identity_credential"."identity_id" AS "identity_credential__identity_id", "identity_credential"."identity_credential_type_id" AS "identity_credential__identity_credential_type_id", "identity_credential__identity_credential_type"."id" AS "identity_credential__identity_credential_type__id", "identity_credential__identity_credential_type"."name" AS "identity_credential__identity_credential_type__name" FROM "identities" LEFT JOIN "identity_credentials" AS "identity_credential" ON ."identity_credential"."identity_id" = "identities"."id". LEFT JOIN "identity_credential_types" AS "identity_credential__identity_credential_type" ON ."identity_credential__identity_credential_type"."id" = "identity_credential"."identity_credential_type_id". WHERE .traits ->> 'email' = 'user-` + uid + `'.`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "traits", "identity_credential__identity_credential_type__name"}).AddRow(uid, []byte(`{"email":"user-`+uid+`", "first_name": "John", "last_name": "Doe", "description": "The OG user.", "idp_group": "BigShot"}`), "password"))
|
||||
return uid
|
||||
}
|
||||
|
||||
func addUsersGroupFetchExpectation(mock sqlmock.Sqlmock, user string) string {
|
||||
uid := uuid.New().String()
|
||||
mock.ExpectQuery(`SELECT "group"."id".* FROM "authsrv_group" AS "group" JOIN authsrv_groupaccount ON authsrv_groupaccount.group_id="group".id WHERE .authsrv_groupaccount.account_id = '` + user + `'`).
|
||||
|
||||
@@ -125,6 +125,9 @@ func (s *userService) createUserRoleRelations(ctx context.Context, db bun.IDB, u
|
||||
continue
|
||||
}
|
||||
role := pnr.GetRole()
|
||||
if role == "" {
|
||||
return &userv3.User{}, nil, fmt.Errorf("cannot use empty role")
|
||||
}
|
||||
entity, err := dao.GetByName(ctx, db, role, &models.Role{})
|
||||
if err != nil {
|
||||
return &userv3.User{}, nil, fmt.Errorf("unable to find role '%v'", role)
|
||||
@@ -445,6 +448,7 @@ func (s *userService) Create(ctx context.Context, user *userv3.User) (*userv3.Us
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
_log.Warn("unable to commit changes", err)
|
||||
return &userv3.User{}, err
|
||||
}
|
||||
|
||||
rl, err := s.ap.GetRecoveryLink(ctx, id)
|
||||
@@ -727,6 +731,7 @@ func (s *userService) Update(ctx context.Context, user *userv3.User) (*userv3.Us
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
_log.Warn("unable to commit changes", err)
|
||||
return &userv3.User{}, fmt.Errorf("unable to update user '%v'", name)
|
||||
}
|
||||
|
||||
CreateUserAuditEvent(ctx, s.al, s.db, AuditActionUpdate, user.GetMetadata().GetName(), usr.ID, rolesBefore, rolesAfter, groupsBefore, groupsAfter)
|
||||
|
||||
+206
-1
@@ -3,12 +3,14 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/google/uuid"
|
||||
"github.com/paralus/paralus/pkg/common"
|
||||
"github.com/paralus/paralus/pkg/query"
|
||||
userrpcv3 "github.com/paralus/paralus/proto/rpc/user"
|
||||
commonv3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
||||
v3 "github.com/paralus/paralus/proto/types/commonpb/v3"
|
||||
userv3 "github.com/paralus/paralus/proto/types/userpb/v3"
|
||||
@@ -127,7 +129,7 @@ func TestCreateUserWithRole(t *testing.T) {
|
||||
role.Project = &pruuid
|
||||
}
|
||||
if tc.namespace {
|
||||
var ns string = "ns"
|
||||
var ns = "ns"
|
||||
role.Namespace = &ns
|
||||
}
|
||||
mock.ExpectQuery(fmt.Sprintf(`INSERT INTO "%v"`, tc.dbname)).
|
||||
@@ -239,6 +241,92 @@ func TestUpdateUserWithGroup(t *testing.T) {
|
||||
performBasicAuthProviderChecks(t, *ap, 0, 1, 0, 0)
|
||||
}
|
||||
|
||||
func TestUpdateUserWithIdpGroupPassed(t *testing.T) {
|
||||
// Having idp groups passed down should not affect, it should come from db
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ap := &mockAuthProvider{}
|
||||
mazc := mockAuthzClient{}
|
||||
us := NewUserService(ap, db, &mazc, nil, common.CliConfigDownloadData{}, getLogger(), true)
|
||||
|
||||
// performing update
|
||||
uuuid := addUserFullFetchExpectation(mock)
|
||||
puuid, ouuid := addParterOrgFetchExpectation(mock)
|
||||
mock.ExpectBegin()
|
||||
_ = addUserRoleMappingsUpdateExpectation(mock, uuuid)
|
||||
addUserGroupMappingsUpdateExpectation(mock, uuuid)
|
||||
ruuid := addResourceRoleFetchExpectation(mock, "project")
|
||||
pruuid := addFetchExpectation(mock, "project")
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_projectaccountresourcerole"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uuid.New().String()))
|
||||
// addFetchExpectation(mock, "group")
|
||||
// mock.ExpectQuery(`INSERT INTO "authsrv_groupaccount"`).
|
||||
// WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uuid.New().String()))
|
||||
mock.ExpectCommit()
|
||||
|
||||
var ns = "ns"
|
||||
user := &userv3.User{
|
||||
Metadata: &v3.Metadata{Partner: "partner-" + puuid, Organization: "org-" + ouuid, Name: "user-" + uuuid},
|
||||
Spec: &userv3.UserSpec{
|
||||
IdpGroups: []string{"group"},
|
||||
ProjectNamespaceRoles: []*userv3.ProjectNamespaceRole{{Project: idnamea(pruuid, "project"), Namespace: &ns, Role: idname(ruuid, "role")}},
|
||||
},
|
||||
}
|
||||
user, err := us.Update(context.Background(), user)
|
||||
if err != nil {
|
||||
t.Fatal("could not create user:", err)
|
||||
}
|
||||
performUserBasicChecks(t, user, uuuid)
|
||||
if user.GetMetadata().GetName() != "user-"+uuuid {
|
||||
t.Errorf("expected name 'user-%v'; got '%v'", uuuid, user.GetMetadata().GetName())
|
||||
}
|
||||
performBasicAuthProviderChecks(t, *ap, 0, 1, 0, 0)
|
||||
}
|
||||
|
||||
func TestUpdateUserWithIdpGroupFetched(t *testing.T) {
|
||||
// Having idp groups passed down should not affect, it should come from db
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ap := &mockAuthProvider{}
|
||||
mazc := mockAuthzClient{}
|
||||
us := NewUserService(ap, db, &mazc, nil, common.CliConfigDownloadData{}, getLogger(), true)
|
||||
|
||||
// performing update
|
||||
uuuid := addUserFullFetchExpectationWithIdpGroups(mock)
|
||||
puuid, ouuid := addParterOrgFetchExpectation(mock)
|
||||
mock.ExpectBegin()
|
||||
_ = addUserRoleMappingsUpdateExpectation(mock, uuuid)
|
||||
addUserGroupMappingsUpdateExpectation(mock, uuuid)
|
||||
ruuid := addResourceRoleFetchExpectation(mock, "project")
|
||||
pruuid := addFetchExpectation(mock, "project")
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_projectaccountresourcerole"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uuid.New().String()))
|
||||
addFetchExpectation(mock, "group")
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_groupaccount"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uuid.New().String()))
|
||||
mock.ExpectCommit()
|
||||
|
||||
var ns = "ns"
|
||||
user := &userv3.User{
|
||||
Metadata: &v3.Metadata{Partner: "partner-" + puuid, Organization: "org-" + ouuid, Name: "user-" + uuuid},
|
||||
Spec: &userv3.UserSpec{
|
||||
IdpGroups: []string{"group"},
|
||||
ProjectNamespaceRoles: []*userv3.ProjectNamespaceRole{{Project: idnamea(pruuid, "project"), Namespace: &ns, Role: idname(ruuid, "role")}},
|
||||
},
|
||||
}
|
||||
user, err := us.Update(context.Background(), user)
|
||||
if err != nil {
|
||||
t.Fatal("could not create user:", err)
|
||||
}
|
||||
performUserBasicChecks(t, user, uuuid)
|
||||
if user.GetMetadata().GetName() != "user-"+uuuid {
|
||||
t.Errorf("expected name 'user-%v'; got '%v'", uuuid, user.GetMetadata().GetName())
|
||||
}
|
||||
performBasicAuthProviderChecks(t, *ap, 0, 1, 0, 0)
|
||||
}
|
||||
|
||||
func TestUpdateUserInvalid(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
@@ -468,6 +556,9 @@ func TestUserList(t *testing.T) {
|
||||
{"simple list", "", 50, 20, "", "", "", "", []string{}, ""},
|
||||
{"simple list with type", "", 50, 20, "", "", "", "", []string{}, "password"},
|
||||
{"sorted list", "", 50, 20, "email", "asc", "", "", []string{}, ""},
|
||||
{"sorted list with ALL projects", "", 50, 20, "email", "asc", "", "", []string{"ALL"}, ""},
|
||||
{"sorted list with single project", "", 50, 20, "email", "asc", "", "", []string{"project1"}, ""},
|
||||
{"sorted list with projects", "", 50, 20, "email", "asc", "", "", []string{"project1", "project2"}, ""},
|
||||
{"sorted list without dir", "", 50, 20, "email", "", "", "", []string{}, ""},
|
||||
{"sorted list with q", "filter-query", 50, 20, "email", "asc", "", "", []string{}, ""},
|
||||
{"sorted list with role", "", 50, 20, "email", "asc", "role-name", "", []string{}, ""},
|
||||
@@ -505,6 +596,12 @@ func TestUserList(t *testing.T) {
|
||||
if tc.group != "" {
|
||||
addFetchExpectation(mock, "group")
|
||||
}
|
||||
for _, p := range tc.projects {
|
||||
if p == "ALL" {
|
||||
continue
|
||||
}
|
||||
addFetchIdByNameExpectation(mock, "project", p)
|
||||
}
|
||||
if tc.role != "" || tc.group != "" || len(tc.projects) != 0 {
|
||||
addSentryLookupExpectation(mock, []string{uuuid1, uuuid2}, puuid, ouuid)
|
||||
mock.ExpectQuery(`SELECT "identities"."id", .*WHERE .identities.id IN .'` + uuuid1 + `', '` + uuuid2 + `'.. ` + q + order + `LIMIT ` + fmt.Sprint(tc.limit) + ` OFFSET ` + fmt.Sprint(tc.offset)).
|
||||
@@ -544,6 +641,7 @@ func TestUserList(t *testing.T) {
|
||||
Role: tc.role,
|
||||
Group: tc.group,
|
||||
Type: tc.utype,
|
||||
Project: strings.Join(tc.projects, ","),
|
||||
}
|
||||
|
||||
userlist, err := us.List(context.Background(), query.WithOptions(qo))
|
||||
@@ -633,3 +731,110 @@ func TestUserDeleteSelf(t *testing.T) {
|
||||
t.Fatal("user able to delete their own account")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserForgotPassword(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ap := &mockAuthProvider{}
|
||||
mazc := mockAuthzClient{}
|
||||
us := NewUserService(ap, db, &mazc, nil, common.CliConfigDownloadData{}, getLogger(), true)
|
||||
|
||||
uuuid := addUserFetchExpectation(mock)
|
||||
|
||||
fpreq := &userrpcv3.ForgotPasswordRequest{Username: "user-" + uuuid}
|
||||
fpresp, err := us.ForgotPassword(context.Background(), fpreq)
|
||||
if err != nil {
|
||||
t.Fatal("could not fetch password recovery link:", err)
|
||||
}
|
||||
if !strings.HasPrefix(fpresp.RecoveryLink, "https://recoverme.testing/") {
|
||||
t.Error("invalid recovery url generated")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserRetrieveCliConfigGet(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ap := &mockAuthProvider{}
|
||||
mazc := mockAuthzClient{}
|
||||
ks := NewApiKeyService(db, getLogger())
|
||||
us := NewUserService(ap, db, &mazc, ks, common.CliConfigDownloadData{}, getLogger(), true)
|
||||
|
||||
uuuid := uuid.NewString()
|
||||
auuid := uuid.NewString()
|
||||
mock.ExpectQuery(`SELECT sap.* FROM "sentry_account_permission" AS "sap" JOIN authsrv_project as proj ON \(proj.id = sap.project_id\) AND \(proj.default = TRUE\) WHERE \(account_id = '` + uuuid + `'\) LIMIT 1`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"account_id"}).AddRow(uuuid))
|
||||
_ = addFetchExpectation(mock, "project")
|
||||
_ = addFetchExpectation(mock, "organization")
|
||||
_ = addFetchExpectation(mock, "partner")
|
||||
|
||||
mock.ExpectQuery(`SELECT "apikey"."id", "apikey"."name",.* FROM "authsrv_apikey" AS "apikey" WHERE \(name = 'user-` + uuuid + `'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"key", "secret"}).AddRow(auuid, "apikey-"+auuid))
|
||||
|
||||
req := &userrpcv3.ApiKeyRequest{Username: "user-" + uuuid, Id: uuuid}
|
||||
resp, err := us.RetrieveCliConfig(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Fatal("could not fetch cli config:", err)
|
||||
}
|
||||
if resp.ApiKey != auuid {
|
||||
t.Error("incorrect apikey generated")
|
||||
}
|
||||
if resp.ApiSecret != "apikey-"+auuid {
|
||||
t.Error("incorrect apisecret generated")
|
||||
}
|
||||
if resp.Project != "project-name" {
|
||||
t.Error("invalid project name")
|
||||
}
|
||||
if resp.Organization != "organization-name" {
|
||||
t.Error("invalid organization name")
|
||||
}
|
||||
if resp.Partner != "partner-name" {
|
||||
t.Error("invalid partner name")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserRetrieveCliConfigCreate(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ap := &mockAuthProvider{}
|
||||
mazc := mockAuthzClient{}
|
||||
ks := NewApiKeyService(db, getLogger())
|
||||
us := NewUserService(ap, db, &mazc, ks, common.CliConfigDownloadData{}, getLogger(), true)
|
||||
|
||||
uuuid := uuid.NewString()
|
||||
auuid := uuid.NewString()
|
||||
mock.ExpectQuery(`SELECT sap.* FROM "sentry_account_permission" AS "sap" JOIN authsrv_project as proj ON \(proj.id = sap.project_id\) AND \(proj.default = TRUE\) WHERE \(account_id = '` + uuuid + `'\) LIMIT 1`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"account_id"}).AddRow(uuuid))
|
||||
_ = addFetchExpectation(mock, "project")
|
||||
_ = addFetchExpectation(mock, "organization")
|
||||
_ = addFetchExpectation(mock, "partner")
|
||||
|
||||
mock.ExpectQuery(`SELECT "apikey"."id", "apikey"."name",.* FROM "authsrv_apikey" AS "apikey" WHERE \(name = 'user-` + uuuid + `'\) AND \(trash = FALSE\)`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}))
|
||||
|
||||
mock.ExpectQuery(`INSERT INTO "authsrv_apikey"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(auuid))
|
||||
|
||||
req := &userrpcv3.ApiKeyRequest{Username: "user-" + uuuid, Id: uuuid}
|
||||
resp, err := us.RetrieveCliConfig(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Fatal("could not fetch cli config:", err)
|
||||
}
|
||||
if len(resp.ApiKey) == 0 {
|
||||
t.Error("no apikey generated")
|
||||
}
|
||||
if len(resp.ApiSecret) == 0 {
|
||||
t.Error("no apisecret generated")
|
||||
}
|
||||
if resp.Project != "project-name" {
|
||||
t.Error("invalid project name")
|
||||
}
|
||||
if resp.Organization != "organization-name" {
|
||||
t.Error("invalid organization name")
|
||||
}
|
||||
if resp.Partner != "partner-name" {
|
||||
t.Error("invalid partner name")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user