Merge pull request #7710 from JimMoen/add-authn-authz-zh_CN-desc
add authn & authz zh_CN i18n support
This commit is contained in:
commit
56b3007d59
|
@ -0,0 +1,228 @@
|
||||||
|
emqx_authn_api {
|
||||||
|
|
||||||
|
authentication_get {
|
||||||
|
desc {
|
||||||
|
en: """List authenticators for global authentication"""
|
||||||
|
zh: """列出全局认证链上的认证器信息"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_post {
|
||||||
|
desc {
|
||||||
|
en: """Create authenticator for global authentication"""
|
||||||
|
zh: """为全局认证链创建认证器信息"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_get {
|
||||||
|
desc {
|
||||||
|
en: """Get authenticator from global authentication chain"""
|
||||||
|
zh: """获取全局认证链上指定的认证器信息"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_put {
|
||||||
|
desc {
|
||||||
|
en: """Update authenticator from global authentication chain"""
|
||||||
|
zh: """更新全局认证链上指定的认证器"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_delete {
|
||||||
|
desc {
|
||||||
|
en: """Delete authenticator from global authentication chain"""
|
||||||
|
zh: """删除全局认证链上指定的认证器信息"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_status_get {
|
||||||
|
desc {
|
||||||
|
en: """Get authenticator status from global authentication chain"""
|
||||||
|
zh: """获取全局认证链上指定的认证器状态"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_get {
|
||||||
|
desc {
|
||||||
|
en: """List authenticators for listener authentication"""
|
||||||
|
zh: """列出监听器上的认证器信息"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_post {
|
||||||
|
desc {
|
||||||
|
en: """Create authenticator for listener authentication"""
|
||||||
|
zh: """在指定的监听器上创建认证器"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_get {
|
||||||
|
desc {
|
||||||
|
en: """Get authenticator from listener authentication chain"""
|
||||||
|
zh: """获取监听器上指定的认证器信息"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_put {
|
||||||
|
desc {
|
||||||
|
en: """Update authenticator from listener authentication chain"""
|
||||||
|
zh: """更新监听器上指定的认证器"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_delete {
|
||||||
|
desc {
|
||||||
|
en: """Delete authenticator from listener authentication chain"""
|
||||||
|
zh: """删除监听器上指定的认证器"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_status_get {
|
||||||
|
desc {
|
||||||
|
en: """Get authenticator status from listener authentication chain"""
|
||||||
|
zh: """获取监听器上指定的认证器状态"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_move_post {
|
||||||
|
desc {
|
||||||
|
en: """Move authenticator in global authentication chain"""
|
||||||
|
zh: """移动全局认证链上认证器的顺序"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_move_post {
|
||||||
|
desc {
|
||||||
|
en: """Move authenticator in listener authentication chain"""
|
||||||
|
zh: """移动监听器上认证器的顺序"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_import_users_post {
|
||||||
|
desc {
|
||||||
|
en: """Import users into authenticator in global authentication chain"""
|
||||||
|
zh: """为全局认证链上的认证器导入用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_import_users_post {
|
||||||
|
desc {
|
||||||
|
en: """Import users into authenticator in listener authentication chain"""
|
||||||
|
zh: """为监听器上的认证器导入用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_users_post {
|
||||||
|
desc {
|
||||||
|
en: """Create users for authenticator in global authentication chain"""
|
||||||
|
zh: """为全局认证链上的认证器创建用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_users_get {
|
||||||
|
desc {
|
||||||
|
en: """List users in authenticator in global authentication chain"""
|
||||||
|
zh: """获取全局认证链上指定的认证器中的用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_users_post {
|
||||||
|
desc {
|
||||||
|
en: """Create users for authenticator in listener authentication chain"""
|
||||||
|
zh: """更新指定监听器上认证器中的用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_users_get {
|
||||||
|
desc {
|
||||||
|
en: """List users in authenticator in listener authentication chain"""
|
||||||
|
zh: """列出指定监听器上认证器中的用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_users_user_id_get {
|
||||||
|
desc {
|
||||||
|
en: """Get user from authenticator in global authentication chain"""
|
||||||
|
zh: """获取指定监听器上认证器中指定的用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_users_user_id_put {
|
||||||
|
desc {
|
||||||
|
en: """Update user in authenticator in global authentication chain"""
|
||||||
|
zh: """为指定监听器上认证器添加用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication_id_users_user_id_delete {
|
||||||
|
desc {
|
||||||
|
en: """Update user in authenticator in global authentication chain"""
|
||||||
|
zh: """更新指定监听器上认证器中的用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_users_user_id_get {
|
||||||
|
desc {
|
||||||
|
en: """Get user from authenticator in listener authentication chain"""
|
||||||
|
zh: """获取指定监听器上认证器中指定的用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_users_user_id_put {
|
||||||
|
desc {
|
||||||
|
en: """Update user in authenticator in listener authentication chain"""
|
||||||
|
zh: """更新指定监听器上认证器中的用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners_listener_id_authentication_id_users_user_id_delete {
|
||||||
|
desc {
|
||||||
|
en: """Delete user in authenticator in listener authentication chain"""
|
||||||
|
zh: """删除指定监听器上认证器中的用户数据"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
param_auth_id {
|
||||||
|
desc {
|
||||||
|
en: """Authenticator ID"""
|
||||||
|
zh: """认证器 ID"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
param_listener_id {
|
||||||
|
desc {
|
||||||
|
en: """Listener ID"""
|
||||||
|
zh: """监听器 ID"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
param_user_id {
|
||||||
|
desc {
|
||||||
|
en: """User ID"""
|
||||||
|
zh: """用户 ID"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
like_username {
|
||||||
|
desc {
|
||||||
|
en: """Fuzzy search username"""
|
||||||
|
zh: """使用用户名模糊查询"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """like_username"""
|
||||||
|
zh: """模糊用户名"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
like_clientid {
|
||||||
|
desc {
|
||||||
|
en: """Fuzzy search clientid"""
|
||||||
|
zh: """使用客户端标识符模糊查询"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """like_clientid"""
|
||||||
|
zh: """模糊用户名"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
emqx_authn_http {
|
||||||
|
get {
|
||||||
|
desc {
|
||||||
|
en: """Settings for HTTP-based authentication (GET)."""
|
||||||
|
zh: """基于 HTTP 的认证请求 (GET)"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """get"""
|
||||||
|
zh: """get"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
desc {
|
||||||
|
en: """Settings for HTTP-based authentication (POST)."""
|
||||||
|
zh: """基于 HTTP 的认证请求 (POST)"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """post"""
|
||||||
|
zh: """post"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
method {
|
||||||
|
desc {
|
||||||
|
en: """HTTP method."""
|
||||||
|
zh: """HTTP 请求方法"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """method"""
|
||||||
|
zh: """请求方法"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url {
|
||||||
|
desc {
|
||||||
|
en: """URL of the auth server."""
|
||||||
|
zh: """认证服务器地址"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """url"""
|
||||||
|
zh: """统一资源定位符"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers {
|
||||||
|
desc {
|
||||||
|
en: """List of HTTP headers."""
|
||||||
|
zh: """HTTP 请求头列表"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """headers"""
|
||||||
|
zh: """请求头"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers_no_content_type {
|
||||||
|
desc {
|
||||||
|
en: """List of HTTP headers. (without <code>content-type</code>)"""
|
||||||
|
zh: """HTTP 请求头列表(无 <code>content-type</code>)"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """headers_no_content_type"""
|
||||||
|
zh: """无content_type的请求头"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
desc {
|
||||||
|
en: """Body of the HTTP request."""
|
||||||
|
zh: """HTTP 请求体"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """body"""
|
||||||
|
zh: """请求体"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request_timeout {
|
||||||
|
desc {
|
||||||
|
en: """HTTP request timeout"""
|
||||||
|
zh: """HTTP 请求超时时长"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """request_timeout"""
|
||||||
|
zh: """请求超时时间"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
emqx_authn_schema {
|
||||||
|
enable {
|
||||||
|
desc {
|
||||||
|
en: """Set to <code>true</code> or <code>false</code> to disable this auth provider"""
|
||||||
|
zh: """设为 <code>true</code> 或 <code>false</code> 以启用或禁用此认证数据源"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """enable"""
|
||||||
|
zh: """启用"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mechanism {
|
||||||
|
desc {
|
||||||
|
en: """Authentication mechanism."""
|
||||||
|
zh: """认证机制"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """mechanism"""
|
||||||
|
zh: """机制"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backend {
|
||||||
|
desc {
|
||||||
|
en: """Backend type."""
|
||||||
|
zh: """后端类型"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """backend"""
|
||||||
|
zh: """后端"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
metrics {
|
||||||
|
desc {
|
||||||
|
en: """The metrics of the resource"""
|
||||||
|
zh: """统计指标"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """metrics"""
|
||||||
|
zh: """指标"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node_metrics {
|
||||||
|
desc {
|
||||||
|
en: """The metrics of the resource for each node"""
|
||||||
|
zh: """每个节点上资源的统计指标"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """node_metrics"""
|
||||||
|
zh: """节点指标"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status {
|
||||||
|
desc {
|
||||||
|
en: """The status of the resource"""
|
||||||
|
zh: """资源状态"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """status"""
|
||||||
|
zh: """状态"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node_status {
|
||||||
|
desc {
|
||||||
|
en: """The status of the resource for each node"""
|
||||||
|
zh: """每个节点上资源的状态"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """node_status"""
|
||||||
|
zh: """节点状态"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matched {
|
||||||
|
desc {
|
||||||
|
en: """Count of this resource is queried"""
|
||||||
|
zh: """请求命中次数"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """matched"""
|
||||||
|
zh: """已命中"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
success {
|
||||||
|
desc {
|
||||||
|
en: """Count of query success"""
|
||||||
|
zh: """请求成功次数"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """success"""
|
||||||
|
zh: """成功"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
failed {
|
||||||
|
desc {
|
||||||
|
en: """Count of query failed"""
|
||||||
|
zh: """请求失败次数"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """failed"""
|
||||||
|
zh: """失败"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rate {
|
||||||
|
desc {
|
||||||
|
en: """The rate of matched, times/second"""
|
||||||
|
zh: """命中速率,单位: 次/秒"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """rate"""
|
||||||
|
zh: """速率"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rate_max {
|
||||||
|
desc {
|
||||||
|
en: """The max rate of matched, times/second"""
|
||||||
|
zh: """最大命中速率,单位: 次/秒"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """rate_max"""
|
||||||
|
zh: """最大速率"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rate_last5m {
|
||||||
|
desc {
|
||||||
|
en: """The average rate of matched in the last 5 minutes, times/second"""
|
||||||
|
zh: """5分钟内平均命中速率,单位: 次/秒"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """rate_last5m"""
|
||||||
|
zh: """5分钟内速率"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node {
|
||||||
|
desc {
|
||||||
|
en: """The node name"""
|
||||||
|
zh: """节点名"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """node"""
|
||||||
|
zh: """节点"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
emqx_authn_jwt {
|
||||||
|
use_jwks {
|
||||||
|
desc {
|
||||||
|
en: """jwks flag"""
|
||||||
|
zh: """jwks 状态"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """use_jwks"""
|
||||||
|
zh: """使用jwks"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
algorithm {
|
||||||
|
desc {
|
||||||
|
en: """Signing algorithm."""
|
||||||
|
zh: """签名算法"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """algorithm"""
|
||||||
|
zh: """算法"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
certificate {
|
||||||
|
desc {
|
||||||
|
en: """The certificate used for signing the token."""
|
||||||
|
zh: """用于签名token的证书"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """certificate"""
|
||||||
|
zh: """证书"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
secret_base64_encoded {
|
||||||
|
desc {
|
||||||
|
en: """Enable/disable base64 encoding of the secret."""
|
||||||
|
zh: """启用/关闭私匙 base64 编码"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """secret_base64_encoded"""
|
||||||
|
zh: """密钥 base64 编码"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
secret {
|
||||||
|
desc {
|
||||||
|
en: """The key to verify the JWT Token using HMAC algorithm."""
|
||||||
|
zh: """使用对称加密的算法"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """secret"""
|
||||||
|
zh: """secret"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint {
|
||||||
|
desc {
|
||||||
|
en: """JWKs endpoint"""
|
||||||
|
zh: """JWKs endpoint"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """endpoint"""
|
||||||
|
zh: """endpoint"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh_interval {
|
||||||
|
desc {
|
||||||
|
en: """JWKs refresh interval"""
|
||||||
|
zh: """JWKs 更新间隔"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """refresh_interval"""
|
||||||
|
zh: """更新间隔"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cacertfile {
|
||||||
|
desc {
|
||||||
|
en: """Path to the SSL CA certificate file."""
|
||||||
|
zh: """SSL CA 证书公钥文件路径"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """cacertfile"""
|
||||||
|
zh: """CA 证书文件"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
certfile {
|
||||||
|
desc {
|
||||||
|
en: """Path to the SSL certificate file."""
|
||||||
|
zh: """证书文件路径"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """certfile"""
|
||||||
|
zh: """证书文件"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyfile {
|
||||||
|
desc {
|
||||||
|
en: """Path to the SSL secret key file."""
|
||||||
|
zh: """SSL 私钥文件路径"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """keyfile"""
|
||||||
|
zh: """私钥文件"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verify {
|
||||||
|
desc {
|
||||||
|
en: """Enable or disable SSL peer verification."""
|
||||||
|
zh: """指定握手过程中是否校验客户端"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """verify"""
|
||||||
|
zh: """verify"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server_name_indication {
|
||||||
|
desc {
|
||||||
|
en: """SSL SNI (Server Name Indication)"""
|
||||||
|
zh: """SSL SNI (服务器名称指示)"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """server_name_indication"""
|
||||||
|
zh: """服务器名称指示"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_claims {
|
||||||
|
desc {
|
||||||
|
en: """The list of claims to verify."""
|
||||||
|
zh: """The list of claims to verify."""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """verify_claims"""
|
||||||
|
zh: """verify_claims"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pool_size {
|
||||||
|
desc {
|
||||||
|
en: """JWKs connection count"""
|
||||||
|
zh: """JWKs 连接数量"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """pool_size"""
|
||||||
|
zh: """pool_size"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl {
|
||||||
|
desc {
|
||||||
|
en: """SSL options."""
|
||||||
|
zh: """SSL 选项"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """ssl"""
|
||||||
|
zh: """ssl"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enable {
|
||||||
|
desc {
|
||||||
|
en: """Enable/disable SSL."""
|
||||||
|
zh: """启用/禁用 SSL"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """enable"""
|
||||||
|
zh: """启用"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hmac-based {
|
||||||
|
desc {
|
||||||
|
en: """Settings for HMAC-based token signing algorithm."""
|
||||||
|
zh: """HMAC-based token 签名配置"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """hmac-based"""
|
||||||
|
zh: """hmac-based"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public-key {
|
||||||
|
desc {
|
||||||
|
en: """Settings for public key-based token signing algorithm."""
|
||||||
|
zh: """公钥token签名配置"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """public-key"""
|
||||||
|
zh: """public-key"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jwks {
|
||||||
|
desc {
|
||||||
|
en: """Settings for a signing using JSON Web Key Set (JWKs)."""
|
||||||
|
zh: """JWks 签名配置"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """jwks"""
|
||||||
|
zh: """jwks"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl_disable {
|
||||||
|
desc {
|
||||||
|
en: """SSL disabled"""
|
||||||
|
zh: """SSL 关闭"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """ssl_disable"""
|
||||||
|
zh: """关闭SSL"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl_enable {
|
||||||
|
desc {
|
||||||
|
en: """SSL configuration."""
|
||||||
|
zh: """SSL 配置"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """ssl_enable"""
|
||||||
|
zh: """启用SSL"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
emqx_authn_mnesia {
|
||||||
|
authentication {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for authentication using the built-in database."""
|
||||||
|
zh: """内置数据库认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """authentication"""
|
||||||
|
zh: """认证配置"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_id_type {
|
||||||
|
desc {
|
||||||
|
en: """Authenticate by Client ID or Username."""
|
||||||
|
zh: """认证类型,基于 Client ID 或 Username"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """user_id_type"""
|
||||||
|
zh: """用户标识类型"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
emqx_authn_mongodb {
|
||||||
|
standalone {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for a standalone MongoDB instance."""
|
||||||
|
zh: """MongoDB 单节点认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """standalone"""
|
||||||
|
zh: """standalone 模式"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
replica-set {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for a replica set."""
|
||||||
|
zh: """MongoDB replica set 模式认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """replica-set"""
|
||||||
|
zh: """replica-set 模式"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sharded-cluster {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for a sharded cluster."""
|
||||||
|
zh: """MongoDB sharded cluster 模式认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """sharded-cluster"""
|
||||||
|
zh: """sharded-cluster 模式"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collection {
|
||||||
|
desc {
|
||||||
|
en: """Collection used to store authentication data."""
|
||||||
|
zh: """认证数据集名称"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """collection"""
|
||||||
|
zh: """数据集"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selector {
|
||||||
|
desc {
|
||||||
|
en: """
|
||||||
|
Statement that is executed during the authentication process.
|
||||||
|
Commands can support following wildcards:\n
|
||||||
|
- `${username}`: substituted with client's username\n
|
||||||
|
- `${clientid}`: substituted with the clientid
|
||||||
|
"""
|
||||||
|
zh: """
|
||||||
|
认证过程中所使用的查询命令。
|
||||||
|
查询命令支持如下占位符:
|
||||||
|
- `${username}`: 代替客户端的用户名
|
||||||
|
- `${clientid}`: 代替客户端的客户端标识符
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """selector"""
|
||||||
|
zh: """认证查询"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
password_hash_field {
|
||||||
|
desc {
|
||||||
|
en: """Document field that contains password hash."""
|
||||||
|
zh: """数据文档中的密码散列值"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """password_hash_field"""
|
||||||
|
zh: """密码散列字段"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
salt_field {
|
||||||
|
desc {
|
||||||
|
en: """Document field that contains the password salt."""
|
||||||
|
zh: """数据文档中的密码加盐"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """salt_field"""
|
||||||
|
zh: """加盐字段"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_superuser_field {
|
||||||
|
desc {
|
||||||
|
en: """Document field that defines if the user has superuser privileges."""
|
||||||
|
zh: """数据文档中的超级用户权限记录"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """is_superuser_field"""
|
||||||
|
zh: """超级用户字段"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
emqx_authn_mysql {
|
||||||
|
authentication {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for authentication using MySQL database."""
|
||||||
|
zh: """MySQL 认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """authentication"""
|
||||||
|
zh: """认证配置"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
desc {
|
||||||
|
en: """SQL query used to lookup client data."""
|
||||||
|
zh: """客户端数据查询 SQL 语句"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """query"""
|
||||||
|
zh: """请求"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query_timeout {
|
||||||
|
dsec {
|
||||||
|
en: """Timeout for the SQL query."""
|
||||||
|
zh: """SQL 查询超时时长"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """query_timeout"""
|
||||||
|
zh: """请求超时"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
emqx_authn_pgsql {
|
||||||
|
authentication {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for PostgreSQL authentication backend."""
|
||||||
|
zh: """PostgreSQL 认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """authentication"""
|
||||||
|
zh: """认证配置"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query {
|
||||||
|
desc {
|
||||||
|
en: """`SQL` query for looking up authentication data."""
|
||||||
|
zh: """客户端数据查询 SQL 语句"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """query"""
|
||||||
|
zh: """请求"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
emqx_authn_redis {
|
||||||
|
standalone {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for a standalone Redis instance."""
|
||||||
|
zh: """Redis 单节点认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """standalone"""
|
||||||
|
zh: """standalone"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for a Redis cluster."""
|
||||||
|
zh: """Redis 集群模式认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """cluster"""
|
||||||
|
zh: """cluster"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sentinel {
|
||||||
|
desc {
|
||||||
|
en: """Configuration for a Redis Sentinel."""
|
||||||
|
zh: """Redis 哨兵模式认证配置"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """sentinel"""
|
||||||
|
zh: """sentinel"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd {
|
||||||
|
desc {
|
||||||
|
en: """Database query used to retrieve authentication data."""
|
||||||
|
zh: """Redis 认证数据查询语句"""
|
||||||
|
}
|
||||||
|
label: {
|
||||||
|
en: """cmd"""
|
||||||
|
zh: """查询命令"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,11 +18,11 @@
|
||||||
|
|
||||||
-behaviour(minirest_api).
|
-behaviour(minirest_api).
|
||||||
|
|
||||||
-include_lib("typerefl/include/types.hrl").
|
|
||||||
-include("emqx_authn.hrl").
|
-include("emqx_authn.hrl").
|
||||||
-include_lib("emqx/include/emqx_placeholder.hrl").
|
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
-include_lib("emqx/include/emqx_placeholder.hrl").
|
||||||
-include_lib("emqx/include/emqx_authentication.hrl").
|
-include_lib("emqx/include/emqx_authentication.hrl").
|
||||||
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-import(hoconsc, [mk/2, ref/1, ref/2]).
|
-import(hoconsc, [mk/2, ref/1, ref/2]).
|
||||||
-import(emqx_dashboard_swagger, [error_codes/2]).
|
-import(emqx_dashboard_swagger, [error_codes/2]).
|
||||||
|
@ -154,7 +154,7 @@ schema("/authentication") ->
|
||||||
'operationId' => authenticators,
|
'operationId' => authenticators,
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"List authenticators for global authentication">>,
|
description => ?DESC(authentication_get),
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_swagger:schema_with_example(
|
200 => emqx_dashboard_swagger:schema_with_example(
|
||||||
hoconsc:array(emqx_authn_schema:authenticator_type()),
|
hoconsc:array(emqx_authn_schema:authenticator_type()),
|
||||||
|
@ -164,7 +164,7 @@ schema("/authentication") ->
|
||||||
},
|
},
|
||||||
post => #{
|
post => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Create authenticator for global authentication">>,
|
description => ?DESC(authentication_post),
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
emqx_authn_schema:authenticator_type(),
|
emqx_authn_schema:authenticator_type(),
|
||||||
authenticator_examples()
|
authenticator_examples()
|
||||||
|
@ -184,7 +184,7 @@ schema("/authentication/:id") ->
|
||||||
'operationId' => authenticator,
|
'operationId' => authenticator,
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Get authenticator from global authentication chain">>,
|
description => ?DESC(authentication_id_get),
|
||||||
parameters => [param_auth_id()],
|
parameters => [param_auth_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_swagger:schema_with_examples(
|
200 => emqx_dashboard_swagger:schema_with_examples(
|
||||||
|
@ -196,7 +196,7 @@ schema("/authentication/:id") ->
|
||||||
},
|
},
|
||||||
put => #{
|
put => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Update authenticator from global authentication chain">>,
|
description => ?DESC(authentication_id_put),
|
||||||
parameters => [param_auth_id()],
|
parameters => [param_auth_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
emqx_authn_schema:authenticator_type(),
|
emqx_authn_schema:authenticator_type(),
|
||||||
|
@ -214,7 +214,7 @@ schema("/authentication/:id") ->
|
||||||
},
|
},
|
||||||
delete => #{
|
delete => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Delete authenticator from global authentication chain">>,
|
description => ?DESC(authentication_id_delete),
|
||||||
parameters => [param_auth_id()],
|
parameters => [param_auth_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"Authenticator deleted">>,
|
204 => <<"Authenticator deleted">>,
|
||||||
|
@ -227,7 +227,7 @@ schema("/authentication/:id/status") ->
|
||||||
'operationId' => authenticator_status,
|
'operationId' => authenticator_status,
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Get authenticator status from global authentication chain">>,
|
description => ?DESC(authentication_id_status_get),
|
||||||
parameters => [param_auth_id()],
|
parameters => [param_auth_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_swagger:schema_with_examples(
|
200 => emqx_dashboard_swagger:schema_with_examples(
|
||||||
|
@ -243,7 +243,7 @@ schema("/listeners/:listener_id/authentication") ->
|
||||||
'operationId' => listener_authenticators,
|
'operationId' => listener_authenticators,
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"List authenticators for listener authentication">>,
|
description => ?DESC(listeners_listener_id_authentication_get),
|
||||||
parameters => [param_listener_id()],
|
parameters => [param_listener_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_swagger:schema_with_example(
|
200 => emqx_dashboard_swagger:schema_with_example(
|
||||||
|
@ -254,7 +254,7 @@ schema("/listeners/:listener_id/authentication") ->
|
||||||
},
|
},
|
||||||
post => #{
|
post => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Create authenticator for listener authentication">>,
|
description => ?DESC(listeners_listener_id_authentication_post),
|
||||||
parameters => [param_listener_id()],
|
parameters => [param_listener_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
emqx_authn_schema:authenticator_type(),
|
emqx_authn_schema:authenticator_type(),
|
||||||
|
@ -275,7 +275,7 @@ schema("/listeners/:listener_id/authentication/:id") ->
|
||||||
'operationId' => listener_authenticator,
|
'operationId' => listener_authenticator,
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Get authenticator from listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_get),
|
||||||
parameters => [param_listener_id(), param_auth_id()],
|
parameters => [param_listener_id(), param_auth_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_swagger:schema_with_examples(
|
200 => emqx_dashboard_swagger:schema_with_examples(
|
||||||
|
@ -287,7 +287,7 @@ schema("/listeners/:listener_id/authentication/:id") ->
|
||||||
},
|
},
|
||||||
put => #{
|
put => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Update authenticator from listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_put),
|
||||||
parameters => [param_listener_id(), param_auth_id()],
|
parameters => [param_listener_id(), param_auth_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
emqx_authn_schema:authenticator_type(),
|
emqx_authn_schema:authenticator_type(),
|
||||||
|
@ -305,7 +305,7 @@ schema("/listeners/:listener_id/authentication/:id") ->
|
||||||
},
|
},
|
||||||
delete => #{
|
delete => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Delete authenticator from listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_delete),
|
||||||
parameters => [param_listener_id(), param_auth_id()],
|
parameters => [param_listener_id(), param_auth_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"Authenticator deleted">>,
|
204 => <<"Authenticator deleted">>,
|
||||||
|
@ -318,7 +318,7 @@ schema("/listeners/:listener_id/authentication/:id/status") ->
|
||||||
'operationId' => listener_authenticator_status,
|
'operationId' => listener_authenticator_status,
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Get authenticator status from listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_status_get),
|
||||||
parameters => [param_listener_id(), param_auth_id()],
|
parameters => [param_listener_id(), param_auth_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_swagger:schema_with_examples(
|
200 => emqx_dashboard_swagger:schema_with_examples(
|
||||||
|
@ -334,7 +334,7 @@ schema("/authentication/:id/move") ->
|
||||||
'operationId' => authenticator_move,
|
'operationId' => authenticator_move,
|
||||||
post => #{
|
post => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Move authenticator in global authentication chain">>,
|
description => ?DESC(authentication_id_move_post),
|
||||||
parameters => [param_auth_id()],
|
parameters => [param_auth_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
ref(request_move),
|
ref(request_move),
|
||||||
|
@ -352,7 +352,7 @@ schema("/listeners/:listener_id/authentication/:id/move") ->
|
||||||
'operationId' => listener_authenticator_move,
|
'operationId' => listener_authenticator_move,
|
||||||
post => #{
|
post => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Move authenticator in listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_move_post),
|
||||||
parameters => [param_listener_id(), param_auth_id()],
|
parameters => [param_listener_id(), param_auth_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
ref(request_move),
|
ref(request_move),
|
||||||
|
@ -370,7 +370,7 @@ schema("/authentication/:id/import_users") ->
|
||||||
'operationId' => authenticator_import_users,
|
'operationId' => authenticator_import_users,
|
||||||
post => #{
|
post => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Import users into authenticator in global authentication chain">>,
|
description => ?DESC(authentication_id_import_users_post),
|
||||||
parameters => [param_auth_id()],
|
parameters => [param_auth_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
ref(request_import_users),
|
ref(request_import_users),
|
||||||
|
@ -388,7 +388,7 @@ schema("/listeners/:listener_id/authentication/:id/import_users") ->
|
||||||
'operationId' => listener_authenticator_import_users,
|
'operationId' => listener_authenticator_import_users,
|
||||||
post => #{
|
post => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Import users into authenticator in listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_import_users_post),
|
||||||
parameters => [param_listener_id(), param_auth_id()],
|
parameters => [param_listener_id(), param_auth_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
ref(request_import_users),
|
ref(request_import_users),
|
||||||
|
@ -406,7 +406,7 @@ schema("/authentication/:id/users") ->
|
||||||
'operationId' => authenticator_users,
|
'operationId' => authenticator_users,
|
||||||
post => #{
|
post => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Create users for authenticator in global authentication chain">>,
|
description => ?DESC(authentication_id_users_post),
|
||||||
parameters => [param_auth_id()],
|
parameters => [param_auth_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
ref(request_user_create),
|
ref(request_user_create),
|
||||||
|
@ -423,7 +423,7 @@ schema("/authentication/:id/users") ->
|
||||||
},
|
},
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"List users in authenticator in global authentication chain">>,
|
description => ?DESC(authentication_id_users_get),
|
||||||
parameters => [
|
parameters => [
|
||||||
param_auth_id(),
|
param_auth_id(),
|
||||||
ref(emqx_dashboard_swagger, page),
|
ref(emqx_dashboard_swagger, page),
|
||||||
|
@ -431,13 +431,13 @@ schema("/authentication/:id/users") ->
|
||||||
{like_username,
|
{like_username,
|
||||||
mk(binary(), #{
|
mk(binary(), #{
|
||||||
in => query,
|
in => query,
|
||||||
desc => <<"Fuzzy search username">>,
|
desc => ?DESC(like_username),
|
||||||
required => false
|
required => false
|
||||||
})},
|
})},
|
||||||
{like_clientid,
|
{like_clientid,
|
||||||
mk(binary(), #{
|
mk(binary(), #{
|
||||||
in => query,
|
in => query,
|
||||||
desc => <<"Fuzzy search clientid">>,
|
desc => ?DESC(like_clientid),
|
||||||
required => false
|
required => false
|
||||||
})}
|
})}
|
||||||
],
|
],
|
||||||
|
@ -455,7 +455,7 @@ schema("/listeners/:listener_id/authentication/:id/users") ->
|
||||||
'operationId' => listener_authenticator_users,
|
'operationId' => listener_authenticator_users,
|
||||||
post => #{
|
post => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Create users for authenticator in global authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_users_post),
|
||||||
parameters => [param_auth_id(), param_listener_id()],
|
parameters => [param_auth_id(), param_listener_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
ref(request_user_create),
|
ref(request_user_create),
|
||||||
|
@ -472,7 +472,7 @@ schema("/listeners/:listener_id/authentication/:id/users") ->
|
||||||
},
|
},
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"List users in authenticator in listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_users_get),
|
||||||
parameters => [
|
parameters => [
|
||||||
param_listener_id(),
|
param_listener_id(),
|
||||||
param_auth_id(),
|
param_auth_id(),
|
||||||
|
@ -493,7 +493,7 @@ schema("/authentication/:id/users/:user_id") ->
|
||||||
'operationId' => authenticator_user,
|
'operationId' => authenticator_user,
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Get user from authenticator in global authentication chain">>,
|
description => ?DESC(authentication_id_users_user_id_get),
|
||||||
parameters => [param_auth_id(), param_user_id()],
|
parameters => [param_auth_id(), param_user_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_swagger:schema_with_examples(
|
200 => emqx_dashboard_swagger:schema_with_examples(
|
||||||
|
@ -505,7 +505,7 @@ schema("/authentication/:id/users/:user_id") ->
|
||||||
},
|
},
|
||||||
put => #{
|
put => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Update user in authenticator in global authentication chain">>,
|
description => ?DESC(authentication_id_users_user_id_put),
|
||||||
parameters => [param_auth_id(), param_user_id()],
|
parameters => [param_auth_id(), param_user_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||||
ref(request_user_update),
|
ref(request_user_update),
|
||||||
|
@ -522,7 +522,7 @@ schema("/authentication/:id/users/:user_id") ->
|
||||||
},
|
},
|
||||||
delete => #{
|
delete => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => <<"Update user in authenticator in global authentication chain">>,
|
description => ?DESC(authentication_id_users_user_id_delete),
|
||||||
parameters => [param_auth_id(), param_user_id()],
|
parameters => [param_auth_id(), param_user_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"User deleted">>,
|
204 => <<"User deleted">>,
|
||||||
|
@ -535,7 +535,7 @@ schema("/listeners/:listener_id/authentication/:id/users/:user_id") ->
|
||||||
'operationId' => listener_authenticator_user,
|
'operationId' => listener_authenticator_user,
|
||||||
get => #{
|
get => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Get user from authenticator in listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_users_user_id_get),
|
||||||
parameters => [param_listener_id(), param_auth_id(), param_user_id()],
|
parameters => [param_listener_id(), param_auth_id(), param_user_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_swagger:schema_with_example(
|
200 => emqx_dashboard_swagger:schema_with_example(
|
||||||
|
@ -547,7 +547,7 @@ schema("/listeners/:listener_id/authentication/:id/users/:user_id") ->
|
||||||
},
|
},
|
||||||
put => #{
|
put => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Update user in authenticator in listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_users_user_id_put),
|
||||||
parameters => [param_listener_id(), param_auth_id(), param_user_id()],
|
parameters => [param_listener_id(), param_auth_id(), param_user_id()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_example(
|
'requestBody' => emqx_dashboard_swagger:schema_with_example(
|
||||||
ref(request_user_update),
|
ref(request_user_update),
|
||||||
|
@ -564,7 +564,7 @@ schema("/listeners/:listener_id/authentication/:id/users/:user_id") ->
|
||||||
},
|
},
|
||||||
delete => #{
|
delete => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => <<"Update user in authenticator in listener authentication chain">>,
|
description => ?DESC(listeners_listener_id_authentication_id_users_user_id_delete),
|
||||||
parameters => [param_listener_id(), param_auth_id(), param_user_id()],
|
parameters => [param_listener_id(), param_auth_id(), param_user_id()],
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"User deleted">>,
|
204 => <<"User deleted">>,
|
||||||
|
@ -578,7 +578,7 @@ param_auth_id() ->
|
||||||
id,
|
id,
|
||||||
mk(binary(), #{
|
mk(binary(), #{
|
||||||
in => path,
|
in => path,
|
||||||
desc => <<"Authenticator ID">>,
|
desc => ?DESC(param_auth_id),
|
||||||
required => true
|
required => true
|
||||||
})
|
})
|
||||||
}.
|
}.
|
||||||
|
@ -588,7 +588,7 @@ param_listener_id() ->
|
||||||
listener_id,
|
listener_id,
|
||||||
mk(binary(), #{
|
mk(binary(), #{
|
||||||
in => path,
|
in => path,
|
||||||
desc => <<"Listener ID">>,
|
desc => ?DESC(param_listener_id),
|
||||||
required => true,
|
required => true,
|
||||||
example => emqx_listeners:id_example()
|
example => emqx_listeners:id_example()
|
||||||
})
|
})
|
||||||
|
@ -599,7 +599,7 @@ param_user_id() ->
|
||||||
user_id,
|
user_id,
|
||||||
mk(binary(), #{
|
mk(binary(), #{
|
||||||
in => path,
|
in => path,
|
||||||
desc => <<"User ID">>
|
desc => ?DESC(param_user_id)
|
||||||
})
|
})
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
-module(emqx_authn_schema).
|
-module(emqx_authn_schema).
|
||||||
|
|
||||||
-elvis([{elvis_style, invalid_dynamic_call, disable}]).
|
-elvis([{elvis_style, invalid_dynamic_call, disable}]).
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
-import(hoconsc, [mk/2, ref/2]).
|
-import(hoconsc, [mk/2, ref/2]).
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
@ -38,7 +38,7 @@ common_fields() ->
|
||||||
|
|
||||||
enable(type) -> boolean();
|
enable(type) -> boolean();
|
||||||
enable(default) -> true;
|
enable(default) -> true;
|
||||||
enable(desc) -> "Set to <code>false</code> to disable this auth provider";
|
enable(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
enable(_) -> undefined.
|
enable(_) -> undefined.
|
||||||
|
|
||||||
authenticator_type() ->
|
authenticator_type() ->
|
||||||
|
@ -74,7 +74,7 @@ mechanism(Name) ->
|
||||||
hoconsc:enum([Name]),
|
hoconsc:enum([Name]),
|
||||||
#{
|
#{
|
||||||
required => true,
|
required => true,
|
||||||
desc => "Authentication mechanism."
|
desc => ?DESC("mechanism")
|
||||||
}
|
}
|
||||||
).
|
).
|
||||||
|
|
||||||
|
@ -83,51 +83,47 @@ backend(Name) ->
|
||||||
hoconsc:enum([Name]),
|
hoconsc:enum([Name]),
|
||||||
#{
|
#{
|
||||||
required => true,
|
required => true,
|
||||||
desc => "Backend type."
|
desc => ?DESC("backend")
|
||||||
}
|
}
|
||||||
).
|
).
|
||||||
|
|
||||||
fields("metrics_status_fields") ->
|
fields("metrics_status_fields") ->
|
||||||
[
|
[
|
||||||
{"metrics", mk(ref(?MODULE, "metrics"), #{desc => "The metrics of the resource"})},
|
{"metrics", mk(ref(?MODULE, "metrics"), #{desc => ?DESC("metrics")})},
|
||||||
{"node_metrics",
|
{"node_metrics",
|
||||||
mk(
|
mk(
|
||||||
hoconsc:array(ref(?MODULE, "node_metrics")),
|
hoconsc:array(ref(?MODULE, "node_metrics")),
|
||||||
#{desc => "The metrics of the resource for each node"}
|
#{desc => ?DESC("node_metrics")}
|
||||||
)},
|
)},
|
||||||
{"status", mk(status(), #{desc => "The status of the resource"})},
|
{"status", mk(status(), #{desc => ?DESC("status")})},
|
||||||
{"node_status",
|
{"node_status",
|
||||||
mk(
|
mk(
|
||||||
hoconsc:array(ref(?MODULE, "node_status")),
|
hoconsc:array(ref(?MODULE, "node_status")),
|
||||||
#{desc => "The status of the resource for each node"}
|
#{desc => ?DESC("node_status")}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
fields("metrics") ->
|
fields("metrics") ->
|
||||||
[
|
[
|
||||||
{"matched", mk(integer(), #{desc => "Count of this resource is queried"})},
|
{"matched", mk(integer(), #{desc => ?DESC("matched")})},
|
||||||
{"success", mk(integer(), #{desc => "Count of query success"})},
|
{"success", mk(integer(), #{desc => ?DESC("success")})},
|
||||||
{"failed", mk(integer(), #{desc => "Count of query failed"})},
|
{"failed", mk(integer(), #{desc => ?DESC("failed")})},
|
||||||
{"rate", mk(float(), #{desc => "The rate of matched, times/second"})},
|
{"rate", mk(float(), #{desc => ?DESC("rate")})},
|
||||||
{"rate_max", mk(float(), #{desc => "The max rate of matched, times/second"})},
|
{"rate_max", mk(float(), #{desc => ?DESC("rate_max")})},
|
||||||
{"rate_last5m",
|
{"rate_last5m", mk(float(), #{desc => ?DESC("rate_last5m")})}
|
||||||
mk(
|
|
||||||
float(),
|
|
||||||
#{desc => "The average rate of matched in the last 5 minutes, times/second"}
|
|
||||||
)}
|
|
||||||
];
|
];
|
||||||
fields("node_metrics") ->
|
fields("node_metrics") ->
|
||||||
[
|
[
|
||||||
node_name(),
|
node_name(),
|
||||||
{"metrics", mk(ref(?MODULE, "metrics"), #{})}
|
{"metrics", mk(ref(?MODULE, "metrics"), #{desc => ?DESC("metrics")})}
|
||||||
];
|
];
|
||||||
fields("node_status") ->
|
fields("node_status") ->
|
||||||
[
|
[
|
||||||
node_name(),
|
node_name(),
|
||||||
{"status", mk(status(), #{desc => "Status of the node."})}
|
{"status", mk(status(), #{desc => ?DESC("node_status")})}
|
||||||
].
|
].
|
||||||
|
|
||||||
status() ->
|
status() ->
|
||||||
hoconsc:enum([connected, disconnected, connecting]).
|
hoconsc:enum([connected, disconnected, connecting]).
|
||||||
|
|
||||||
node_name() ->
|
node_name() ->
|
||||||
{"node", mk(binary(), #{desc => "The node name", example => "emqx@127.0.0.1"})}.
|
{"node", mk(binary(), #{desc => ?DESC("node"), example => "emqx@127.0.0.1"})}.
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
-include("emqx_authn.hrl").
|
-include("emqx_authn.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||||
|
|
||||||
-behaviour(hocon_schema).
|
-behaviour(hocon_schema).
|
||||||
|
@ -62,19 +62,19 @@ roots() ->
|
||||||
|
|
||||||
fields(get) ->
|
fields(get) ->
|
||||||
[
|
[
|
||||||
{method, #{type => get, required => true, default => post, desc => "HTTP method."}},
|
{method, #{type => get, required => true, default => post, desc => ?DESC(method)}},
|
||||||
{headers, fun headers_no_content_type/1}
|
{headers, fun headers_no_content_type/1}
|
||||||
] ++ common_fields();
|
] ++ common_fields();
|
||||||
fields(post) ->
|
fields(post) ->
|
||||||
[
|
[
|
||||||
{method, #{type => post, required => true, default => post, desc => "HTTP method."}},
|
{method, #{type => post, required => true, default => post, desc => ?DESC(method)}},
|
||||||
{headers, fun headers/1}
|
{headers, fun headers/1}
|
||||||
] ++ common_fields().
|
] ++ common_fields().
|
||||||
|
|
||||||
desc(get) ->
|
desc(get) ->
|
||||||
"Settings for HTTP-based authentication (GET).";
|
?DESC(get);
|
||||||
desc(post) ->
|
desc(post) ->
|
||||||
"Settings for HTTP-based authentication (POST).";
|
?DESC(post);
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
|
@ -83,8 +83,7 @@ common_fields() ->
|
||||||
{mechanism, emqx_authn_schema:mechanism(password_based)},
|
{mechanism, emqx_authn_schema:mechanism(password_based)},
|
||||||
{backend, emqx_authn_schema:backend(http)},
|
{backend, emqx_authn_schema:backend(http)},
|
||||||
{url, fun url/1},
|
{url, fun url/1},
|
||||||
{body,
|
{body, hoconsc:mk(map([{fuzzy, term(), binary()}]), #{desc => ?DESC(body)})},
|
||||||
hoconsc:mk(map([{fuzzy, term(), binary()}]), #{desc => "Body of the HTTP request."})},
|
|
||||||
{request_timeout, fun request_timeout/1}
|
{request_timeout, fun request_timeout/1}
|
||||||
] ++ emqx_authn_schema:common_fields() ++
|
] ++ emqx_authn_schema:common_fields() ++
|
||||||
maps:to_list(
|
maps:to_list(
|
||||||
|
@ -104,7 +103,7 @@ validations() ->
|
||||||
].
|
].
|
||||||
|
|
||||||
url(type) -> binary();
|
url(type) -> binary();
|
||||||
url(desc) -> "URL of the auth server.";
|
url(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
url(validator) -> [?NOT_EMPTY("the value of the field 'url' cannot be empty")];
|
url(validator) -> [?NOT_EMPTY("the value of the field 'url' cannot be empty")];
|
||||||
url(required) -> true;
|
url(required) -> true;
|
||||||
url(_) -> undefined.
|
url(_) -> undefined.
|
||||||
|
@ -112,7 +111,7 @@ url(_) -> undefined.
|
||||||
headers(type) ->
|
headers(type) ->
|
||||||
map();
|
map();
|
||||||
headers(desc) ->
|
headers(desc) ->
|
||||||
"List of HTTP headers.";
|
?DESC(?FUNCTION_NAME);
|
||||||
headers(converter) ->
|
headers(converter) ->
|
||||||
fun(Headers) ->
|
fun(Headers) ->
|
||||||
maps:merge(default_headers(), transform_header_name(Headers))
|
maps:merge(default_headers(), transform_header_name(Headers))
|
||||||
|
@ -125,7 +124,7 @@ headers(_) ->
|
||||||
headers_no_content_type(type) ->
|
headers_no_content_type(type) ->
|
||||||
map();
|
map();
|
||||||
headers_no_content_type(desc) ->
|
headers_no_content_type(desc) ->
|
||||||
"List of HTTP headers.";
|
?DESC(?FUNCTION_NAME);
|
||||||
headers_no_content_type(converter) ->
|
headers_no_content_type(converter) ->
|
||||||
fun(Headers) ->
|
fun(Headers) ->
|
||||||
maps:merge(default_headers_no_content_type(), transform_header_name(Headers))
|
maps:merge(default_headers_no_content_type(), transform_header_name(Headers))
|
||||||
|
@ -136,7 +135,7 @@ headers_no_content_type(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
request_timeout(type) -> emqx_schema:duration_ms();
|
request_timeout(type) -> emqx_schema:duration_ms();
|
||||||
request_timeout(desc) -> "HTTP request timeout";
|
request_timeout(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
request_timeout(default) -> <<"5s">>;
|
request_timeout(default) -> <<"5s">>;
|
||||||
request_timeout(_) -> undefined.
|
request_timeout(_) -> undefined.
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
-module(emqx_authn_jwt).
|
-module(emqx_authn_jwt).
|
||||||
|
|
||||||
-include("emqx_authn.hrl").
|
-include("emqx_authn.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-behaviour(hocon_schema).
|
-behaviour(hocon_schema).
|
||||||
-behaviour(emqx_authentication).
|
-behaviour(emqx_authentication).
|
||||||
|
@ -55,22 +55,22 @@ roots() ->
|
||||||
|
|
||||||
fields('hmac-based') ->
|
fields('hmac-based') ->
|
||||||
[
|
[
|
||||||
{use_jwks, sc(hoconsc:enum([false]), #{required => true, desc => ""})},
|
{use_jwks, sc(hoconsc:enum([false]), #{required => true, desc => ?DESC(use_jwks)})},
|
||||||
{algorithm,
|
{algorithm,
|
||||||
sc(hoconsc:enum(['hmac-based']), #{required => true, desc => "Signing algorithm."})},
|
sc(hoconsc:enum(['hmac-based']), #{required => true, desc => ?DESC(algorithm)})},
|
||||||
{secret, fun secret/1},
|
{secret, fun secret/1},
|
||||||
{secret_base64_encoded, fun secret_base64_encoded/1}
|
{secret_base64_encoded, fun secret_base64_encoded/1}
|
||||||
] ++ common_fields();
|
] ++ common_fields();
|
||||||
fields('public-key') ->
|
fields('public-key') ->
|
||||||
[
|
[
|
||||||
{use_jwks, sc(hoconsc:enum([false]), #{required => true, desc => ""})},
|
{use_jwks, sc(hoconsc:enum([false]), #{required => true, desc => ?DESC(use_jwks)})},
|
||||||
{algorithm,
|
{algorithm,
|
||||||
sc(hoconsc:enum(['public-key']), #{required => true, desc => "Signing algorithm."})},
|
sc(hoconsc:enum(['public-key']), #{required => true, desc => ?DESC(algorithm)})},
|
||||||
{certificate, fun certificate/1}
|
{certificate, fun certificate/1}
|
||||||
] ++ common_fields();
|
] ++ common_fields();
|
||||||
fields('jwks') ->
|
fields('jwks') ->
|
||||||
[
|
[
|
||||||
{use_jwks, sc(hoconsc:enum([true]), #{required => true, desc => ""})},
|
{use_jwks, sc(hoconsc:enum([true]), #{required => true, desc => ?DESC(use_jwks)})},
|
||||||
{endpoint, fun endpoint/1},
|
{endpoint, fun endpoint/1},
|
||||||
{pool_size, fun pool_size/1},
|
{pool_size, fun pool_size/1},
|
||||||
{refresh_interval, fun refresh_interval/1},
|
{refresh_interval, fun refresh_interval/1},
|
||||||
|
@ -79,14 +79,14 @@ fields('jwks') ->
|
||||||
hoconsc:ref(?MODULE, ssl_enable),
|
hoconsc:ref(?MODULE, ssl_enable),
|
||||||
hoconsc:ref(?MODULE, ssl_disable)
|
hoconsc:ref(?MODULE, ssl_disable)
|
||||||
]),
|
]),
|
||||||
desc => "Enable/disable SSL.",
|
desc => ?DESC(ssl),
|
||||||
default => #{<<"enable">> => false},
|
default => #{<<"enable">> => false},
|
||||||
required => false
|
required => false
|
||||||
}}
|
}}
|
||||||
] ++ common_fields();
|
] ++ common_fields();
|
||||||
fields(ssl_enable) ->
|
fields(ssl_enable) ->
|
||||||
[
|
[
|
||||||
{enable, #{type => true, desc => ""}},
|
{enable, #{type => true, desc => ?DESC(enable)}},
|
||||||
{cacertfile, fun cacertfile/1},
|
{cacertfile, fun cacertfile/1},
|
||||||
{certfile, fun certfile/1},
|
{certfile, fun certfile/1},
|
||||||
{keyfile, fun keyfile/1},
|
{keyfile, fun keyfile/1},
|
||||||
|
@ -94,18 +94,18 @@ fields(ssl_enable) ->
|
||||||
{server_name_indication, fun server_name_indication/1}
|
{server_name_indication, fun server_name_indication/1}
|
||||||
];
|
];
|
||||||
fields(ssl_disable) ->
|
fields(ssl_disable) ->
|
||||||
[{enable, #{type => false, desc => ""}}].
|
[{enable, #{type => false, desc => ?DESC(enable)}}].
|
||||||
|
|
||||||
desc('hmac-based') ->
|
desc('hmac-based') ->
|
||||||
"Settings for HMAC-based token signing algorithm.";
|
?DESC('hmac-based');
|
||||||
desc('public-key') ->
|
desc('public-key') ->
|
||||||
"Settings for public key-based token signing algorithm.";
|
?DESC('public-key');
|
||||||
desc('jwks') ->
|
desc('jwks') ->
|
||||||
"Settings for a signing using JSON Web Key Set (JWKs).";
|
?DESC('jwks');
|
||||||
desc(ssl_disable) ->
|
desc(ssl_disable) ->
|
||||||
"";
|
?DESC(ssl_disable);
|
||||||
desc(ssl_enable) ->
|
desc(ssl_enable) ->
|
||||||
"SSL configuration.";
|
?DESC(ssl_enable);
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
|
@ -116,56 +116,56 @@ common_fields() ->
|
||||||
] ++ emqx_authn_schema:common_fields().
|
] ++ emqx_authn_schema:common_fields().
|
||||||
|
|
||||||
secret(type) -> binary();
|
secret(type) -> binary();
|
||||||
secret(desc) -> "The key to verify the JWT Token using HMAC algorithm.";
|
secret(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
secret(required) -> true;
|
secret(required) -> true;
|
||||||
secret(_) -> undefined.
|
secret(_) -> undefined.
|
||||||
|
|
||||||
secret_base64_encoded(type) -> boolean();
|
secret_base64_encoded(type) -> boolean();
|
||||||
secret_base64_encoded(desc) -> "Enable/disable base64 encoding of the secret.";
|
secret_base64_encoded(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
secret_base64_encoded(default) -> false;
|
secret_base64_encoded(default) -> false;
|
||||||
secret_base64_encoded(_) -> undefined.
|
secret_base64_encoded(_) -> undefined.
|
||||||
|
|
||||||
certificate(type) -> string();
|
certificate(type) -> string();
|
||||||
certificate(desc) -> "The certificate used for signing the token.";
|
certificate(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
certificate(required) -> ture;
|
certificate(required) -> ture;
|
||||||
certificate(_) -> undefined.
|
certificate(_) -> undefined.
|
||||||
|
|
||||||
endpoint(type) -> string();
|
endpoint(type) -> string();
|
||||||
endpoint(desc) -> "JWKs endpoint.";
|
endpoint(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
endpoint(required) -> true;
|
endpoint(required) -> true;
|
||||||
endpoint(_) -> undefined.
|
endpoint(_) -> undefined.
|
||||||
|
|
||||||
refresh_interval(type) -> integer();
|
refresh_interval(type) -> integer();
|
||||||
refresh_interval(desc) -> "JWKs refresh interval";
|
refresh_interval(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
refresh_interval(default) -> 300;
|
refresh_interval(default) -> 300;
|
||||||
refresh_interval(validator) -> [fun(I) -> I > 0 end];
|
refresh_interval(validator) -> [fun(I) -> I > 0 end];
|
||||||
refresh_interval(_) -> undefined.
|
refresh_interval(_) -> undefined.
|
||||||
|
|
||||||
cacertfile(type) -> string();
|
cacertfile(type) -> string();
|
||||||
cacertfile(desc) -> "Path to the SSL CA certificate file.";
|
cacertfile(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
cacertfile(_) -> undefined.
|
cacertfile(_) -> undefined.
|
||||||
|
|
||||||
certfile(type) -> string();
|
certfile(type) -> string();
|
||||||
certfile(desc) -> "Path to the SSL certificate file.";
|
certfile(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
certfile(_) -> undefined.
|
certfile(_) -> undefined.
|
||||||
|
|
||||||
keyfile(type) -> string();
|
keyfile(type) -> string();
|
||||||
keyfile(desc) -> "Path to the SSL secret key file.";
|
keyfile(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
keyfile(_) -> undefined.
|
keyfile(_) -> undefined.
|
||||||
|
|
||||||
verify(type) -> hoconsc:enum([verify_peer, verify_none]);
|
verify(type) -> hoconsc:enum([verify_peer, verify_none]);
|
||||||
verify(desc) -> "Enable or disable SSL peer verification.";
|
verify(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
verify(default) -> verify_none;
|
verify(default) -> verify_none;
|
||||||
verify(_) -> undefined.
|
verify(_) -> undefined.
|
||||||
|
|
||||||
server_name_indication(type) -> string();
|
server_name_indication(type) -> string();
|
||||||
server_name_indication(desc) -> "SSL SNI (Server Name Indication)";
|
server_name_indication(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
server_name_indication(_) -> undefined.
|
server_name_indication(_) -> undefined.
|
||||||
|
|
||||||
verify_claims(type) ->
|
verify_claims(type) ->
|
||||||
list();
|
list();
|
||||||
verify_claims(desc) ->
|
verify_claims(desc) ->
|
||||||
"The list of claims to verify.";
|
?DESC(?FUNCTION_NAME);
|
||||||
verify_claims(default) ->
|
verify_claims(default) ->
|
||||||
#{};
|
#{};
|
||||||
verify_claims(validator) ->
|
verify_claims(validator) ->
|
||||||
|
@ -180,7 +180,7 @@ verify_claims(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
pool_size(type) -> integer();
|
pool_size(type) -> integer();
|
||||||
pool_size(desc) -> "JWKS connection count";
|
pool_size(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
pool_size(default) -> 8;
|
pool_size(default) -> 8;
|
||||||
pool_size(validator) -> [fun(I) -> I > 0 end];
|
pool_size(validator) -> [fun(I) -> I > 0 end];
|
||||||
pool_size(_) -> undefined.
|
pool_size(_) -> undefined.
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
-include("emqx_authn.hrl").
|
-include("emqx_authn.hrl").
|
||||||
-include_lib("stdlib/include/ms_transform.hrl").
|
-include_lib("stdlib/include/ms_transform.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-behaviour(hocon_schema).
|
-behaviour(hocon_schema).
|
||||||
-behaviour(emqx_authentication).
|
-behaviour(emqx_authentication).
|
||||||
|
@ -110,12 +110,12 @@ fields(?CONF_NS) ->
|
||||||
] ++ emqx_authn_schema:common_fields().
|
] ++ emqx_authn_schema:common_fields().
|
||||||
|
|
||||||
desc(?CONF_NS) ->
|
desc(?CONF_NS) ->
|
||||||
"Configuration for authentication using the built-in database.";
|
?DESC(?CONF_NS);
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
user_id_type(type) -> user_id_type();
|
user_id_type(type) -> user_id_type();
|
||||||
user_id_type(desc) -> "Authenticate by client ID or username.";
|
user_id_type(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
user_id_type(default) -> <<"username">>;
|
user_id_type(default) -> <<"username">>;
|
||||||
user_id_type(required) -> true;
|
user_id_type(required) -> true;
|
||||||
user_id_type(_) -> undefined.
|
user_id_type(_) -> undefined.
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
-include("emqx_authn.hrl").
|
-include("emqx_authn.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-behaviour(hocon_schema).
|
-behaviour(hocon_schema).
|
||||||
-behaviour(emqx_authentication).
|
-behaviour(emqx_authentication).
|
||||||
|
@ -61,17 +61,17 @@ fields('sharded-cluster') ->
|
||||||
common_fields() ++ emqx_connector_mongo:fields(sharded).
|
common_fields() ++ emqx_connector_mongo:fields(sharded).
|
||||||
|
|
||||||
desc(standalone) ->
|
desc(standalone) ->
|
||||||
"Configuration for a standalone MongoDB instance.";
|
?DESC(standalone);
|
||||||
desc('replica-set') ->
|
desc('replica-set') ->
|
||||||
"Configuration for a replica set.";
|
?DESC('replica-set');
|
||||||
desc('sharded-cluster') ->
|
desc('sharded-cluster') ->
|
||||||
"Configuration for a sharded cluster.";
|
?DESC('sharded-cluster');
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
common_fields() ->
|
common_fields() ->
|
||||||
[
|
[
|
||||||
{mechanism, emqx_authn_schema:mechanism('password_based')},
|
{mechanism, emqx_authn_schema:mechanism(password_based)},
|
||||||
{backend, emqx_authn_schema:backend(mongodb)},
|
{backend, emqx_authn_schema:backend(mongodb)},
|
||||||
{collection, fun collection/1},
|
{collection, fun collection/1},
|
||||||
{selector, fun selector/1},
|
{selector, fun selector/1},
|
||||||
|
@ -82,32 +82,29 @@ common_fields() ->
|
||||||
] ++ emqx_authn_schema:common_fields().
|
] ++ emqx_authn_schema:common_fields().
|
||||||
|
|
||||||
collection(type) -> binary();
|
collection(type) -> binary();
|
||||||
collection(desc) -> "Collection used to store authentication data.";
|
collection(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
collection(required) -> true;
|
collection(required) -> true;
|
||||||
collection(_) -> undefined.
|
collection(_) -> undefined.
|
||||||
|
|
||||||
selector(type) ->
|
selector(type) ->
|
||||||
map();
|
map();
|
||||||
selector(desc) ->
|
selector(desc) ->
|
||||||
"Statement that is executed during the authentication process. "
|
?DESC(?FUNCTION_NAME);
|
||||||
"Commands can support following wildcards:\n"
|
|
||||||
" - `${username}`: substituted with client's username\n"
|
|
||||||
" - `${clientid}`: substituted with the clientid";
|
|
||||||
selector(_) ->
|
selector(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
password_hash_field(type) -> binary();
|
password_hash_field(type) -> binary();
|
||||||
password_hash_field(desc) -> "Document field that contains password hash.";
|
password_hash_field(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
password_hash_field(required) -> false;
|
password_hash_field(required) -> false;
|
||||||
password_hash_field(_) -> undefined.
|
password_hash_field(_) -> undefined.
|
||||||
|
|
||||||
salt_field(type) -> binary();
|
salt_field(type) -> binary();
|
||||||
salt_field(desc) -> "Document field that contains the password salt.";
|
salt_field(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
salt_field(required) -> false;
|
salt_field(required) -> false;
|
||||||
salt_field(_) -> undefined.
|
salt_field(_) -> undefined.
|
||||||
|
|
||||||
is_superuser_field(type) -> binary();
|
is_superuser_field(type) -> binary();
|
||||||
is_superuser_field(desc) -> "Document field that defines if the user has superuser privileges.";
|
is_superuser_field(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
is_superuser_field(required) -> false;
|
is_superuser_field(required) -> false;
|
||||||
is_superuser_field(_) -> undefined.
|
is_superuser_field(_) -> undefined.
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
-include("emqx_authn.hrl").
|
-include("emqx_authn.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-behaviour(hocon_schema).
|
-behaviour(hocon_schema).
|
||||||
-behaviour(emqx_authentication).
|
-behaviour(emqx_authentication).
|
||||||
|
@ -59,17 +59,17 @@ fields(?CONF_NS) ->
|
||||||
proplists:delete(prepare_statement, emqx_connector_mysql:fields(config)).
|
proplists:delete(prepare_statement, emqx_connector_mysql:fields(config)).
|
||||||
|
|
||||||
desc(?CONF_NS) ->
|
desc(?CONF_NS) ->
|
||||||
"Configuration for authentication using MySQL database.";
|
?DESC(?CONF_NS);
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
query(type) -> string();
|
query(type) -> string();
|
||||||
query(desc) -> "SQL query used to lookup client data.";
|
query(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
query(required) -> true;
|
query(required) -> true;
|
||||||
query(_) -> undefined.
|
query(_) -> undefined.
|
||||||
|
|
||||||
query_timeout(type) -> emqx_schema:duration_ms();
|
query_timeout(type) -> emqx_schema:duration_ms();
|
||||||
query_timeout(desc) -> "Timeout for the SQL query.";
|
query_timeout(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
query_timeout(default) -> "5s";
|
query_timeout(default) -> "5s";
|
||||||
query_timeout(_) -> undefined.
|
query_timeout(_) -> undefined.
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-include("emqx_authn.hrl").
|
-include("emqx_authn.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("epgsql/include/epgsql.hrl").
|
-include_lib("epgsql/include/epgsql.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-behaviour(hocon_schema).
|
-behaviour(hocon_schema).
|
||||||
-behaviour(emqx_authentication).
|
-behaviour(emqx_authentication).
|
||||||
|
@ -63,12 +63,12 @@ fields(?CONF_NS) ->
|
||||||
proplists:delete(prepare_statement, emqx_connector_pgsql:fields(config)).
|
proplists:delete(prepare_statement, emqx_connector_pgsql:fields(config)).
|
||||||
|
|
||||||
desc(?CONF_NS) ->
|
desc(?CONF_NS) ->
|
||||||
"Configuration for PostgreSQL authentication backend.";
|
?DESC(?CONF_NS);
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
query(type) -> string();
|
query(type) -> string();
|
||||||
query(desc) -> "`SQL` query for looking up authentication data.";
|
query(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
query(required) -> true;
|
query(required) -> true;
|
||||||
query(_) -> undefined.
|
query(_) -> undefined.
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
-include("emqx_authn.hrl").
|
-include("emqx_authn.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-behaviour(hocon_schema).
|
-behaviour(hocon_schema).
|
||||||
-behaviour(emqx_authentication).
|
-behaviour(emqx_authentication).
|
||||||
|
@ -61,24 +61,24 @@ fields(sentinel) ->
|
||||||
common_fields() ++ emqx_connector_redis:fields(sentinel).
|
common_fields() ++ emqx_connector_redis:fields(sentinel).
|
||||||
|
|
||||||
desc(standalone) ->
|
desc(standalone) ->
|
||||||
"Configuration for a standalone Redis instance.";
|
?DESC(standalone);
|
||||||
desc(cluster) ->
|
desc(cluster) ->
|
||||||
"Configuration for a Redis cluster.";
|
?DESC(cluster);
|
||||||
desc(sentinel) ->
|
desc(sentinel) ->
|
||||||
"Configuration for a Redis Sentinel.";
|
?DESC(sentinel);
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
"".
|
"".
|
||||||
|
|
||||||
common_fields() ->
|
common_fields() ->
|
||||||
[
|
[
|
||||||
{mechanism, emqx_authn_schema:mechanism('password_based')},
|
{mechanism, emqx_authn_schema:mechanism(password_based)},
|
||||||
{backend, emqx_authn_schema:backend(redis)},
|
{backend, emqx_authn_schema:backend(redis)},
|
||||||
{cmd, fun cmd/1},
|
{cmd, fun cmd/1},
|
||||||
{password_hash_algorithm, fun emqx_authn_password_hashing:type_ro/1}
|
{password_hash_algorithm, fun emqx_authn_password_hashing:type_ro/1}
|
||||||
] ++ emqx_authn_schema:common_fields().
|
] ++ emqx_authn_schema:common_fields().
|
||||||
|
|
||||||
cmd(type) -> string();
|
cmd(type) -> string();
|
||||||
cmd(desc) -> "Redis query.";
|
cmd(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
cmd(required) -> true;
|
cmd(required) -> true;
|
||||||
cmd(_) -> undefined.
|
cmd(_) -> undefined.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
emqx_authz_api_cache {
|
||||||
|
authorization_cache_delete {
|
||||||
|
en: """Clean all authorization cache in the cluster."""
|
||||||
|
zh: """清除集群中所有鉴权数据缓存"""
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
emqx_authz_api_mnesia {
|
||||||
|
users_username_get {
|
||||||
|
desc {
|
||||||
|
en: """Show the list of record for username"""
|
||||||
|
zh: """获取内置数据库中所有用户名类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
users_username_post {
|
||||||
|
desc {
|
||||||
|
en: """Add new records for username"""
|
||||||
|
zh: """添加内置数据库中用户名类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
users_clientid_get {
|
||||||
|
desc {
|
||||||
|
en: """Show the list of record for clientid"""
|
||||||
|
zh: """获取内置数据库中所有客户端标识符类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
users_clientid_post {
|
||||||
|
desc {
|
||||||
|
en: """Add new records for clientid"""
|
||||||
|
zh: """添加内置数据库中客户端标识符类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
user_username_get {
|
||||||
|
desc {
|
||||||
|
en: """Get record info for username"""
|
||||||
|
zh: """获取内置数据库中指定用户名类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_username_put {
|
||||||
|
desc {
|
||||||
|
en: """Set record for username"""
|
||||||
|
zh: """更新内置数据库中指定用户名类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_username_delete {
|
||||||
|
desc {
|
||||||
|
en: """Delete one record for username"""
|
||||||
|
zh: """删除内置数据库中指定用户名类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_clientid_get {
|
||||||
|
desc {
|
||||||
|
en: """Get record info for clientid"""
|
||||||
|
zh: """获取内置数据库中指定客户端标识符类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_clientid_put {
|
||||||
|
desc {
|
||||||
|
en: """Set record for clientid"""
|
||||||
|
zh: """更新内置数据库中指定客户端标识符类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_clientid_delete {
|
||||||
|
desc {
|
||||||
|
en: """Delete one record for clientid"""
|
||||||
|
zh: """删除内置数据库中指定客户端标识符类型的规则记录"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rules_for_all_get {
|
||||||
|
desc {
|
||||||
|
en: """Show the list of rules for all"""
|
||||||
|
zh: """列出为所有客户端启用的规则列表"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rules_for_all_post {
|
||||||
|
desc {
|
||||||
|
en: """
|
||||||
|
Create/Update the list of rules for all.
|
||||||
|
Set a empty list to clean up rules
|
||||||
|
"""
|
||||||
|
zh: """
|
||||||
|
创建/更新 为所有客户端启用的规则列表。
|
||||||
|
设为空列表以清楚所有规则
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
purge_all_delete {
|
||||||
|
desc {
|
||||||
|
en: """Purge all records for username/clientid/all"""
|
||||||
|
zh: """清除所有内置数据库中的规则, 用户名/客户端标识符/所有"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fuzzy_username {
|
||||||
|
desc {
|
||||||
|
en: """Fuzzy search `username` as substring"""
|
||||||
|
zh: """使用字串匹配模糊搜索用户名"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """fuzzy_username"""
|
||||||
|
zh: """用户名子串"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fuzzy_clientid {
|
||||||
|
desc {
|
||||||
|
en: """Fuzzy search `clientid` as substring"""
|
||||||
|
zh: """使用字串匹配模糊搜索客户端标识符"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """fuzzy_clientid"""
|
||||||
|
zh: """客户端标识符子串"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
topic {
|
||||||
|
desc {
|
||||||
|
en: """Rule on specific topic"""
|
||||||
|
zh: """在指定主题上的规则"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """topic"""
|
||||||
|
zh: """主题"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
permission {
|
||||||
|
desc {
|
||||||
|
en: """Permission"""
|
||||||
|
zh: """权限"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """permission"""
|
||||||
|
zh: """权限"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
action {
|
||||||
|
desc {
|
||||||
|
en: """Authorized action (pub/sub/all)"""
|
||||||
|
zh: """被授权的行为 (发布/订阅/所有)"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """action"""
|
||||||
|
zh: """行为"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clientid {
|
||||||
|
desc {
|
||||||
|
en: """ClientID"""
|
||||||
|
zh: """客户端标识符"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """clientid"""
|
||||||
|
zh: """客户端标识符"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
username {
|
||||||
|
desc {
|
||||||
|
en: """Username"""
|
||||||
|
zh: """用户名"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """username"""
|
||||||
|
zh: """用户名"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,188 @@
|
||||||
|
emqx_authz_api_schema {
|
||||||
|
enable {
|
||||||
|
desc {
|
||||||
|
en: """Set to <code>true</code> or <code>false</code> to disable this ACL provider"""
|
||||||
|
zh: """设为 <code>true</code> 或 <code>false</code> 以启用或禁用此访问控制数据源"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """enable"""
|
||||||
|
zh: """enable"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type {
|
||||||
|
desc {
|
||||||
|
en: """Backend type."""
|
||||||
|
zh: """数据后端类型"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """type"""
|
||||||
|
zh: """type"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_file
|
||||||
|
|
||||||
|
rules {
|
||||||
|
desc {
|
||||||
|
en: """Authorization static file rules."""
|
||||||
|
zh: """静态鉴权文件规则"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """rules"""
|
||||||
|
zh: """规则"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_http
|
||||||
|
|
||||||
|
method {
|
||||||
|
desc {
|
||||||
|
en: """HTTP method."""
|
||||||
|
zh: """HTTP 请求方法"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """method"""
|
||||||
|
zh: """method"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url {
|
||||||
|
desc {
|
||||||
|
en: """URL of the auth server."""
|
||||||
|
zh: """认证服务器 URL"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """url"""
|
||||||
|
zh: """url"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers {
|
||||||
|
desc {
|
||||||
|
en: """List of HTTP headers."""
|
||||||
|
zh: """"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """headers"""
|
||||||
|
zh: """请求头"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers_no_content_type {
|
||||||
|
desc {
|
||||||
|
en: """List of HTTP headers (without `content_type`)."""
|
||||||
|
zh: """"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """headers_no_content_type"""
|
||||||
|
zh: """请求头(无 content-type)"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
desc {
|
||||||
|
en: """HTTP request body."""
|
||||||
|
zh: """HTTP 请求体"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """body"""
|
||||||
|
zh: """请求体"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request_timeout {
|
||||||
|
desc {
|
||||||
|
en: """Request timeout."""
|
||||||
|
zh: """请求超时时间"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """request_timeout"""
|
||||||
|
zh: """请求超时"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_mnesia
|
||||||
|
|
||||||
|
# only common fields(`enable` and `type`)
|
||||||
|
|
||||||
|
#==== authz_mongo
|
||||||
|
|
||||||
|
collection {
|
||||||
|
desc {
|
||||||
|
en: """`MongoDB` collection containing the authorization data."""
|
||||||
|
zh: """`MongoDB` 鉴权数据集"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """collection"""
|
||||||
|
zh: """数据集"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selector {
|
||||||
|
desc {
|
||||||
|
en: """
|
||||||
|
Statement that is executed during the authorize process.
|
||||||
|
Commands can support following wildcards:\n
|
||||||
|
- `${username}`: substituted with client's username\n
|
||||||
|
- `${clientid}`: substituted with the clientid
|
||||||
|
"""
|
||||||
|
zh: """
|
||||||
|
鉴权过程中所使用的查询命令。
|
||||||
|
查询命令支持如下占位符:
|
||||||
|
- `${username}`: 代替客户端的用户名
|
||||||
|
- `${clientid}`: 代替客户端的客户端标识符"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """selector"""
|
||||||
|
zh: """selector"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_mysql
|
||||||
|
|
||||||
|
# `query`, is common field
|
||||||
|
|
||||||
|
#==== authz_pgsql
|
||||||
|
|
||||||
|
# `query`, is common field
|
||||||
|
|
||||||
|
#==== authz_redis
|
||||||
|
|
||||||
|
cmd {
|
||||||
|
desc {
|
||||||
|
en: """Database query used to retrieve authorization data."""
|
||||||
|
zh: """访问控制数据查询命令"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """cmd"""
|
||||||
|
zh: """查询命令"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== common field for DBs (except mongodb and redis)
|
||||||
|
|
||||||
|
query {
|
||||||
|
desc {
|
||||||
|
en: """Database query used to retrieve authorization data."""
|
||||||
|
zh: """访问控制数据查询语句"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """query"""
|
||||||
|
zh: """查询语句"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== fields
|
||||||
|
|
||||||
|
position {
|
||||||
|
desc {
|
||||||
|
en: """Where to place the source"""
|
||||||
|
zh: """认证数据源位置"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """position"""
|
||||||
|
zh: """位置"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
emqx_authz_api_settings {
|
||||||
|
authorization_settings_get {
|
||||||
|
en: """Get authorization settings"""
|
||||||
|
zh: """获取鉴权配置"""
|
||||||
|
}
|
||||||
|
|
||||||
|
authorization_settings_put {
|
||||||
|
en: """Update authorization settings"""
|
||||||
|
zh: """更新鉴权配置"""
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
emqx_authz_api_sources {
|
||||||
|
authorization_sources_get {
|
||||||
|
desc {
|
||||||
|
en: """List all authorization sources"""
|
||||||
|
zh: """列出所有鉴权数据源"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorization_sources_post {
|
||||||
|
desc {
|
||||||
|
en: """Add a new source"""
|
||||||
|
zh: """添加鉴权数据源"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorization_sources_type_get {
|
||||||
|
desc {
|
||||||
|
en: """Get a authorization source"""
|
||||||
|
zh: """获取指定类型的鉴权数据源"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorization_sources_type_put {
|
||||||
|
desc {
|
||||||
|
en: """Update source"""
|
||||||
|
zh: """更新指定类型的鉴权数据源"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorization_sources_type_delete {
|
||||||
|
desc {
|
||||||
|
en: """Delete source"""
|
||||||
|
zh: """删除指定类型的鉴权数据源"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorization_sources_type_status_get {
|
||||||
|
desc {
|
||||||
|
en: """Get a authorization source"""
|
||||||
|
zh: """获取指定鉴权数据源的状态"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorization_sources_type_move_post {
|
||||||
|
desc {
|
||||||
|
en: """Change the exection order of sources"""
|
||||||
|
zh: """更新鉴权数据源的优先执行顺序"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sources {
|
||||||
|
desc {
|
||||||
|
en: """Authorization source"""
|
||||||
|
zh: """鉴权数据源列表"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """sources"""
|
||||||
|
zh: """数据源列表"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sources {
|
||||||
|
desc {
|
||||||
|
en: """Authorization sources"""
|
||||||
|
zh: """鉴权数据源列表"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """sources"""
|
||||||
|
zh: """数据源列表"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source_config {
|
||||||
|
desc {
|
||||||
|
en: """Source config"""
|
||||||
|
zh: """数据源配置"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """source_config"""
|
||||||
|
zh: """数据源配置"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source {
|
||||||
|
desc {
|
||||||
|
en: """Authorization source"""
|
||||||
|
zh: """鉴权数据源"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """source"""
|
||||||
|
zh: """数据源"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source_config {
|
||||||
|
desc {
|
||||||
|
en: """Source config"""
|
||||||
|
zh: """数据源配置"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """source_config"""
|
||||||
|
zh: """数据源配置"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source_type {
|
||||||
|
desc {
|
||||||
|
en: """Authorization type"""
|
||||||
|
zh: """数据源类型"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """source_type"""
|
||||||
|
zh: """数据源类型"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,349 @@
|
||||||
|
emqx_authz_schema {
|
||||||
|
sources {
|
||||||
|
desc {
|
||||||
|
en: """
|
||||||
|
Authorization data sources.<br>
|
||||||
|
An array of authorization (ACL) data providers.
|
||||||
|
It is designed as an array, not a hash-map, so the sources can be
|
||||||
|
ordered to form a chain of access controls.<br>
|
||||||
|
|
||||||
|
When authorizing a 'publish' or 'subscribe' action, the configured
|
||||||
|
sources are checked in order. When checking an ACL source,
|
||||||
|
in case the client (identified by username or client ID) is not found,
|
||||||
|
it moves on to the next source. And it stops immediately
|
||||||
|
once an 'allow' or 'deny' decision is returned.<br>
|
||||||
|
|
||||||
|
If the client is not found in any of the sources,
|
||||||
|
the default action configured in 'authorization.no_match' is applied.<br>
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
The source elements are identified by their 'type'.
|
||||||
|
It is NOT allowed to configure two or more sources of the same type.
|
||||||
|
"""
|
||||||
|
zh: """"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """sources"""
|
||||||
|
zh: """"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorization {
|
||||||
|
desc {
|
||||||
|
en: """Configuration related to the client authorization."""
|
||||||
|
zh: """"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """authorization"""
|
||||||
|
zh: """授权"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enable {
|
||||||
|
desc {
|
||||||
|
en: """Set to <code>true</code> or <code>false</code> to disable this ACL provider"""
|
||||||
|
zh: """设为 <code>true</code> 或 <code>false</code> 以启用或禁用此访问控制数据源"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """enable"""
|
||||||
|
zh: """enable"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type {
|
||||||
|
desc {
|
||||||
|
en: """Backend type."""
|
||||||
|
zh: """数据后端类型"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """type"""
|
||||||
|
zh: """type"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_file
|
||||||
|
|
||||||
|
file {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a static file."""
|
||||||
|
zh: """使用静态文件鉴权"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """file"""
|
||||||
|
zh: """文件"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path {
|
||||||
|
desc {
|
||||||
|
en: """
|
||||||
|
Path to the file which contains the ACL rules.<br>
|
||||||
|
If the file provisioned before starting EMQX node,
|
||||||
|
it can be placed anywhere as long as EMQX has read access to it.
|
||||||
|
|
||||||
|
In case the rule-set is created from EMQX dashboard or management API,
|
||||||
|
the file will be placed in `authz` subdirectory inside EMQX's `data_dir`,
|
||||||
|
and the new rules will override all rules from the old config file.
|
||||||
|
"""
|
||||||
|
zh: """"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """path"""
|
||||||
|
zh: """path"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_http
|
||||||
|
|
||||||
|
http_get {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using an external HTTP server (via GET requests)."""
|
||||||
|
zh: """使用外部 HTTP 服务器鉴权(GET 请求)."""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """http_get"""
|
||||||
|
zh: """http_get"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
http_post {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using an external HTTP server (via POST requests)."""
|
||||||
|
zh: """使用外部 HTTP 服务器鉴权(POST 请求)."""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """http_post"""
|
||||||
|
zh: """http_post"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
method {
|
||||||
|
desc {
|
||||||
|
en: """HTTP method."""
|
||||||
|
zh: """HTTP 请求方法"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """method"""
|
||||||
|
zh: """method"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url {
|
||||||
|
desc {
|
||||||
|
en: """URL of the auth server."""
|
||||||
|
zh: """认证服务器 URL"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """url"""
|
||||||
|
zh: """url"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers {
|
||||||
|
desc {
|
||||||
|
en: """List of HTTP headers."""
|
||||||
|
zh: """"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """headers"""
|
||||||
|
zh: """请求头"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers_no_content_type {
|
||||||
|
desc {
|
||||||
|
en: """List of HTTP headers (without `content_type`)."""
|
||||||
|
zh: """"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """headers_no_content_type"""
|
||||||
|
zh: """请求头(无 content-type)"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
desc {
|
||||||
|
en: """HTTP request body."""
|
||||||
|
zh: """HTTP 请求体"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """body"""
|
||||||
|
zh: """请求体"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request_timeout {
|
||||||
|
desc {
|
||||||
|
en: """Request timeout."""
|
||||||
|
zh: """请求超时时间"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """request_timeout"""
|
||||||
|
zh: """请求超时"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_mnesia
|
||||||
|
|
||||||
|
mnesia {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a built-in database (mnesia)."""
|
||||||
|
zh: """使用内部数据库鉴权 (mnesia)."""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """mnesia"""
|
||||||
|
zh: """mnesia"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_mongo
|
||||||
|
|
||||||
|
mongo_single {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a single MongoDB instance."""
|
||||||
|
zh: """使用 MongoDB 鉴权(单实例)"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """mongo_single"""
|
||||||
|
zh: """mongo_single"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mongo_rs {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a MongoDB replica set."""
|
||||||
|
zh: """使用 MongoDB 鉴权(副本集模式)"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """mongo_rs"""
|
||||||
|
zh: """mongo_rs"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mongo_sharded {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a sharded MongoDB cluster."""
|
||||||
|
zh: """使用 MongoDB 鉴权(分片集群模式)"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """mongo_sharded"""
|
||||||
|
zh: """mongo_sharded"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collection {
|
||||||
|
desc {
|
||||||
|
en: """`MongoDB` collection containing the authorization data."""
|
||||||
|
zh: """`MongoDB` 鉴权数据集"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """collection"""
|
||||||
|
zh: """数据集"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selector {
|
||||||
|
desc {
|
||||||
|
en: """
|
||||||
|
Statement that is executed during the authorize process.
|
||||||
|
Commands can support following wildcards:\n
|
||||||
|
- `${username}`: substituted with client's username\n
|
||||||
|
- `${clientid}`: substituted with the clientid
|
||||||
|
"""
|
||||||
|
zh: """
|
||||||
|
鉴权过程中所使用的查询命令。
|
||||||
|
查询命令支持如下占位符:
|
||||||
|
- `${username}`: 代替客户端的用户名
|
||||||
|
- `${clientid}`: 代替客户端的客户端标识符"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """selector"""
|
||||||
|
zh: """selector"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_mysql
|
||||||
|
|
||||||
|
mysql {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a MySQL database."""
|
||||||
|
zh: """使用 MySOL 数据库鉴权"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """mysql"""
|
||||||
|
zh: """mysql"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_pgsql
|
||||||
|
|
||||||
|
postgresql {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a PostgreSQL database."""
|
||||||
|
zh: """使用 PostgreSQL 数据库鉴权"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """postgresql"""
|
||||||
|
zh: """postgresql"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== authz_redis
|
||||||
|
|
||||||
|
redis_single {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a single Redis instance."""
|
||||||
|
zh: """使用 Redis 鉴权(单实例)"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """redis_single"""
|
||||||
|
zh: """redis_single"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redis_sentinel {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a Redis Sentinel."""
|
||||||
|
zh: """使用 Redis 鉴权(哨兵模式)"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """redis_sentinel"""
|
||||||
|
zh: """redis_sentinel"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redis_cluster {
|
||||||
|
desc {
|
||||||
|
en: """Authorization using a Redis cluster."""
|
||||||
|
zh: """使用 Redis 鉴权(集群模式)"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """redis_cluster"""
|
||||||
|
zh: """redis_cluster"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd {
|
||||||
|
desc {
|
||||||
|
en: """Database query used to retrieve authorization data."""
|
||||||
|
zh: """访问控制数据查查询命令"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """cmd"""
|
||||||
|
zh: """查询命令"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#==== common field for DBs (except redis)
|
||||||
|
|
||||||
|
query {
|
||||||
|
desc {
|
||||||
|
en: """Database query used to retrieve authorization data."""
|
||||||
|
zh: """访问控制数据查询语句/查询命令"""
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
en: """query"""
|
||||||
|
zh: """查询语句"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
-behaviour(minirest_api).
|
-behaviour(minirest_api).
|
||||||
|
|
||||||
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
api_spec/0,
|
api_spec/0,
|
||||||
paths/0,
|
paths/0,
|
||||||
|
@ -47,7 +49,7 @@ schema("/authorization/cache") ->
|
||||||
'operationId' => clean_cache,
|
'operationId' => clean_cache,
|
||||||
delete =>
|
delete =>
|
||||||
#{
|
#{
|
||||||
description => <<"Clean all authorization cache in the cluster.">>,
|
description => ?DESC(authorization_cache_delete),
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
204 => <<"No Content">>,
|
204 => <<"No Content">>,
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
-include("emqx_authz.hrl").
|
-include("emqx_authz.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-import(hoconsc, [mk/1, mk/2, ref/1, ref/2, array/1, enum/1]).
|
-import(hoconsc, [mk/1, mk/2, ref/1, ref/2, array/1, enum/1]).
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ schema("/authorization/sources/built_in_database/username") ->
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Show the list of record for username">>,
|
description => ?DESC(users_username_get),
|
||||||
parameters =>
|
parameters =>
|
||||||
[
|
[
|
||||||
ref(emqx_dashboard_swagger, page),
|
ref(emqx_dashboard_swagger, page),
|
||||||
|
@ -96,7 +96,7 @@ schema("/authorization/sources/built_in_database/username") ->
|
||||||
mk(binary(), #{
|
mk(binary(), #{
|
||||||
in => query,
|
in => query,
|
||||||
required => false,
|
required => false,
|
||||||
desc => <<"Fuzzy search `username` as substring">>
|
desc => ?DESC(fuzzy_username)
|
||||||
})}
|
})}
|
||||||
],
|
],
|
||||||
responses =>
|
responses =>
|
||||||
|
@ -110,7 +110,7 @@ schema("/authorization/sources/built_in_database/username") ->
|
||||||
post =>
|
post =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Add new records for username">>,
|
description => ?DESC(users_username_post),
|
||||||
'requestBody' => swagger_with_example(
|
'requestBody' => swagger_with_example(
|
||||||
{rules_for_username, ?TYPE_ARRAY},
|
{rules_for_username, ?TYPE_ARRAY},
|
||||||
{username, ?POST_ARRAY_EXAMPLE}
|
{username, ?POST_ARRAY_EXAMPLE}
|
||||||
|
@ -130,7 +130,7 @@ schema("/authorization/sources/built_in_database/clientid") ->
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Show the list of record for clientid">>,
|
description => ?DESC(users_clientid_get),
|
||||||
parameters =>
|
parameters =>
|
||||||
[
|
[
|
||||||
ref(emqx_dashboard_swagger, page),
|
ref(emqx_dashboard_swagger, page),
|
||||||
|
@ -141,7 +141,7 @@ schema("/authorization/sources/built_in_database/clientid") ->
|
||||||
#{
|
#{
|
||||||
in => query,
|
in => query,
|
||||||
required => false,
|
required => false,
|
||||||
desc => <<"Fuzzy search `clientid` as substring">>
|
desc => ?DESC(fuzzy_clientid)
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
],
|
],
|
||||||
|
@ -156,7 +156,7 @@ schema("/authorization/sources/built_in_database/clientid") ->
|
||||||
post =>
|
post =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Add new records for clientid">>,
|
description => ?DESC(users_clientid_post),
|
||||||
'requestBody' => swagger_with_example(
|
'requestBody' => swagger_with_example(
|
||||||
{rules_for_clientid, ?TYPE_ARRAY},
|
{rules_for_clientid, ?TYPE_ARRAY},
|
||||||
{clientid, ?POST_ARRAY_EXAMPLE}
|
{clientid, ?POST_ARRAY_EXAMPLE}
|
||||||
|
@ -176,7 +176,7 @@ schema("/authorization/sources/built_in_database/username/:username") ->
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Get record info for username">>,
|
description => ?DESC(user_username_get),
|
||||||
parameters => [ref(username)],
|
parameters => [ref(username)],
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
|
@ -192,7 +192,7 @@ schema("/authorization/sources/built_in_database/username/:username") ->
|
||||||
put =>
|
put =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Set record for username">>,
|
description => ?DESC(user_username_put),
|
||||||
parameters => [ref(username)],
|
parameters => [ref(username)],
|
||||||
'requestBody' => swagger_with_example(
|
'requestBody' => swagger_with_example(
|
||||||
{rules_for_username, ?TYPE_REF},
|
{rules_for_username, ?TYPE_REF},
|
||||||
|
@ -209,7 +209,7 @@ schema("/authorization/sources/built_in_database/username/:username") ->
|
||||||
delete =>
|
delete =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Delete one record for username">>,
|
description => ?DESC(user_username_delete),
|
||||||
parameters => [ref(username)],
|
parameters => [ref(username)],
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
|
@ -229,7 +229,7 @@ schema("/authorization/sources/built_in_database/clientid/:clientid") ->
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Get record info for clientid">>,
|
description => ?DESC(user_clientid_get),
|
||||||
parameters => [ref(clientid)],
|
parameters => [ref(clientid)],
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
|
@ -245,7 +245,7 @@ schema("/authorization/sources/built_in_database/clientid/:clientid") ->
|
||||||
put =>
|
put =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Set record for clientid">>,
|
description => ?DESC(user_clientid_put),
|
||||||
parameters => [ref(clientid)],
|
parameters => [ref(clientid)],
|
||||||
'requestBody' => swagger_with_example(
|
'requestBody' => swagger_with_example(
|
||||||
{rules_for_clientid, ?TYPE_REF},
|
{rules_for_clientid, ?TYPE_REF},
|
||||||
|
@ -262,7 +262,7 @@ schema("/authorization/sources/built_in_database/clientid/:clientid") ->
|
||||||
delete =>
|
delete =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Delete one record for clientid">>,
|
description => ?DESC(user_clientid_delete),
|
||||||
parameters => [ref(clientid)],
|
parameters => [ref(clientid)],
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
|
@ -282,17 +282,14 @@ schema("/authorization/sources/built_in_database/all") ->
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Show the list of rules for all">>,
|
description => ?DESC(rules_for_all_get),
|
||||||
responses =>
|
responses =>
|
||||||
#{200 => swagger_with_example({rules, ?TYPE_REF}, {all, ?PUT_MAP_EXAMPLE})}
|
#{200 => swagger_with_example({rules, ?TYPE_REF}, {all, ?PUT_MAP_EXAMPLE})}
|
||||||
},
|
},
|
||||||
post =>
|
post =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<
|
description => ?DESC(rules_for_all_post),
|
||||||
"Create/Update the list of rules for all. "
|
|
||||||
"Set a empty list to clean up rules"
|
|
||||||
>>,
|
|
||||||
'requestBody' =>
|
'requestBody' =>
|
||||||
swagger_with_example({rules, ?TYPE_REF}, {all, ?PUT_MAP_EXAMPLE}),
|
swagger_with_example({rules, ?TYPE_REF}, {all, ?PUT_MAP_EXAMPLE}),
|
||||||
responses =>
|
responses =>
|
||||||
|
@ -310,7 +307,7 @@ schema("/authorization/sources/built_in_database/purge-all") ->
|
||||||
delete =>
|
delete =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
description => <<"Purge all records">>,
|
description => ?DESC(purge_all_delete),
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
204 => <<"Deleted">>,
|
204 => <<"Deleted">>,
|
||||||
|
@ -328,7 +325,7 @@ fields(rule_item) ->
|
||||||
string(),
|
string(),
|
||||||
#{
|
#{
|
||||||
required => true,
|
required => true,
|
||||||
desc => <<"Rule on specific topic">>,
|
desc => ?DESC(topic),
|
||||||
example => <<"test/topic/1">>
|
example => <<"test/topic/1">>
|
||||||
}
|
}
|
||||||
)},
|
)},
|
||||||
|
@ -336,7 +333,7 @@ fields(rule_item) ->
|
||||||
mk(
|
mk(
|
||||||
enum([allow, deny]),
|
enum([allow, deny]),
|
||||||
#{
|
#{
|
||||||
desc => <<"Permission">>,
|
desc => ?DESC(permission),
|
||||||
required => true,
|
required => true,
|
||||||
example => allow
|
example => allow
|
||||||
}
|
}
|
||||||
|
@ -345,9 +342,9 @@ fields(rule_item) ->
|
||||||
mk(
|
mk(
|
||||||
enum([publish, subscribe, all]),
|
enum([publish, subscribe, all]),
|
||||||
#{
|
#{
|
||||||
|
desc => ?DESC(action),
|
||||||
required => true,
|
required => true,
|
||||||
example => publish,
|
example => publish
|
||||||
desc => <<"Authorized action">>
|
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
|
@ -359,7 +356,7 @@ fields(clientid) ->
|
||||||
#{
|
#{
|
||||||
in => path,
|
in => path,
|
||||||
required => true,
|
required => true,
|
||||||
desc => <<"ClientID">>,
|
desc => ?DESC(clientid),
|
||||||
example => <<"client1">>
|
example => <<"client1">>
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
|
@ -372,7 +369,7 @@ fields(username) ->
|
||||||
#{
|
#{
|
||||||
in => path,
|
in => path,
|
||||||
required => true,
|
required => true,
|
||||||
desc => <<"Username">>,
|
desc => ?DESC(username),
|
||||||
example => <<"user1">>
|
example => <<"user1">>
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
-module(emqx_authz_api_schema).
|
-module(emqx_authz_api_schema).
|
||||||
|
|
||||||
-include("emqx_authz.hrl").
|
-include("emqx_authz.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||||
|
|
||||||
-import(hoconsc, [mk/2, enum/1]).
|
-import(hoconsc, [mk/2, enum/1]).
|
||||||
|
@ -32,14 +32,26 @@
|
||||||
%% Hocon Schema
|
%% Hocon Schema
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fields(file) ->
|
||||||
|
authz_common_fields(file) ++
|
||||||
|
[
|
||||||
|
{rules, #{
|
||||||
|
type => binary(),
|
||||||
|
required => true,
|
||||||
|
example =>
|
||||||
|
<<"{allow,{username,\"^dashboard?\"},", "subscribe,[\"$SYS/#\"]}.\n",
|
||||||
|
"{allow,{ipaddr,\"127.0.0.1\"},all,[\"$SYS/#\",\"#\"]}.">>,
|
||||||
|
desc => ?DESC(rules)
|
||||||
|
}}
|
||||||
|
];
|
||||||
fields(http_get) ->
|
fields(http_get) ->
|
||||||
[
|
[
|
||||||
{method, #{type => get, default => get, required => true}},
|
{method, #{type => get, default => get, required => true, desc => ?DESC(method)}},
|
||||||
{headers, fun headers_no_content_type/1}
|
{headers, fun headers_no_content_type/1}
|
||||||
] ++ authz_http_common_fields();
|
] ++ authz_http_common_fields();
|
||||||
fields(http_post) ->
|
fields(http_post) ->
|
||||||
[
|
[
|
||||||
{method, #{type => post, default => post, required => true}},
|
{method, #{type => post, default => post, required => true, desc => ?DESC(method)}},
|
||||||
{headers, fun headers/1}
|
{headers, fun headers/1}
|
||||||
] ++ authz_http_common_fields();
|
] ++ authz_http_common_fields();
|
||||||
fields(built_in_database) ->
|
fields(built_in_database) ->
|
||||||
|
@ -55,11 +67,11 @@ fields(mongo_sharded) ->
|
||||||
emqx_connector_mongo:fields(sharded);
|
emqx_connector_mongo:fields(sharded);
|
||||||
fields(mysql) ->
|
fields(mysql) ->
|
||||||
authz_common_fields(mysql) ++
|
authz_common_fields(mysql) ++
|
||||||
[{query, mk(binary(), #{required => true})}] ++
|
[{query, query()}] ++
|
||||||
proplists:delete(prepare_statement, emqx_connector_mysql:fields(config));
|
proplists:delete(prepare_statement, emqx_connector_mysql:fields(config));
|
||||||
fields(postgresql) ->
|
fields(postgresql) ->
|
||||||
authz_common_fields(postgresql) ++
|
authz_common_fields(postgresql) ++
|
||||||
[{query, mk(binary(), #{required => true})}] ++
|
[{query, query()}] ++
|
||||||
proplists:delete(prepare_statement, emqx_connector_pgsql:fields(config));
|
proplists:delete(prepare_statement, emqx_connector_pgsql:fields(config));
|
||||||
fields(redis_single) ->
|
fields(redis_single) ->
|
||||||
authz_redis_common_fields() ++
|
authz_redis_common_fields() ++
|
||||||
|
@ -70,24 +82,13 @@ fields(redis_sentinel) ->
|
||||||
fields(redis_cluster) ->
|
fields(redis_cluster) ->
|
||||||
authz_redis_common_fields() ++
|
authz_redis_common_fields() ++
|
||||||
emqx_connector_redis:fields(cluster);
|
emqx_connector_redis:fields(cluster);
|
||||||
fields(file) ->
|
|
||||||
authz_common_fields(file) ++
|
|
||||||
[
|
|
||||||
{rules, #{
|
|
||||||
type => binary(),
|
|
||||||
required => true,
|
|
||||||
example =>
|
|
||||||
<<"{allow,{username,\"^dashboard?\"},", "subscribe,[\"$SYS/#\"]}.\n",
|
|
||||||
"{allow,{ipaddr,\"127.0.0.1\"},all,[\"$SYS/#\",\"#\"]}.">>
|
|
||||||
}}
|
|
||||||
];
|
|
||||||
fields(position) ->
|
fields(position) ->
|
||||||
[
|
[
|
||||||
{position,
|
{position,
|
||||||
mk(
|
mk(
|
||||||
string(),
|
string(),
|
||||||
#{
|
#{
|
||||||
desc => <<"Where to place the source">>,
|
desc => ?DESC(position),
|
||||||
required => true,
|
required => true,
|
||||||
in => body
|
in => body
|
||||||
}
|
}
|
||||||
|
@ -102,7 +103,8 @@ authz_http_common_fields() ->
|
||||||
[
|
[
|
||||||
{url, fun url/1},
|
{url, fun url/1},
|
||||||
{body, map([{fuzzy, term(), binary()}])},
|
{body, map([{fuzzy, term(), binary()}])},
|
||||||
{request_timeout, mk_duration("Request timeout", #{default => "30s"})}
|
{request_timeout,
|
||||||
|
mk_duration("Request timeout", #{default => "30s", desc => ?DESC(request_timeout)})}
|
||||||
] ++
|
] ++
|
||||||
maps:to_list(
|
maps:to_list(
|
||||||
maps:without(
|
maps:without(
|
||||||
|
@ -117,12 +119,13 @@ authz_http_common_fields() ->
|
||||||
url(type) -> binary();
|
url(type) -> binary();
|
||||||
url(validator) -> [?NOT_EMPTY("the value of the field 'url' cannot be empty")];
|
url(validator) -> [?NOT_EMPTY("the value of the field 'url' cannot be empty")];
|
||||||
url(required) -> true;
|
url(required) -> true;
|
||||||
|
url(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
url(_) -> undefined.
|
url(_) -> undefined.
|
||||||
|
|
||||||
headers(type) ->
|
headers(type) ->
|
||||||
map();
|
map();
|
||||||
headers(desc) ->
|
headers(desc) ->
|
||||||
"List of HTTP headers.";
|
?DESC(?FUNCTION_NAME);
|
||||||
headers(converter) ->
|
headers(converter) ->
|
||||||
fun(Headers) ->
|
fun(Headers) ->
|
||||||
maps:merge(default_headers(), transform_header_name(Headers))
|
maps:merge(default_headers(), transform_header_name(Headers))
|
||||||
|
@ -135,7 +138,7 @@ headers(_) ->
|
||||||
headers_no_content_type(type) ->
|
headers_no_content_type(type) ->
|
||||||
map();
|
map();
|
||||||
headers_no_content_type(desc) ->
|
headers_no_content_type(desc) ->
|
||||||
"List of HTTP headers.";
|
?DESC(?FUNCTION_NAME);
|
||||||
headers_no_content_type(converter) ->
|
headers_no_content_type(converter) ->
|
||||||
fun(Headers) ->
|
fun(Headers) ->
|
||||||
maps:merge(default_headers_no_content_type(), transform_header_name(Headers))
|
maps:merge(default_headers_no_content_type(), transform_header_name(Headers))
|
||||||
|
@ -182,17 +185,14 @@ authz_mongo_common_fields() ->
|
||||||
].
|
].
|
||||||
|
|
||||||
collection(type) -> binary();
|
collection(type) -> binary();
|
||||||
collection(desc) -> "Collection used to store authentication data.";
|
collection(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
collection(required) -> true;
|
collection(required) -> true;
|
||||||
collection(_) -> undefined.
|
collection(_) -> undefined.
|
||||||
|
|
||||||
selector(type) ->
|
selector(type) ->
|
||||||
map();
|
map();
|
||||||
selector(desc) ->
|
selector(desc) ->
|
||||||
"Statement that is executed during the authentication process. "
|
?DESC(?FUNCTION_NAME);
|
||||||
"Commands can support following wildcards:\n"
|
|
||||||
" - `${username}`: substituted with client's username\n"
|
|
||||||
" - `${clientid}`: substituted with the clientid";
|
|
||||||
selector(_) ->
|
selector(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
|
@ -205,6 +205,7 @@ authz_redis_common_fields() ->
|
||||||
{cmd,
|
{cmd,
|
||||||
mk(binary(), #{
|
mk(binary(), #{
|
||||||
required => true,
|
required => true,
|
||||||
|
desc => ?DESC(cmd),
|
||||||
example => <<"HGETALL mqtt_authz">>
|
example => <<"HGETALL mqtt_authz">>
|
||||||
})}
|
})}
|
||||||
].
|
].
|
||||||
|
@ -216,18 +217,35 @@ authz_common_fields(Type) when is_atom(Type) ->
|
||||||
[
|
[
|
||||||
{enable, fun enable/1},
|
{enable, fun enable/1},
|
||||||
{type, #{
|
{type, #{
|
||||||
type => enum([Type]),
|
type => Type,
|
||||||
default => Type,
|
default => Type,
|
||||||
required => true,
|
required => true,
|
||||||
|
desc => ?DESC(type),
|
||||||
in => body
|
in => body
|
||||||
}}
|
}}
|
||||||
].
|
].
|
||||||
|
|
||||||
enable(type) -> boolean();
|
enable(type) -> boolean();
|
||||||
enable(default) -> true;
|
enable(default) -> true;
|
||||||
enable(desc) -> "Set to <code>false</code> to disable this auth provider";
|
enable(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
enable(_) -> undefined.
|
enable(_) -> undefined.
|
||||||
|
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
%% Authz DB query
|
||||||
|
|
||||||
|
query() ->
|
||||||
|
#{
|
||||||
|
type => binary(),
|
||||||
|
desc => ?DESC(query),
|
||||||
|
required => true,
|
||||||
|
validator => fun(S) ->
|
||||||
|
case size(S) > 0 of
|
||||||
|
true -> ok;
|
||||||
|
_ -> {error, "Request query"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}.
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Internal funcs
|
%% Internal funcs
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
-behaviour(minirest_api).
|
-behaviour(minirest_api).
|
||||||
|
|
||||||
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-import(hoconsc, [mk/1, ref/2]).
|
-import(hoconsc, [mk/1, ref/2]).
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
@ -45,13 +47,13 @@ schema("/authorization/settings") ->
|
||||||
'operationId' => settings,
|
'operationId' => settings,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
description => <<"Get authorization settings">>,
|
description => ?DESC(authorization_settings_get),
|
||||||
responses =>
|
responses =>
|
||||||
#{200 => ref_authz_schema()}
|
#{200 => ref_authz_schema()}
|
||||||
},
|
},
|
||||||
put =>
|
put =>
|
||||||
#{
|
#{
|
||||||
description => <<"Update authorization settings">>,
|
description => ?DESC(authorization_settings_put),
|
||||||
'requestBody' => ref_authz_schema(),
|
'requestBody' => ref_authz_schema(),
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
|
|
||||||
-behaviour(minirest_api).
|
-behaviour(minirest_api).
|
||||||
|
|
||||||
-include_lib("typerefl/include/types.hrl").
|
|
||||||
-include("emqx_authz.hrl").
|
-include("emqx_authz.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
-import(hoconsc, [mk/1, mk/2, ref/2, array/1, enum/1]).
|
-import(hoconsc, [mk/1, mk/2, ref/2, array/1, enum/1]).
|
||||||
|
|
||||||
|
@ -63,27 +63,26 @@ paths() ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Schema for each URI
|
%% Schema for each URI
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
schema("/authorization/sources") ->
|
schema("/authorization/sources") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => sources,
|
'operationId' => sources,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
description => <<"List all authorization sources">>,
|
description => ?DESC(authorization_sources_get),
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
200 => mk(
|
200 => mk(
|
||||||
array(hoconsc:union(authz_sources_type_refs())),
|
array(hoconsc:union(authz_sources_type_refs())),
|
||||||
#{desc => <<"Authorization source">>}
|
#{desc => ?DESC(sources)}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
post =>
|
post =>
|
||||||
#{
|
#{
|
||||||
description => <<"Add a new source">>,
|
description => ?DESC(authorization_sources_post),
|
||||||
'requestBody' => mk(
|
'requestBody' => mk(
|
||||||
hoconsc:union(authz_sources_type_refs()),
|
hoconsc:union(authz_sources_type_refs()),
|
||||||
#{desc => <<"Source config">>}
|
#{desc => ?DESC(source_config)}
|
||||||
),
|
),
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
|
@ -100,20 +99,20 @@ schema("/authorization/sources/:type") ->
|
||||||
'operationId' => source,
|
'operationId' => source,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
description => <<"Get a authorization source">>,
|
description => ?DESC(authorization_sources_type_get),
|
||||||
parameters => parameters_field(),
|
parameters => parameters_field(),
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
200 => mk(
|
200 => mk(
|
||||||
hoconsc:union(authz_sources_type_refs()),
|
hoconsc:union(authz_sources_type_refs()),
|
||||||
#{desc => <<"Authorization source">>}
|
#{desc => ?DESC(source)}
|
||||||
),
|
),
|
||||||
404 => emqx_dashboard_swagger:error_codes([?NOT_FOUND], <<"Not Found">>)
|
404 => emqx_dashboard_swagger:error_codes([?NOT_FOUND], <<"Not Found">>)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
put =>
|
put =>
|
||||||
#{
|
#{
|
||||||
description => <<"Update source">>,
|
description => ?DESC(authorization_sources_type_put),
|
||||||
parameters => parameters_field(),
|
parameters => parameters_field(),
|
||||||
'requestBody' => mk(hoconsc:union(authz_sources_type_refs())),
|
'requestBody' => mk(hoconsc:union(authz_sources_type_refs())),
|
||||||
responses =>
|
responses =>
|
||||||
|
@ -124,7 +123,7 @@ schema("/authorization/sources/:type") ->
|
||||||
},
|
},
|
||||||
delete =>
|
delete =>
|
||||||
#{
|
#{
|
||||||
description => <<"Delete source">>,
|
description => ?DESC(authorization_sources_type_delete),
|
||||||
parameters => parameters_field(),
|
parameters => parameters_field(),
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
|
@ -138,7 +137,7 @@ schema("/authorization/sources/:type/status") ->
|
||||||
'operationId' => source_status,
|
'operationId' => source_status,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
description => <<"Get a authorization source">>,
|
description => ?DESC(authorization_sources_type_status_get),
|
||||||
parameters => parameters_field(),
|
parameters => parameters_field(),
|
||||||
responses =>
|
responses =>
|
||||||
#{
|
#{
|
||||||
|
@ -158,7 +157,7 @@ schema("/authorization/sources/:type/move") ->
|
||||||
'operationId' => move_source,
|
'operationId' => move_source,
|
||||||
post =>
|
post =>
|
||||||
#{
|
#{
|
||||||
description => <<"Change the order of sources">>,
|
description => ?DESC(authorization_sources_type_move_post),
|
||||||
parameters => parameters_field(),
|
parameters => parameters_field(),
|
||||||
'requestBody' =>
|
'requestBody' =>
|
||||||
emqx_dashboard_swagger:schema_with_examples(
|
emqx_dashboard_swagger:schema_with_examples(
|
||||||
|
@ -508,7 +507,7 @@ parameters_field() ->
|
||||||
{type,
|
{type,
|
||||||
mk(
|
mk(
|
||||||
enum(?API_SCHEMA_MODULE:authz_sources_types(simple)),
|
enum(?API_SCHEMA_MODULE:authz_sources_types(simple)),
|
||||||
#{in => path, desc => <<"Authorization type">>}
|
#{in => path, desc => ?DESC(source_type)}
|
||||||
)}
|
)}
|
||||||
].
|
].
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ authorize(
|
||||||
} = Client,
|
} = Client,
|
||||||
PubSub,
|
PubSub,
|
||||||
Topic,
|
Topic,
|
||||||
#{type := 'built_in_database'}
|
#{type := built_in_database}
|
||||||
) ->
|
) ->
|
||||||
Rules =
|
Rules =
|
||||||
case mnesia:dirty_read(?ACL_TABLE, {?ACL_TABLE_CLIENTID, Clientid}) of
|
case mnesia:dirty_read(?ACL_TABLE, {?ACL_TABLE_CLIENTID, Clientid}) of
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
-module(emqx_authz_schema).
|
-module(emqx_authz_schema).
|
||||||
|
|
||||||
-include("emqx_authz.hrl").
|
-include("emqx_authz.hrl").
|
||||||
-include_lib("typerefl/include/types.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||||
|
|
||||||
-reflect_type([
|
-reflect_type([
|
||||||
|
@ -71,134 +71,104 @@ fields("authorization") ->
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
default => [],
|
default => [],
|
||||||
desc =>
|
desc => ?DESC(sources)
|
||||||
"\n"
|
|
||||||
"Authorization data sources.<br>\n"
|
|
||||||
"An array of authorization (ACL) data providers.\n"
|
|
||||||
"It is designed as an array, not a hash-map, so the sources can be\n"
|
|
||||||
"ordered to form a chain of access controls.<br>\n"
|
|
||||||
"\n"
|
|
||||||
"When authorizing a 'publish' or 'subscribe' action, the configured\n"
|
|
||||||
"sources are checked in order. When checking an ACL source,\n"
|
|
||||||
"in case the client (identified by username or client ID) is not found,\n"
|
|
||||||
"it moves on to the next source. And it stops immediately\n"
|
|
||||||
"once an 'allow' or 'deny' decision is returned.<br>\n"
|
|
||||||
"\n"
|
|
||||||
"If the client is not found in any of the sources,\n"
|
|
||||||
"the default action configured in 'authorization.no_match' is applied.<br>\n"
|
|
||||||
"\n"
|
|
||||||
"NOTE:\n"
|
|
||||||
"The source elements are identified by their 'type'.\n"
|
|
||||||
"It is NOT allowed to configure two or more sources of the same type.\n"
|
|
||||||
}}
|
}}
|
||||||
];
|
];
|
||||||
fields(file) ->
|
fields(file) ->
|
||||||
[
|
authz_common_fields(file) ++
|
||||||
{type, #{type => file, required => true, desc => "Backend type."}},
|
[{path, #{type => string(), required => true, desc => ?DESC(path)}}];
|
||||||
{enable, #{
|
|
||||||
type => boolean(),
|
|
||||||
default => true,
|
|
||||||
desc => "Enable this backend."
|
|
||||||
}},
|
|
||||||
{path, #{
|
|
||||||
type => string(),
|
|
||||||
required => true,
|
|
||||||
desc =>
|
|
||||||
"\n"
|
|
||||||
"Path to the file which contains the ACL rules.<br>\n"
|
|
||||||
"If the file provisioned before starting EMQX node,\n"
|
|
||||||
"it can be placed anywhere as long as EMQX has read access to it.\n"
|
|
||||||
"\n"
|
|
||||||
"In case the rule-set is created from EMQX dashboard or management API,\n"
|
|
||||||
"the file will be placed in `authz` subdirectory inside EMQX's `data_dir`,\n"
|
|
||||||
"and the new rules will override all rules from the old config file.\n"
|
|
||||||
}}
|
|
||||||
];
|
|
||||||
fields(http_get) ->
|
fields(http_get) ->
|
||||||
|
authz_common_fields(http) ++
|
||||||
|
http_common_fields() ++
|
||||||
[
|
[
|
||||||
{method, #{type => get, default => get, required => true, desc => "HTTP method."}},
|
{method, #{type => get, default => get, required => true, desc => ?DESC(method)}},
|
||||||
{headers, fun headers_no_content_type/1}
|
{headers, fun headers_no_content_type/1}
|
||||||
] ++ http_common_fields();
|
|
||||||
fields(http_post) ->
|
|
||||||
[
|
|
||||||
{method, #{type => post, default => post, required => true, desc => "HTTP method."}},
|
|
||||||
{headers, fun headers/1}
|
|
||||||
] ++ http_common_fields();
|
|
||||||
fields(mnesia) ->
|
|
||||||
[
|
|
||||||
{type, #{type => 'built_in_database', required => true, desc => "Backend type."}},
|
|
||||||
{enable, #{
|
|
||||||
type => boolean(),
|
|
||||||
default => true,
|
|
||||||
desc => "Enable this backend."
|
|
||||||
}}
|
|
||||||
];
|
];
|
||||||
|
fields(http_post) ->
|
||||||
|
authz_common_fields(http) ++
|
||||||
|
http_common_fields() ++
|
||||||
|
[
|
||||||
|
{method, #{type => post, default => post, required => true, desc => ?DESC(method)}},
|
||||||
|
{headers, fun headers/1}
|
||||||
|
];
|
||||||
|
fields(mnesia) ->
|
||||||
|
authz_common_fields(built_in_database);
|
||||||
fields(mongo_single) ->
|
fields(mongo_single) ->
|
||||||
mongo_common_fields() ++ emqx_connector_mongo:fields(single);
|
authz_common_fields(mongodb) ++
|
||||||
|
mongo_common_fields() ++
|
||||||
|
emqx_connector_mongo:fields(single);
|
||||||
fields(mongo_rs) ->
|
fields(mongo_rs) ->
|
||||||
mongo_common_fields() ++ emqx_connector_mongo:fields(rs);
|
authz_common_fields(mongodb) ++
|
||||||
|
mongo_common_fields() ++
|
||||||
|
emqx_connector_mongo:fields(rs);
|
||||||
fields(mongo_sharded) ->
|
fields(mongo_sharded) ->
|
||||||
mongo_common_fields() ++ emqx_connector_mongo:fields(sharded);
|
authz_common_fields(mongodb) ++
|
||||||
|
mongo_common_fields() ++
|
||||||
|
emqx_connector_mongo:fields(sharded);
|
||||||
fields(mysql) ->
|
fields(mysql) ->
|
||||||
|
authz_common_fields(mysql) ++
|
||||||
connector_fields(mysql) ++
|
connector_fields(mysql) ++
|
||||||
[{query, query()}];
|
[{query, query()}];
|
||||||
fields(postgresql) ->
|
fields(postgresql) ->
|
||||||
[
|
authz_common_fields(postgresql) ++
|
||||||
{query, query()},
|
emqx_connector_pgsql:fields(config) ++
|
||||||
{type, #{type => postgresql, required => true, desc => "Backend type."}},
|
[{query, query()}];
|
||||||
{enable, #{
|
|
||||||
type => boolean(),
|
|
||||||
desc => "Enable this backend.",
|
|
||||||
default => true
|
|
||||||
}}
|
|
||||||
] ++ emqx_connector_pgsql:fields(config);
|
|
||||||
fields(redis_single) ->
|
fields(redis_single) ->
|
||||||
|
authz_common_fields(redis) ++
|
||||||
connector_fields(redis, single) ++
|
connector_fields(redis, single) ++
|
||||||
[{cmd, query()}];
|
[{cmd, cmd()}];
|
||||||
fields(redis_sentinel) ->
|
fields(redis_sentinel) ->
|
||||||
|
authz_common_fields(redis) ++
|
||||||
connector_fields(redis, sentinel) ++
|
connector_fields(redis, sentinel) ++
|
||||||
[{cmd, query()}];
|
[{cmd, cmd()}];
|
||||||
fields(redis_cluster) ->
|
fields(redis_cluster) ->
|
||||||
|
authz_common_fields(redis) ++
|
||||||
connector_fields(redis, cluster) ++
|
connector_fields(redis, cluster) ++
|
||||||
[{cmd, query()}].
|
[{cmd, cmd()}].
|
||||||
|
|
||||||
desc("authorization") ->
|
desc(?CONF_NS) ->
|
||||||
"Configuration related to the client authorization.";
|
?DESC(?CONF_NS);
|
||||||
desc(file) ->
|
desc(file) ->
|
||||||
"Authorization using a static file.";
|
?DESC(file);
|
||||||
desc(http_get) ->
|
desc(http_get) ->
|
||||||
"Authorization using an external HTTP server (via GET requests).";
|
?DESC(http_get);
|
||||||
desc(http_post) ->
|
desc(http_post) ->
|
||||||
"Authorization using an external HTTP server (via POST requests).";
|
?DESC(http_post);
|
||||||
desc(mnesia) ->
|
desc(mnesia) ->
|
||||||
"Authorization using a built-in database (mnesia).";
|
?DESC(mnesia);
|
||||||
desc(mongo_single) ->
|
desc(mongo_single) ->
|
||||||
"Authorization using a single MongoDB instance.";
|
?DESC(mongo_single);
|
||||||
desc(mongo_rs) ->
|
desc(mongo_rs) ->
|
||||||
"Authorization using a MongoDB replica set.";
|
?DESC(mongo_rs);
|
||||||
desc(mongo_sharded) ->
|
desc(mongo_sharded) ->
|
||||||
"Authorization using a sharded MongoDB cluster.";
|
?DESC(mongo_sharded);
|
||||||
desc(mysql) ->
|
desc(mysql) ->
|
||||||
"Authorization using a MySQL database.";
|
?DESC(mysql);
|
||||||
desc(postgresql) ->
|
desc(postgresql) ->
|
||||||
"Authorization using a PostgreSQL database.";
|
?DESC(postgresql);
|
||||||
desc(redis_single) ->
|
desc(redis_single) ->
|
||||||
"Authorization using a single Redis instance.";
|
?DESC(redis_single);
|
||||||
desc(redis_sentinel) ->
|
desc(redis_sentinel) ->
|
||||||
"Authorization using a Redis Sentinel.";
|
?DESC(redis_sentinel);
|
||||||
desc(redis_cluster) ->
|
desc(redis_cluster) ->
|
||||||
"Authorization using a Redis cluster.";
|
?DESC(redis_cluster);
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
|
authz_common_fields(Type) ->
|
||||||
|
[
|
||||||
|
{type, #{type => Type, required => true, desc => ?DESC(type)}},
|
||||||
|
{enable, #{type => boolean(), default => true, desc => ?DESC(enable)}}
|
||||||
|
].
|
||||||
|
|
||||||
http_common_fields() ->
|
http_common_fields() ->
|
||||||
[
|
[
|
||||||
{url, fun url/1},
|
{url, fun url/1},
|
||||||
{request_timeout,
|
{request_timeout,
|
||||||
emqx_schema:mk_duration("Request timeout", #{
|
emqx_schema:mk_duration("Request timeout", #{
|
||||||
default => "30s", desc => "Request timeout."
|
default => "30s", desc => ?DESC(request_timeout)
|
||||||
})},
|
})},
|
||||||
{body, #{type => map(), required => false, desc => "HTTP request body."}}
|
{body, #{type => map(), required => false, desc => ?DESC(body)}}
|
||||||
] ++
|
] ++
|
||||||
maps:to_list(
|
maps:to_list(
|
||||||
maps:without(
|
maps:without(
|
||||||
|
@ -215,18 +185,12 @@ mongo_common_fields() ->
|
||||||
{collection, #{
|
{collection, #{
|
||||||
type => atom(),
|
type => atom(),
|
||||||
required => true,
|
required => true,
|
||||||
desc => "`MongoDB` collection containing the authorization data."
|
desc => ?DESC(collection)
|
||||||
}},
|
}},
|
||||||
{selector, #{
|
{selector, #{
|
||||||
type => map(),
|
type => map(),
|
||||||
required => true,
|
required => true,
|
||||||
desc => "MQL query used to select the authorization record."
|
desc => ?DESC(selector)
|
||||||
}},
|
|
||||||
{type, #{type => mongodb, required => true, desc => "Database backend."}},
|
|
||||||
{enable, #{
|
|
||||||
type => boolean(),
|
|
||||||
default => true,
|
|
||||||
desc => "Enable or disable the backend."
|
|
||||||
}}
|
}}
|
||||||
].
|
].
|
||||||
|
|
||||||
|
@ -238,7 +202,7 @@ validations() ->
|
||||||
headers(type) ->
|
headers(type) ->
|
||||||
list({binary(), binary()});
|
list({binary(), binary()});
|
||||||
headers(desc) ->
|
headers(desc) ->
|
||||||
"List of HTTP headers.";
|
?DESC(?FUNCTION_NAME);
|
||||||
headers(converter) ->
|
headers(converter) ->
|
||||||
fun(Headers) ->
|
fun(Headers) ->
|
||||||
maps:to_list(maps:merge(default_headers(), transform_header_name(Headers)))
|
maps:to_list(maps:merge(default_headers(), transform_header_name(Headers)))
|
||||||
|
@ -251,7 +215,7 @@ headers(_) ->
|
||||||
headers_no_content_type(type) ->
|
headers_no_content_type(type) ->
|
||||||
list({binary(), binary()});
|
list({binary(), binary()});
|
||||||
headers_no_content_type(desc) ->
|
headers_no_content_type(desc) ->
|
||||||
"List of HTTP headers.";
|
?DESC(?FUNCTION_NAME);
|
||||||
headers_no_content_type(converter) ->
|
headers_no_content_type(converter) ->
|
||||||
fun(Headers) ->
|
fun(Headers) ->
|
||||||
maps:to_list(maps:merge(default_headers_no_content_type(), transform_header_name(Headers)))
|
maps:to_list(maps:merge(default_headers_no_content_type(), transform_header_name(Headers)))
|
||||||
|
@ -269,7 +233,7 @@ headers_no_content_type(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
url(type) -> binary();
|
url(type) -> binary();
|
||||||
url(desc) -> "URL of the auth server.";
|
url(desc) -> ?DESC(?FUNCTION_NAME);
|
||||||
url(validator) -> [?NOT_EMPTY("the value of the field 'url' cannot be empty")];
|
url(validator) -> [?NOT_EMPTY("the value of the field 'url' cannot be empty")];
|
||||||
url(required) -> true;
|
url(required) -> true;
|
||||||
url(_) -> undefined.
|
url(_) -> undefined.
|
||||||
|
@ -328,7 +292,20 @@ union_array(Item) when is_list(Item) ->
|
||||||
query() ->
|
query() ->
|
||||||
#{
|
#{
|
||||||
type => binary(),
|
type => binary(),
|
||||||
desc => "Database query used to retrieve authorization data.",
|
desc => ?DESC(query),
|
||||||
|
required => true,
|
||||||
|
validator => fun(S) ->
|
||||||
|
case size(S) > 0 of
|
||||||
|
true -> ok;
|
||||||
|
_ -> {error, "Request query"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}.
|
||||||
|
|
||||||
|
cmd() ->
|
||||||
|
#{
|
||||||
|
type => binary(),
|
||||||
|
desc => ?DESC(cmd),
|
||||||
required => true,
|
required => true,
|
||||||
validator => fun(S) ->
|
validator => fun(S) ->
|
||||||
case size(S) > 0 of
|
case size(S) > 0 of
|
||||||
|
@ -351,14 +328,7 @@ connector_fields(DB, Fields) ->
|
||||||
error:Reason ->
|
error:Reason ->
|
||||||
erlang:error(Reason)
|
erlang:error(Reason)
|
||||||
end,
|
end,
|
||||||
[
|
erlang:apply(Mod, fields, [Fields]).
|
||||||
{type, #{type => DB, desc => "Database backend."}},
|
|
||||||
{enable, #{
|
|
||||||
type => boolean(),
|
|
||||||
default => true,
|
|
||||||
desc => "Enable or disable the backend."
|
|
||||||
}}
|
|
||||||
] ++ erlang:apply(Mod, fields, [Fields]).
|
|
||||||
|
|
||||||
to_list(A) when is_atom(A) ->
|
to_list(A) when is_atom(A) ->
|
||||||
atom_to_list(A);
|
atom_to_list(A);
|
||||||
|
|
Loading…
Reference in New Issue