mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-29 17:07:24 +02:00
core/opa: update for rego 1.0 (#4895)
* core/opa: update headers rego script * core/opa: update ppl * further updates
This commit is contained in:
parent
5e0079c649
commit
24b04bed35
9 changed files with 289 additions and 319 deletions
|
@ -5,84 +5,74 @@ import "github.com/open-policy-agent/opa/ast"
|
|||
|
||||
// GetSession gets the session for the given id.
|
||||
func GetSession() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
get_session(id) = v {
|
||||
return MustParse(`
|
||||
get_session(id) := v if {
|
||||
v = get_databroker_record("type.googleapis.com/user.ServiceAccount", id)
|
||||
v != null
|
||||
} else = iv {
|
||||
} else := iv if {
|
||||
v = get_databroker_record("type.googleapis.com/session.Session", id)
|
||||
v != null
|
||||
object.get(v, "impersonate_session_id", "") != ""
|
||||
|
||||
iv = get_databroker_record("type.googleapis.com/session.Session", v.impersonate_session_id)
|
||||
iv != null
|
||||
} else = v {
|
||||
} else := v if {
|
||||
v = get_databroker_record("type.googleapis.com/session.Session", id)
|
||||
v != null
|
||||
object.get(v, "impersonate_session_id", "") == ""
|
||||
} else = {} {
|
||||
true
|
||||
}
|
||||
} else := {}
|
||||
`)
|
||||
}
|
||||
|
||||
// GetUser returns the user for the given session.
|
||||
func GetUser() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
get_user(session) = v {
|
||||
return MustParse(`
|
||||
get_user(session) := v if {
|
||||
v = get_databroker_record("type.googleapis.com/user.User", session.user_id)
|
||||
v != null
|
||||
} else = {} {
|
||||
true
|
||||
}
|
||||
} else := {}
|
||||
`)
|
||||
}
|
||||
|
||||
// GetUserEmail gets the user email, either the impersonate email, or the user email.
|
||||
func GetUserEmail() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
get_user_email(session, user) = v {
|
||||
return MustParse(`
|
||||
get_user_email(session, user) := v if {
|
||||
v = user.email
|
||||
} else = "" {
|
||||
true
|
||||
}
|
||||
} else := ""
|
||||
`)
|
||||
}
|
||||
|
||||
// GetDeviceCredential gets the device credential for the given session.
|
||||
func GetDeviceCredential() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
get_device_credential(session, device_type_id) = v {
|
||||
return MustParse(`
|
||||
get_device_credential(session, device_type_id) := v if {
|
||||
device_credential_id := [x.Credential.Id|x:=session.device_credentials[_];x.type_id==device_type_id][0]
|
||||
v = get_databroker_record("type.googleapis.com/pomerium.device.Credential", device_credential_id)
|
||||
v != null
|
||||
} else = {} {
|
||||
true
|
||||
}
|
||||
} else := {}
|
||||
`)
|
||||
}
|
||||
|
||||
// GetDeviceEnrollment gets the device enrollment for the given device credential.
|
||||
func GetDeviceEnrollment() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
get_device_enrollment(device_credential) = v {
|
||||
return MustParse(`
|
||||
get_device_enrollment(device_credential) := v if {
|
||||
v = get_databroker_record("type.googleapis.com/pomerium.device.Enrollment", device_credential.enrollment_id)
|
||||
v != null
|
||||
} else = {} {
|
||||
true
|
||||
}
|
||||
} else := {}
|
||||
`)
|
||||
}
|
||||
|
||||
// MergeWithAnd merges criterion results using `and`.
|
||||
func MergeWithAnd() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
merge_with_and(results) = [true, reasons, additional_data] {
|
||||
return MustParse(`
|
||||
merge_with_and(results) := [true, reasons, additional_data] if {
|
||||
true_results := [x|x:=results[i];x[0]]
|
||||
count(true_results) == count(results)
|
||||
reasons := union({x|x:=true_results[i][1]})
|
||||
additional_data := object_union({x|x:=true_results[i][2]})
|
||||
} else = [false, reasons, additional_data] {
|
||||
} else := [false, reasons, additional_data] if {
|
||||
false_results := [x|x:=results[i];not x[0]]
|
||||
reasons := union({x|x:=false_results[i][1]})
|
||||
additional_data := object_union({x|x:=false_results[i][2]})
|
||||
|
@ -92,13 +82,13 @@ merge_with_and(results) = [true, reasons, additional_data] {
|
|||
|
||||
// MergeWithOr merges criterion results using `or`.
|
||||
func MergeWithOr() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
merge_with_or(results) = [true, reasons, additional_data] {
|
||||
return MustParse(`
|
||||
merge_with_or(results) := [true, reasons, additional_data] if {
|
||||
true_results := [x|x:=results[i];x[0]]
|
||||
count(true_results) > 0
|
||||
reasons := union({x|x:=true_results[i][1]})
|
||||
additional_data := object_union({x|x:=true_results[i][2]})
|
||||
} else = [false, reasons, additional_data] {
|
||||
} else := [false, reasons, additional_data] if {
|
||||
false_results := [x|x:=results[i];not x[0]]
|
||||
reasons := union({x|x:=false_results[i][1]})
|
||||
additional_data := object_union({x|x:=false_results[i][2]})
|
||||
|
@ -109,27 +99,27 @@ merge_with_or(results) = [true, reasons, additional_data] {
|
|||
// InvertCriterionResult changes the criterion result's value from false to
|
||||
// true, or vice-versa.
|
||||
func InvertCriterionResult() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
invert_criterion_result(in) = out {
|
||||
in[0]
|
||||
out = array.concat([false], array.slice(in, 1, count(in)))
|
||||
} else = out {
|
||||
not in[0]
|
||||
out = array.concat([true], array.slice(in, 1, count(in)))
|
||||
return MustParse(`
|
||||
invert_criterion_result(v) := out if {
|
||||
v[0]
|
||||
out = array.concat([false], array.slice(v, 1, count(v)))
|
||||
} else := out if {
|
||||
not v[0]
|
||||
out = array.concat([true], array.slice(v, 1, count(v)))
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
// NormalizeCriterionResult converts a criterion result into a standard form.
|
||||
func NormalizeCriterionResult() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
normalize_criterion_result(result) = v {
|
||||
return MustParse(`
|
||||
normalize_criterion_result(result) := v if {
|
||||
is_boolean(result)
|
||||
v = [result, set()]
|
||||
} else = v {
|
||||
} else := v if {
|
||||
is_array(result)
|
||||
v = result
|
||||
} else = v {
|
||||
} else := v if {
|
||||
v = [false, set()]
|
||||
}
|
||||
`)
|
||||
|
@ -137,33 +127,33 @@ normalize_criterion_result(result) = v {
|
|||
|
||||
// ObjectGet recursively gets a value from an object.
|
||||
func ObjectGet() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
return MustParse(`
|
||||
# object_get is like object.get, but supports converting "/" in keys to separate lookups
|
||||
# rego doesn't support recursion, so we hard code a limited number of /'s
|
||||
|
||||
object_get(obj, key, def) = value {
|
||||
object_get(obj, key, def) := value if {
|
||||
undefined := "10a0fd35-0f1a-4e5b-97ce-631e89e1bafa"
|
||||
value = object.get(obj, key, undefined)
|
||||
value != undefined
|
||||
} else = value {
|
||||
} else := value if {
|
||||
segments := split(replace(key, ".", "/"), "/")
|
||||
count(segments) == 2
|
||||
o1 := object.get(obj, segments[0], {})
|
||||
value = object.get(o1, segments[1], def)
|
||||
} else = value {
|
||||
} else := value if {
|
||||
segments := split(replace(key, ".", "/"), "/")
|
||||
count(segments) == 3
|
||||
o1 := object.get(obj, segments[0], {})
|
||||
o2 := object.get(o1, segments[1], {})
|
||||
value = object.get(o2, segments[2], def)
|
||||
} else = value {
|
||||
} else := value if {
|
||||
segments := split(replace(key, ".", "/"), "/")
|
||||
count(segments) == 4
|
||||
o1 := object.get(obj, segments[0], {})
|
||||
o2 := object.get(o1, segments[1], {})
|
||||
o3 := object.get(o2, segments[2], {})
|
||||
value = object.get(o3, segments[3], def)
|
||||
} else = value {
|
||||
} else := value if {
|
||||
segments := split(replace(key, ".", "/"), "/")
|
||||
count(segments) == 5
|
||||
o1 := object.get(obj, segments[0], {})
|
||||
|
@ -171,7 +161,7 @@ object_get(obj, key, def) = value {
|
|||
o3 := object.get(o2, segments[2], {})
|
||||
o4 := object.get(o3, segments[3], {})
|
||||
value = object.get(o4, segments[4], def)
|
||||
} else = value {
|
||||
} else := value if {
|
||||
value = object.get(obj, key, def)
|
||||
}
|
||||
`)
|
||||
|
@ -179,8 +169,8 @@ object_get(obj, key, def) = value {
|
|||
|
||||
// ObjectUnion merges objects together. It expects a set of objects.
|
||||
func ObjectUnion() *ast.Rule {
|
||||
return ast.MustParseRule(`
|
||||
object_union(xs) = merged {
|
||||
return MustParse(`
|
||||
object_union(xs) := merged if {
|
||||
merged = { k: v |
|
||||
some k
|
||||
xs[_][k]
|
||||
|
@ -190,3 +180,14 @@ object_union(xs) = merged {
|
|||
}
|
||||
`)
|
||||
}
|
||||
|
||||
// MustParse parses an AST rule.
|
||||
func MustParse(str string) *ast.Rule {
|
||||
r, err := ast.ParseRuleWithOpts(str, ast.ParserOptions{
|
||||
RegoVersion: ast.RegoV1,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue