Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
37
pkg/adminroles/roles.go
Normal file
37
pkg/adminroles/roles.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package adminroles
|
||||
|
||||
import "fiskerinc.com/modules/utils/envtool"
|
||||
|
||||
// RoleID for groups
|
||||
type RoleID string
|
||||
type RoleMap map[string][]RoleID
|
||||
|
||||
var (
|
||||
RoleCreate RoleID = RoleID(envtool.GetEnv("ROLE_CREATE", "REPLACE_ME"))
|
||||
RoleReadOnly RoleID = RoleID(envtool.GetEnv("ROLE_READ_ONLY", "REPLACE_ME"))
|
||||
RoleDelete RoleID = RoleID(envtool.GetEnv("ROLE_DELETE", "REPLACE_ME"))
|
||||
RoleGenerateCertificate RoleID = RoleID(envtool.GetEnv("ROLE_GENERATE_CERTIFICATE", "REPLACE_ME"))
|
||||
RoleManufacture RoleID = RoleID(envtool.GetEnv("ROLE_MANUFACTURE", "REPLACE_ME"))
|
||||
RoleCarDiagnostic RoleID = RoleID(envtool.GetEnv("ROLE_CAR_DIAGNOSTIC", "REPLACE_ME"))
|
||||
RoleSupplier RoleID = RoleID(envtool.GetEnv("ROLE_SUPPLIER", "REPLACE_ME"))
|
||||
RoleSupplierApprover RoleID = RoleID(envtool.GetEnv("ROLE_SUPPLIER_APPROVER", "REPLACE_ME"))
|
||||
RoleAfterSalesAccess RoleID = RoleID(envtool.GetEnv("ROLE_AFTER_SALES_ACCESS", "REPLACE_ME"))
|
||||
RoleAfterSalesAccessFSP RoleID = RoleID(envtool.GetEnv("ROLE_AFTER_SALES_ACCESS_FSP", "REPLACE_ME"))
|
||||
RoleSAPIntegration RoleID = RoleID(envtool.GetEnv("ROLE_SAP_INTEGRATION", "REPLACE_ME"))
|
||||
RoleMagna RoleID = RoleID(envtool.GetEnv("MAGNA_GROUP_ID", "REPLACE_ME"))
|
||||
RoleManifestMigration RoleID = RoleID(envtool.GetEnv("ROLE_MANIFEST_MIGRATION", "REPLACE_ME"))
|
||||
RoleUpdateDeploy RoleID = RoleID(envtool.GetEnv("ROLE_UPDATE_DEPLOY", "REPLACE_ME"))
|
||||
)
|
||||
|
||||
func (r RoleMap) CopyAndMerge(m RoleMap) RoleMap {
|
||||
nMap := make(RoleMap)
|
||||
for k, v := range r {
|
||||
nMap[k] = v
|
||||
}
|
||||
|
||||
for k, v := range m {
|
||||
nMap[k] = v
|
||||
}
|
||||
|
||||
return nMap
|
||||
}
|
||||
109
pkg/adminroles/roles_checker.go
Normal file
109
pkg/adminroles/roles_checker.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package adminroles
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"fiskerinc.com/modules/validator"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const MissingPermissionError = "missing permission"
|
||||
|
||||
type RolesChecker struct {
|
||||
RequiredRoles []string
|
||||
}
|
||||
|
||||
func (rc *RolesChecker) Check(roles []string) error {
|
||||
if len(rc.RequiredRoles) != 0 {
|
||||
return rc.HasRole(roles)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rc *RolesChecker) CheckGroups(groups interface{}) error {
|
||||
if len(rc.RequiredRoles) != 0 {
|
||||
roles, err := rc.parseRolesFromGroups(groups)
|
||||
if err != nil {
|
||||
return errors.New(MissingPermissionError)
|
||||
}
|
||||
|
||||
return rc.HasRole(roles)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rc *RolesChecker) HasRole(roles []string) error {
|
||||
err := validator.ValidateField(roles, "max=1024,dive,uuid")
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
for _, required := range rc.RequiredRoles {
|
||||
if rc.containsRole(required, roles) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New(MissingPermissionError)
|
||||
}
|
||||
|
||||
func (rc *RolesChecker) parseRolesFromGroups(groups interface{}) ([]string, error) {
|
||||
|
||||
if str, ok := groups.(string); ok {
|
||||
return rc.parseStringRoles(str)
|
||||
}
|
||||
|
||||
if items, ok := groups.([]interface{}); ok && len(items) > 0 {
|
||||
if _, ok := items[0].(string); ok {
|
||||
return rc.parseSliceRoles(items)
|
||||
}
|
||||
}
|
||||
return nil, errors.New(MissingPermissionError)
|
||||
}
|
||||
|
||||
func (rc *RolesChecker) parseSliceRoles(groups []interface{}) ([]string, error) {
|
||||
items := make([]string, len(groups))
|
||||
|
||||
for i, item := range groups {
|
||||
items[i] = item.(string)
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (rc *RolesChecker) parseStringRoles(groups string) ([]string, error) {
|
||||
clean := strings.Trim(strings.ReplaceAll(groups, " ", ""), "[]")
|
||||
if len(clean) == 0 {
|
||||
return nil, errors.New(MissingPermissionError)
|
||||
}
|
||||
|
||||
items := strings.Split(clean, ",")
|
||||
if items == nil || len(items) == 0 {
|
||||
return nil, errors.New(MissingPermissionError)
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (rc *RolesChecker) containsRole(role string, groups []string) bool {
|
||||
for _, group := range groups {
|
||||
if role == group {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (rc *RolesChecker) SetRequiredRoles(roles []RoleID) {
|
||||
result := make([]string, len(roles))
|
||||
|
||||
for i, role := range roles {
|
||||
result[i] = string(role)
|
||||
}
|
||||
|
||||
rc.RequiredRoles = result
|
||||
}
|
||||
117
pkg/adminroles/roles_checker_test.go
Normal file
117
pkg/adminroles/roles_checker_test.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package adminroles_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"fiskerinc.com/modules/adminroles"
|
||||
"fiskerinc.com/modules/testhelper"
|
||||
)
|
||||
|
||||
const testRole = "7bcdcdb2-3279-44bf-a998-771bab4b33e1"
|
||||
const missingPermission = "missing permission"
|
||||
|
||||
func TestCheck(t *testing.T) {
|
||||
type testCase struct {
|
||||
Name string
|
||||
Roles []string
|
||||
ExpectedError string
|
||||
}
|
||||
|
||||
tests := []testCase{
|
||||
{
|
||||
Name: "Nil roles",
|
||||
Roles: nil,
|
||||
ExpectedError: missingPermission,
|
||||
},
|
||||
{
|
||||
Name: "Empty roles",
|
||||
Roles: []string{},
|
||||
ExpectedError: missingPermission,
|
||||
},
|
||||
{
|
||||
Name: "Bad role",
|
||||
Roles: []string{"XXXXXXXXXXXXX"},
|
||||
ExpectedError: "Key: '[0]' Error:Field validation for '[0]' failed on the 'uuid' tag",
|
||||
},
|
||||
{
|
||||
Name: "Bad role 2",
|
||||
Roles: []string{testRole, "YYYYYY", "ZZZZZZZ"},
|
||||
ExpectedError: `Key: '[1]' Error:Field validation for '[1]' failed on the 'uuid' tag
|
||||
Key: '[2]' Error:Field validation for '[2]' failed on the 'uuid' tag`,
|
||||
},
|
||||
{
|
||||
Name: "Good",
|
||||
Roles: []string{testRole},
|
||||
ExpectedError: "",
|
||||
},
|
||||
}
|
||||
|
||||
checker := adminroles.RolesChecker{
|
||||
RequiredRoles: []string{testRole},
|
||||
}
|
||||
for _, test := range tests {
|
||||
err := checker.Check(test.Roles)
|
||||
if err != nil && err.Error() != test.ExpectedError {
|
||||
t.Errorf(testhelper.TestErrorTemplate, test.Name, test.ExpectedError, err.Error())
|
||||
}
|
||||
if test.ExpectedError == "" && err != nil {
|
||||
t.Errorf(testhelper.TestErrorTemplate, test.Name, test.ExpectedError, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckGroup(t *testing.T) {
|
||||
|
||||
type testCase struct {
|
||||
Name string
|
||||
Groups string
|
||||
ExpectedError string
|
||||
}
|
||||
|
||||
tests := []testCase{
|
||||
{
|
||||
Name: "No groups",
|
||||
Groups: "",
|
||||
ExpectedError: missingPermission,
|
||||
},
|
||||
{
|
||||
Name: "No groups 2",
|
||||
Groups: " ",
|
||||
ExpectedError: missingPermission,
|
||||
},
|
||||
{
|
||||
Name: "Does not have group",
|
||||
Groups: "[8d8278a5-9c0e-4c7f-918a-811fd1d236e4, 6c3cf98d-0ada-48c6-ae94-b171cfa275fc, 56ef4bec-d739-4ddf-a003-ecc813085b8d, efcc3025-e2d8-4212-8227-805c7be39d2c, 5515a98f-4668-4121-8e8d-fee2825699cf, 86956a2f-8d46-47ff-9b29-f99079ae3c1d, c4d4361c-8882-47b4-8641-fd3ab68ae722]",
|
||||
ExpectedError: missingPermission,
|
||||
},
|
||||
{
|
||||
Name: "Partial role id",
|
||||
Groups: "[7bcdcdb2-3279-44bf-a998]",
|
||||
ExpectedError: "Key: '[0]' Error:Field validation for '[0]' failed on the 'uuid' tag",
|
||||
},
|
||||
{
|
||||
Name: "Bad group ids",
|
||||
Groups: "[[8d8278a59c0e4c7f918a811fd1d236e4, 6c3cf98d-0ada-48c6-ae94-b171cfa275fcXXXXXXX]",
|
||||
ExpectedError: `Key: '[0]' Error:Field validation for '[0]' failed on the 'uuid' tag
|
||||
Key: '[1]' Error:Field validation for '[1]' failed on the 'uuid' tag`,
|
||||
},
|
||||
{
|
||||
Name: "Has permission",
|
||||
Groups: "[8d8278a5-9c0e-4c7f-918a-811fd1d236e4, 6c3cf98d-0ada-48c6-ae94-b171cfa275fc, 56ef4bec-d739-4ddf-a003-ecc813085b8d, efcc3025-e2d8-4212-8227-805c7be39d2c, 5515a98f-4668-4121-8e8d-fee2825699cf, 86956a2f-8d46-47ff-9b29-f99079ae3c1d, c4d4361c-8882-47b4-8641-fd3ab68ae722, 7bcdcdb2-3279-44bf-a998-771bab4b33e1]",
|
||||
ExpectedError: "",
|
||||
},
|
||||
}
|
||||
|
||||
checker := adminroles.RolesChecker{
|
||||
RequiredRoles: []string{testRole},
|
||||
}
|
||||
for _, test := range tests {
|
||||
err := checker.CheckGroups(test.Groups)
|
||||
if err != nil && err.Error() != test.ExpectedError {
|
||||
t.Errorf(testhelper.TestErrorTemplate, test.Name, test.ExpectedError, err.Error())
|
||||
}
|
||||
if test.ExpectedError == "" && err != nil {
|
||||
t.Errorf(testhelper.TestErrorTemplate, test.Name, test.ExpectedError, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user