# The Flask secret key for cookies. You MUST change this.
SECRET_KEY = "change me before you go in production"

# The interface on which canaille will be served
# SERVER_NAME = "auth.mydomain.example"
# PREFERRED_URL_SCHEME = "https"

[CANAILLE]

# Your organization name.
# NAME = "Canaille"

# You can display a logo to be recognized on login screens
# LOGO = "/static/img/canaille-head.webp"

# Your favicon. If unset the LOGO will be used.
# FAVICON = "/static/img/canaille-c.webp"

# The name of a theme in the 'theme' directory, or a path path
# to a theme. Defaults to 'default'. Theming is done with
# https://github.com/tktech/flask-themer
# THEME = "default"

# If unset, language is detected
# LANGUAGE = "en"

# The timezone in which datetimes will be displayed to the users.
# If unset, the server timezone will be used.
# TIMEZONE = UTC

# If you have a sentry instance, you can set its dsn here:
# SENTRY_DSN = "https://examplePublicKey@o0.ingest.sentry.io/0"

# Enables javascript to smooth the user experience
# JAVASCRIPT = true

# Accelerates webpages with async requests
# HTMX = true

# If EMAIL_CONFIRMATION is set to true, users will need to click on a
# confirmation link sent by email when they want to add a new email.
# By default, this is true if SMTP is configured, else this is false.
# If explicitly set to true and SMTP is disabled, the email field
# will be read-only.
# EMAIL_CONFIRMATION = True

# If ENABLE_REGISTRATION is true, then users can freely create an account
# at this instance. If email verification is available, users must confirm
# their email before the account is created.
# ENABLE_REGISTRATION = false

# If HIDE_INVALID_LOGINS is set to true (the default), when a user
# tries to sign in with an invalid login, a message is shown indicating
# that the password is wrong, but does not give a clue whether the login
# exists or not.
# If HIDE_INVALID_LOGINS is set to false, when a user tries to sign in with
# an invalid login, a message is shown indicating that the login does not
# exist.
# HIDE_INVALID_LOGINS = true

# If ENABLE_PASSWORD_RECOVERY is false, then users cannot ask for a password
# recovery link by email. This option is true by default.
# ENABLE_PASSWORD_RECOVERY = true

# If ENABLE_INTRUDER_LOCKOUT is true, then users will have to wait for an
# increasingly long time between each failed login attempt. This option is false by default.
# ENABLE_INTRUDER_LOCKOUT = false

# If OTP_METHOD is defined, then users will need to authenticate themselves
# using a one-time password (OTP) via an authenticator app.
# Two options are supported : "TOTP" for time one-time password,
# and "HOTP" for HMAC-based one-time password.
# This option is deactivated by default.
# OTP_METHOD = "TOTP"

# If EMAIL_OTP is true, then users will need to authenticate themselves
# via a one-time password sent to their primary email address.
# This option is false by default.
# EMAIL_OTP = false

# If SMS_OTP is true, then users will need to authenticate themselves
# via a one-time password sent to their primary phone number.
# This option is false by default.
# SMS_OTP = false

# The validity duration of registration invitations, in seconds.
# Defaults to 2 days
# INVITATION_EXPIRATION = 172800

# LOGGING configures the logging output:
# - if unset, everything is logged in the standard output
#   the log level is debug if DEBUG is True, else this is INFO
# - if this is a dictionary, it is passed to the python dictConfig method:
#   https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig
# - if this is a string, it is passed to the python fileConfig method
#   https://docs.python.org/3/library/logging.config.html#logging.config.fileConfig

# Minimum length for user password.
# It is possible not to set a minimum, by entering None or 0.
# MIN_PASSWORD_LENGTH = 8

# Maximum length for user password.
# There is a technical limit with passlib used by sql database of 4096
# characters. If the value entered is 0 or None, or greater than 4096,
# then 4096 will be retained.
# MAX_PASSWORD_LENGTH = 1000

# Administration email contact.
# In certain special cases (example : questioning about password
# corruption), it is necessary to provide an administration contact
# email.
# ADMIN_EMAIL = "admin@mydomain.example"

# If :py:data:`True`, Canaille will check for password compromise on HIBP
# every time a new password is register.
# (https://haveibeenpwned.com/)
# ENABLE_PASSWORD_COMPROMISSION_CHECK = False

# Have i been pwned api url for compromission checks.
# This url should not be modified.
# API_URL_HIBP = "https://api.pwnedpasswords.com/range/"

# [CANAILLE_SQL]
# The SQL database connection string
# Details on https://docs.sqlalchemy.org/en/20/core/engines.html
# DATABASE_URI = "postgresql://user:password@localhost/database"

# [CANAILLE_LDAP]
# URI = "ldap://ldap"
# ROOT_DN = "dc=mydomain,dc=tld"
# BIND_DN = "cn=admin,dc=mydomain,dc=tld"
# BIND_PW = "admin"
# TIMEOUT =

# Where to search for users?
# USER_BASE = "ou=users,dc=mydomain,dc=tld"

# The object class to use for creating new users
# Note : If you plan on using TOTP/HOTP authentication, use : USER_CLASS = ["inetOrgPerson", "oathHOTPToken"]
# USER_CLASS = "inetOrgPerson"

# The attribute to identify an object in the User dn.
# USER_RDN = "uid"

# Filter to match users on sign in. Jinja syntax is supported
# and a `login` variable is available containing the value
# passed in the login field.
# USER_FILTER = "(|(uid={{ login }})(mail={{ login }}))"

