docs: rewrite README with structured overview and quick start guide

Replaces the minimal project description with a comprehensive README
including a component overview table, quick start instructions, common
Ansible operations, and links to detailed documentation. Aligns with
Red Panda Approval™ standards.
This commit is contained in:
2026-03-03 12:49:06 +00:00
parent c7be03a743
commit b4d60f2f38
219 changed files with 34586 additions and 2 deletions

154
ansible/casdoor/app.conf.j2 Normal file
View File

@@ -0,0 +1,154 @@
# -----------------------------------------------------------------------------
# Casdoor Application Configuration
# -----------------------------------------------------------------------------
# Generated by Ansible - do not edit manually
# See: https://casdoor.org/docs/basic/server-installation
# -----------------------------------------------------------------------------
appname = casdoor
httpport = {{ casdoor_port | default(8000) }}
runmode = {{ casdoor_runmode | default('prod') }}
copyrequestbody = true
# -----------------------------------------------------------------------------
# Database Configuration
# -----------------------------------------------------------------------------
# Connects to native PostgreSQL on localhost (deployed by postgresql_ssl playbook)
driverName = postgres
dataSourceName = user={{ casdoor_db_user }} password={{ casdoor_db_password }} host=localhost port={{ casdoor_db_port | default(5432) }} sslmode={{ casdoor_db_sslmode | default('disable') }} dbname={{ casdoor_db_name }}
dbName = {{ casdoor_db_name }}
tableNamePrefix =
showSql = {{ casdoor_showsql | default('false') }}
# -----------------------------------------------------------------------------
# Cache Configuration
# -----------------------------------------------------------------------------
redisEndpoint = {{ casdoor_redis_endpoint | default('') }}
# -----------------------------------------------------------------------------
# Storage Configuration
# -----------------------------------------------------------------------------
# OCI Object Storage via S3-compatible API
defaultStorageProvider = {{ casdoor_default_storage_provider | default('') }}
{% if casdoor_s3_endpoint is defined and casdoor_s3_endpoint %}
storageProvider = {
"owner": "admin",
"name": "oci-s3",
"createdTime": "",
"displayName": "OCI Object Storage",
"category": "Storage",
"type": "AWS S3",
"subType": "",
"method": "",
"clientId": "{{ casdoor_s3_access_key }}",
"clientSecret": "{{ casdoor_s3_secret_key }}",
"clientId2": "",
"clientSecret2": "",
"cert": "",
"customAuthUrl": "",
"customScope": "",
"customTokenUrl": "",
"customUserInfoUrl": "",
"customLogo": "",
"scopes": "",
"userMapping": null,
"host": "",
"port": 0,
"disableSsl": false,
"title": "",
"content": "",
"receiver": "",
"regionId": "{{ casdoor_s3_region | default('ca-toronto-1') }}",
"signName": "",
"templateCode": "",
"appId": "",
"endpoint": "https://{{ casdoor_s3_endpoint }}",
"intranetEndpoint": "",
"domain": "{{ casdoor_s3_bucket }}",
"bucket": "{{ casdoor_s3_bucket }}",
"pathPrefix": "",
"metadata": "",
"idP": "",
"issuerUrl": "",
"enableSignAuthnRequest": false,
"providerUrl": ""
}
{% endif %}
# -----------------------------------------------------------------------------
# Security Configuration
# -----------------------------------------------------------------------------
isCloudIntranet = false
authState = {{ casdoor_auth_state | default(casdoor_secret_key) }}
socks5Proxy =
verificationCodeTimeout = 10
initScore = 0
logPostOnly = true
isUsernameLowered = false
# -----------------------------------------------------------------------------
# Origin Configuration
# -----------------------------------------------------------------------------
# Must match the external URL used to access Casdoor
origin = {{ casdoor_origin }}
originFrontend = {{ casdoor_origin_frontend | default(casdoor_origin) }}
staticBaseUrl = "https://cdn.casbin.org"
# -----------------------------------------------------------------------------
# Application Settings
# -----------------------------------------------------------------------------
isDemoMode = false
batchSize = 100
enableErrorMask = true
enableGzip = true
# Session timeout in minutes
inactiveTimeoutMinutes = {{ casdoor_inactive_timeout_minutes | default(60) }}
# -----------------------------------------------------------------------------
# Theme Configuration
# -----------------------------------------------------------------------------
themeData = {"themeType": "default", "colorPrimary": "#ffa415", "borderRadius": 6, "isCompact": false}
# -----------------------------------------------------------------------------
# LDAP Configuration
# -----------------------------------------------------------------------------
ldapServerPort = {{ casdoor_ldap_server_port | default(0) }}
ldapsCertId = {{ casdoor_ldaps_cert_id | default('') }}
ldapsServerPort = {{ casdoor_ldaps_server_port | default(0) }}
# -----------------------------------------------------------------------------
# RADIUS Configuration
# -----------------------------------------------------------------------------
radiusServerPort = {{ casdoor_radius_server_port | default(0) }}
radiusDefaultOrganization = {{ casdoor_radius_default_organization | default('built-in') }}
radiusSecret = {{ casdoor_radius_secret | default('') }}
# -----------------------------------------------------------------------------
# Resource Quotas
# -----------------------------------------------------------------------------
quota = {"organization": -1, "user": -1, "application": -1, "provider": -1}
# -----------------------------------------------------------------------------
# Logging Configuration
# -----------------------------------------------------------------------------
logConfig = {"adapter":"console"}
# -----------------------------------------------------------------------------
# Initialization
# -----------------------------------------------------------------------------
initDataNewOnly = true
initDataFile = "/conf/init_data.json"
frontendBaseDir = "../cc_0"

