Initial commit: git-hangman-lab and keycloak-hangman-lab skills
This commit is contained in:
80
git-hangman-lab/SKILL.md
Normal file
80
git-hangman-lab/SKILL.md
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
---
|
||||||
|
name: git-hangman-lab
|
||||||
|
description: Git operations for hangman-lab.top - manage accounts, tokens, repositories, and Gitea settings.
|
||||||
|
---
|
||||||
|
|
||||||
|
> ⚠️ **Note**: All scripts must be executed via the `pcexec` tool.
|
||||||
|
|
||||||
|
## Git Operations
|
||||||
|
|
||||||
|
### Check Git Credentials
|
||||||
|
|
||||||
|
Verify git credentials are configured correctly.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/git/git-ctrl check-git-cred
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create Git Account
|
||||||
|
|
||||||
|
Create a new git account and configure access.
|
||||||
|
|
||||||
|
> ⚠️ **Warning**: Do not execute this command unless explicitly requested. If you don't have a git account, contact **agent-resource-director** or **hangman** to guide you through the process.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/git/git-ctrl create-git-account --username <username> --email <email>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generate Access Token
|
||||||
|
|
||||||
|
Generate an access token for the current user.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/git/git-ctrl generate-access-token
|
||||||
|
```
|
||||||
|
|
||||||
|
### Link Keycloak Account
|
||||||
|
|
||||||
|
Link Keycloak account with Gitea (for OAuth binding).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/git/git-ctrl link-keycloak
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Repository Collaborator
|
||||||
|
|
||||||
|
Add a collaborator to a repository.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Add to specific repository
|
||||||
|
{baseDir}/scripts/git/git-ctrl repo-add-collaborators --user <user> --repo <repo>
|
||||||
|
|
||||||
|
# Add to roster repository (hzhang/.roster)
|
||||||
|
# ⚠️ This command can only be executed by agent-resource-director
|
||||||
|
{baseDir}/scripts/git/git-ctrl repo-add-collaborators --user <user> --roster
|
||||||
|
```
|
||||||
|
|
||||||
|
### Repository Config
|
||||||
|
|
||||||
|
When you clone a repository from git.hangman-lab.top and are ready to develop, or after creating a new local repo with git init, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/git/git-ctrl repo-config --repo-path <path to your repo> --email <your email>
|
||||||
|
```
|
||||||
|
|
||||||
|
### External Login Control
|
||||||
|
|
||||||
|
Enable or disable local login on Gitea.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/git/git-ctrl external-login-ctrl --enable
|
||||||
|
{baseDir}/scripts/git/git-ctrl external-login-ctrl --disable
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reset Password
|
||||||
|
|
||||||
|
Reset password for the current user (reads username from pass_mgr).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/git/git-ctrl reset-password
|
||||||
|
```
|
||||||
28
git-hangman-lab/scripts/git/check-git-cred
Executable file
28
git-hangman-lab/scripts/git/check-git-cred
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
GIT_URL="https://git.hangman-lab.top"
|
||||||
|
|
||||||
|
USER="$(pass_mgr get-username --key git)"
|
||||||
|
PASS="$(pass_mgr get-secret --key git)"
|
||||||
|
|
||||||
|
if [[ -z "$USER" || -z "$PASS" ]]; then
|
||||||
|
echo "Missing credentials from pass_mgr (key: git)"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
response=$(curl -s -w "%{http_code}" -u "$USER:$PASS" "$GIT_URL/api/v1/user")
|
||||||
|
http_code="${response: -3}"
|
||||||
|
body="${response:0:-3}"
|
||||||
|
|
||||||
|
if [[ "$http_code" == "200" ]]; then
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
|
elif [[ "$http_code" == "401" ]]; then
|
||||||
|
echo "AUTH FAILED"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "ERROR: HTTP $http_code"
|
||||||
|
echo "$body"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
38
git-hangman-lab/scripts/git/create-git-account
Executable file
38
git-hangman-lab/scripts/git/create-git-account
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--username)
|
||||||
|
username="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--email)
|
||||||
|
email="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if username and email are provided
|
||||||
|
if [[ -z "$username" || -z "$email" ]]; then
|
||||||
|
echo "Usage: $0 --username <username> --email <email>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate git credentials (do not print secret)
|
||||||
|
pass_mgr generate --username "$username" --key git >/dev/null
|
||||||
|
|
||||||
|
# Create gitea user
|
||||||
|
"$SCRIPT_DIR/gitea" admin user create \
|
||||||
|
--username "$(pass_mgr get-username --key git)" \
|
||||||
|
--password "$(pass_mgr get-secret --key git)" \
|
||||||
|
--email "$email" \
|
||||||
|
--must-change-password=false
|
||||||
100
git-hangman-lab/scripts/git/external-login-ctrl
Executable file
100
git-hangman-lab/scripts/git/external-login-ctrl
Executable file
@@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
enable=false
|
||||||
|
disable=false
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--enable)
|
||||||
|
enable=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--disable)
|
||||||
|
disable=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
echo "Usage: $0 [--enable | --disable]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$enable" == "false" && "$disable" == "false" ]]; then
|
||||||
|
echo "Usage: $0 [--enable | --disable]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$enable" == "true" && "$disable" == "true" ]]; then
|
||||||
|
echo "Error: Cannot use both --enable and --disable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
REMOTE_HOST="vps.git"
|
||||||
|
REMOTE_USER="root"
|
||||||
|
GITEA_URL="https://git.hangman-lab.top/user/login"
|
||||||
|
MAX_RETRIES=10
|
||||||
|
RETRY_INTERVAL=3
|
||||||
|
TARGET_VALUE="true"
|
||||||
|
ACTION_WORD="disabled"
|
||||||
|
|
||||||
|
if [[ "$enable" == "true" ]]; then
|
||||||
|
TARGET_VALUE="false"
|
||||||
|
ACTION_WORD="enabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
wait_for_gitea() {
|
||||||
|
echo "[INFO] Waiting for Gitea to be ready..."
|
||||||
|
for i in $(seq 1 $MAX_RETRIES); do
|
||||||
|
STATUS=$(curl -s -o /dev/null -w '%{http_code}' "$GITEA_URL" 2>/dev/null || echo "000")
|
||||||
|
if [[ "$STATUS" == "200" ]]; then
|
||||||
|
echo "[INFO] Gitea is ready (HTTP 200)."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "[INFO] Waiting for Gitea ($i/$MAX_RETRIES), current status: $STATUS..."
|
||||||
|
sleep $RETRY_INTERVAL
|
||||||
|
done
|
||||||
|
echo "[WARN] Gitea did not return 200 within expected time."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "[INFO] Setting REQUIRE_EXTERNAL_LOGIN = $TARGET_VALUE on Dockerized Gitea..."
|
||||||
|
ssh "$REMOTE_USER@$REMOTE_HOST" "
|
||||||
|
set -euo pipefail
|
||||||
|
python3 - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
p = Path('/root/git-kc/gitea/app.ini')
|
||||||
|
lines = p.read_text().splitlines()
|
||||||
|
out = []
|
||||||
|
in_auth = False
|
||||||
|
updated_in_auth = False
|
||||||
|
for line in lines:
|
||||||
|
stripped = line.strip()
|
||||||
|
if stripped.startswith('['):
|
||||||
|
if in_auth and not updated_in_auth:
|
||||||
|
out.append('REQUIRE_EXTERNAL_LOGIN = $TARGET_VALUE')
|
||||||
|
updated_in_auth = True
|
||||||
|
in_auth = (stripped == '[auth]')
|
||||||
|
out.append(line)
|
||||||
|
continue
|
||||||
|
if stripped.startswith('REQUIRE_EXTERNAL_LOGIN = '):
|
||||||
|
if in_auth and not updated_in_auth:
|
||||||
|
out.append('REQUIRE_EXTERNAL_LOGIN = $TARGET_VALUE')
|
||||||
|
updated_in_auth = True
|
||||||
|
# drop all duplicates outside [auth], and extra duplicates inside [auth]
|
||||||
|
continue
|
||||||
|
out.append(line)
|
||||||
|
if in_auth and not updated_in_auth:
|
||||||
|
out.append('REQUIRE_EXTERNAL_LOGIN = $TARGET_VALUE')
|
||||||
|
if not any(l.strip() == '[auth]' for l in lines):
|
||||||
|
out.extend(['', '[auth]', 'REQUIRE_EXTERNAL_LOGIN = $TARGET_VALUE'])
|
||||||
|
p.write_text('\n'.join(out) + '\n')
|
||||||
|
PY
|
||||||
|
docker restart git-kc-gitea >/dev/null
|
||||||
|
" <&0
|
||||||
|
|
||||||
|
wait_for_gitea
|
||||||
|
echo "[DONE] Local login $ACTION_WORD."
|
||||||
14
git-hangman-lab/scripts/git/generate-access-token
Executable file
14
git-hangman-lab/scripts/git/generate-access-token
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Verify git credentials first
|
||||||
|
"$SCRIPT_DIR/check-git-cred"
|
||||||
|
|
||||||
|
username=$(pass_mgr get-username --key git)
|
||||||
|
token=$("$SCRIPT_DIR/gitea" admin user generate-access-token --username "$username" --token-name "$username")
|
||||||
|
|
||||||
|
pass_mgr set --key git-access-token --username "$username" --secret "$token"
|
||||||
|
|
||||||
|
echo "Access token generated and stored successfully"
|
||||||
57
git-hangman-lab/scripts/git/git-ctrl
Executable file
57
git-hangman-lab/scripts/git/git-ctrl
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Check if subcommand is provided
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "Usage: $0 <command> [options]"
|
||||||
|
echo ""
|
||||||
|
echo "Commands:"
|
||||||
|
echo " check-git-cred Verify git credentials"
|
||||||
|
echo " create-git-account Create a new git account"
|
||||||
|
echo " generate-access-token Generate access token for current user"
|
||||||
|
echo " link-keycloak Link Keycloak account with Gitea"
|
||||||
|
echo " repo-add-collaborators Add collaborator to repository"
|
||||||
|
echo " repo-config Configure repository"
|
||||||
|
echo " external-login-ctrl Enable/disable local login"
|
||||||
|
echo " reset-password Reset user password"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get subcommand
|
||||||
|
subcommand="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
# Route to appropriate script
|
||||||
|
case "$subcommand" in
|
||||||
|
check-git-cred)
|
||||||
|
"$SCRIPT_DIR/check-git-cred" "$@"
|
||||||
|
;;
|
||||||
|
create-git-account)
|
||||||
|
"$SCRIPT_DIR/create-git-account" "$@"
|
||||||
|
;;
|
||||||
|
generate-access-token)
|
||||||
|
"$SCRIPT_DIR/generate-access-token" "$@"
|
||||||
|
;;
|
||||||
|
link-keycloak)
|
||||||
|
"$SCRIPT_DIR/link-keycloak" "$@"
|
||||||
|
;;
|
||||||
|
repo-add-collaborators)
|
||||||
|
"$SCRIPT_DIR/repo-add-collaborators" "$@"
|
||||||
|
;;
|
||||||
|
repo-config)
|
||||||
|
"$SCRIPT_DIR/repo-config" "$@"
|
||||||
|
;;
|
||||||
|
external-login-ctrl)
|
||||||
|
"$SCRIPT_DIR/external-login-ctrl" "$@"
|
||||||
|
;;
|
||||||
|
reset-password)
|
||||||
|
"$SCRIPT_DIR/reset-password" "$@"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown command: $subcommand"
|
||||||
|
echo "Run '$0' for usage information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
9
git-hangman-lab/scripts/git/gitea
Executable file
9
git-hangman-lab/scripts/git/gitea
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REMOTE_HOST="vps.git"
|
||||||
|
REMOTE_USER="root"
|
||||||
|
CONTAINER_NAME="git-kc-gitea"
|
||||||
|
|
||||||
|
ssh "$REMOTE_USER@$REMOTE_HOST" \
|
||||||
|
"docker exec -i $CONTAINER_NAME gitea --config /etc/gitea/app.ini $(printf '%q ' "$@")" <&0
|
||||||
140
git-hangman-lab/scripts/git/link-keycloak
Executable file
140
git-hangman-lab/scripts/git/link-keycloak
Executable file
@@ -0,0 +1,140 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
USERNAME=$(pass_mgr get-username --key git)
|
||||||
|
KC_PASS=$(pass_mgr get-secret --key keycloak)
|
||||||
|
GITEA_PASS=$(pass_mgr get-secret --key git)
|
||||||
|
|
||||||
|
if [[ -z "$USERNAME" || -z "$KC_PASS" || -z "$GITEA_PASS" ]]; then
|
||||||
|
echo "[ERROR] Missing required credentials in pass_mgr" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sql_escape() {
|
||||||
|
printf '%s' "$1" | sed "s/'/''/g"
|
||||||
|
}
|
||||||
|
|
||||||
|
WORKDIR="/tmp"
|
||||||
|
COOKIES_FILE="$WORKDIR/${USERNAME}_oidc_cookies.txt"
|
||||||
|
KC_LOGIN_HTML="$WORKDIR/${USERNAME}_kc_login.html"
|
||||||
|
KC_POST_LOGIN_HTML="$WORKDIR/${USERNAME}_kc_post_login.html"
|
||||||
|
KC_POST_LOGIN_LOG="$WORKDIR/${USERNAME}_kc_post_login.log"
|
||||||
|
GITEA_CALLBACK_HTML="$WORKDIR/${USERNAME}_gitea_after_callback.html"
|
||||||
|
GITEA_LINK_HTML="$WORKDIR/${USERNAME}_gitea_link_account.html"
|
||||||
|
GITEA_LINK_RESP_HTML="$WORKDIR/${USERNAME}_gitea_link_signin.html"
|
||||||
|
GITEA_LINK_RESP_LOG="$WORKDIR/${USERNAME}_gitea_link_signin.log"
|
||||||
|
|
||||||
|
OIDC_URL="https://git.hangman-lab.top/user/oauth2/hangman-lab"
|
||||||
|
ESCAPED_USERNAME=$(sql_escape "$USERNAME")
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
"$SCRIPT_DIR/external-login-ctrl" --disable >/dev/null 2>&1 || true
|
||||||
|
if [[ -n "${ORIG_LOGIN_TYPE:-}" && -n "${ORIG_LOGIN_SOURCE:-}" ]]; then
|
||||||
|
ssh root@vps.git "
|
||||||
|
set -euo pipefail
|
||||||
|
. /root/git-kc/.env
|
||||||
|
docker exec -i git-kc-mysql mysql -uroot -p\"\$MYSQL_ROOT_PASSWORD\" giteadb -e \"UPDATE user SET login_type=${ORIG_LOGIN_TYPE}, login_source=${ORIG_LOGIN_SOURCE}, login_name=${ORIG_LOGIN_NAME_SQL:-NULL} WHERE name='${ESCAPED_USERNAME}';\"
|
||||||
|
" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
rm -f "$COOKIES_FILE" "$KC_LOGIN_HTML" "$KC_POST_LOGIN_HTML" "$KC_POST_LOGIN_LOG" \
|
||||||
|
"$GITEA_CALLBACK_HTML" "$GITEA_LINK_HTML" "$GITEA_LINK_RESP_HTML" "$GITEA_LINK_RESP_LOG"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
rm -f "$COOKIES_FILE" "$KC_LOGIN_HTML" "$KC_POST_LOGIN_HTML" "$KC_POST_LOGIN_LOG" \
|
||||||
|
"$GITEA_CALLBACK_HTML" "$GITEA_LINK_HTML" "$GITEA_LINK_RESP_HTML" "$GITEA_LINK_RESP_LOG"
|
||||||
|
|
||||||
|
# Capture original login fields so we can restore them exactly.
|
||||||
|
ORIG_STATE=$(ssh root@vps.git "
|
||||||
|
set -euo pipefail
|
||||||
|
. /root/git-kc/.env
|
||||||
|
docker exec -i git-kc-mysql mysql -N -B -uroot -p\"\$MYSQL_ROOT_PASSWORD\" giteadb -e \"SELECT login_type, login_source, COALESCE(login_name, '__NULL__') FROM user WHERE name='${ESCAPED_USERNAME}' LIMIT 1;\"
|
||||||
|
")
|
||||||
|
|
||||||
|
if [[ -z "$ORIG_STATE" ]]; then
|
||||||
|
echo "[ERROR] User not found in Gitea DB: $USERNAME" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS=$'\t' read -r ORIG_LOGIN_TYPE ORIG_LOGIN_SOURCE ORIG_LOGIN_NAME <<< "$ORIG_STATE"
|
||||||
|
if [[ "$ORIG_LOGIN_NAME" == "__NULL__" ]]; then
|
||||||
|
ORIG_LOGIN_NAME_SQL="NULL"
|
||||||
|
else
|
||||||
|
ORIG_LOGIN_NAME_SQL="'$(sql_escape "$ORIG_LOGIN_NAME")'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$SCRIPT_DIR/external-login-ctrl" --enable
|
||||||
|
|
||||||
|
echo "[INFO] 通过 OIDC 入口触发跳转,获取 Keycloak 登录页..."
|
||||||
|
curl -s -L -c "$COOKIES_FILE" "$OIDC_URL" -o "$KC_LOGIN_HTML"
|
||||||
|
|
||||||
|
KC_LOGIN_URL=$(perl -ne '
|
||||||
|
if(/<form id="kc-form-login"/ .. /<\/form>/){
|
||||||
|
if(/action="([^"]+)"/){
|
||||||
|
my $u=$1; $u=~s/&/&/g; print $u; exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' "$KC_LOGIN_HTML")
|
||||||
|
|
||||||
|
if [[ -z "${KC_LOGIN_URL:-}" ]]; then
|
||||||
|
echo "[ERROR] 未找到 kc-form-login 表单的 action URL" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[INFO] 登录 Keycloak..."
|
||||||
|
curl -v "$KC_LOGIN_URL" \
|
||||||
|
-b "$COOKIES_FILE" -c "$COOKIES_FILE" \
|
||||||
|
--data-urlencode "username=$USERNAME" \
|
||||||
|
--data-urlencode "password=$KC_PASS" \
|
||||||
|
-d "credentialId=" \
|
||||||
|
-o "$KC_POST_LOGIN_HTML" \
|
||||||
|
2>"$KC_POST_LOGIN_LOG" || true
|
||||||
|
|
||||||
|
GITEA_CALLBACK_URL=$(grep -i "location: https://git.hangman-lab.top" "$KC_POST_LOGIN_LOG" | sed -E 's/.*location: (https:[^\r]+).*/\1/i' | tail -n1)
|
||||||
|
|
||||||
|
if [[ -z "${GITEA_CALLBACK_URL:-}" ]]; then
|
||||||
|
echo "[ERROR] 登录后未发现返回 Gitea 的 callback URL" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[INFO] 调用 Gitea 回调..."
|
||||||
|
curl -s -L -b "$COOKIES_FILE" -c "$COOKIES_FILE" "$GITEA_CALLBACK_URL" -o "$GITEA_CALLBACK_HTML"
|
||||||
|
|
||||||
|
echo "[INFO] 访问 Gitea Link Account 页面..."
|
||||||
|
curl -s -b "$COOKIES_FILE" "https://git.hangman-lab.top/user/link_account" -o "$GITEA_LINK_HTML"
|
||||||
|
|
||||||
|
CSRF_TOKEN=$(perl -ne 'if(/name="_csrf" value="([^"]+)"/){print $1; exit}' "$GITEA_LINK_HTML" || true)
|
||||||
|
|
||||||
|
if [[ -z "${CSRF_TOKEN:-}" ]]; then
|
||||||
|
echo "[ERROR] 未能从 Link Account 页面解析出 _csrf" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[INFO] 临时将 login_type 改为本地登录..."
|
||||||
|
ssh root@vps.git "
|
||||||
|
set -euo pipefail
|
||||||
|
. /root/git-kc/.env
|
||||||
|
docker exec -i git-kc-mysql mysql -uroot -p\"\$MYSQL_ROOT_PASSWORD\" giteadb -e \"UPDATE user SET login_type=0, login_source=0, login_name=NULL WHERE name='${ESCAPED_USERNAME}';\"
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "[INFO] 提交 link_account_signin..."
|
||||||
|
curl -v "https://git.hangman-lab.top/user/link_account_signin" \
|
||||||
|
-b "$COOKIES_FILE" -c "$COOKIES_FILE" \
|
||||||
|
--data-urlencode "_csrf=$CSRF_TOKEN" \
|
||||||
|
--data-urlencode "user_name=$USERNAME" \
|
||||||
|
--data-urlencode "password=$GITEA_PASS" \
|
||||||
|
-o "$GITEA_LINK_RESP_HTML" \
|
||||||
|
2>"$GITEA_LINK_RESP_LOG" || true
|
||||||
|
|
||||||
|
echo "[INFO] 恢复原始登录方式..."
|
||||||
|
ssh root@vps.git "
|
||||||
|
set -euo pipefail
|
||||||
|
. /root/git-kc/.env
|
||||||
|
docker exec -i git-kc-mysql mysql -uroot -p\"\$MYSQL_ROOT_PASSWORD\" giteadb -e \"UPDATE user SET login_type=${ORIG_LOGIN_TYPE}, login_source=${ORIG_LOGIN_SOURCE}, login_name=${ORIG_LOGIN_NAME_SQL} WHERE name='${ESCAPED_USERNAME}';\"
|
||||||
|
"
|
||||||
|
unset ORIG_LOGIN_TYPE ORIG_LOGIN_SOURCE ORIG_LOGIN_NAME ORIG_LOGIN_NAME_SQL
|
||||||
|
|
||||||
|
echo "[DONE] Keycloak 账号关联完成"
|
||||||
65
git-hangman-lab/scripts/git/repo-add-collaborators
Executable file
65
git-hangman-lab/scripts/git/repo-add-collaborators
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
roster=false
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--repo)
|
||||||
|
repo="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--user)
|
||||||
|
user="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--roster)
|
||||||
|
roster=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if user is provided
|
||||||
|
if [[ -z "$user" ]]; then
|
||||||
|
echo "Usage: $0 --user <user> [--repo <repo>] [--roster]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Handle roster mode
|
||||||
|
if [[ "$roster" == "true" ]]; then
|
||||||
|
owner="hzhang"
|
||||||
|
repo=".roster"
|
||||||
|
|
||||||
|
# Check if git-adm key exists
|
||||||
|
if ! pass_mgr list | grep -q "git-adm"; then
|
||||||
|
echo "you dont have permission to run this script"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
token=$(pass_mgr get-secret --key git-adm)
|
||||||
|
else
|
||||||
|
# Check if repo and git-access-token are provided
|
||||||
|
if [[ -z "$repo" ]]; then
|
||||||
|
echo "Usage: $0 --user <user> --repo <repo>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! pass_mgr list | grep -q "git-access-token"; then
|
||||||
|
echo "generate your access token first"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
owner=$(pass_mgr get-username --key git)
|
||||||
|
token=$(pass_mgr get-secret --key git-access-token)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute
|
||||||
|
curl -X PUT -H "Authorization: token $token" -H "Content-Type: application/json" -d '{"permission":"write"}' "https://git.hangman-lab.top/api/v1/repos/$owner/$repo/collaborators/$user"
|
||||||
132
git-hangman-lab/scripts/git/repo-config
Executable file
132
git-hangman-lab/scripts/git/repo-config
Executable file
@@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 --repo-path <path> --email <email> [--recursive]"
|
||||||
|
echo " --repo-path: Path to the git repository"
|
||||||
|
echo " --email: Email address to configure"
|
||||||
|
echo " --recursive: Also configure all submodules (recursive)"
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
REPO_PATH=""
|
||||||
|
EMAIL=""
|
||||||
|
RECURSIVE=false
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--repo-path)
|
||||||
|
REPO_PATH="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--email)
|
||||||
|
EMAIL="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--recursive)
|
||||||
|
RECURSIVE=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$REPO_PATH" || -z "$EMAIL" ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if it's a git repo (either .git is a directory or a file with gitdir: reference)
|
||||||
|
is_git_repo() {
|
||||||
|
local repo="$1"
|
||||||
|
if [[ -d "$repo/.git" ]]; then
|
||||||
|
return 0
|
||||||
|
elif [[ -f "$repo/.git" ]]; then
|
||||||
|
local gitdir
|
||||||
|
gitdir=$(grep -m1 "gitdir:" "$repo/.git" | cut -d' ' -f2 | tr -d ' ')
|
||||||
|
if [[ -n "$gitdir" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! is_git_repo "$REPO_PATH"; then
|
||||||
|
echo "Not a git repo: $REPO_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
USER="$(pass_mgr get-username --key git)"
|
||||||
|
PASS="$(pass_mgr get-secret --key git)"
|
||||||
|
|
||||||
|
if [[ -z "$USER" || -z "$PASS" ]]; then
|
||||||
|
echo "Missing credentials from pass_mgr (key: git)"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# URL-encode username for credential URL
|
||||||
|
ENC_USER="$(U="$USER" python3 - <<'PY'
|
||||||
|
import os, urllib.parse
|
||||||
|
print(urllib.parse.quote(os.environ['U'], safe=''))
|
||||||
|
PY
|
||||||
|
)"
|
||||||
|
|
||||||
|
# Function to configure a single repo
|
||||||
|
configure_repo() {
|
||||||
|
local repo="$1"
|
||||||
|
local relative="${2:-}"
|
||||||
|
|
||||||
|
# Get relative path name for display
|
||||||
|
local name="${relative:-$repo}"
|
||||||
|
|
||||||
|
echo "Configuring: $name"
|
||||||
|
|
||||||
|
# Set local user.name / user.email
|
||||||
|
( cd "$repo" && git config user.name "$USER" )
|
||||||
|
( cd "$repo" && git config user.email "$EMAIL" )
|
||||||
|
|
||||||
|
# Resolve the real git dir (works for normal repos and submodules)
|
||||||
|
local git_dir
|
||||||
|
git_dir="$(cd "$repo" && git rev-parse --absolute-git-dir)"
|
||||||
|
local cred_file="${git_dir}/credentials"
|
||||||
|
|
||||||
|
( cd "$repo" && git config credential.helper "store --file ${cred_file}" )
|
||||||
|
( cd "$repo" && GIT_ASKPASS=true git credential-store --file "${cred_file}" store <<EOF
|
||||||
|
protocol=https
|
||||||
|
host=git.hangman-lab.top
|
||||||
|
username=${ENC_USER}
|
||||||
|
password=${PASS}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
echo " - user.name: $USER"
|
||||||
|
echo " - user.email: $EMAIL"
|
||||||
|
echo " - credential.helper: configured"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure main repo
|
||||||
|
configure_repo "$REPO_PATH"
|
||||||
|
|
||||||
|
# Configure submodules if --recursive is specified
|
||||||
|
if [[ "$RECURSIVE" == "true" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "Configuring submodules..."
|
||||||
|
|
||||||
|
# Get submodules list
|
||||||
|
submodules=$(cd "$REPO_PATH" && git submodule status --recursive 2>/dev/null | awk '{print $2}' || true)
|
||||||
|
|
||||||
|
if [[ -z "$submodules" ]]; then
|
||||||
|
echo "No submodules found"
|
||||||
|
else
|
||||||
|
for sm in $submodules; do
|
||||||
|
sm_path="$REPO_PATH/$sm"
|
||||||
|
if is_git_repo "$sm_path"; then
|
||||||
|
configure_repo "$sm_path" "$sm"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "OK"
|
||||||
19
git-hangman-lab/scripts/git/reset-password
Executable file
19
git-hangman-lab/scripts/git/reset-password
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Get username from pass_mgr
|
||||||
|
username=$(pass_mgr get-username --key git)
|
||||||
|
if [[ -z "$username" ]]; then
|
||||||
|
echo "Error: No username found in pass_mgr for key 'git'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate new password
|
||||||
|
password=$(pass_mgr generate --key git --username "$username")
|
||||||
|
|
||||||
|
# Update password via gitea admin
|
||||||
|
"$SCRIPT_DIR/gitea" admin user change-password --username "$username" --password "$password" --must-change-password=false
|
||||||
|
|
||||||
|
echo "Password updated for user: $username"
|
||||||
42
keycloak-hangman-lab/SKILL.md
Normal file
42
keycloak-hangman-lab/SKILL.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
name: keycloak-hangman-lab
|
||||||
|
description: Keycloak operations for hangman-lab.top - manage accounts, email verification, and passwords.
|
||||||
|
---
|
||||||
|
|
||||||
|
> ⚠️ **Note**: All scripts must be executed via the `pcexec` tool.
|
||||||
|
|
||||||
|
## Keycloak Operations
|
||||||
|
|
||||||
|
### Create Keycloak Account
|
||||||
|
|
||||||
|
Create a new Keycloak account.
|
||||||
|
|
||||||
|
> ⚠️ **Warning**: Do not execute this command unless explicitly requested. If you don't have a Keycloak account, contact **agent-resource-director** or **hangman** to guide you through the process.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/keycloak/kc-ctrl create-keycloak-account --username <username> --email <email>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify Email
|
||||||
|
|
||||||
|
Verify user email in Keycloak.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/keycloak/kc-ctrl verify-email
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set User Name
|
||||||
|
|
||||||
|
Set user firstName and lastName in Keycloak.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/keycloak/kc-ctrl set-name
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reset Password
|
||||||
|
|
||||||
|
Reset password for the current user (reads username from pass_mgr).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{baseDir}/scripts/keycloak/kc-ctrl reset-password
|
||||||
|
```
|
||||||
49
keycloak-hangman-lab/scripts/keycloak/create-keycloak-account
Executable file
49
keycloak-hangman-lab/scripts/keycloak/create-keycloak-account
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--username)
|
||||||
|
username="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--email)
|
||||||
|
email="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if username and email are provided
|
||||||
|
if [[ -z "$username" || -z "$email" ]]; then
|
||||||
|
echo "Usage: $0 --username <username> --email <email>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate keycloak credentials (do not print secret)
|
||||||
|
pass_mgr generate --username "$username" --key keycloak >/dev/null
|
||||||
|
|
||||||
|
# Get the generated username and password
|
||||||
|
user=$(pass_mgr get-username --key keycloak)
|
||||||
|
pass=$(pass_mgr get-secret --key keycloak)
|
||||||
|
|
||||||
|
realm="Hangman-Lab"
|
||||||
|
|
||||||
|
# Create keycloak user
|
||||||
|
"$SCRIPT_DIR/kcadm" create users -r "$realm" -s "username=$user" -s "enabled=true" -s "email=$email" || true
|
||||||
|
|
||||||
|
# Set password for the user
|
||||||
|
"$SCRIPT_DIR/kcadm" set-password -r "$realm" --username "$user" --new-password "$pass"
|
||||||
|
|
||||||
|
# Verify email and set profile fields to avoid VERIFY_PROFILE during first OIDC login
|
||||||
|
"$SCRIPT_DIR/verify-email" --username "$user"
|
||||||
|
"$SCRIPT_DIR/set-name" --username "$user" >/dev/null 2>&1 || "$SCRIPT_DIR/set-name"
|
||||||
|
|
||||||
|
echo "Keycloak account created for: $user (realm: $realm)"
|
||||||
41
keycloak-hangman-lab/scripts/keycloak/kc-ctrl
Executable file
41
keycloak-hangman-lab/scripts/keycloak/kc-ctrl
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Check if subcommand is provided
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "Usage: $0 <command> [options]"
|
||||||
|
echo ""
|
||||||
|
echo "Commands:"
|
||||||
|
echo " create-keycloak-account Create a new Keycloak account"
|
||||||
|
echo " set-name Set user firstName and lastName"
|
||||||
|
echo " verify-email Verify user email"
|
||||||
|
echo " reset-password Reset user password"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get subcommand
|
||||||
|
subcommand="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
# Route to appropriate script
|
||||||
|
case "$subcommand" in
|
||||||
|
create-keycloak-account)
|
||||||
|
"$SCRIPT_DIR/create-keycloak-account" "$@"
|
||||||
|
;;
|
||||||
|
set-name)
|
||||||
|
"$SCRIPT_DIR/set-name" "$@"
|
||||||
|
;;
|
||||||
|
verify-email)
|
||||||
|
"$SCRIPT_DIR/verify-email" "$@"
|
||||||
|
;;
|
||||||
|
reset-password)
|
||||||
|
"$SCRIPT_DIR/reset-password" "$@"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown command: $subcommand"
|
||||||
|
echo "Run '$0' for usage information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
47
keycloak-hangman-lab/scripts/keycloak/kcadm
Executable file
47
keycloak-hangman-lab/scripts/keycloak/kcadm
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
# pcguard || exit 1
|
||||||
|
|
||||||
|
REMOTE_HOST="vps.git"
|
||||||
|
REMOTE_USER="root"
|
||||||
|
CONTAINER_NAME="git-kc-keycloak"
|
||||||
|
HOST_CONFIG="/root/.keycloak/kcadm.config"
|
||||||
|
CONTAINER_CONFIG="/tmp/kcadm.config"
|
||||||
|
ENV_FILE="/root/git-kc/.env"
|
||||||
|
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
ssh "$REMOTE_USER@$REMOTE_HOST" \
|
||||||
|
"docker exec -i $CONTAINER_NAME /opt/keycloak/bin/kcadm.sh --help" <&0
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
SUBCOMMAND="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
ssh "$REMOTE_USER@$REMOTE_HOST" "
|
||||||
|
set -euo pipefail
|
||||||
|
mkdir -p /root/.keycloak
|
||||||
|
if [ -f $HOST_CONFIG ]; then
|
||||||
|
docker cp $HOST_CONFIG $CONTAINER_NAME:$CONTAINER_CONFIG >/dev/null 2>&1 || true
|
||||||
|
docker exec --user 0:0 $CONTAINER_NAME /bin/chmod 666 $CONTAINER_CONFIG >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $(printf '%q' "$SUBCOMMAND") != config ] && [ -f $ENV_FILE ]; then
|
||||||
|
set -a
|
||||||
|
. $ENV_FILE
|
||||||
|
set +a
|
||||||
|
docker exec -i $CONTAINER_NAME /opt/keycloak/bin/kcadm.sh config credentials \
|
||||||
|
--config $CONTAINER_CONFIG \
|
||||||
|
--server http://127.0.0.1:8080 \
|
||||||
|
--realm master \
|
||||||
|
--user \"\$KC_BOOTSTRAP_ADMIN_USERNAME\" \
|
||||||
|
--password \"\$KC_BOOTSTRAP_ADMIN_PASSWORD\" >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
set +e
|
||||||
|
docker exec -i $CONTAINER_NAME /opt/keycloak/bin/kcadm.sh $(printf '%q ' "$SUBCOMMAND") --config $CONTAINER_CONFIG $(printf '%q ' "$@")
|
||||||
|
status=\$?
|
||||||
|
set -e
|
||||||
|
docker cp $CONTAINER_NAME:$CONTAINER_CONFIG $HOST_CONFIG >/dev/null 2>&1 || true
|
||||||
|
exit \$status
|
||||||
|
" <&0
|
||||||
21
keycloak-hangman-lab/scripts/keycloak/reset-password
Executable file
21
keycloak-hangman-lab/scripts/keycloak/reset-password
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Get username from pass_mgr
|
||||||
|
username=$(pass_mgr get-username --key keycloak)
|
||||||
|
if [[ -z "$username" ]]; then
|
||||||
|
echo "Error: No username found in pass_mgr for key 'keycloak'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
realm="Hangman-Lab"
|
||||||
|
|
||||||
|
# Generate new password
|
||||||
|
password=$(pass_mgr generate --key keycloak --username "$username")
|
||||||
|
|
||||||
|
# Update password via kcadm
|
||||||
|
"$SCRIPT_DIR/kcadm" set-password -r "$realm" --username "$username" --new-password "$password"
|
||||||
|
|
||||||
|
echo "Password updated for user: $username (realm: $realm)"
|
||||||
51
keycloak-hangman-lab/scripts/keycloak/set-name
Executable file
51
keycloak-hangman-lab/scripts/keycloak/set-name
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Optional explicit username
|
||||||
|
username=""
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--username)
|
||||||
|
username="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
echo "Usage: $0 [--username <username>]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Default to pass_mgr if not provided
|
||||||
|
if [[ -z "$username" ]]; then
|
||||||
|
username=$(pass_mgr get-username --key keycloak)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$username" ]]; then
|
||||||
|
echo "Error: No keycloak username found in pass_mgr"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
realm="Hangman-Lab"
|
||||||
|
|
||||||
|
# Check if user exists
|
||||||
|
result=$("$SCRIPT_DIR/kcadm" get users -r "$realm" -q "username=$username")
|
||||||
|
user_count=$(echo "$result" | jq 'length')
|
||||||
|
|
||||||
|
if [[ "$user_count" -eq 0 ]]; then
|
||||||
|
echo "Error: User $username not found in Keycloak"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get user ID
|
||||||
|
userid=$(echo "$result" | jq -r '.[0].id')
|
||||||
|
|
||||||
|
# Set firstName and lastName
|
||||||
|
"$SCRIPT_DIR/kcadm" update users/"$userid" -r "$realm" \
|
||||||
|
--set "firstName=$username" \
|
||||||
|
--set "lastName=$username"
|
||||||
|
|
||||||
|
echo "Name set for user: $username (firstName=$username, lastName=$username)"
|
||||||
31
keycloak-hangman-lab/scripts/keycloak/verify-email
Executable file
31
keycloak-hangman-lab/scripts/keycloak/verify-email
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Get username from pass_mgr
|
||||||
|
username=$(pass_mgr get-username --key keycloak)
|
||||||
|
|
||||||
|
if [[ -z "$username" ]]; then
|
||||||
|
echo "Error: No keycloak username found in pass_mgr"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
realm="Hangman-Lab"
|
||||||
|
|
||||||
|
# Check if user exists
|
||||||
|
result=$("$SCRIPT_DIR/kcadm" get users -r "$realm" -q "username=$username")
|
||||||
|
user_count=$(echo "$result" | jq 'length')
|
||||||
|
|
||||||
|
if [[ "$user_count" -eq 0 ]]; then
|
||||||
|
echo "Error: User $username not found in Keycloak"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get user ID
|
||||||
|
userid=$(echo "$result" | jq -r '.[0].id')
|
||||||
|
|
||||||
|
# Set email verified
|
||||||
|
"$SCRIPT_DIR/kcadm" update users/"$userid" -r "$realm" -s "emailVerified=true"
|
||||||
|
|
||||||
|
echo "Email verified for user: $username"
|
||||||
Reference in New Issue
Block a user