mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-04 09:19:39 +02:00
core/ppl: add groups criterion (#4916)
* core/ppl: add groups criterion * remove dead code * add additional test
This commit is contained in:
parent
3ca2f2462d
commit
6a833b365a
16 changed files with 268 additions and 109 deletions
|
@ -11,7 +11,7 @@ func TestAccept(t *testing.T) {
|
|||
allow:
|
||||
and:
|
||||
- accept: 1
|
||||
`, []dataBrokerRecord{}, Input{})
|
||||
`, nil, Input{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonAccept}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
)
|
||||
|
||||
|
@ -14,7 +15,7 @@ func TestAuthenticatedUser(t *testing.T) {
|
|||
allow:
|
||||
and:
|
||||
- authenticated_user: 1
|
||||
`, []dataBrokerRecord{}, Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
`, nil, 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"])
|
||||
|
@ -25,11 +26,11 @@ allow:
|
|||
and:
|
||||
- authenticated_user: 1
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||
)
|
||||
|
@ -16,7 +17,7 @@ func TestClaims(t *testing.T) {
|
|||
allow:
|
||||
and:
|
||||
- claim/family_name: Smith
|
||||
`, []dataBrokerRecord{}, Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
`, nil, 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"])
|
||||
|
@ -27,11 +28,11 @@ allow:
|
|||
and:
|
||||
- claim/family_name: Smith
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
@ -44,18 +45,18 @@ allow:
|
|||
and:
|
||||
- claim/family_name: Smith
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
Claims: map[string]*structpb.ListValue{
|
||||
"family_name": {Values: []*structpb.Value{structpb.NewStringValue("Smith")}},
|
||||
},
|
||||
},
|
||||
&user.User{
|
||||
}),
|
||||
makeRecord(&user.User{
|
||||
Id: "USER_ID",
|
||||
Email: "test@example.com",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
@ -68,18 +69,18 @@ allow:
|
|||
and:
|
||||
- claim/family_name: Smith
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
},
|
||||
&user.User{
|
||||
}),
|
||||
makeRecord(&user.User{
|
||||
Id: "USER_ID",
|
||||
Email: "test@example.com",
|
||||
Claims: map[string]*structpb.ListValue{
|
||||
"family_name": {Values: []*structpb.Value{structpb.NewStringValue("Smith")}},
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
@ -92,18 +93,18 @@ allow:
|
|||
and:
|
||||
- claim/example.com/key: value
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
Claims: map[string]*structpb.ListValue{
|
||||
"example.com/key": {Values: []*structpb.Value{structpb.NewStringValue("value")}},
|
||||
},
|
||||
},
|
||||
&user.User{
|
||||
}),
|
||||
makeRecord(&user.User{
|
||||
Id: "USER_ID",
|
||||
Email: "test@example.com",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -13,7 +13,7 @@ func TestCORSPreflight(t *testing.T) {
|
|||
allow:
|
||||
and:
|
||||
- cors_preflight: 1
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{
|
||||
`, nil, Input{HTTP: InputHTTP{
|
||||
Method: "OPTIONS",
|
||||
Headers: map[string][]string{
|
||||
"Access-Control-Request-Method": {http.MethodGet},
|
||||
|
@ -29,7 +29,7 @@ allow:
|
|||
allow:
|
||||
and:
|
||||
- cors_preflight: 1
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{
|
||||
`, nil, Input{HTTP: InputHTTP{
|
||||
Method: "OPTIONS",
|
||||
}})
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -14,7 +14,9 @@ import (
|
|||
"github.com/open-policy-agent/opa/rego"
|
||||
"github.com/open-policy-agent/opa/types"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"github.com/pomerium/pomerium/pkg/policy/generator"
|
||||
"github.com/pomerium/pomerium/pkg/policy/parser"
|
||||
"github.com/pomerium/pomerium/pkg/protoutil"
|
||||
|
@ -71,14 +73,33 @@ func generateRegoFromYAML(raw string) (string, error) {
|
|||
return string(bs), nil
|
||||
}
|
||||
|
||||
type dataBrokerRecord interface {
|
||||
func makeRecord(object interface {
|
||||
proto.Message
|
||||
GetId() string
|
||||
},
|
||||
) *databroker.Record {
|
||||
a := protoutil.NewAny(object)
|
||||
return &databroker.Record{
|
||||
Type: a.GetTypeUrl(),
|
||||
Id: object.GetId(),
|
||||
Data: a,
|
||||
ModifiedAt: timestamppb.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func makeStructRecord(recordType, recordID string, object interface{}) *databroker.Record {
|
||||
s := protoutil.ToStruct(object).GetStructValue()
|
||||
return &databroker.Record{
|
||||
Type: recordType,
|
||||
Id: recordID,
|
||||
Data: protoutil.NewAny(s),
|
||||
ModifiedAt: timestamppb.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func evaluate(t *testing.T,
|
||||
rawPolicy string,
|
||||
dataBrokerRecords []dataBrokerRecord,
|
||||
dataBrokerRecords []*databroker.Record,
|
||||
input Input,
|
||||
) (rego.Vars, error) {
|
||||
regoPolicy, err := generateRegoFromYAML(rawPolicy)
|
||||
|
@ -106,10 +127,10 @@ func evaluate(t *testing.T,
|
|||
}
|
||||
|
||||
for _, record := range dataBrokerRecords {
|
||||
data := protoutil.NewAny(record)
|
||||
if string(recordType) == data.GetTypeUrl() &&
|
||||
if string(recordType) == record.GetType() &&
|
||||
string(recordID) == record.GetId() {
|
||||
bs, _ := json.Marshal(record)
|
||||
msg, _ := record.GetData().UnmarshalNew()
|
||||
bs, _ := json.Marshal(msg)
|
||||
v, err := ast.ValueFromReader(bytes.NewReader(bs))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/device"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
)
|
||||
|
@ -25,7 +26,7 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
is: dc1
|
||||
`, []dataBrokerRecord{}, Input{Session: InputSession{ID: "s1"}})
|
||||
`, nil, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonUserUnauthenticated}, M{"device_type": "any"}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
|
@ -36,8 +37,8 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
is: dc1
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "any", "dc1"),
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "any", "dc1")),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonDeviceUnauthenticated}, M{"device_type": "any"}}, res["allow"])
|
||||
|
@ -49,10 +50,10 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
is: dc1
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "any", "dc1"),
|
||||
&device.Credential{Id: "dc1", EnrollmentId: "de1"},
|
||||
&device.Enrollment{Id: "de1"},
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "any", "dc1")),
|
||||
makeRecord(&device.Credential{Id: "dc1", EnrollmentId: "de1"}),
|
||||
makeRecord(&device.Enrollment{Id: "de1"}),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonDeviceOK}, M{"device_type": "any"}}, res["allow"])
|
||||
|
@ -64,12 +65,12 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
is: dc2
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "any", "dc1"),
|
||||
&device.Credential{Id: "dc1", EnrollmentId: "de1"},
|
||||
&device.Enrollment{Id: "de1"},
|
||||
&device.Credential{Id: "dc2", EnrollmentId: "de2"},
|
||||
&device.Enrollment{Id: "de2"},
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "any", "dc1")),
|
||||
makeRecord(&device.Credential{Id: "dc1", EnrollmentId: "de1"}),
|
||||
makeRecord(&device.Enrollment{Id: "de1"}),
|
||||
makeRecord(&device.Credential{Id: "dc2", EnrollmentId: "de2"}),
|
||||
makeRecord(&device.Enrollment{Id: "de2"}),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonDeviceUnauthorized}, M{"device_type": "any"}}, res["allow"])
|
||||
|
@ -81,10 +82,10 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
approved: true
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "any", "dc1"),
|
||||
&device.Credential{Id: "dc1", EnrollmentId: "de1"},
|
||||
&device.Enrollment{Id: "de1", ApprovedBy: "u1"},
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "any", "dc1")),
|
||||
makeRecord(&device.Credential{Id: "dc1", EnrollmentId: "de1"}),
|
||||
makeRecord(&device.Enrollment{Id: "de1", ApprovedBy: "u1"}),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonDeviceOK}, M{"device_type": "any"}}, res["allow"])
|
||||
|
@ -96,10 +97,10 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
approved: true
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "any", "dc1"),
|
||||
&device.Credential{Id: "dc1", EnrollmentId: "de1"},
|
||||
&device.Enrollment{Id: "de1"},
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "any", "dc1")),
|
||||
makeRecord(&device.Credential{Id: "dc1", EnrollmentId: "de1"}),
|
||||
makeRecord(&device.Enrollment{Id: "de1"}),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonDeviceUnauthorized}, M{"device_type": "any"}}, res["allow"])
|
||||
|
@ -111,10 +112,10 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
approved: false
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "any", "dc1"),
|
||||
&device.Credential{Id: "dc1", EnrollmentId: "de1"},
|
||||
&device.Enrollment{Id: "de1"},
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "any", "dc1")),
|
||||
makeRecord(&device.Credential{Id: "dc1", EnrollmentId: "de1"}),
|
||||
makeRecord(&device.Enrollment{Id: "de1"}),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonDeviceOK}, M{"device_type": "any"}}, res["allow"])
|
||||
|
@ -126,10 +127,10 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
approved: false
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "any", "dc1"),
|
||||
&device.Credential{Id: "dc1", EnrollmentId: "de1"},
|
||||
&device.Enrollment{Id: "de1", ApprovedBy: "u1"},
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "any", "dc1")),
|
||||
makeRecord(&device.Credential{Id: "dc1", EnrollmentId: "de1"}),
|
||||
makeRecord(&device.Enrollment{Id: "de1", ApprovedBy: "u1"}),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonDeviceUnauthorized}, M{"device_type": "any"}}, res["allow"])
|
||||
|
@ -141,10 +142,10 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
type: t1
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "t1", "dc1"),
|
||||
&device.Credential{Id: "dc1", EnrollmentId: "de1", TypeId: "t1"},
|
||||
&device.Enrollment{Id: "de1", ApprovedBy: "u1"},
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "t1", "dc1")),
|
||||
makeRecord(&device.Credential{Id: "dc1", EnrollmentId: "de1", TypeId: "t1"}),
|
||||
makeRecord(&device.Enrollment{Id: "de1", ApprovedBy: "u1"}),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonDeviceOK}, M{"device_type": "t1"}}, res["allow"])
|
||||
|
@ -156,10 +157,10 @@ allow:
|
|||
and:
|
||||
- device:
|
||||
type: t2
|
||||
`, []dataBrokerRecord{
|
||||
mkDeviceSession("s1", "t1", "dc1"),
|
||||
&device.Credential{Id: "dc1", EnrollmentId: "de1", TypeId: "t1"},
|
||||
&device.Enrollment{Id: "de1", ApprovedBy: "u1"},
|
||||
`, []*databroker.Record{
|
||||
makeRecord(mkDeviceSession("s1", "t1", "dc1")),
|
||||
makeRecord(&device.Credential{Id: "dc1", EnrollmentId: "de1", TypeId: "t1"}),
|
||||
makeRecord(&device.Enrollment{Id: "de1", ApprovedBy: "u1"}),
|
||||
}, Input{Session: InputSession{ID: "s1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonDeviceUnauthenticated}, M{"device_type": "t2"}}, res["allow"])
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||
)
|
||||
|
@ -16,7 +17,7 @@ allow:
|
|||
and:
|
||||
- domain:
|
||||
is: example.com
|
||||
`, []dataBrokerRecord{}, Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
`, []*databroker.Record{}, 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"])
|
||||
|
@ -28,15 +29,15 @@ allow:
|
|||
- domain:
|
||||
is: example.com
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
},
|
||||
&user.User{
|
||||
}),
|
||||
makeRecord(&user.User{
|
||||
Id: "USER_ID",
|
||||
Email: "test@example.com",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
@ -50,15 +51,15 @@ allow:
|
|||
- domain:
|
||||
is: example.com
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
},
|
||||
&user.User{
|
||||
}),
|
||||
makeRecord(&user.User{
|
||||
Id: "USER_ID",
|
||||
Email: "test1@example.com",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||
)
|
||||
|
@ -17,7 +18,7 @@ allow:
|
|||
and:
|
||||
- email:
|
||||
is: test@example.com
|
||||
`, []dataBrokerRecord{}, Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
`, []*databroker.Record{}, 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"])
|
||||
|
@ -29,15 +30,15 @@ allow:
|
|||
- email:
|
||||
is: test@example.com
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
},
|
||||
&user.User{
|
||||
}),
|
||||
makeRecord(&user.User{
|
||||
Id: "USER_ID",
|
||||
Email: "test@example.com",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
@ -51,24 +52,24 @@ allow:
|
|||
- email:
|
||||
is: test2@example.com
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION1",
|
||||
UserId: "USER1",
|
||||
ImpersonateSessionId: proto.String("SESSION2"),
|
||||
},
|
||||
&session.Session{
|
||||
}),
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION2",
|
||||
UserId: "USER2",
|
||||
},
|
||||
&user.User{
|
||||
}),
|
||||
makeRecord(&user.User{
|
||||
Id: "USER1",
|
||||
Email: "test1@example.com",
|
||||
},
|
||||
&user.User{
|
||||
}),
|
||||
makeRecord(&user.User{
|
||||
Id: "USER2",
|
||||
Email: "test2@example.com",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION1"}})
|
||||
require.NoError(t, err)
|
||||
|
|
53
pkg/policy/criteria/groups.go
Normal file
53
pkg/policy/criteria/groups.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package criteria
|
||||
|
||||
import (
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
|
||||
"github.com/pomerium/datasource/pkg/directory"
|
||||
"github.com/pomerium/pomerium/pkg/policy/generator"
|
||||
"github.com/pomerium/pomerium/pkg/policy/parser"
|
||||
"github.com/pomerium/pomerium/pkg/policy/rules"
|
||||
)
|
||||
|
||||
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) {
|
||||
body := ast.Body{
|
||||
ast.Assign.Expr(ast.VarTerm("record_type"), ast.StringTerm(directory.UserRecordType)),
|
||||
|
||||
ast.MustParseExpr(`session := get_session(input.session.id)`),
|
||||
ast.MustParseExpr(`directory_user := get_databroker_record(record_type, session.user_id)`),
|
||||
ast.MustParseExpr(`group_ids := object.get(directory_user, "group_ids", [])`),
|
||||
}
|
||||
|
||||
err := matchStringList(&body, ast.VarTerm("group_ids"), data)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
r := NewCriterionSessionRule(c.g, c.Name(),
|
||||
ReasonGroupsOK, ReasonGroupsUnauthorized,
|
||||
body)
|
||||
return r, []*ast.Rule{
|
||||
rules.GetSession(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Groups returns a Criterion on a user's group ids
|
||||
func Groups(generator *Generator) Criterion {
|
||||
return groupsCriterion{g: generator}
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(Groups)
|
||||
}
|
69
pkg/policy/criteria/groups_test.go
Normal file
69
pkg/policy/criteria/groups_test.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package criteria
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pomerium/datasource/pkg/directory"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"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
|
||||
`, []*databroker.Record{}, Input{Session: InputSession{ID: "session1"}})
|
||||
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
|
||||
`,
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "session1",
|
||||
UserId: "user1",
|
||||
}),
|
||||
makeStructRecord(directory.UserRecordType, "user1", map[string]any{
|
||||
"group_ids": []any{"group1", "group2"},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "session1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonGroupsOK}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
})
|
||||
t.Run("not allowed", func(t *testing.T) {
|
||||
res, err := evaluate(t, `
|
||||
allow:
|
||||
and:
|
||||
- groups:
|
||||
has: group1
|
||||
`,
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "session1",
|
||||
UserId: "user1",
|
||||
}),
|
||||
makeStructRecord(directory.UserRecordType, "user1", map[string]any{
|
||||
"group_ids": []any{"group2"},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "session1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonGroupsUnauthorized}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
})
|
||||
}
|
|
@ -5,6 +5,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
)
|
||||
|
||||
func TestHTTPMethod(t *testing.T) {
|
||||
|
@ -14,7 +16,7 @@ allow:
|
|||
and:
|
||||
- http_method:
|
||||
is: GET
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{Method: http.MethodGet}})
|
||||
`, []*databroker.Record{}, Input{HTTP: InputHTTP{Method: http.MethodGet}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonHTTPMethodOK}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
|
@ -25,7 +27,7 @@ allow:
|
|||
and:
|
||||
- http_method:
|
||||
is: GET
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{Method: "POST"}})
|
||||
`, []*databroker.Record{}, Input{HTTP: InputHTTP{Method: "POST"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonHTTPMethodUnauthorized}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
)
|
||||
|
||||
func TestHTTPPath(t *testing.T) {
|
||||
|
@ -13,7 +15,7 @@ allow:
|
|||
and:
|
||||
- http_path:
|
||||
is: /test
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{Path: "/test"}})
|
||||
`, []*databroker.Record{}, Input{HTTP: InputHTTP{Path: "/test"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonHTTPPathOK}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
|
@ -24,7 +26,7 @@ allow:
|
|||
and:
|
||||
- http_path:
|
||||
is: /test
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{Path: "/not-test"}})
|
||||
`, []*databroker.Record{}, Input{HTTP: InputHTTP{Path: "/not-test"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonHTTPPathUnauthorized}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
)
|
||||
|
||||
func TestInvalidClientCertificate(t *testing.T) {
|
||||
|
@ -51,7 +53,7 @@ deny:
|
|||
t.Run(c.label, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
res, err := evaluate(t, policy, []dataBrokerRecord{}, c.input)
|
||||
res, err := evaluate(t, policy, []*databroker.Record{}, c.input)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, A{false, A{}}, res["allow"])
|
||||
assert.Equal(t, c.expected, res["deny"])
|
||||
|
|
|
@ -21,6 +21,8 @@ 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"
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
)
|
||||
|
||||
func TestReject(t *testing.T) {
|
||||
|
@ -11,7 +13,7 @@ func TestReject(t *testing.T) {
|
|||
allow:
|
||||
and:
|
||||
- reject: 1
|
||||
`, []dataBrokerRecord{}, Input{})
|
||||
`, []*databroker.Record{}, Input{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonReject}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
)
|
||||
|
||||
|
@ -16,7 +17,7 @@ allow:
|
|||
and:
|
||||
- user:
|
||||
is: USER_ID
|
||||
`, []dataBrokerRecord{}, Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
`, []*databroker.Record{}, 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"])
|
||||
|
@ -28,11 +29,11 @@ allow:
|
|||
- user:
|
||||
is: USER_ID
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION_ID"}})
|
||||
require.NoError(t, err)
|
||||
|
@ -46,16 +47,16 @@ allow:
|
|||
- user:
|
||||
is: USER2
|
||||
`,
|
||||
[]dataBrokerRecord{
|
||||
&session.Session{
|
||||
[]*databroker.Record{
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION1",
|
||||
UserId: "USER1",
|
||||
ImpersonateSessionId: proto.String("SESSION2"),
|
||||
},
|
||||
&session.Session{
|
||||
}),
|
||||
makeRecord(&session.Session{
|
||||
Id: "SESSION2",
|
||||
UserId: "USER2",
|
||||
},
|
||||
}),
|
||||
},
|
||||
Input{Session: InputSession{ID: "SESSION1"}})
|
||||
require.NoError(t, err)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue