matrix-authentication-service: 0.12.0 -> 0.13.0
This is included here as, since OPA is a dependency of MAS, the versions of these two packages need to be updated together. (since 0.12.0 MAS does not work with 1.0.0 OPA). I have removed the sea-query check as it's no longer loading a special case rc tag from a git repo. Signed-off-by: Charlie Egan <charlieegan3@users.noreply.github.com>
This commit is contained in:
-7602
File diff suppressed because it is too large
Load Diff
@@ -17,29 +17,25 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "matrix-authentication-service";
|
||||
version = "0.12.0";
|
||||
version = "0.13.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "element-hq";
|
||||
repo = "matrix-authentication-service";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-QLtyYxV2yXHJtwWgGcyi7gRcKypYoy9Z8bkEuTopVXc=";
|
||||
hash = "sha256-rFex6stw++xNrcCYnYn3N0HrUQd91DAw9QU0R2MUzyQ=";
|
||||
};
|
||||
|
||||
cargoLock = {
|
||||
lockFile = ./Cargo.lock;
|
||||
outputHashes = {
|
||||
"sea-query-0.32.0-rc.1" = "sha256-Q/NFiIBu8L5rQj4jwcIo8ACmAhLBy4HSTcJv06UdK8E=";
|
||||
};
|
||||
};
|
||||
cargoHash = "sha256-iUAdVnIeBxURqEmqom8MTMLuNnggDxoeVHVlNN8dyJ0=";
|
||||
|
||||
npmDeps = fetchNpmDeps {
|
||||
name = "${pname}-${version}-npm-deps";
|
||||
src = "${src}/${npmRoot}";
|
||||
hash = "sha256-EfDxbdjzF0yLQlueIYKmdpU4v9dx7g8bltU63mIWfo0=";
|
||||
hash = "sha256-4tFE7za2bBOCtX0fSaLvvyD4UTGtvtJlgO30lHCv07Y=";
|
||||
};
|
||||
|
||||
npmRoot = "frontend";
|
||||
npmFlags = [ "--legacy-peer-deps" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
@@ -92,8 +88,6 @@ rustPlatform.buildRustPackage rec {
|
||||
cp -r translations "$out/share/$pname/translations"
|
||||
'';
|
||||
|
||||
patches = [ ./v1_rego.patch ];
|
||||
|
||||
meta = {
|
||||
description = "OAuth2.0 + OpenID Provider for Matrix Homeservers";
|
||||
homepage = "https://github.com/element-hq/matrix-authentication-service";
|
||||
|
||||
@@ -1,802 +0,0 @@
|
||||
diff --git a/policies/authorization_grant.rego b/policies/authorization_grant.rego
|
||||
index 0ce1d63d..4cc87dce 100644
|
||||
--- a/policies/authorization_grant.rego
|
||||
+++ b/policies/authorization_grant.rego
|
||||
@@ -3,39 +3,39 @@
|
||||
# - input: schema["authorization_grant_input"]
|
||||
package authorization_grant
|
||||
|
||||
-import future.keywords.in
|
||||
+import rego.v1
|
||||
|
||||
default allow := false
|
||||
|
||||
-allow {
|
||||
+allow if {
|
||||
count(violation) == 0
|
||||
}
|
||||
|
||||
# Users can request admin scopes if either:
|
||||
# 1. They are in the admin_users list
|
||||
-can_request_admin(user) {
|
||||
+can_request_admin(user) if {
|
||||
some admin_user in data.admin_users
|
||||
user.username == admin_user
|
||||
}
|
||||
|
||||
# 2. They have the can_request_admin flag set to true
|
||||
-can_request_admin(user) {
|
||||
+can_request_admin(user) if {
|
||||
user.can_request_admin
|
||||
}
|
||||
|
||||
-interactive_grant_type("authorization_code") = true
|
||||
+interactive_grant_type("authorization_code") := true
|
||||
|
||||
-interactive_grant_type("urn:ietf:params:oauth:grant-type:device_code") = true
|
||||
+interactive_grant_type("urn:ietf:params:oauth:grant-type:device_code") := true
|
||||
|
||||
# Special case to make empty scope work
|
||||
-allowed_scope("") = true
|
||||
+allowed_scope("") := true
|
||||
|
||||
-allowed_scope("openid") = true
|
||||
+allowed_scope("openid") := true
|
||||
|
||||
-allowed_scope("email") = true
|
||||
+allowed_scope("email") := true
|
||||
|
||||
# This grants access to Synapse's admin API endpoints
|
||||
-allowed_scope("urn:synapse:admin:*") {
|
||||
+allowed_scope("urn:synapse:admin:*") if {
|
||||
# Synapse doesn't support user-less tokens yet, so access to the admin API
|
||||
# can only be used with an authorization_code grant or a device code grant
|
||||
# as the user is present
|
||||
@@ -44,39 +44,39 @@ allowed_scope("urn:synapse:admin:*") {
|
||||
}
|
||||
|
||||
# This grants access to the /graphql API endpoint
|
||||
-allowed_scope("urn:mas:graphql:*") = true
|
||||
+allowed_scope("urn:mas:graphql:*") := true
|
||||
|
||||
# This makes it possible to query and do anything in the GraphQL API as an admin
|
||||
-allowed_scope("urn:mas:admin") {
|
||||
+allowed_scope("urn:mas:admin") if {
|
||||
interactive_grant_type(input.grant_type)
|
||||
can_request_admin(input.user)
|
||||
}
|
||||
|
||||
# This makes it possible to get the admin scope for clients that are allowed
|
||||
-allowed_scope("urn:mas:admin") {
|
||||
+allowed_scope("urn:mas:admin") if {
|
||||
input.grant_type == "client_credentials"
|
||||
some client in data.admin_clients
|
||||
input.client.id == client
|
||||
}
|
||||
|
||||
-allowed_scope(scope) {
|
||||
+allowed_scope(scope) if {
|
||||
# Grant access to the C-S API only if there is a user
|
||||
interactive_grant_type(input.grant_type)
|
||||
regex.match("^urn:matrix:org.matrix.msc2967.client:device:[A-Za-z0-9._~!$&'()*+,;=:@/-]{10,}$", scope)
|
||||
}
|
||||
|
||||
-allowed_scope("urn:matrix:org.matrix.msc2967.client:api:*") {
|
||||
+allowed_scope("urn:matrix:org.matrix.msc2967.client:api:*") if {
|
||||
# Grant access to the C-S API only if there is a user
|
||||
interactive_grant_type(input.grant_type)
|
||||
}
|
||||
|
||||
-violation[{"msg": msg}] {
|
||||
+violation contains {"msg": msg} if {
|
||||
some scope in split(input.scope, " ")
|
||||
not allowed_scope(scope)
|
||||
msg := sprintf("scope '%s' not allowed", [scope])
|
||||
}
|
||||
|
||||
-violation[{"msg": "only one device scope is allowed at a time"}] {
|
||||
+violation contains {"msg": "only one device scope is allowed at a time"} if {
|
||||
scope_list := split(input.scope, " ")
|
||||
count({key | scope_list[key]; startswith(scope_list[key], "urn:matrix:org.matrix.msc2967.client:device:")}) > 1
|
||||
}
|
||||
diff --git a/policies/authorization_grant_test.rego b/policies/authorization_grant_test.rego
|
||||
index fc30f353..286a644b 100644
|
||||
--- a/policies/authorization_grant_test.rego
|
||||
+++ b/policies/authorization_grant_test.rego
|
||||
@@ -1,10 +1,12 @@
|
||||
package authorization_grant
|
||||
|
||||
+import rego.v1
|
||||
+
|
||||
user := {"username": "john"}
|
||||
|
||||
client := {"client_id": "client"}
|
||||
|
||||
-test_standard_scopes {
|
||||
+test_standard_scopes if {
|
||||
allow with input.user as user
|
||||
with input.client as client
|
||||
with input.scope as ""
|
||||
@@ -32,7 +34,7 @@ test_standard_scopes {
|
||||
with input.scope as "profile"
|
||||
}
|
||||
|
||||
-test_matrix_scopes {
|
||||
+test_matrix_scopes if {
|
||||
allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
@@ -49,7 +51,7 @@ test_matrix_scopes {
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:api:*"
|
||||
}
|
||||
|
||||
-test_device_scopes {
|
||||
+test_device_scopes if {
|
||||
allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
@@ -84,7 +86,7 @@ test_device_scopes {
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01"
|
||||
}
|
||||
|
||||
-test_synapse_admin_scopes {
|
||||
+test_synapse_admin_scopes if {
|
||||
allow with input.user as user
|
||||
with input.client as client
|
||||
with data.admin_users as ["john"]
|
||||
@@ -138,7 +140,7 @@ test_synapse_admin_scopes {
|
||||
with input.scope as "urn:synapse:admin:*"
|
||||
}
|
||||
|
||||
-test_mas_scopes {
|
||||
+test_mas_scopes if {
|
||||
allow with input.user as user
|
||||
with input.client as client
|
||||
with input.scope as "urn:mas:graphql:*"
|
||||
diff --git a/policies/client_registration.rego b/policies/client_registration.rego
|
||||
index 0104979c..d842d592 100644
|
||||
--- a/policies/client_registration.rego
|
||||
+++ b/policies/client_registration.rego
|
||||
@@ -3,26 +3,26 @@
|
||||
# - input: schema["client_registration_input"]
|
||||
package client_registration
|
||||
|
||||
-import future.keywords.in
|
||||
+import rego.v1
|
||||
|
||||
default allow := false
|
||||
|
||||
-allow {
|
||||
+allow if {
|
||||
count(violation) == 0
|
||||
}
|
||||
|
||||
-parse_uri(url) = obj {
|
||||
+parse_uri(url) := obj if {
|
||||
is_string(url)
|
||||
[matches] := regex.find_all_string_submatch_n("^(?P<scheme>[a-z][a-z0-9+.-]*):(?://(?P<host>((?:(?:[a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])\\.)*(?:[a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])|127.0.0.1|0.0.0.0|\\[::1\\])(?::(?P<port>[0-9]+))?))?(?P<path>/[A-Za-z0-9/.-]*)$", url, 1)
|
||||
obj := {"scheme": matches[1], "authority": matches[2], "host": matches[3], "port": matches[4], "path": matches[5]}
|
||||
}
|
||||
|
||||
-secure_url(x) {
|
||||
+secure_url(x) if {
|
||||
x
|
||||
data.client_registration.allow_insecure_uris
|
||||
}
|
||||
|
||||
-secure_url(x) {
|
||||
+secure_url(x) if {
|
||||
url := parse_uri(x)
|
||||
url.scheme == "https"
|
||||
|
||||
@@ -36,14 +36,14 @@ secure_url(x) {
|
||||
url.port == ""
|
||||
}
|
||||
|
||||
-host_matches_client_uri(x) {
|
||||
+host_matches_client_uri(x) if {
|
||||
x
|
||||
|
||||
# Do not check we allow host mismatch
|
||||
data.client_registration.allow_host_mismatch
|
||||
}
|
||||
|
||||
-host_matches_client_uri(x) {
|
||||
+host_matches_client_uri(x) if {
|
||||
x
|
||||
|
||||
# Do not check if the client_uri is missing and we allow that
|
||||
@@ -51,103 +51,103 @@ host_matches_client_uri(x) {
|
||||
not data.client_metadata.client_uri
|
||||
}
|
||||
|
||||
-host_matches_client_uri(x) {
|
||||
+host_matches_client_uri(x) if {
|
||||
client_uri := parse_uri(input.client_metadata.client_uri)
|
||||
uri := parse_uri(x)
|
||||
is_subdomain(client_uri.host, uri.host)
|
||||
}
|
||||
|
||||
-violation[{"msg": "missing client_uri"}] {
|
||||
+violation contains {"msg": "missing client_uri"} if {
|
||||
not data.client_registration.allow_missing_client_uri
|
||||
not input.client_metadata.client_uri
|
||||
}
|
||||
|
||||
-violation[{"msg": "invalid client_uri"}] {
|
||||
+violation contains {"msg": "invalid client_uri"} if {
|
||||
not secure_url(input.client_metadata.client_uri)
|
||||
}
|
||||
|
||||
-violation[{"msg": "invalid tos_uri"}] {
|
||||
+violation contains {"msg": "invalid tos_uri"} if {
|
||||
input.client_metadata.tos_uri
|
||||
not secure_url(input.client_metadata.tos_uri)
|
||||
}
|
||||
|
||||
-violation[{"msg": "tos_uri not on the same host as the client_uri"}] {
|
||||
+violation contains {"msg": "tos_uri not on the same host as the client_uri"} if {
|
||||
input.client_metadata.tos_uri
|
||||
not host_matches_client_uri(input.client_metadata.tos_uri)
|
||||
}
|
||||
|
||||
-violation[{"msg": "invalid policy_uri"}] {
|
||||
+violation contains {"msg": "invalid policy_uri"} if {
|
||||
input.client_metadata.policy_uri
|
||||
not secure_url(input.client_metadata.policy_uri)
|
||||
}
|
||||
|
||||
-violation[{"msg": "policy_uri not on the same host as the client_uri"}] {
|
||||
+violation contains {"msg": "policy_uri not on the same host as the client_uri"} if {
|
||||
input.client_metadata.policy_uri
|
||||
not host_matches_client_uri(input.client_metadata.policy_uri)
|
||||
}
|
||||
|
||||
-violation[{"msg": "invalid logo_uri"}] {
|
||||
+violation contains {"msg": "invalid logo_uri"} if {
|
||||
input.client_metadata.logo_uri
|
||||
not secure_url(input.client_metadata.logo_uri)
|
||||
}
|
||||
|
||||
-violation[{"msg": "logo_uri not on the same host as the client_uri"}] {
|
||||
+violation contains {"msg": "logo_uri not on the same host as the client_uri"} if {
|
||||
input.client_metadata.logo_uri
|
||||
not host_matches_client_uri(input.client_metadata.logo_uri)
|
||||
}
|
||||
|
||||
-violation[{"msg": "missing contacts"}] {
|
||||
+violation contains {"msg": "missing contacts"} if {
|
||||
not data.client_registration.allow_missing_contacts
|
||||
not input.client_metadata.contacts
|
||||
}
|
||||
|
||||
-violation[{"msg": "invalid contacts"}] {
|
||||
+violation contains {"msg": "invalid contacts"} if {
|
||||
not is_array(input.client_metadata.contacts)
|
||||
}
|
||||
|
||||
-violation[{"msg": "empty contacts"}] {
|
||||
+violation contains {"msg": "empty contacts"} if {
|
||||
count(input.client_metadata.contacts) == 0
|
||||
}
|
||||
|
||||
# If the grant_types is missing, we assume it is authorization_code
|
||||
-uses_grant_type("authorization_code") {
|
||||
+uses_grant_type("authorization_code") if {
|
||||
not input.client_metadata.grant_types
|
||||
}
|
||||
|
||||
# Else, we check that the grant_types contains the given grant_type
|
||||
-uses_grant_type(grant_type) {
|
||||
+uses_grant_type(grant_type) if {
|
||||
some gt in input.client_metadata.grant_types
|
||||
gt == grant_type
|
||||
}
|
||||
|
||||
# Consider a client public if the authentication method is none
|
||||
-is_public_client {
|
||||
+is_public_client if {
|
||||
input.client_metadata.token_endpoint_auth_method == "none"
|
||||
}
|
||||
|
||||
-requires_redirect_uris {
|
||||
+requires_redirect_uris if {
|
||||
uses_grant_type("authorization_code")
|
||||
}
|
||||
|
||||
-requires_redirect_uris {
|
||||
+requires_redirect_uris if {
|
||||
uses_grant_type("implicit")
|
||||
}
|
||||
|
||||
-violation[{"msg": "client_credentials grant_type requires some form of client authentication"}] {
|
||||
+violation contains {"msg": "client_credentials grant_type requires some form of client authentication"} if {
|
||||
uses_grant_type("client_credentials")
|
||||
is_public_client
|
||||
}
|
||||
|
||||
-violation[{"msg": "missing redirect_uris"}] {
|
||||
+violation contains {"msg": "missing redirect_uris"} if {
|
||||
requires_redirect_uris
|
||||
not input.client_metadata.redirect_uris
|
||||
}
|
||||
|
||||
-violation[{"msg": "invalid redirect_uris"}] {
|
||||
+violation contains {"msg": "invalid redirect_uris"} if {
|
||||
not is_array(input.client_metadata.redirect_uris)
|
||||
}
|
||||
|
||||
-violation[{"msg": "empty redirect_uris"}] {
|
||||
+violation contains {"msg": "empty redirect_uris"} if {
|
||||
requires_redirect_uris
|
||||
count(input.client_metadata.redirect_uris) == 0
|
||||
}
|
||||
@@ -156,7 +156,7 @@ violation[{"msg": "empty redirect_uris"}] {
|
||||
# another host.
|
||||
# This is used so a redirect_uri like 'com.example.app:/' works for
|
||||
# a 'client_uri' of 'https://example.com/'
|
||||
-reverse_dns_match(host, reverse_dns) {
|
||||
+reverse_dns_match(host, reverse_dns) if {
|
||||
is_string(host)
|
||||
is_string(reverse_dns)
|
||||
|
||||
@@ -171,7 +171,7 @@ reverse_dns_match(host, reverse_dns) {
|
||||
}
|
||||
|
||||
# Used to verify that all the various URIs are subdomains of the client_uri
|
||||
-is_subdomain(host, subdomain) {
|
||||
+is_subdomain(host, subdomain) if {
|
||||
is_string(host)
|
||||
is_string(subdomain)
|
||||
|
||||
@@ -185,27 +185,27 @@ is_subdomain(host, subdomain) {
|
||||
array.slice(subdomain_parts, 0, count(host_parts)) == host_parts
|
||||
}
|
||||
|
||||
-valid_native_redirector(x) {
|
||||
+valid_native_redirector(x) if {
|
||||
url := parse_uri(x)
|
||||
is_localhost(url.host)
|
||||
url.scheme == "http"
|
||||
}
|
||||
|
||||
-is_localhost(host) {
|
||||
+is_localhost(host) if {
|
||||
host == "localhost"
|
||||
}
|
||||
|
||||
-is_localhost(host) {
|
||||
+is_localhost(host) if {
|
||||
host == "127.0.0.1"
|
||||
}
|
||||
|
||||
-is_localhost(host) {
|
||||
+is_localhost(host) if {
|
||||
host == "[::1]"
|
||||
}
|
||||
|
||||
# Custom schemes should match the client_uri, reverse-dns style
|
||||
# e.g. io.element.app:/ matches https://app.element.io/
|
||||
-valid_native_redirector(x) {
|
||||
+valid_native_redirector(x) if {
|
||||
url := parse_uri(x)
|
||||
url.scheme != "http"
|
||||
url.scheme != "https"
|
||||
@@ -216,17 +216,17 @@ valid_native_redirector(x) {
|
||||
reverse_dns_match(client_uri.host, url.scheme)
|
||||
}
|
||||
|
||||
-valid_redirect_uri(uri) {
|
||||
+valid_redirect_uri(uri) if {
|
||||
input.client_metadata.application_type == "native"
|
||||
valid_native_redirector(uri)
|
||||
}
|
||||
|
||||
-valid_redirect_uri(uri) {
|
||||
+valid_redirect_uri(uri) if {
|
||||
secure_url(uri)
|
||||
host_matches_client_uri(uri)
|
||||
}
|
||||
|
||||
-violation[{"msg": "invalid redirect_uri", "redirect_uri": redirect_uri}] {
|
||||
+violation contains {"msg": "invalid redirect_uri", "redirect_uri": redirect_uri} if {
|
||||
some redirect_uri in input.client_metadata.redirect_uris
|
||||
not valid_redirect_uri(redirect_uri)
|
||||
}
|
||||
diff --git a/policies/client_registration_test.rego b/policies/client_registration_test.rego
|
||||
index e7510f98..2e46004c 100644
|
||||
--- a/policies/client_registration_test.rego
|
||||
+++ b/policies/client_registration_test.rego
|
||||
@@ -1,6 +1,8 @@
|
||||
package client_registration
|
||||
|
||||
-test_valid {
|
||||
+import rego.v1
|
||||
+
|
||||
+test_valid if {
|
||||
allow with input.client_metadata as {
|
||||
"grant_types": ["authorization_code"],
|
||||
"client_uri": "https://example.com/",
|
||||
@@ -9,7 +11,7 @@ test_valid {
|
||||
}
|
||||
}
|
||||
|
||||
-test_missing_client_uri {
|
||||
+test_missing_client_uri if {
|
||||
not allow with input.client_metadata as {
|
||||
"grant_types": [],
|
||||
"contacts": ["contact@example.com"],
|
||||
@@ -22,7 +24,7 @@ test_missing_client_uri {
|
||||
with data.client_registration.allow_missing_client_uri as true
|
||||
}
|
||||
|
||||
-test_insecure_client_uri {
|
||||
+test_insecure_client_uri if {
|
||||
not allow with input.client_metadata as {
|
||||
"grant_types": [],
|
||||
"client_uri": "http://example.com/",
|
||||
@@ -30,7 +32,7 @@ test_insecure_client_uri {
|
||||
}
|
||||
}
|
||||
|
||||
-test_tos_uri {
|
||||
+test_tos_uri if {
|
||||
allow with input.client_metadata as {
|
||||
"grant_types": [],
|
||||
"client_uri": "https://example.com/",
|
||||
@@ -81,7 +83,7 @@ test_tos_uri {
|
||||
with data.client_registration.allow_host_mismatch as true
|
||||
}
|
||||
|
||||
-test_logo_uri {
|
||||
+test_logo_uri if {
|
||||
allow with input.client_metadata as {
|
||||
"grant_types": [],
|
||||
"client_uri": "https://example.com/",
|
||||
@@ -132,7 +134,7 @@ test_logo_uri {
|
||||
with data.client_registration.allow_host_mismatch as true
|
||||
}
|
||||
|
||||
-test_policy_uri {
|
||||
+test_policy_uri if {
|
||||
allow with input.client_metadata as {
|
||||
"grant_types": [],
|
||||
"client_uri": "https://example.com/",
|
||||
@@ -183,7 +185,7 @@ test_policy_uri {
|
||||
with data.client_registration.allow_host_mismatch as true
|
||||
}
|
||||
|
||||
-test_redirect_uris {
|
||||
+test_redirect_uris if {
|
||||
# Missing redirect_uris
|
||||
not allow with input.client_metadata as {
|
||||
"client_uri": "https://example.com/",
|
||||
@@ -226,7 +228,7 @@ test_redirect_uris {
|
||||
}
|
||||
}
|
||||
|
||||
-test_web_redirect_uri {
|
||||
+test_web_redirect_uri if {
|
||||
allow with input.client_metadata as {
|
||||
"application_type": "web",
|
||||
"client_uri": "https://example.com/",
|
||||
@@ -309,7 +311,7 @@ test_web_redirect_uri {
|
||||
}
|
||||
}
|
||||
|
||||
-test_native_redirect_uri {
|
||||
+test_native_redirect_uri if {
|
||||
# This has all the redirect URIs types we're supporting for native apps
|
||||
allow with input.client_metadata as {
|
||||
"application_type": "native",
|
||||
@@ -375,13 +377,13 @@ test_native_redirect_uri {
|
||||
}
|
||||
}
|
||||
|
||||
-test_reverse_dns_match {
|
||||
+test_reverse_dns_match if {
|
||||
client_uri := parse_uri("https://element.io/")
|
||||
redirect_uri := parse_uri("io.element.app:/callback")
|
||||
reverse_dns_match(client_uri.host, redirect_uri.scheme)
|
||||
}
|
||||
|
||||
-test_contacts {
|
||||
+test_contacts if {
|
||||
# Missing contacts
|
||||
not allow with input.client_metadata as {
|
||||
"grant_types": [],
|
||||
@@ -410,7 +412,7 @@ test_contacts {
|
||||
}
|
||||
}
|
||||
|
||||
-test_client_credentials_grant {
|
||||
+test_client_credentials_grant if {
|
||||
# Allowed for confidential clients
|
||||
allow with input.client_metadata as {
|
||||
"grant_types": ["client_credentials"],
|
||||
@@ -434,14 +436,14 @@ test_client_credentials_grant {
|
||||
}
|
||||
}
|
||||
|
||||
-test_is_subdomain {
|
||||
+test_is_subdomain if {
|
||||
is_subdomain("example.com", "example.com")
|
||||
is_subdomain("example.com", "app.example.com")
|
||||
not is_subdomain("example.com", "example.org")
|
||||
not is_subdomain("test.com", "example.com")
|
||||
}
|
||||
|
||||
-test_reverse_dns_match {
|
||||
+test_reverse_dns_match if {
|
||||
reverse_dns_match("example.com", "com.example")
|
||||
reverse_dns_match("example.com", "com.example.app")
|
||||
not reverse_dns_match("example.com", "org.example")
|
||||
diff --git a/policies/email.rego b/policies/email.rego
|
||||
index fecad108..83a00ea6 100644
|
||||
--- a/policies/email.rego
|
||||
+++ b/policies/email.rego
|
||||
@@ -3,32 +3,32 @@
|
||||
# - input: schema["email_input"]
|
||||
package email
|
||||
|
||||
-import future.keywords.in
|
||||
+import rego.v1
|
||||
|
||||
default allow := false
|
||||
|
||||
-allow {
|
||||
+allow if {
|
||||
count(violation) == 0
|
||||
}
|
||||
|
||||
# Allow any domains if the data.allowed_domains array is not set
|
||||
-email_domain_allowed {
|
||||
+email_domain_allowed if {
|
||||
not data.allowed_domains
|
||||
}
|
||||
|
||||
# Allow an email only if its domain is in the list of allowed domains
|
||||
-email_domain_allowed {
|
||||
+email_domain_allowed if {
|
||||
[_, domain] := split(input.email, "@")
|
||||
some allowed_domain in data.allowed_domains
|
||||
glob.match(allowed_domain, ["."], domain)
|
||||
}
|
||||
|
||||
-violation[{"msg": "email domain is not allowed"}] {
|
||||
+violation contains {"msg": "email domain is not allowed"} if {
|
||||
not email_domain_allowed
|
||||
}
|
||||
|
||||
# Deny emails with their domain in the domains banlist
|
||||
-violation[{"msg": "email domain is banned"}] {
|
||||
+violation contains {"msg": "email domain is banned"} if {
|
||||
[_, domain] := split(input.email, "@")
|
||||
some banned_domain in data.banned_domains
|
||||
glob.match(banned_domain, ["."], domain)
|
||||
diff --git a/policies/email_test.rego b/policies/email_test.rego
|
||||
index efda51bd..779594a4 100644
|
||||
--- a/policies/email_test.rego
|
||||
+++ b/policies/email_test.rego
|
||||
@@ -1,25 +1,27 @@
|
||||
package email
|
||||
|
||||
-test_allow_all_domains {
|
||||
+import rego.v1
|
||||
+
|
||||
+test_allow_all_domains if {
|
||||
allow with input.email as "hello@staging.element.io"
|
||||
}
|
||||
|
||||
-test_allowed_domain {
|
||||
+test_allowed_domain if {
|
||||
allow with input.email as "hello@staging.element.io"
|
||||
with data.allowed_domains as ["*.element.io"]
|
||||
}
|
||||
|
||||
-test_not_allowed_domain {
|
||||
+test_not_allowed_domain if {
|
||||
not allow with input.email as "hello@staging.element.io"
|
||||
with data.allowed_domains as ["example.com"]
|
||||
}
|
||||
|
||||
-test_banned_domain {
|
||||
+test_banned_domain if {
|
||||
not allow with input.email as "hello@staging.element.io"
|
||||
with data.banned_domains as ["*.element.io"]
|
||||
}
|
||||
|
||||
-test_banned_subdomain {
|
||||
+test_banned_subdomain if {
|
||||
not allow with input.email as "hello@staging.element.io"
|
||||
with data.allowed_domains as ["*.element.io"]
|
||||
with data.banned_domains as ["staging.element.io"]
|
||||
diff --git a/policies/register.rego b/policies/register.rego
|
||||
index 05193549..edcad662 100644
|
||||
--- a/policies/register.rego
|
||||
+++ b/policies/register.rego
|
||||
@@ -3,38 +3,38 @@
|
||||
# - input: schema["register_input"]
|
||||
package register
|
||||
|
||||
-import data.email as email_policy
|
||||
+import rego.v1
|
||||
|
||||
-import future.keywords.in
|
||||
+import data.email as email_policy
|
||||
|
||||
default allow := false
|
||||
|
||||
-allow {
|
||||
+allow if {
|
||||
count(violation) == 0
|
||||
}
|
||||
|
||||
-violation[{"field": "username", "msg": "username too short"}] {
|
||||
+violation contains {"field": "username", "msg": "username too short"} if {
|
||||
count(input.username) <= 2
|
||||
}
|
||||
|
||||
-violation[{"field": "username", "msg": "username too long"}] {
|
||||
+violation contains {"field": "username", "msg": "username too long"} if {
|
||||
count(input.username) > 64
|
||||
}
|
||||
|
||||
-violation[{"field": "username", "msg": "username contains invalid characters"}] {
|
||||
+violation contains {"field": "username", "msg": "username contains invalid characters"} if {
|
||||
not regex.match("^[a-z0-9.=_/-]+$", input.username)
|
||||
}
|
||||
|
||||
-violation[{"msg": "unspecified registration method"}] {
|
||||
+violation contains {"msg": "unspecified registration method"} if {
|
||||
not input.registration_method
|
||||
}
|
||||
|
||||
-violation[{"msg": "unknown registration method"}] {
|
||||
+violation contains {"msg": "unknown registration method"} if {
|
||||
not input.registration_method in ["password", "upstream-oauth2"]
|
||||
}
|
||||
|
||||
# Check that we supplied an email for password registration
|
||||
-violation[{"field": "email", "msg": "email required for password-based registration"}] {
|
||||
+violation contains {"field": "email", "msg": "email required for password-based registration"} if {
|
||||
input.registration_method == "password"
|
||||
|
||||
not input.email
|
||||
@@ -42,7 +42,7 @@ violation[{"field": "email", "msg": "email required for password-based registrat
|
||||
|
||||
# Check if the email is valid using the email policy
|
||||
# and add the email field to the violation object
|
||||
-violation[object.union({"field": "email"}, v)] {
|
||||
+violation contains object.union({"field": "email"}, v) if {
|
||||
# Check if we have an email set in the input
|
||||
input.email
|
||||
|
||||
diff --git a/policies/register_test.rego b/policies/register_test.rego
|
||||
index 4d8d5476..e5853a60 100644
|
||||
--- a/policies/register_test.rego
|
||||
+++ b/policies/register_test.rego
|
||||
@@ -1,52 +1,54 @@
|
||||
package register
|
||||
|
||||
+import rego.v1
|
||||
+
|
||||
mock_registration := {
|
||||
"registration_method": "password",
|
||||
"username": "hello",
|
||||
"email": "hello@staging.element.io",
|
||||
}
|
||||
|
||||
-test_allow_all_domains {
|
||||
+test_allow_all_domains if {
|
||||
allow with input as mock_registration
|
||||
}
|
||||
|
||||
-test_allowed_domain {
|
||||
+test_allowed_domain if {
|
||||
allow with input as mock_registration
|
||||
with data.allowed_domains as ["*.element.io"]
|
||||
}
|
||||
|
||||
-test_not_allowed_domain {
|
||||
+test_not_allowed_domain if {
|
||||
not allow with input as mock_registration
|
||||
with data.allowed_domains as ["example.com"]
|
||||
}
|
||||
|
||||
-test_banned_domain {
|
||||
+test_banned_domain if {
|
||||
not allow with input as mock_registration
|
||||
with data.banned_domains as ["*.element.io"]
|
||||
}
|
||||
|
||||
-test_banned_subdomain {
|
||||
+test_banned_subdomain if {
|
||||
not allow with input as mock_registration
|
||||
with data.allowed_domains as ["*.element.io"]
|
||||
with data.banned_domains as ["staging.element.io"]
|
||||
}
|
||||
|
||||
-test_email_required {
|
||||
+test_email_required if {
|
||||
not allow with input as {"username": "hello", "registration_method": "password"}
|
||||
}
|
||||
|
||||
-test_no_email {
|
||||
+test_no_email if {
|
||||
allow with input as {"username": "hello", "registration_method": "upstream-oauth2"}
|
||||
}
|
||||
|
||||
-test_short_username {
|
||||
+test_short_username if {
|
||||
not allow with input as {"username": "a", "registration_method": "upstream-oauth2"}
|
||||
}
|
||||
|
||||
-test_long_username {
|
||||
+test_long_username if {
|
||||
not allow with input as {"username": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "registration_method": "upstream-oauth2"}
|
||||
}
|
||||
|
||||
-test_invalid_username {
|
||||
+test_invalid_username if {
|
||||
not allow with input as {"username": "hello world", "registration_method": "upstream-oauth2"}
|
||||
}
|
||||
diff --git a/policies/util/coveralls.rego b/policies/util/coveralls.rego
|
||||
index 881c7f6f..5ff50129 100644
|
||||
--- a/policies/util/coveralls.rego
|
||||
+++ b/policies/util/coveralls.rego
|
||||
@@ -1,6 +1,6 @@
|
||||
package coveralls
|
||||
|
||||
-import future.keywords
|
||||
+import rego.v1
|
||||
|
||||
from_opa := {"source_files": coverage}
|
||||
|
||||
@@ -9,7 +9,7 @@ coverage contains obj if {
|
||||
obj := {"name": file, "coverage": to_lines(report)}
|
||||
}
|
||||
|
||||
-covered_map(report) = cm if {
|
||||
+covered_map(report) := cm if {
|
||||
covered := object.get(report, "covered", [])
|
||||
cm := {line: 1 |
|
||||
some item in covered
|
||||
@@ -17,7 +17,7 @@ covered_map(report) = cm if {
|
||||
}
|
||||
}
|
||||
|
||||
-not_covered_map(report) = ncm if {
|
||||
+not_covered_map(report) := ncm if {
|
||||
not_covered := object.get(report, "not_covered", [])
|
||||
ncm := {line: 0 |
|
||||
some item in not_covered
|
||||
@@ -25,7 +25,7 @@ not_covered_map(report) = ncm if {
|
||||
}
|
||||
}
|
||||
|
||||
-to_lines(report) = lines if {
|
||||
+to_lines(report) := lines if {
|
||||
cm := covered_map(report)
|
||||
ncm := not_covered_map(report)
|
||||
keys := sort([line | some line, _ in object.union(cm, ncm)])
|
||||
@@ -37,15 +37,15 @@ to_lines(report) = lines if {
|
||||
]
|
||||
}
|
||||
|
||||
-to_value(cm, _, line) = 1 if {
|
||||
+to_value(cm, _, line) := 1 if {
|
||||
cm[line]
|
||||
}
|
||||
|
||||
-to_value(_, ncm, line) = 0 if {
|
||||
+to_value(_, ncm, line) := 0 if {
|
||||
ncm[line]
|
||||
}
|
||||
|
||||
-to_value(cm, ncm, line) = null if {
|
||||
+to_value(cm, ncm, line) := null if {
|
||||
not cm[line]
|
||||
not ncm[line]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user