100 lines
2.5 KiB
Rego
100 lines
2.5 KiB
Rego
# Copyright 2025 New Vector Ltd.
|
|
#
|
|
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
# Please see LICENSE files in the repository root for full details.
|
|
|
|
# METADATA
|
|
# schemas:
|
|
# - input: schema["register_input"]
|
|
package register
|
|
|
|
import rego.v1
|
|
|
|
import data.common
|
|
import data.email as email_policy
|
|
|
|
default allow := false
|
|
|
|
allow if {
|
|
count(violation) == 0
|
|
}
|
|
|
|
username_allowed if {
|
|
not data.registration.allowed_usernames
|
|
}
|
|
|
|
username_allowed if {
|
|
common.matches_string_constraints(input.username, data.registration.allowed_usernames)
|
|
}
|
|
|
|
# METADATA
|
|
# entrypoint: true
|
|
violation contains {"field": "username", "code": "username-too-short", "msg": "username too short"} if {
|
|
count(input.username) == 0
|
|
}
|
|
|
|
violation contains {"field": "username", "code": "username-too-long", "msg": "username too long"} if {
|
|
user_id := common.mxid(input.username, data.server_name)
|
|
count(user_id) > 255
|
|
}
|
|
|
|
violation contains {
|
|
"field": "username", "code": "username-all-numeric",
|
|
"msg": "username must contain at least one non-numeric character",
|
|
} if {
|
|
regex.match(`^[0-9]+$`, input.username)
|
|
}
|
|
|
|
violation contains {
|
|
"field": "username", "code": "username-invalid-chars",
|
|
"msg": "username contains invalid characters",
|
|
} if {
|
|
not regex.match(`^[a-z0-9.=_/-]+$`, input.username)
|
|
}
|
|
|
|
violation contains {
|
|
"field": "username", "code": "username-banned",
|
|
"msg": "username is banned",
|
|
} if {
|
|
common.matches_string_constraints(input.username, data.registration.banned_usernames)
|
|
}
|
|
|
|
violation contains {
|
|
"field": "username", "code": "username-not-allowed",
|
|
"msg": "username is not allowed",
|
|
} if {
|
|
not username_allowed
|
|
}
|
|
|
|
violation contains {"msg": "unspecified registration method"} if {
|
|
not input.registration_method
|
|
}
|
|
|
|
violation contains {"msg": "unknown registration method"} if {
|
|
not input.registration_method in ["password", "upstream-oauth2"]
|
|
}
|
|
|
|
violation contains {"msg": sprintf(
|
|
"Requester [%s] isn't allowed to do this action",
|
|
[common.format_requester(input.requester)],
|
|
)} if {
|
|
common.requester_banned(input.requester, data.requester)
|
|
}
|
|
|
|
# Check that we supplied an email for password registration
|
|
violation contains {"field": "email", "msg": "email required for password-based registration"} if {
|
|
input.registration_method == "password"
|
|
|
|
not input.email
|
|
}
|
|
|
|
# Check if the email is valid using the email policy
|
|
# and add the email field to the violation object
|
|
violation contains object.union({"field": "email"}, v) if {
|
|
# Check if we have an email set in the input
|
|
input.email
|
|
|
|
# Get the violation object from the email policy
|
|
some v in email_policy.violation
|
|
}
|