155
ansible/casdoor/deploy.yml Normal file
View File

@@ -0,0 +1,155 @@
---
# -----------------------------------------------------------------------------
# Casdoor Deployment Playbook
# -----------------------------------------------------------------------------
# Deploys Casdoor SSO Docker container
# Host: titania.incus (Incus container)
# Endpoint: id.ouranos.helu.ca via HAProxy on Titania
#
# Prerequisites:
# - postgresql_ssl must be deployed first (provides the database)
# - Docker must be installed
# - Alloy must be configured for syslog
#
# Secrets are fetched from Ansible Vault via group_vars/all/vault.yml
# -----------------------------------------------------------------------------
- name: Deploy Casdoor
hosts: ubuntu
tasks:
- name: Check if host has casdoor service
ansible.builtin.set_fact:
has_casdoor_service: "{{ 'casdoor' in services | default([]) }}"
- name: Skip hosts without casdoor service
ansible.builtin.meta: end_host
when: not has_casdoor_service
# -------------------------------------------------------------------------
# Create User and Group (system-assigned UID/GID)
# -------------------------------------------------------------------------
- name: Create casdoor group
become: true
ansible.builtin.group:
name: "{{ casdoor_group }}"
system: true
- name: Create casdoor user
become: true
ansible.builtin.user:
name: "{{ casdoor_user }}"
comment: "Casdoor service account"
group: "{{ casdoor_group }}"
system: true
create_home: false
shell: /usr/sbin/nologin
- name: Add ansible_user to casdoor group
become: true
ansible.builtin.user:
name: "{{ ansible_user }}"
groups: "{{ casdoor_group }}"
append: true
# -------------------------------------------------------------------------
# Query uid/gid for Docker container user
# -------------------------------------------------------------------------
- name: Get casdoor user uid
ansible.builtin.shell: |
getent passwd {{ casdoor_user }} | cut -d: -f3
register: casdoor_uid_result
changed_when: false
- name: Get casdoor group gid
ansible.builtin.shell: |
getent group {{ casdoor_group }} | cut -d: -f3
register: casdoor_gid_result
changed_when: false
- name: Set uid/gid facts
ansible.builtin.set_fact:
casdoor_uid: "{{ casdoor_uid_result.stdout }}"
casdoor_gid: "{{ casdoor_gid_result.stdout }}"
# -------------------------------------------------------------------------
# Create Directories
# -------------------------------------------------------------------------
- name: Create casdoor base directory
become: true
ansible.builtin.file:
path: "{{ casdoor_directory }}"
owner: "{{ casdoor_user }}"
group: "{{ casdoor_group }}"
state: directory
mode: '0750'
- name: Create casdoor conf directory
become: true
ansible.builtin.file:
path: "{{ casdoor_directory }}/conf"
owner: "{{ casdoor_user }}"
group: "{{ casdoor_group }}"
state: directory
mode: '0750'
# -------------------------------------------------------------------------
# Template Configuration Files
# -------------------------------------------------------------------------
- name: Template docker-compose.yml
become: true
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ casdoor_directory }}/docker-compose.yml"
owner: "{{ casdoor_user }}"
group: "{{ casdoor_group }}"
mode: '0640'
notify: restart casdoor
- name: Template app.conf
become: true
ansible.builtin.template:
src: app.conf.j2
dest: "{{ casdoor_directory }}/conf/app.conf"
owner: "{{ casdoor_user }}"
group: "{{ casdoor_group }}"
mode: '0640'
notify: restart casdoor
- name: Template init_data.json
become: true
ansible.builtin.template:
src: init_data.json.j2
dest: "{{ casdoor_directory }}/conf/init_data.json"
owner: "{{ casdoor_user }}"
group: "{{ casdoor_group }}"
mode: '0640'
notify: restart casdoor
# -------------------------------------------------------------------------
# Reset SSH Connection (apply group changes)
# -------------------------------------------------------------------------
- name: Reset SSH connection to apply group changes
ansible.builtin.meta: reset_connection
# -------------------------------------------------------------------------
# Start Services
# -------------------------------------------------------------------------
- name: Start Casdoor service
become: true
community.docker.docker_compose_v2:
project_src: "{{ casdoor_directory }}"
state: present
pull: always
handlers:
- name: restart casdoor
become: true
community.docker.docker_compose_v2:
project_src: "{{ casdoor_directory }}"
state: restarted

