#!/usr/bin/env bash
# ====================================================================
# 第 15 章 - 安全与多租户
# acl_examples.sh - 常用 ACL / Quota 操作集合（生产可直接复用）
# --------------------------------------------------------------------
# 前提：authorizer.class.name=...StandardAuthorizer 已开启
#       allow.everyone.if.no.acl.found=false
# ====================================================================
set -euo pipefail

BS=${BOOTSTRAP:-localhost:9092}
CC=${COMMAND_CONFIG:-/etc/kafka/admin.properties}

acl() {
  kafka-acls.sh --bootstrap-server "$BS" --command-config "$CC" "$@"
}
cfg() {
  kafka-configs.sh --bootstrap-server "$BS" --command-config "$CC" "$@"
}

# --------------------------------------------------------------------
# 0) 列出当前所有 ACL（一上来先看清现状）
# --------------------------------------------------------------------
list_all_acls() { acl --list; }
list_acls_of_user()  { acl --list --principal "$1"; }
list_acls_of_topic() { acl --list --topic "$1"; }

# --------------------------------------------------------------------
# 1) 单 Topic 的最小 Producer 权限（含幂等 Producer）
# --------------------------------------------------------------------
grant_producer() {
  local user=$1 topic=$2
  acl --add --allow-principal "User:${user}" \
      --operation Write --operation Describe \
      --topic "$topic"
  acl --add --allow-principal "User:${user}" \
      --operation IdempotentWrite --cluster
}

# --------------------------------------------------------------------
# 2) 单 Topic + 单 Group 的最小 Consumer 权限
# --------------------------------------------------------------------
grant_consumer() {
  local user=$1 topic=$2 group=$3
  acl --add --allow-principal "User:${user}" \
      --operation Read --operation Describe --topic "$topic"
  acl --add --allow-principal "User:${user}" \
      --operation Read --operation Describe --group "$group"
}

# --------------------------------------------------------------------
# 3) 事务 Producer 额外 TransactionalId 权限
# --------------------------------------------------------------------
grant_tx_producer() {
  local user=$1 tx_id_prefix=$2
  acl --add --allow-principal "User:${user}" \
      --operation Write --operation Describe \
      --transactional-id "$tx_id_prefix" \
      --resource-pattern-type PREFIXED
}

# --------------------------------------------------------------------
# 4) 多租户：PREFIXED ACL（最常用）
# --------------------------------------------------------------------
grant_team_prefix() {
  local team=$1   # team-order
  local env=$2    # prod
  local prefix="${env}.${team}."

  acl --add --allow-principal "User:${team}" \
      --operation Read --operation Write --operation Describe \
      --operation Create --operation Alter \
      --topic "$prefix" --resource-pattern-type PREFIXED

  acl --add --allow-principal "User:${team}" \
      --operation Read --operation Describe \
      --group "$prefix" --resource-pattern-type PREFIXED

  acl --add --allow-principal "User:${team}" \
      --operation IdempotentWrite --cluster

  acl --add --allow-principal "User:${team}" \
      --operation Write --operation Describe \
      --transactional-id "$prefix" --resource-pattern-type PREFIXED
}

# --------------------------------------------------------------------
# 5) 跨团队消费
# --------------------------------------------------------------------
grant_cross_team_read() {
  local consumer_user=$1 source_topic=$2 consumer_group=$3
  acl --add --allow-principal "User:${consumer_user}" \
      --operation Read --operation Describe --topic "$source_topic"
  acl --add --allow-principal "User:${consumer_user}" \
      --operation Read --operation Describe --group "$consumer_group"
}

# --------------------------------------------------------------------
# 6) Deny（优先级 > Allow）
# --------------------------------------------------------------------
deny_topic_for_user() {
  local user=$1 topic=$2
  acl --add --deny-principal "User:${user}" \
      --operation All --topic "$topic"
}

