#!/usr/bin/env bash set -Eeuo pipefail action="${1:-}" account="${2:-}" database="${3:-}" permission="${4:-read}" usage() { echo "用法:" >&2 echo " $0 create 用户名 数据库编码 read|write" >&2 echo " $0 revoke 用户名" >&2 exit 2 } [[ "${action}" == "create" || "${action}" == "revoke" ]] || usage [[ "${account}" =~ ^[a-z][a-z0-9_]{2,31}$ ]] || { echo "用户名只能使用 3–32 位小写字母、数字和下划线,并以字母开头" >&2 exit 2 } run_mysql() { docker compose exec -T mysql sh -eu -c \ 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql --protocol=socket --user=root --batch --skip-column-names' } if [[ "${action}" == "revoke" ]]; then printf "DROP USER IF EXISTS '%s'@'%%';\n" "${account}" | run_mysql echo "MySQL 管理账号已撤销:${account}" exit 0 fi [[ "${database}" =~ ^[A-Za-z][A-Za-z0-9_]{1,63}$ ]] || { echo "数据库编码不合法" >&2 exit 2 } [[ "${permission}" == "read" || "${permission}" == "write" ]] || usage database_exists="$( printf "SELECT COUNT(*) FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='%s';\n" "${database}" | run_mysql )" if [[ "${database_exists}" != "1" ]]; then echo "数据库不存在:${database}" >&2 exit 1 fi password="$(openssl rand -hex 24)" privileges="SELECT, SHOW VIEW" if [[ "${permission}" == "write" ]]; then privileges="SELECT, INSERT, UPDATE, DELETE, SHOW VIEW" fi sql="$(printf \ "CREATE USER '%s'@'%%' IDENTIFIED BY '%s' PASSWORD EXPIRE INTERVAL 90 DAY FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1; GRANT %s ON \`%s\`.* TO '%s'@'%%';" \ "${account}" "${password}" "${privileges}" "${database}" "${account}")" printf '%s\n' "${sql}" | run_mysql echo "账号已创建(完整密码只显示本次):" echo " 用户名:${account}" echo " 数据库:${database}" echo " 权限:${permission}" echo " 密码:${password}" echo "请通过安全渠道交付,首次保存后清除终端历史;不要通过聊天或邮件明文发送。"