From be9eeb8a5b3f06000703e00d8ebf9ef904072bc9 Mon Sep 17 00:00:00 2001 From: Emmanuel Averty Date: Wed, 5 Jul 2023 16:20:06 +0200 Subject: [PATCH] allow yunohost admin users to access forgejo admin page --- doc/ADMIN.md | 12 ++++-------- hooks/post_app_addaccess | 20 ++++++++++++++++++++ hooks/post_app_removeaccess | 20 ++++++++++++++++++++ hooks/post_user_create | 20 ++++++++++++++++++++ hooks/post_user_delete | 20 ++++++++++++++++++++ hooks/post_user_update | 24 ++++++++++++++++++++++++ manifest.toml | 2 +- scripts/_common.sh | 35 +++++++++++++++++++++++++++++++++++ scripts/install | 7 +++++++ scripts/upgrade | 24 ++++++++++++++++++++---- 10 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 hooks/post_app_addaccess create mode 100644 hooks/post_app_removeaccess create mode 100644 hooks/post_user_create create mode 100644 hooks/post_user_delete create mode 100644 hooks/post_user_update diff --git a/doc/ADMIN.md b/doc/ADMIN.md index 64f8110..114d6d6 100644 --- a/doc/ADMIN.md +++ b/doc/ADMIN.md @@ -1,14 +1,10 @@ ## Additional informations -### Known issue about admin access -This package ask during its installation which group of users should be considered as forgejo administrators. These users should be able to access the admin page of forgejo. But they won't :( -Two forgejo features are not yet compatible : -- the reverse proxy authentication (which allows yunohost user to be automatically logged in forgejo) -- the login source (which tells forgejo to check yunohost users base to know if it is an admin or not) +### User synchronization +In order to allow access to Forgejo admin section, YunoHost users are automaticaly synchronized with Forgejo's. +You can use «Forgejo (admin)» permission to manage which user is considered as forgejo admin. -The choice have been done to keep the reverse proxy authentication. But an [issue](https://codeberg.org/forgejo/forgejo/issues/930) is created to have both features. - -In conclusion, this forgejo installation does not (yet) allow to access the forgejo admin page. +**Known issue** : when a user is added to a group (e.g. the one with «Forgejo (admin)» permission), the synchronization is not triggered by YunoHost. You have to update a user (without any modification) to trigger it. (https://github.com/YunoHost/issues/issues/2213) ### Notes on SSH usage diff --git a/hooks/post_app_addaccess b/hooks/post_app_addaccess new file mode 100644 index 0000000..fa3ab69 --- /dev/null +++ b/hooks/post_app_addaccess @@ -0,0 +1,20 @@ +#!/bin/bash + +# IMPORT GENERIC HELPERS +source /usr/share/yunohost/helpers + +pwd=$(dirname $0) +filename=$(basename $0) + +# Set vars for following script + +# The file name is - +app=${filename#*-} + +domain=$(ynh_app_setting_get --app=$app --key=domain) +path=$(ynh_app_setting_get --app=$app --key=path) + +# Load common variables and helpers +source ${pwd}/../../apps/${app}/scripts/_common.sh + +synchronize_users \ No newline at end of file diff --git a/hooks/post_app_removeaccess b/hooks/post_app_removeaccess new file mode 100644 index 0000000..fa3ab69 --- /dev/null +++ b/hooks/post_app_removeaccess @@ -0,0 +1,20 @@ +#!/bin/bash + +# IMPORT GENERIC HELPERS +source /usr/share/yunohost/helpers + +pwd=$(dirname $0) +filename=$(basename $0) + +# Set vars for following script + +# The file name is - +app=${filename#*-} + +domain=$(ynh_app_setting_get --app=$app --key=domain) +path=$(ynh_app_setting_get --app=$app --key=path) + +# Load common variables and helpers +source ${pwd}/../../apps/${app}/scripts/_common.sh + +synchronize_users \ No newline at end of file diff --git a/hooks/post_user_create b/hooks/post_user_create new file mode 100644 index 0000000..fa3ab69 --- /dev/null +++ b/hooks/post_user_create @@ -0,0 +1,20 @@ +#!/bin/bash + +# IMPORT GENERIC HELPERS +source /usr/share/yunohost/helpers + +pwd=$(dirname $0) +filename=$(basename $0) + +# Set vars for following script + +# The file name is - +app=${filename#*-} + +domain=$(ynh_app_setting_get --app=$app --key=domain) +path=$(ynh_app_setting_get --app=$app --key=path) + +# Load common variables and helpers +source ${pwd}/../../apps/${app}/scripts/_common.sh + +synchronize_users \ No newline at end of file diff --git a/hooks/post_user_delete b/hooks/post_user_delete new file mode 100644 index 0000000..fa3ab69 --- /dev/null +++ b/hooks/post_user_delete @@ -0,0 +1,20 @@ +#!/bin/bash + +# IMPORT GENERIC HELPERS +source /usr/share/yunohost/helpers + +pwd=$(dirname $0) +filename=$(basename $0) + +# Set vars for following script + +# The file name is - +app=${filename#*-} + +domain=$(ynh_app_setting_get --app=$app --key=domain) +path=$(ynh_app_setting_get --app=$app --key=path) + +# Load common variables and helpers +source ${pwd}/../../apps/${app}/scripts/_common.sh + +synchronize_users \ No newline at end of file diff --git a/hooks/post_user_update b/hooks/post_user_update new file mode 100644 index 0000000..d8023a1 --- /dev/null +++ b/hooks/post_user_update @@ -0,0 +1,24 @@ +#!/bin/bash + +### +# This hook is only used because yunohost doesn't trigger any hook when adding a user to a group (e.g. admin) +# After adding a user to a group, one should update a user to trigger this hook (https://forum.yunohost.org/t/hook-when-a-user-is-added-in-a-group/25437) + +# IMPORT GENERIC HELPERS +source /usr/share/yunohost/helpers + +pwd=$(dirname $0) +filename=$(basename $0) + +# Set vars for following script + +# The file name is - +app=${filename#*-} + +domain=$(ynh_app_setting_get --app=$app --key=domain) +path=$(ynh_app_setting_get --app=$app --key=path) + +# Load common variables and helpers +source ${pwd}/../../apps/${app}/scripts/_common.sh + +synchronize_users \ No newline at end of file diff --git a/manifest.toml b/manifest.toml index 2841ac3..53412ed 100644 --- a/manifest.toml +++ b/manifest.toml @@ -5,7 +5,7 @@ name = "Forgejo" description.en = "Lightweight software forge" description.fr = "Forge logiciel légère" -version = "1.19.3-0~ynh2" +version = "1.19.3-0~ynh3" maintainers = ["Emmanuel Averty"] diff --git a/scripts/_common.sh b/scripts/_common.sh index a548f93..b307ed8 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -5,7 +5,42 @@ #================================================= function set_forgejo_login_source() { + ynh_print_info --message="Creating forgejo login source" pushd "$install_dir" ynh_exec_as $app ./forgejo admin auth add-ldap-simple --security-protocol "Unencrypted" --name "YunoHost LDAP" --host "localhost" --port "389" --skip-tls-verify --user-search-base "ou=users,dc=yunohost,dc=org" --user-dn "uid=%s,ou=Users,dc=yunohost,dc=org" --user-filter "(&(objectclass=posixAccount)(uid=%s)(permission=cn=$app.main,ou=permission,dc=yunohost,dc=org))" --admin-filter "(permission=cn=forgejo.admin,ou=permission,dc=yunohost,dc=org)" --username-attribute "uid" --firstname-attribute "givenName" --surname-attribute "sn" --email-attribute "mail" popd +} + +function enable_login_source_sync() { + ynh_print_info --message="Set forgejo login source as synchronizable" + # Enable login source synchronisation manualy because forgejo command does not allow it (https://codeberg.org/forgejo/forgejo/issues/952) + ynh_psql_execute_as_root --database $db_name --sql "update login_source set is_sync_enabled = true where type = 5 and name = 'YunoHost LDAP'" +} + +function create_forgejo_api_user() { + ynh_print_info --message="Creating forgejo api user" + forgejo_api_user=yunohost_api + forgejo_api_pwd=$(ynh_string_random --length=24) + ynh_app_setting_set --app=$app --key=forgejo_api_user --value=$forgejo_api_user + ynh_app_setting_set --app=$app --key=forgejo_api_pwd --value=$forgejo_api_pwd + pushd "$install_dir" + ynh_exec_as $app ./forgejo admin user create --username $forgejo_api_user --password $forgejo_api_pwd --email admin@${domain} --admin --must-change-password=false + forgejo_api_token=$(ynh_exec_as $app ./forgejo admin user generate-access-token --username $forgejo_api_user --token-name "admin" --scopes "sudo" --raw | tail -1) + ynh_app_setting_set --app=$app --key=forgejo_api_token --value=$forgejo_api_token + popd +} + +function set_users_login_source() { + # Previously created users have «Local» login source. It should be «YunoHost LDAP» + for username in $(ynh_user_list); do + ynh_print_info --message="Updating forgejo user login type for ${username}" + + ynh_psql_execute_as_root --database $db_name --sql "update public.user set login_source = (select id from login_source where name = 'YunoHost LDAP' and type = 5), login_name = name, login_type = 5 where name = '${username}'" + done +} + +function synchronize_users() { + ynh_print_info --message="Synchronizing forgejo users" + # User synchronization must be launched using API : no cli exists for this purpose (https://codeberg.org/forgejo/forgejo/issues/953) + curl --url https://${domain}${path}/api/v1/admin/cron/sync_external_users -X POST -H "Authorization: token $(ynh_app_setting_get --app=$app --key=forgejo_api_token)" -kfsS } \ No newline at end of file diff --git a/scripts/install b/scripts/install index 243cd0f..e687306 100644 --- a/scripts/install +++ b/scripts/install @@ -98,6 +98,13 @@ ynh_add_fail2ban_config --logpath "/var/log/$app/forgejo.log" --failregex ".*Fai #================================================= ynh_script_progression --message="Adding LDAP configuration..." --weight=1 set_forgejo_login_source +enable_login_source_sync + +# API user creation +create_forgejo_api_user + +# Yunohost user creation +synchronize_users #================================================= # END OF SCRIPT diff --git a/scripts/upgrade b/scripts/upgrade index 3ed1fea..ca8e1c0 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -28,7 +28,7 @@ ynh_systemd_action --service_name=$app --action="stop" --log_path="systemd" #================================================= ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 -# Update forgejo login source +# Update forgejo login source (1.19.3-0~ynh2) pushd "$install_dir" old_login_source_id=$(ynh_exec_as $app ./forgejo admin auth list | grep "YunoHost LDAP" | grep "via BindDN" | cut -f 1) if [ ! -z $old_login_source_id ]; then @@ -40,6 +40,16 @@ pushd "$install_dir" fi popd +# Update login source synchronization flag (1.19.3-0~ynh3) +enable_login_source_sync + +if [ -z ${forgejo_api_user:-} ]; then + create_forgejo_api_user +fi + +# Update users login source (1.19.3-0~ynh3) +set_users_login_source + # forgejo home directory has changed (yunohost packaging v2) # .ssh directory should move from old home dir (data_dir) to new one # (/var/www/$app is the default value for home in resources.system_user) @@ -48,19 +58,19 @@ if [ -d "$data_dir/.ssh" ]; then fi # If secret_key doesn't exist, create it -if [ -z "$secret_key" ]; then +if [ -z ${secret_key:-} ]; then secret_key=$($install_dir/forgejo generate secret SECRET_KEY) ynh_app_setting_set --app=$app --key=secret_key --value=$secret_key fi # If lfs_jwt_secret doesn't exist, create it -if [ -z "$lfs_jwt_secret" ]; then +if [ -z ${lfs_jwt_secret:-} ]; then lfs_jwt_secret=$($install_dir/forgejo generate secret JWT_SECRET) ynh_app_setting_set --app=$app --key=lfs_jwt_secret --value=$lfs_jwt_secret fi # If internal_token doesn't exist, create it -if [ -z "$internal_token" ]; then +if [ -z ${internal_token:-} ]; then internal_token=$($install_dir/forgejo generate secret INTERNAL_TOKEN) ynh_app_setting_set --app=$app --key=internal_token --value=$internal_token fi @@ -130,6 +140,12 @@ ynh_script_progression --message="Starting a systemd service..." --weight=3 # Start a systemd service ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/forgejo.log" --line_match="Starting new Web server: tcp:127.0.0.1:" + +#================================================= +# Synchronize users (backward compatibility 1.19.3-0~ynh3) +#================================================= +synchronize_users + #================================================= # SETUP FAIL2BAN #=================================================