move directory providers (#3633)

* remove directory providers and support for groups

* idp: remove directory providers

* better error messages

* fix errors

* restore postgres

* fix test
This commit is contained in:
Caleb Doxsey 2022-11-03 11:33:56 -06:00 committed by GitHub
parent bb5c80bae9
commit c178819875
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
78 changed files with 723 additions and 8703 deletions

View file

@ -1,82 +0,0 @@
package criteria
import (
"github.com/open-policy-agent/opa/ast"
"github.com/pomerium/pomerium/pkg/policy/generator"
"github.com/pomerium/pomerium/pkg/policy/parser"
"github.com/pomerium/pomerium/pkg/policy/rules"
)
var groupsBody = ast.Body{
ast.MustParseExpr(`
session := get_session(input.session.id)
`),
ast.MustParseExpr(`
directory_user := get_directory_user(session)
`),
ast.MustParseExpr(`
group_ids := get_group_ids(session, directory_user)
`),
ast.MustParseExpr(`
group_names := [directory_group.name |
some i
group_id := group_ids[i]
directory_group := get_directory_group(group_id)
directory_group != null
directory_group.name != null]
`),
ast.MustParseExpr(`
group_emails := [directory_group.email |
some i
group_id := group_ids[i]
directory_group := get_directory_group(group_id)
directory_group != null
directory_group.email != null]
`),
ast.MustParseExpr(`
groups = array.concat(group_ids, array.concat(group_names, group_emails))
`),
}
type groupsCriterion struct {
g *Generator
}
func (groupsCriterion) DataType() generator.CriterionDataType {
return CriterionDataTypeStringListMatcher
}
func (groupsCriterion) Name() string {
return "groups"
}
func (c groupsCriterion) GenerateRule(_ string, data parser.Value) (*ast.Rule, []*ast.Rule, error) {
var body ast.Body
body = append(body, groupsBody...)
err := matchStringList(&body, ast.VarTerm("groups"), data)
if err != nil {
return nil, nil, err
}
rule := NewCriterionSessionRule(c.g, c.Name(),
ReasonGroupsOK, ReasonGroupsUnauthorized,
body)
return rule, []*ast.Rule{
rules.GetSession(),
rules.GetDirectoryUser(),
rules.GetDirectoryGroup(),
rules.GetGroupIDs(),
}, nil
}
// Groups returns a Criterion on a user's group ids, names or emails.
func Groups(generator *Generator) Criterion {
return groupsCriterion{g: generator}
}
func init() {
Register(Groups)
}

View file

@ -1,100 +0,0 @@
package criteria
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/pomerium/pomerium/pkg/grpc/directory"
"github.com/pomerium/pomerium/pkg/grpc/session"
)
func TestGroups(t *testing.T) {
t.Run("no session", func(t *testing.T) {
res, err := evaluate(t, `
allow:
and:
- groups:
has: group1
- groups:
has: group2
`, []dataBrokerRecord{}, Input{Session: InputSession{ID: "SESSION_ID"}})
require.NoError(t, err)
require.Equal(t, A{false, A{ReasonUserUnauthenticated}, M{}}, res["allow"])
require.Equal(t, A{false, A{}}, res["deny"])
})
t.Run("by id", func(t *testing.T) {
res, err := evaluate(t, `
allow:
and:
- groups:
has: group1
`,
[]dataBrokerRecord{
&session.Session{
Id: "SESSION_ID",
UserId: "USER_ID",
},
&directory.User{
Id: "USER_ID",
GroupIds: []string{"group1"},
},
},
Input{Session: InputSession{ID: "SESSION_ID"}})
require.NoError(t, err)
require.Equal(t, A{true, A{ReasonGroupsOK}, M{}}, res["allow"])
require.Equal(t, A{false, A{}}, res["deny"])
})
t.Run("by email", func(t *testing.T) {
res, err := evaluate(t, `
allow:
and:
- groups:
has: "group1@example.com"
`,
[]dataBrokerRecord{
&session.Session{
Id: "SESSION_ID",
UserId: "USER_ID",
},
&directory.User{
Id: "USER_ID",
GroupIds: []string{"group1"},
},
&directory.Group{
Id: "group1",
Email: "group1@example.com",
},
},
Input{Session: InputSession{ID: "SESSION_ID"}})
require.NoError(t, err)
require.Equal(t, A{true, A{ReasonGroupsOK}, M{}}, res["allow"])
require.Equal(t, A{false, A{}}, res["deny"])
})
t.Run("by name", func(t *testing.T) {
res, err := evaluate(t, `
allow:
and:
- groups:
has: "Group 1"
`,
[]dataBrokerRecord{
&session.Session{
Id: "SESSION_ID",
UserId: "USER_ID",
},
&directory.User{
Id: "USER_ID",
GroupIds: []string{"group1"},
},
&directory.Group{
Id: "group1",
Name: "Group 1",
},
},
Input{Session: InputSession{ID: "SESSION_ID"}})
require.NoError(t, err)
require.Equal(t, A{true, A{ReasonGroupsOK}, M{}}, res["allow"])
require.Equal(t, A{false, A{}}, res["deny"])
})
}

View file

@ -18,8 +18,6 @@ const (
ReasonDomainUnauthorized = "domain-unauthorized"
ReasonEmailOK = "email-ok"
ReasonEmailUnauthorized = "email-unauthorized"
ReasonGroupsOK = "groups-ok"
ReasonGroupsUnauthorized = "groups-unauthorized"
ReasonHTTPMethodOK = "http-method-ok"
ReasonHTTPMethodUnauthorized = "http-method-unauthorized"
ReasonHTTPPathOK = "http-path-ok"

View file

@ -74,42 +74,6 @@ get_device_enrollment(device_credential) = v {
`)
}
// GetDirectoryUser returns the directory user for the given session.
func GetDirectoryUser() *ast.Rule {
return ast.MustParseRule(`
get_directory_user(session) = v {
v = get_databroker_record("type.googleapis.com/directory.User", session.user_id)
v != null
} else = "" {
true
}
`)
}
// GetDirectoryGroup returns the directory group for the given id.
func GetDirectoryGroup() *ast.Rule {
return ast.MustParseRule(`
get_directory_group(id) = v {
v = get_databroker_record("type.googleapis.com/directory.Group", id)
v != null
} else = {} {
true
}
`)
}
// GetGroupIDs returns the group ids for the given session or directory user.
func GetGroupIDs() *ast.Rule {
return ast.MustParseRule(`
get_group_ids(session, directory_user) = v {
v = directory_user.group_ids
v != null
} else = [] {
true
}
`)
}
// MergeWithAnd merges criterion results using `and`.
func MergeWithAnd() *ast.Rule {
return ast.MustParseRule(`