View File

@@ -0,0 +1,34 @@
# -----------------------------------------------------------------------------
# Casdoor Docker Compose
# -----------------------------------------------------------------------------
# Casdoor SSO - connects to native PostgreSQL on localhost
# Generated by Ansible - do not edit manually
# -----------------------------------------------------------------------------
services:
# ---------------------------------------------------------------------------
# Casdoor - SSO Identity Provider
# ---------------------------------------------------------------------------
casdoor:
image: casbin/casdoor:latest
pull_policy: always
container_name: casdoor
network_mode: host # Access localhost PostgreSQL directly
environment:
RUNNING_IN_DOCKER: "true"
user: "{{ casdoor_uid }}:{{ casdoor_gid }}"
volumes:
- ./conf:/conf:ro
logging:
driver: syslog
options:
syslog-address: "tcp://127.0.0.1:{{ casdoor_syslog_port }}"
syslog-format: "{{ syslog_format | default('rfc3164') }}"
tag: "casdoor"
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:{{ casdoor_port }}/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s

View File

@@ -0,0 +1,350 @@
{
"organizations": [
{
"owner": "admin",
"name": "heluca",
"displayName": "Helu.ca",
"websiteUrl": "https://helu.ca",
"favicon": "https://helu.ca/media/images/favicon.original.png",
"logo": "https://helu.ca/media/images/helu-ca_logo.original.svg",
"passwordType": "bcrypt",
"passwordSalt": "",
"passwordOptions": ["AtLeast6"],
"countryCodes": ["CA", "US"],
"defaultAvatar": "",
"defaultApplication": "angelia",
"tags": [],
"languages": ["en", "fr"],
"masterPassword": "",
"defaultPassword": "",
"initScore": 2000,
"enableSoftDeletion": false,
"isProfilePublic": true,
"useEmailAsUsername": true,
"disableSignin": false,
"accountItems": [
{"name": "Organization", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "ID", "visible": true, "viewRule": "Public", "modifyRule": "Immutable"},
{"name": "Name", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Display name", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Avatar", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "User type", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Password", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "Email", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Phone", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Country code", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Country/Region", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Location", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Address", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Affiliation", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Title", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Homepage", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Bio", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Roles", "visible": true, "viewRule": "Public", "modifyRule": "Immutable"},
{"name": "Permissions", "visible": true, "viewRule": "Public", "modifyRule": "Immutable"},
{"name": "Groups", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "3rd-party logins", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "Properties", "visible": true, "viewRule": "Admin", "modifyRule": "Admin"},
{"name": "Is admin", "visible": true, "viewRule": "Admin", "modifyRule": "Admin"},
{"name": "Is forbidden", "visible": true, "viewRule": "Admin", "modifyRule": "Admin"},
{"name": "Is deleted", "visible": true, "viewRule": "Admin", "modifyRule": "Admin"},
{"name": "Multi-factor authentication", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "WebAuthn credentials", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "Managed accounts", "visible": true, "viewRule": "Self", "modifyRule": "Self"}
]
}
],
"applications": [
{
"owner": "admin",
"name": "angelia",
"displayName": "Helu.ca",
"logo": "https://helu.ca/media/images/helu-ca_logo.original.svg",
"homepageUrl": "https://helu.ca",
"organization": "heluca",
"cert": "cert-heluca",
"enablePassword": true,
"enableSignUp": true,
"disableSignin": false,
"clientId": "{{ vault_angelia_oauth_client_id }}",
"clientSecret": "{{ vault_angelia_oauth_client_secret }}",
"providers": [],
"signinMethods": [
{"name": "Password", "displayName": "Password", "rule": "All"},
{"name": "Verification code", "displayName": "Verification code", "rule": "All"},
{"name": "WebAuthn", "displayName": "WebAuthn", "rule": "None"}
],
"signupItems": [
{"name": "ID", "visible": false, "required": true, "prompted": false, "rule": "Random"},
{"name": "Email", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Display name", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Password", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Confirm password", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Agreement", "visible": true, "required": true, "prompted": false, "rule": "None"}
],
"grantTypes": [
"authorization_code",
"password",
"client_credentials",
"token",
"id_token",
"refresh_token"
],
"redirectUris": [
"https://ouranos.helu.ca/callback"
],
"tokenFormat": "JWT",
"tokenFields": [],
"expireInHours": 168,
"failedSigninLimit": 5,
"failedSigninFrozenTime": 15,
"formCss": "<style>.login-panel{background-color:#ffffff;border-radius:10px;box-shadow:0 0 30px 20px rgba(255,164,21,0.12)}.ant-btn-primary{background-color:#4b96ff!important;border-color:#4b96ff!important}.ant-btn-primary:hover{background-color:#58c0ff!important;border-color:#58c0ff!important}a{color:#ffa415}a:hover{color:#ffc219}.ant-input:focus,.ant-input-focused{border-color:#4b96ff!important;box-shadow:0 0 0 2px rgba(75,150,255,0.2)!important}.ant-checkbox-checked .ant-checkbox-inner{background-color:#4b96ff!important;border-color:#4b96ff!important}</style>",
"footerHtml": "<div style=\"text-align:center;padding:10px;color:#666;\"><a href=\"https://helu.ca\" style=\"color:#4b96ff;text-decoration:none;\">Powered by Helu.ca</a></div>"
},
{
"owner": "admin",
"name": "gitea",
"displayName": "Gitea",
"logo": "https://helu.ca/media/images/helu-ca_logo.original.svg",
"homepageUrl": "https://gitea.ouranos.helu.ca",
"organization": "heluca",
"cert": "cert-heluca",
"enablePassword": true,
"enableSignUp": false,
"clientId": "{{ vault_gitea_oauth_client_id }}",
"clientSecret": "{{ vault_gitea_oauth_client_secret }}",
"providers": [],
"signinMethods": [
{"name": "Password", "displayName": "Password", "rule": "All"}
],
"signupItems": [
{"name": "ID", "visible": false, "required": true, "prompted": false, "rule": "Random"},
{"name": "Email", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Display name", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Password", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Confirm password", "visible": true, "required": true, "prompted": false, "rule": "None"}
],
"grantTypes": [
"authorization_code",
"refresh_token"
],
"redirectUris": [
"https://gitea.ouranos.helu.ca/user/oauth2/casdoor/callback"
],
"tokenFormat": "JWT",
"expireInHours": 168,
"formCss": "<style>.login-panel{background-color:#ffffff;border-radius:10px;box-shadow:0 0 30px 20px rgba(255,164,21,0.12)}.ant-btn-primary{background-color:#4b96ff!important;border-color:#4b96ff!important}.ant-btn-primary:hover{background-color:#58c0ff!important;border-color:#58c0ff!important}a{color:#ffa415}a:hover{color:#ffc219}</style>",
"footerHtml": "<div style=\"text-align:center;padding:10px;color:#666;\"><a href=\"https://helu.ca\" style=\"color:#4b96ff;text-decoration:none;\">Powered by Helu.ca</a></div>"
},
{
"owner": "admin",
"name": "jupyterlab",
"displayName": "JupyterLab",
"logo": "https://helu.ca/media/images/helu-ca_logo.original.svg",
"homepageUrl": "https://jupyterlab.ouranos.helu.ca",
"organization": "heluca",
"cert": "cert-heluca",
"enablePassword": true,
"enableSignUp": false,
"clientId": "{{ vault_jupyterlab_oauth_client_id }}",
"clientSecret": "{{ vault_jupyterlab_oauth_client_secret }}",
"providers": [],
"signinMethods": [
{"name": "Password", "displayName": "Password", "rule": "All"}
],
"signupItems": [
{"name": "ID", "visible": false, "required": true, "prompted": false, "rule": "Random"},
{"name": "Email", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Display name", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Password", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Confirm password", "visible": true, "required": true, "prompted": false, "rule": "None"}
],
"grantTypes": [
"authorization_code",
"refresh_token"
],
"redirectUris": [
"https://jupyterlab.ouranos.helu.ca/oauth2/callback"
],
"tokenFormat": "JWT",
"expireInHours": 168,
"formCss": "<style>.login-panel{background-color:#ffffff;border-radius:10px;box-shadow:0 0 30px 20px rgba(255,164,21,0.12)}.ant-btn-primary{background-color:#4b96ff!important;border-color:#4b96ff!important}.ant-btn-primary:hover{background-color:#58c0ff!important;border-color:#58c0ff!important}a{color:#ffa415}a:hover{color:#ffc219}</style>",
"footerHtml": "<div style=\"text-align:center;padding:10px;color:#666;\"><a href=\"https://helu.ca\" style=\"color:#4b96ff;text-decoration:none;\">Powered by Helu.ca</a></div>"
},
{
"owner": "admin",
"name": "searxng",
"displayName": "SearXNG",
"logo": "https://helu.ca/media/images/helu-ca_logo.original.svg",
"homepageUrl": "https://searxng.ouranos.helu.ca",
"organization": "heluca",
"cert": "cert-heluca",
"enablePassword": true,
"enableSignUp": false,
"clientId": "{{ vault_searxng_oauth_client_id }}",
"clientSecret": "{{ vault_searxng_oauth_client_secret }}",
"providers": [],
"signinMethods": [
{"name": "Password", "displayName": "Password", "rule": "All"}
],
"signupItems": [
{"name": "ID", "visible": false, "required": true, "prompted": false, "rule": "Random"},
{"name": "Email", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Display name", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Password", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Confirm password", "visible": true, "required": true, "prompted": false, "rule": "None"}
],
"grantTypes": [
"authorization_code",
"refresh_token"
],
"redirectUris": [
"https://searxng.ouranos.helu.ca/oauth2/callback"
],
"tokenFormat": "JWT",
"expireInHours": 168,
"formCss": "<style>.login-panel{background-color:#ffffff;border-radius:10px;box-shadow:0 0 30px 20px rgba(255,164,21,0.12)}.ant-btn-primary{background-color:#4b96ff!important;border-color:#4b96ff!important}.ant-btn-primary:hover{background-color:#58c0ff!important;border-color:#58c0ff!important}a{color:#ffa415}a:hover{color:#ffc219}</style>",
"footerHtml": "<div style=\"text-align:center;padding:10px;color:#666;\"><a href=\"https://helu.ca\" style=\"color:#4b96ff;text-decoration:none;\">Powered by Helu.ca</a></div>"
},
{
"owner": "admin",
"name": "openwebui",
"displayName": "Open WebUI",
"logo": "https://helu.ca/media/images/helu-ca_logo.original.svg",
"homepageUrl": "https://openwebui.ouranos.helu.ca",
"organization": "heluca",
"cert": "cert-heluca",
"enablePassword": true,
"enableSignUp": false,
"clientId": "{{ vault_openwebui_oauth_client_id }}",
"clientSecret": "{{ vault_openwebui_oauth_client_secret }}",
"providers": [],
"signinMethods": [
{"name": "Password", "displayName": "Password", "rule": "All"}
],
"signupItems": [
{"name": "ID", "visible": false, "required": true, "prompted": false, "rule": "Random"},
{"name": "Email", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Display name", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Password", "visible": true, "required": true, "prompted": false, "rule": "None"},
{"name": "Confirm password", "visible": true, "required": true, "prompted": false, "rule": "None"}
],
"grantTypes": [
"authorization_code",
"refresh_token"
],
"redirectUris": [
"https://openwebui.ouranos.helu.ca/oauth/oidc/callback"
],
"tokenFormat": "JWT",
"expireInHours": 168,
"formCss": "<style>.login-panel{background-color:#ffffff;border-radius:10px;box-shadow:0 0 30px 20px rgba(255,164,21,0.12)}.ant-btn-primary{background-color:#4b96ff!important;border-color:#4b96ff!important}.ant-btn-primary:hover{background-color:#58c0ff!important;border-color:#58c0ff!important}a{color:#ffa415}a:hover{color:#ffc219}</style>",
"footerHtml": "<div style=\"text-align:center;padding:10px;color:#666;\"><a href=\"https://helu.ca\" style=\"color:#4b96ff;text-decoration:none;\">Powered by Helu.ca</a></div>"
}
],
"users": [
{
"owner": "heluca",
"name": "robert@helu.ca",
"type": "normal-user",
"password": "ChangeMe!",
"displayName": "Heluca",
"avatar": "",
"email": "robert@helu.ca",
"phone": "",
"countryCode": "CA",
"address": [],
"affiliation": "Helu.ca",
"tag": "owner",
"title": "Owner",
"score": 2000,
"ranking": 1,
"isAdmin": true,
"isForbidden": false,
"isDeleted": false,
"signupApplication": "angelia",
"createdIp": "",
"groups": []
},
{
"owner": "heluca",
"name": "r@helu.ca",
"type": "normal-user",
"password": "ChangeMe!",
"displayName": "Robert",
"avatar": "",
"email": "r@helu.ca",
"phone": "",
"countryCode": "CA",
"address": [],
"affiliation": "Helu.ca",
"tag": "sysadmin",
"title": "Owner",
"bio": "",
"score": 2000,
"ranking": 2,
"isAdmin": false,
"isForbidden": false,
"isDeleted": false,
"signupApplication": "angelia",
"createdIp": "",
"groups": []
}
],
"providers": [
{
"owner": "admin",
"name": "provider-email-smtp4dev",
"displayName": "smtp4dev Email",
"category": "Email",
"type": "SMTP",
"host": "{{ smtp_host }}",
"port": {{ smtp_port }},
"disableSsl": true,
"fromAddress": "{{ smtp_from }}",
"fromName": "{{ smtp_from_name }}",
"clientSecret": ""
}
],
"certs": [
{
"owner": "admin",
"name": "cert-built-in",
"displayName": "Built-in Certificate",
"scope": "JWT",
"type": "x509",
"cryptoAlgorithm": "RS256",
"bitSize": 4096,
"expireInYears": 20,
"certificate": "",
"privateKey": ""
},
{
"owner": "admin",
"name": "cert-heluca",
"displayName": "Helu.ca JWT Certificate",
"scope": "JWT",
"type": "x509",
"cryptoAlgorithm": "RS256",
"bitSize": 4096,
"expireInYears": 20,
"certificate": "",
"privateKey": ""
}
],
"ldaps": [],
"models": [],
"permissions": [],
"roles": [],
"groups": [],
"adapters": [],
"enforcers": [],
"plans": [],
"pricings": [],
"payments": [],
"products": [],
"resources": [],
"syncers": [],
"tokens": [],
"webhooks": []
}

View File

@@ -0,0 +1,524 @@
{
"organizations": [
{
"owner": "",
"name": "",
"displayName": "",
"websiteUrl": "",
"favicon": "",
"passwordType": "bcrypt",
"passwordSalt": "",
"passwordOptions": [
"AtLeast6"
],
"countryCodes": [
"US",
"GB",
"ES",
"FR",
"DE",
"CN",
"JP",
"KR",
"VN",
"ID",
"SG",
"IN",
"IT",
"MY",
"TR",
"DZ",
"IL",
"PH",
"NL",
"PL",
"FI",
"SE",
"UA",
"KZ",
"CZ",
"SK",
"AZ"
],
"defaultAvatar": "",
"defaultApplication": "",
"tags": [],
"languages": [
"en",
"es",
"fr",
"de",
"ja",
"zh",
"vi",
"pt",
"tr",
"pl",
"uk"
],
"masterPassword": "",
"defaultPassword": "",
"initScore": 2000,
"enableSoftDeletion": false,
"isProfilePublic": true,
"disableSignin": false,
"accountItems": [
{"name": "Organization", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "ID", "visible": true, "viewRule": "Public", "modifyRule": "Immutable"},
{"name": "Name", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Display name", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Avatar", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "User type", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Password", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "Email", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Phone", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Country code", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Country/Region", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Location", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Address", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Addresses", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Affiliation", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Title", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "ID card type", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "ID card", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Real name", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "ID verification", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "Homepage", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Bio", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
{"name": "Tag", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Signup application", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Register type", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Register source", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "Roles", "visible": true, "viewRule": "Public", "modifyRule": "Immutable"},
{"name": "Permissions", "visible": true, "viewRule": "Public", "modifyRule": "Immutable"},
{"name": "Groups", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
{"name": "3rd-party logins", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "Properties", "visible": true, "viewRule": "Admin", "modifyRule": "Admin"},
{"name": "Is admin", "visible": true, "viewRule": "Admin", "modifyRule": "Admin"},
{"name": "Is forbidden", "visible": true, "viewRule": "Admin", "modifyRule": "Admin"},
{"name": "Is deleted", "visible": true, "viewRule": "Admin", "modifyRule": "Admin"},
{"name": "Multi-factor authentication", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "WebAuthn credentials", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "Managed accounts", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
{"name": "MFA accounts", "visible": true, "viewRule": "Self", "modifyRule": "Self"}
]
}
],
"applications": [
{
"owner": "",
"name": "",
"displayName": "",
"logo": "",
"homepageUrl": "",
"organization": "",
"cert": "",
"enablePassword": true,
"enableSignUp": true,
"disableSignin": false,
"clientId": "",
"clientSecret": "",
"providers": [
{
"name": "",
"canSignUp": true,
"canSignIn": true,
"canUnlink": false,
"prompted": false,
"alertType": "None"
}
],
"signinMethods": [
{
"name": "Password",
"displayName": "Password",
"rule": "All"
},
{
"name": "Verification code",
"displayName": "Verification code",
"rule": "All"
},
{
"name": "WebAuthn",
"displayName": "WebAuthn",
"rule": "None"
},
{
"name": "Face ID",
"displayName": "Face ID",
"rule": "None"
}
],
"signupItems": [
{
"name": "ID",
"visible": false,
"required": true,
"prompted": false,
"rule": "Random"
},
{
"name": "Username",
"visible": true,
"required": true,
"prompted": false,
"rule": "None"
},
{
"name": "Display name",
"visible": true,
"required": true,
"prompted": false,
"rule": "None"
},
{
"name": "Password",
"visible": true,
"required": true,
"prompted": false,
"rule": "None"
},
{
"name": "Confirm password",
"visible": true,
"required": true,
"prompted": false,
"rule": "None"
},
{
"name": "Email",
"visible": true,
"required": true,
"prompted": false,
"rule": "None"
},
{
"name": "Phone",
"visible": true,
"required": true,
"prompted": false,
"rule": "None"
},
{
"name": "Agreement",
"visible": true,
"required": true,
"prompted": false,
"rule": "None"
}
],
"grantTypes": [
"authorization_code",
"password",
"client_credentials",
"token",
"id_token",
"refresh_token"
],
"redirectUris": [
"http://localhost:9000/callback"
],
"tokenFormat": "JWT",
"tokenFields": [],
"expireInHours": 168,
"failedSigninLimit": 5,
"failedSigninFrozenTime": 15
}
],
"users": [
{
"owner": "",
"name": "",
"type": "normal-user",
"password": "",
"displayName": "",
"avatar": "",
"email": "",
"phone": "",
"countryCode": "",
"address": [],
"addresses": [],
"affiliation": "",
"tag": "",
"score": 2000,
"ranking": 1,
"isAdmin": true,
"isForbidden": false,
"isDeleted": false,
"signupApplication": "",
"createdIp": "",
"groups": []
}
],
"providers": [
{
"owner": "",
"name": "",
"displayName": "",
"category": "",
"type": ""
}
],
"certs": [
{
"owner": "",
"name": "",
"displayName": "",
"scope": "JWT",
"type": "x509",
"cryptoAlgorithm": "RS256",
"bitSize": 4096,
"expireInYears": 20,
"certificate": "",
"privateKey": ""
}
],
"ldaps": [
{
"id": "",
"owner": "",
"serverName": "",
"host": "",
"port": 389,
"username": "",
"password": "",
"baseDn": "",
"autoSync": 0,
"lastSync": ""
}
],
"models": [
{
"owner": "",
"name": "",
"modelText": "",
"displayName": ""
}
],
"permissions": [
{
"actions": [],
"displayName": "",
"effect": "",
"isEnabled": true,
"model": "",
"name": "",
"owner": "",
"resourceType": "",
"resources": [],
"roles": [],
"users": []
}
],
"payments": [
{
"currency": "",
"detail": "",
"displayName": "",
"invoiceRemark": "",
"invoiceTaxId": "",
"invoiceTitle": "",
"invoiceType": "",
"invoiceUrl": "",
"message": "",
"name": "",
"organization": "",
"owner": "",
"payUrl": "",
"personEmail": "",
"personIdCard": "",
"personName": "",
"personPhone": "",
"price": 0,
"productDisplayName": "",
"productName": "",
"provider": "",
"returnUrl": "",
"state": "",
"tag": "",
"type": "",
"user": ""
}
],
"products": [
{
"currency": "",
"detail": "",
"displayName": "",
"image": "",
"name": "",
"owner": "",
"price": 0,
"providers": [],
"quantity": 0,
"returnUrl": "",
"sold": 0,
"state": "",
"tag": ""
}
],
"resources": [
{
"owner": "",
"name": "",
"user": "",
"provider": "",
"application": "",
"tag": "",
"parent": "",
"fileName": "",
"fileType": "",
"fileFormat": "",
"url": "",
"description": ""
}
],
"roles": [
{
"displayName": "",
"isEnabled": true,
"name": "",
"owner": "",
"roles": [],
"users": []
}
],
"syncers": [
{
"affiliationTable": "",
"avatarBaseUrl": "",
"database": "",
"databaseType": "",
"errorText": "",
"host": "",
"isEnabled": false,
"name": "",
"organization": "",
"owner": "",
"password": "",
"port": 0,
"syncInterval": 0,
"table": "",
"tableColumns": [
{
"casdoorName": "",
"isHashed": true,
"name": "",
"type": "",
"values": []
}
],
"tablePrimaryKey": "",
"type": "",
"user": ""
}
],
"tokens": [
{
"accessToken": "",
"application": "",
"code": "",
"codeChallenge": "",
"codeExpireIn": 0,
"codeIsUsed": true,
"createdTime": "",
"expiresIn": 0,
"name": "",
"organization": "",
"owner": "",
"refreshToken": "",
"scope": "",
"tokenType": "",
"user": ""
}
],
"webhooks": [
{
"contentType": "",
"events": [],
"headers": [
{
"name": "",
"value": ""
}
],
"isEnabled": true,
"isUserExtended": true,
"method": "",
"name": "",
"organization": "",
"owner": "",
"url": ""
}
],
"groups": [
{
"owner": "",
"name": "",
"displayName": "",
"manager": "",
"contactEmail": "",
"type": "",
"parent_id": "",
"isTopGroup": true,
"title": "",
"key": "",
"children": [],
"isEnabled": true
}
],
"adapters": [
{
"owner": "",
"name": "",
"table": "",
"useSameDb": true,
"type": "",
"databaseType": "",
"database": "",
"host": "",
"port": 0,
"user": "",
"password": ""
}
],
"enforcers": [
{
"owner": "",
"name": "",
"displayName": "",
"description": "",
"model": "",
"adapter": "",
"enforcer": ""
}
],
"plans": [
{
"owner": "",
"name": "",
"displayName": "",
"description": "",
"price": 0,
"currency": "",
"period": "",
"product": "",
"paymentProviders": [],
"isEnabled": true,
"role": ""
}
],
"pricings": [
{
"owner": "",
"name": "",
"displayName": "",
"description": "",
"plans": [],
"isEnabled": true,
"trialDuration": 0,
"application": ""
}
]
}

View File

@@ -0,0 +1,75 @@
---
# -----------------------------------------------------------------------------
# Casdoor Removal Playbook
# -----------------------------------------------------------------------------
# Removes Casdoor SSO including:
# - Docker containers and volumes
# - Configuration files
# - PostgreSQL data directory
# - Service user and group
#
# WARNING: This will permanently delete all Casdoor data including the database!
# -----------------------------------------------------------------------------
- name: Remove Casdoor
hosts: ubuntu
tasks:
- name: Check if host has casdoor service
ansible.builtin.set_fact:
has_casdoor_service: "{{ 'casdoor' in services | default([]) }}"
- name: Skip hosts without casdoor service
ansible.builtin.meta: end_host
when: not has_casdoor_service
# -------------------------------------------------------------------------
# Stop and Remove Docker Services
# -------------------------------------------------------------------------
- name: Check if docker-compose.yml exists
become: true
ansible.builtin.stat:
path: "{{ casdoor_directory }}/docker-compose.yml"
register: compose_file
- name: Stop and remove Casdoor containers
become: true
community.docker.docker_compose_v2:
project_src: "{{ casdoor_directory }}"
state: absent
remove_volumes: true
when: compose_file.stat.exists
# -------------------------------------------------------------------------
# Remove Data Directory
# -------------------------------------------------------------------------
- name: Remove casdoor directory and all data
become: true
ansible.builtin.file:
path: "{{ casdoor_directory }}"
state: absent
# -------------------------------------------------------------------------
# Remove User and Group
# -------------------------------------------------------------------------
- name: Remove ponos from casdoor group
become: true
ansible.builtin.command:
cmd: gpasswd -d ponos {{ casdoor_group }}
register: gpasswd_result
changed_when: gpasswd_result.rc == 0
failed_when: false
- name: Remove casdoor user
become: true
ansible.builtin.user:
name: "{{ casdoor_user }}"
state: absent
- name: Remove casdoor group
become: true
ansible.builtin.group:
name: "{{ casdoor_group }}"
state: absent