# --------------------------------------------------------------------
# 7) Quota
# --------------------------------------------------------------------
set_user_quota() {
  local user=$1 producer_mb=$2 consumer_mb=$3
  cfg --alter \
      --add-config "producer_byte_rate=$((producer_mb*1024*1024)),consumer_byte_rate=$((consumer_mb*1024*1024))" \
      --entity-type users --entity-name "$user"
}

set_default_quota() {
  local producer_mb=$1 consumer_mb=$2
  cfg --alter \
      --add-config "producer_byte_rate=$((producer_mb*1024*1024)),consumer_byte_rate=$((consumer_mb*1024*1024))" \
      --entity-type users --entity-default
}

set_request_quota() {
  local user=$1 percentage=$2
  cfg --alter --add-config "request_percentage=${percentage}" \
      --entity-type users --entity-name "$user"
}

list_quotas() {
  cfg --describe --entity-type users
}

# --------------------------------------------------------------------
# 8) 收回权限
# --------------------------------------------------------------------
revoke_topic_write() {
  local user=$1 topic=$2
  acl --remove --allow-principal "User:${user}" \
      --operation Write --topic "$topic"
}

# ====================================================================
# Demo：组装一个完整的多租户 onboarding 流程
# ====================================================================
onboard_team_demo() {
  local team=team-order
  local env=prod

  echo "[1] 创建团队 SCRAM 用户"
  ./scram_user_setup.sh add "$team" "$(openssl rand -base64 18)"

  echo "[2] 给团队 PREFIXED ACL"
  grant_team_prefix "$team" "$env"

  echo "[3] 给团队 Quota（写 10MB/s 读 20MB/s）"
  set_user_quota "$team" 10 20

  echo "[4] 设置默认兜底 Quota（写 5MB/s 读 10MB/s）"
  set_default_quota 5 10

  echo "[5] 验收：列出 ACL + Quota"
  list_acls_of_user "User:${team}"
  cfg --describe --entity-type users --entity-name "$team"
}

# ====================================================================
# 命令分发
# ====================================================================
case "${1:-help}" in
  list)            list_all_acls ;;
  list-user)       list_acls_of_user "${2:?need User:xxx}" ;;
  list-topic)      list_acls_of_topic "${2:?need topic}" ;;
  grant-producer)  grant_producer "$2" "$3" ;;
  grant-consumer)  grant_consumer "$2" "$3" "$4" ;;
  grant-tx)        grant_tx_producer "$2" "$3" ;;
  grant-team)      grant_team_prefix "$2" "$3" ;;
  grant-cross)     grant_cross_team_read "$2" "$3" "$4" ;;
  deny)            deny_topic_for_user "$2" "$3" ;;
  quota)           set_user_quota "$2" "$3" "$4" ;;
  quota-default)   set_default_quota "$2" "$3" ;;
  quota-request)   set_request_quota "$2" "$3" ;;
  list-quotas)     list_quotas ;;
  revoke-write)    revoke_topic_write "$2" "$3" ;;
  onboard-demo)    onboard_team_demo ;;
  *)
    cat <<EOF
Usage: $0 <subcommand> [args]

  list                                       列出所有 ACL
  list-user      User:alice                  列出某用户 ACL
  list-topic     learn.orders                列出某 Topic ACL
  grant-producer alice  learn.orders         授权 Producer
  grant-consumer alice  learn.orders order-svc
  grant-tx       alice  order-tx-            授权事务 Producer（前缀）
  grant-team     team-order prod             团队 PREFIXED 一键授权
  grant-cross    team-b prod.team-a.payment.refunded prod.team-b.watch
  deny           bob   learn.secret          Deny 全部操作
  quota          alice 10 20                 单用户 Quota（producer/consumer MB/s）
  quota-default  5 10                        默认兜底 Quota
  quota-request  alice 200                   Request 时间百分比
  list-quotas                                列出所有用户 Quota
  revoke-write   alice learn.orders          收回写权限
  onboard-demo                               演示多租户 onboarding 全流程
EOF
    ;;
esac