# Where to search for groups?
# GROUP_BASE = "ou=groups,dc=mydomain,dc=tld"

# The object class to use for creating new groups
# GROUP_CLASS = "groupOfNames"

# The attribute to identify an object in the User dn.
# GROUP_RDN = "cn"

# The attribute to use to identify a group
# GROUP_NAME_ATTRIBUTE = "cn"

[CANAILLE.ACL]
# You can define access controls that define what users can do on canaille
# An access control consists in a FILTER to match users, a list of PERMISSIONS
# matched users will be able to perform, and fields users will be able
# to READ and WRITE. Users matching several filters will cumulate permissions.
#
# 'FILTER' parameter can be:
# - absent, in which case all the users will match this access control
# - a mapping where keys are user attributes name and the values those user
#   attribute values. All the values must be matched for the user to be part
#   of the access control.
# - a list of those mappings. If a user values match at least one mapping,
#   then the user will be part of the access control
#
# Here are some examples
#     FILTER = {user_name = 'admin'}
#     FILTER =
#       - {groups = 'admins}
#       - {groups = 'moderators'}
#
# The 'PERMISSIONS' parameter that is an list of items the users in the access
# control will be able to manage. 'PERMISSIONS' is optional. Values can be:
# - "edit_self" to allow users to edit their own profile
# - "use_oidc" to allow OpenID Connect authentication
# - "manage_oidc" to allow OpenID Connect client managements
# - "manage_users" to allow other users management
# - "manage_groups" to allow group edition and creation
# - "delete_account" allows a user to delete his own account. If used with
#                    manage_users, the user can delete any account
# - "impersonate_users" to allow a user to take the identity of another user
#
# The 'READ' and 'WRITE' attributes are the LDAP attributes of the user
# object that users will be able to read and/or write.
[CANAILLE.ACL.DEFAULT]
PERMISSIONS = ["edit_self", "use_oidc"]
READ = [
    "user_name",
    "groups",
    "lock_date",
]
WRITE = [
    "photo",
    "given_name",
    "family_name",
    "display_name",
    "password",
    "phone_numbers",
    "emails",
    "profile_url",
    "formatted_address",
    "street",
    "postal_code",
    "locality",
    "region",
    "preferred_language",
    "employee_number",
    "department",
    "title",
    "organization",
]

[CANAILLE.ACL.ADMIN]
FILTER = {groups = "admins"}
PERMISSIONS = [
    "manage_users",
    "manage_groups",
    "manage_oidc",
    "delete_account",
    "impersonate_users",
]
WRITE = [
    "groups",
    "lock_date",
]

[CANAILLE_OIDC]
# Whether a token is needed for the RFC7591 dynamical client registration.
# If true, no token is needed to register a client.
# If false, dynamical client registration needs a token defined
# in DYNAMIC_CLIENT_REGISTRATION_TOKENS
# DYNAMIC_CLIENT_REGISTRATION_OPEN = false

# A list of tokens that can be used for dynamic client registration
# DYNAMIC_CLIENT_REGISTRATION_TOKENS = [
#     "xxxxxxx-yyyyyyy-zzzzzz",
# ]

# REQUIRE_NONCE force the nonce exchange during the authentication flows.
# This adds security but may not be supported by all clients.
# REQUIRE_NONCE = true

[CANAILLE_OIDC.JWT]
# PRIVATE_KEY and PUBLIC_KEY are the private and
# the public key. You can generate a RSA keypair with:
# openssl genrsa -out private.pem 4096
# openssl rsa -in private.pem -pubout -outform PEM -out public.pem
# If the variables are unset, and debug mode is enabled,
# a in-memory keypair will be used.
# PRIVATE_KEY = "..."
# PUBLIC_KEY = "..."
# The URI of the identity provider
# ISS = "https://auth.mydomain.example"
# The key type parameter
# KTY = "RSA"
# The key algorithm
# ALG = "RS256"
# The time the JWT will be valid, in seconds
# EXP = 3600

[CANAILLE_OIDC.JWT.MAPPING]
# Mapping between JWT fields and LDAP attributes from your
# User objectClass.
# {attribute} will be replaced by the user ldap attribute value.
# Default values fits inetOrgPerson.
# SUB = "{{ user.user_name }}"
# NAME = "{{ user.formatted_name }}"
# PHONE_NUMBER = "{{ user.phone_numbers[0] }}"
# EMAIL = "{{ user.preferred_email }}"
# GIVEN_NAME = "{{ user.given_name }}"
# FAMILY_NAME = "{{ user.family_name }}"
# PREFERRED_USERNAME = "{{ user.display_name }}"
# LOCALE = "{{ user.preferred_language }}"
# ADDRESS = "{{ user.formatted_address }}"
# PICTURE = "{% if user.photo %}{{ url_for('core.account.photo', user=user, field='photo', _external=True) }}{% endif %}"
# WEBSITE = "{{ user.profile_url }}"

# The SMTP server options. If not set, mail related features such as
# user invitations, and password reset emails, will be disabled.
[CANAILLE.SMTP]
# HOST = "localhost"
# PORT = 25
# TLS = false
# SSL = false
# LOGIN = ""
# PASSWORD = ""
# FROM_ADDR = "admin@mydomain.example"

# The SMPP server options. If not set, sms related features such as
# sms one-time passwords will be disabled.
[CANAILLE.SMPP]
# HOST = "localhost"
# PORT = 2775
# LOGIN = ""
# PASSWORD = ""
