Add logic mapping applying a mapping
parent
b3f917e56c
commit
a61eb73a19
|
@ -0,0 +1,111 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
func MappedRole(o *chronograf.Organization, p oauth2.Principal) *chronograf.Role {
|
||||
roles := []*chronograf.Role{}
|
||||
for _, mapping := range o.Mappings {
|
||||
role := applyMapping(mapping, p)
|
||||
if role != nil {
|
||||
role.Organization = o.ID
|
||||
roles = append(roles, role)
|
||||
}
|
||||
}
|
||||
|
||||
return maxRole(roles)
|
||||
}
|
||||
|
||||
func applyMapping(m chronograf.Mapping, p oauth2.Principal) *chronograf.Role {
|
||||
switch m.Provider {
|
||||
case chronograf.MappingWildcard, p.Issuer:
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
switch m.Scheme {
|
||||
case chronograf.MappingWildcard, "oauth2":
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Group == chronograf.MappingWildcard {
|
||||
return &chronograf.Role{
|
||||
Name: m.GrantedRole,
|
||||
}
|
||||
}
|
||||
|
||||
groups := strings.Split(p.Group, ",")
|
||||
|
||||
match := matchGroup(m.Group, groups)
|
||||
|
||||
if match {
|
||||
return &chronograf.Role{
|
||||
Name: m.GrantedRole,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func matchGroup(match string, groups []string) bool {
|
||||
for _, group := range groups {
|
||||
if match == group {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func maxRole(roles []*chronograf.Role) *chronograf.Role {
|
||||
var max *chronograf.Role
|
||||
for _, role := range roles {
|
||||
max = maximumRole(max, role)
|
||||
}
|
||||
|
||||
return max
|
||||
}
|
||||
|
||||
func maximumRole(r1, r2 *chronograf.Role) *chronograf.Role {
|
||||
if r1 == nil {
|
||||
return r2
|
||||
}
|
||||
if r2 == nil {
|
||||
return r2
|
||||
}
|
||||
if r1.Name == roles.AdminRoleName {
|
||||
return r1
|
||||
}
|
||||
if r2.Name == roles.AdminRoleName {
|
||||
return r2
|
||||
}
|
||||
|
||||
if r1.Name == roles.EditorRoleName {
|
||||
return r1
|
||||
}
|
||||
if r2.Name == roles.EditorRoleName {
|
||||
return r2
|
||||
}
|
||||
|
||||
if r1.Name == roles.ViewerRoleName {
|
||||
return r1
|
||||
}
|
||||
if r2.Name == roles.ViewerRoleName {
|
||||
return r2
|
||||
}
|
||||
|
||||
if r1.Name == roles.MemberRoleName {
|
||||
return r1
|
||||
}
|
||||
if r2.Name == roles.MemberRoleName {
|
||||
return r2
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,391 @@
|
|||
package server_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
"github.com/influxdata/chronograf/server"
|
||||
)
|
||||
|
||||
func TestMappedRole(t *testing.T) {
|
||||
type args struct {
|
||||
org *chronograf.Organization
|
||||
principal oauth2.Principal
|
||||
}
|
||||
type wants struct {
|
||||
role *chronograf.Role
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "single mapping all wildcards",
|
||||
args: args{
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "two mapping all wildcards",
|
||||
args: args{
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "two mapping all wildcards, different order",
|
||||
args: args{
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "two mappings with explicit principal",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "google",
|
||||
Group: "influxdata.com",
|
||||
},
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: "oauth2",
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.MemberRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "different two mapping all wildcards",
|
||||
args: args{
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "different two mapping all wildcards, different ordering",
|
||||
args: args{
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "three mapping all wildcards",
|
||||
args: args{
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "three mapping only one match",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "google",
|
||||
Group: "influxdata.com",
|
||||
},
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: "google",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "influxdata.com",
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "google",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "not_influxdata",
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: "ldap",
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "three mapping only two matches",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "google",
|
||||
Group: "influxdata.com",
|
||||
},
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: "google",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "influxdata.com",
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "google",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: "ldap",
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing provider",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "google",
|
||||
Group: "influxdata.com",
|
||||
},
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: "",
|
||||
Scheme: "ldap",
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user is in multiple github groups",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "github",
|
||||
Group: "influxdata,another,mimi",
|
||||
},
|
||||
org: &chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "influxdata",
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "mimi",
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "another",
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
role := server.MappedRole(tt.args.org, tt.args.principal)
|
||||
|
||||
if diff := cmp.Diff(role, tt.wants.role); diff != "" {
|
||||
t.Errorf("%q. MappedRole():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue