docs: authz i18n zh_CN support
This commit is contained in:
parent
86c38d283d
commit
11d2ae117c
|
@ -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).
|
||||
|
||||
-include_lib("hocon/include/hoconsc.hrl").
|
||||
|
||||
-export([
|
||||
api_spec/0,
|
||||
paths/0,
|
||||
|
@ -47,7 +49,7 @@ schema("/authorization/cache") ->
|
|||
'operationId' => clean_cache,
|
||||
delete =>
|
||||
#{
|
||||
description => <<"Clean all authorization cache in the cluster.">>,
|
||||
description => ?DESC(authorization_cache_delete),
|
||||
responses =>
|
||||
#{
|
||||
204 => <<"No Content">>,
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
-include("emqx_authz.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]).
|
||||
|
||||
|
@ -87,7 +87,7 @@ schema("/authorization/sources/built_in_database/username") ->
|
|||
get =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Show the list of record for username">>,
|
||||
description => ?DESC(users_username_get),
|
||||
parameters =>
|
||||
[
|
||||
ref(emqx_dashboard_swagger, page),
|
||||
|
@ -96,7 +96,7 @@ schema("/authorization/sources/built_in_database/username") ->
|
|||
mk(binary(), #{
|
||||
in => query,
|
||||
required => false,
|
||||
desc => <<"Fuzzy search `username` as substring">>
|
||||
desc => ?DESC(fuzzy_username)
|
||||
})}
|
||||
],
|
||||
responses =>
|
||||
|
@ -110,7 +110,7 @@ schema("/authorization/sources/built_in_database/username") ->
|
|||
post =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Add new records for username">>,
|
||||
description => ?DESC(users_username_post),
|
||||
'requestBody' => swagger_with_example(
|
||||
{rules_for_username, ?TYPE_ARRAY},
|
||||
{username, ?POST_ARRAY_EXAMPLE}
|
||||
|
@ -130,7 +130,7 @@ schema("/authorization/sources/built_in_database/clientid") ->
|
|||
get =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Show the list of record for clientid">>,
|
||||
description => ?DESC(users_clientid_get),
|
||||
parameters =>
|
||||
[
|
||||
ref(emqx_dashboard_swagger, page),
|
||||
|
@ -141,7 +141,7 @@ schema("/authorization/sources/built_in_database/clientid") ->
|
|||
#{
|
||||
in => query,
|
||||
required => false,
|
||||
desc => <<"Fuzzy search `clientid` as substring">>
|
||||
desc => ?DESC(fuzzy_clientid)
|
||||
}
|
||||
)}
|
||||
],
|
||||
|
@ -156,7 +156,7 @@ schema("/authorization/sources/built_in_database/clientid") ->
|
|||
post =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Add new records for clientid">>,
|
||||
description => ?DESC(users_clientid_post),
|
||||
'requestBody' => swagger_with_example(
|
||||
{rules_for_clientid, ?TYPE_ARRAY},
|
||||
{clientid, ?POST_ARRAY_EXAMPLE}
|
||||
|
@ -176,7 +176,7 @@ schema("/authorization/sources/built_in_database/username/:username") ->
|
|||
get =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Get record info for username">>,
|
||||
description => ?DESC(user_username_get),
|
||||
parameters => [ref(username)],
|
||||
responses =>
|
||||
#{
|
||||
|
@ -192,7 +192,7 @@ schema("/authorization/sources/built_in_database/username/:username") ->
|
|||
put =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Set record for username">>,
|
||||
description => ?DESC(user_username_put),
|
||||
parameters => [ref(username)],
|
||||
'requestBody' => swagger_with_example(
|
||||
{rules_for_username, ?TYPE_REF},
|
||||
|
@ -209,7 +209,7 @@ schema("/authorization/sources/built_in_database/username/:username") ->
|
|||
delete =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Delete one record for username">>,
|
||||
description => ?DESC(user_username_delete),
|
||||
parameters => [ref(username)],
|
||||
responses =>
|
||||
#{
|
||||
|
@ -229,7 +229,7 @@ schema("/authorization/sources/built_in_database/clientid/:clientid") ->
|
|||
get =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Get record info for clientid">>,
|
||||
description => ?DESC(user_clientid_get),
|
||||
parameters => [ref(clientid)],
|
||||
responses =>
|
||||
#{
|
||||
|
@ -245,7 +245,7 @@ schema("/authorization/sources/built_in_database/clientid/:clientid") ->
|
|||
put =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Set record for clientid">>,
|
||||
description => ?DESC(user_clientid_put),
|
||||
parameters => [ref(clientid)],
|
||||
'requestBody' => swagger_with_example(
|
||||
{rules_for_clientid, ?TYPE_REF},
|
||||
|
@ -262,7 +262,7 @@ schema("/authorization/sources/built_in_database/clientid/:clientid") ->
|
|||
delete =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Delete one record for clientid">>,
|
||||
description => ?DESC(user_clientid_delete),
|
||||
parameters => [ref(clientid)],
|
||||
responses =>
|
||||
#{
|
||||
|
@ -282,17 +282,14 @@ schema("/authorization/sources/built_in_database/all") ->
|
|||
get =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Show the list of rules for all">>,
|
||||
description => ?DESC(rules_for_all_get),
|
||||
responses =>
|
||||
#{200 => swagger_with_example({rules, ?TYPE_REF}, {all, ?PUT_MAP_EXAMPLE})}
|
||||
},
|
||||
post =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<
|
||||
"Create/Update the list of rules for all. "
|
||||
"Set a empty list to clean up rules"
|
||||
>>,
|
||||
description => ?DESC(rules_for_all_post),
|
||||
'requestBody' =>
|
||||
swagger_with_example({rules, ?TYPE_REF}, {all, ?PUT_MAP_EXAMPLE}),
|
||||
responses =>
|
||||
|
@ -310,7 +307,7 @@ schema("/authorization/sources/built_in_database/purge-all") ->
|
|||
delete =>
|
||||
#{
|
||||
tags => [<<"authorization">>],
|
||||
description => <<"Purge all records">>,
|
||||
description => ?DESC(purge_all_delete),
|
||||
responses =>
|
||||
#{
|
||||
204 => <<"Deleted">>,
|
||||
|
@ -328,7 +325,7 @@ fields(rule_item) ->
|
|||
string(),
|
||||
#{
|
||||
required => true,
|
||||
desc => <<"Rule on specific topic">>,
|
||||
desc => ?DESC(topic),
|
||||
example => <<"test/topic/1">>
|
||||
}
|
||||
)},
|
||||
|
@ -336,7 +333,7 @@ fields(rule_item) ->
|
|||
mk(
|
||||
enum([allow, deny]),
|
||||
#{
|
||||
desc => <<"Permission">>,
|
||||
desc => ?DESC(permission),
|
||||
required => true,
|
||||
example => allow
|
||||
}
|
||||
|
@ -345,9 +342,9 @@ fields(rule_item) ->
|
|||
mk(
|
||||
enum([publish, subscribe, all]),
|
||||
#{
|
||||
desc => ?DESC(action),
|
||||
required => true,
|
||||
example => publish,
|
||||
desc => <<"Authorized action">>
|
||||
example => publish
|
||||
}
|
||||
)}
|
||||
];
|
||||
|
@ -359,7 +356,7 @@ fields(clientid) ->
|
|||
#{
|
||||
in => path,
|
||||
required => true,
|
||||
desc => <<"ClientID">>,
|
||||
desc => ?DESC(clientid),
|
||||
example => <<"client1">>
|
||||
}
|
||||
)}
|
||||
|
@ -372,7 +369,7 @@ fields(username) ->
|
|||
#{
|
||||
in => path,
|
||||
required => true,
|
||||
desc => <<"Username">>,
|
||||
desc => ?DESC(username),
|
||||
example => <<"user1">>
|
||||
}
|
||||
)}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
-module(emqx_authz_api_schema).
|
||||
|
||||
-include("emqx_authz.hrl").
|
||||
-include_lib("typerefl/include/types.hrl").
|
||||
-include_lib("hocon/include/hoconsc.hrl").
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
|
||||
-import(hoconsc, [mk/2, enum/1]).
|
||||
|
@ -32,14 +32,26 @@
|
|||
%% 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) ->
|
||||
[
|
||||
{method, #{type => get, default => get, required => true}},
|
||||
{method, #{type => get, default => get, required => true, desc => ?DESC(method)}},
|
||||
{headers, fun headers_no_content_type/1}
|
||||
] ++ authz_http_common_fields();
|
||||
fields(http_post) ->
|
||||
[
|
||||
{method, #{type => post, default => post, required => true}},
|
||||
{method, #{type => post, default => post, required => true, desc => ?DESC(method)}},
|
||||
{headers, fun headers/1}
|
||||
] ++ authz_http_common_fields();
|
||||
fields(built_in_database) ->
|
||||
|
@ -55,11 +67,11 @@ fields(mongo_sharded) ->
|
|||
emqx_connector_mongo:fields(sharded);
|
||||
fields(mysql) ->
|
||||
authz_common_fields(mysql) ++
|
||||
[{query, mk(binary(), #{required => true})}] ++
|
||||
[{query, query()}] ++
|
||||
proplists:delete(prepare_statement, emqx_connector_mysql:fields(config));
|
||||
fields(postgresql) ->
|
||||
authz_common_fields(postgresql) ++
|
||||
[{query, mk(binary(), #{required => true})}] ++
|
||||
[{query, query()}] ++
|
||||
proplists:delete(prepare_statement, emqx_connector_pgsql:fields(config));
|
||||
fields(redis_single) ->
|
||||
authz_redis_common_fields() ++
|
||||
|
@ -70,24 +82,13 @@ fields(redis_sentinel) ->
|
|||
fields(redis_cluster) ->
|
||||
authz_redis_common_fields() ++
|
||||
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) ->
|
||||
[
|
||||
{position,
|
||||
mk(
|
||||
string(),
|
||||
#{
|
||||
desc => <<"Where to place the source">>,
|
||||
desc => ?DESC(position),
|
||||
required => true,
|
||||
in => body
|
||||
}
|
||||
|
@ -102,7 +103,8 @@ authz_http_common_fields() ->
|
|||
[
|
||||
{url, fun url/1},
|
||||
{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:without(
|
||||
|
@ -117,12 +119,13 @@ authz_http_common_fields() ->
|
|||
url(type) -> binary();
|
||||
url(validator) -> [?NOT_EMPTY("the value of the field 'url' cannot be empty")];
|
||||
url(required) -> true;
|
||||
url(desc) -> ?DESC(?FUNCTION_NAME);
|
||||
url(_) -> undefined.
|
||||
|
||||
headers(type) ->
|
||||
map();
|
||||
headers(desc) ->
|
||||
"List of HTTP headers.";
|
||||
?DESC(?FUNCTION_NAME);
|
||||
headers(converter) ->
|
||||
fun(Headers) ->
|
||||
maps:merge(default_headers(), transform_header_name(Headers))
|
||||
|
@ -135,7 +138,7 @@ headers(_) ->
|
|||
headers_no_content_type(type) ->
|
||||
map();
|
||||
headers_no_content_type(desc) ->
|
||||
"List of HTTP headers.";
|
||||
?DESC(?FUNCTION_NAME);
|
||||
headers_no_content_type(converter) ->
|
||||
fun(Headers) ->
|
||||
maps:merge(default_headers_no_content_type(), transform_header_name(Headers))
|
||||
|
@ -182,17 +185,14 @@ authz_mongo_common_fields() ->
|
|||
].
|
||||
|
||||
collection(type) -> binary();
|
||||
collection(desc) -> "Collection used to store authentication data.";
|
||||
collection(desc) -> ?DESC(?FUNCTION_NAME);
|
||||
collection(required) -> true;
|
||||
collection(_) -> undefined.
|
||||
|
||||
selector(type) ->
|
||||
map();
|
||||
selector(desc) ->
|
||||
"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";
|
||||
?DESC(?FUNCTION_NAME);
|
||||
selector(_) ->
|
||||
undefined.
|
||||
|
||||
|
@ -205,6 +205,7 @@ authz_redis_common_fields() ->
|
|||
{cmd,
|
||||
mk(binary(), #{
|
||||
required => true,
|
||||
desc => ?DESC(cmd),
|
||||
example => <<"HGETALL mqtt_authz">>
|
||||
})}
|
||||
].
|
||||
|
@ -216,18 +217,35 @@ authz_common_fields(Type) when is_atom(Type) ->
|
|||
[
|
||||
{enable, fun enable/1},
|
||||
{type, #{
|
||||
type => enum([Type]),
|
||||
type => Type,
|
||||
default => Type,
|
||||
required => true,
|
||||
desc => ?DESC(type),
|
||||
in => body
|
||||
}}
|
||||
].
|
||||
|
||||
enable(type) -> boolean();
|
||||
enable(default) -> true;
|
||||
enable(desc) -> "Set to <code>false</code> to disable this auth provider";
|
||||
enable(desc) -> ?DESC(?FUNCTION_NAME);
|
||||
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
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
-behaviour(minirest_api).
|
||||
|
||||
-include_lib("hocon/include/hoconsc.hrl").
|
||||
|
||||
-import(hoconsc, [mk/1, ref/2]).
|
||||
|
||||
-export([
|
||||
|
@ -45,13 +47,13 @@ schema("/authorization/settings") ->
|
|||
'operationId' => settings,
|
||||
get =>
|
||||
#{
|
||||
description => <<"Get authorization settings">>,
|
||||
description => ?DESC(authorization_settings_get),
|
||||
responses =>
|
||||
#{200 => ref_authz_schema()}
|
||||
},
|
||||
put =>
|
||||
#{
|
||||
description => <<"Update authorization settings">>,
|
||||
description => ?DESC(authorization_settings_put),
|
||||
'requestBody' => ref_authz_schema(),
|
||||
responses =>
|
||||
#{
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
|
||||
-behaviour(minirest_api).
|
||||
|
||||
-include_lib("typerefl/include/types.hrl").
|
||||
-include("emqx_authz.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]).
|
||||
|
||||
|
@ -63,27 +63,26 @@ paths() ->
|
|||
%%--------------------------------------------------------------------
|
||||
%% Schema for each URI
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
schema("/authorization/sources") ->
|
||||
#{
|
||||
'operationId' => sources,
|
||||
get =>
|
||||
#{
|
||||
description => <<"List all authorization sources">>,
|
||||
description => ?DESC(authorization_sources_get),
|
||||
responses =>
|
||||
#{
|
||||
200 => mk(
|
||||
array(hoconsc:union(authz_sources_type_refs())),
|
||||
#{desc => <<"Authorization source">>}
|
||||
#{desc => ?DESC(sources)}
|
||||
)
|
||||
}
|
||||
},
|
||||
post =>
|
||||
#{
|
||||
description => <<"Add a new source">>,
|
||||
description => ?DESC(authorization_sources_post),
|
||||
'requestBody' => mk(
|
||||
hoconsc:union(authz_sources_type_refs()),
|
||||
#{desc => <<"Source config">>}
|
||||
#{desc => ?DESC(source_config)}
|
||||
),
|
||||
responses =>
|
||||
#{
|
||||
|
@ -100,20 +99,20 @@ schema("/authorization/sources/:type") ->
|
|||
'operationId' => source,
|
||||
get =>
|
||||
#{
|
||||
description => <<"Get a authorization source">>,
|
||||
description => ?DESC(authorization_sources_type_get),
|
||||
parameters => parameters_field(),
|
||||
responses =>
|
||||
#{
|
||||
200 => mk(
|
||||
hoconsc:union(authz_sources_type_refs()),
|
||||
#{desc => <<"Authorization source">>}
|
||||
#{desc => ?DESC(source)}
|
||||
),
|
||||
404 => emqx_dashboard_swagger:error_codes([?NOT_FOUND], <<"Not Found">>)
|
||||
}
|
||||
},
|
||||
put =>
|
||||
#{
|
||||
description => <<"Update source">>,
|
||||
description => ?DESC(authorization_sources_type_put),
|
||||
parameters => parameters_field(),
|
||||
'requestBody' => mk(hoconsc:union(authz_sources_type_refs())),
|
||||
responses =>
|
||||
|
@ -124,7 +123,7 @@ schema("/authorization/sources/:type") ->
|
|||
},
|
||||
delete =>
|
||||
#{
|
||||
description => <<"Delete source">>,
|
||||
description => ?DESC(authorization_sources_type_delete),
|
||||
parameters => parameters_field(),
|
||||
responses =>
|
||||
#{
|
||||
|
@ -138,7 +137,7 @@ schema("/authorization/sources/:type/status") ->
|
|||
'operationId' => source_status,
|
||||
get =>
|
||||
#{
|
||||
description => <<"Get a authorization source">>,
|
||||
description => ?DESC(authorization_sources_type_status_get),
|
||||
parameters => parameters_field(),
|
||||
responses =>
|
||||
#{
|
||||
|
@ -158,7 +157,7 @@ schema("/authorization/sources/:type/move") ->
|
|||
'operationId' => move_source,
|
||||
post =>
|
||||
#{
|
||||
description => <<"Change the order of sources">>,
|
||||
description => ?DESC(authorization_sources_type_move_post),
|
||||
parameters => parameters_field(),
|
||||
'requestBody' =>
|
||||
emqx_dashboard_swagger:schema_with_examples(
|
||||
|
@ -508,7 +507,7 @@ parameters_field() ->
|
|||
{type,
|
||||
mk(
|
||||
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,
|
||||
PubSub,
|
||||
Topic,
|
||||
#{type := 'built_in_database'}
|
||||
#{type := built_in_database}
|
||||
) ->
|
||||
Rules =
|
||||
case mnesia:dirty_read(?ACL_TABLE, {?ACL_TABLE_CLIENTID, Clientid}) of
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
-module(emqx_authz_schema).
|
||||
|
||||
-include("emqx_authz.hrl").
|
||||
-include_lib("typerefl/include/types.hrl").
|
||||
-include_lib("hocon/include/hoconsc.hrl").
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
|
||||
-reflect_type([
|
||||
|
@ -71,134 +71,104 @@ fields("authorization") ->
|
|||
]
|
||||
),
|
||||
default => [],
|
||||
desc =>
|
||||
"\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"
|
||||
desc => ?DESC(sources)
|
||||
}}
|
||||
];
|
||||
fields(file) ->
|
||||
[
|
||||
{type, #{type => file, required => true, desc => "Backend type."}},
|
||||
{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"
|
||||
}}
|
||||
];
|
||||
authz_common_fields(file) ++
|
||||
[{path, #{type => string(), required => true, desc => ?DESC(path)}}];
|
||||
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}
|
||||
] ++ 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) ->
|
||||
mongo_common_fields() ++ emqx_connector_mongo:fields(single);
|
||||
authz_common_fields(mongodb) ++
|
||||
mongo_common_fields() ++
|
||||
emqx_connector_mongo:fields(single);
|
||||
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) ->
|
||||
mongo_common_fields() ++ emqx_connector_mongo:fields(sharded);
|
||||
authz_common_fields(mongodb) ++
|
||||
mongo_common_fields() ++
|
||||
emqx_connector_mongo:fields(sharded);
|
||||
fields(mysql) ->
|
||||
authz_common_fields(mysql) ++
|
||||
connector_fields(mysql) ++
|
||||
[{query, query()}];
|
||||
fields(postgresql) ->
|
||||
[
|
||||
{query, query()},
|
||||
{type, #{type => postgresql, required => true, desc => "Backend type."}},
|
||||
{enable, #{
|
||||
type => boolean(),
|
||||
desc => "Enable this backend.",
|
||||
default => true
|
||||
}}
|
||||
] ++ emqx_connector_pgsql:fields(config);
|
||||
authz_common_fields(postgresql) ++
|
||||
emqx_connector_pgsql:fields(config) ++
|
||||
[{query, query()}];
|
||||
fields(redis_single) ->
|
||||
authz_common_fields(redis) ++
|
||||
connector_fields(redis, single) ++
|
||||
[{cmd, query()}];
|
||||
[{cmd, cmd()}];
|
||||
fields(redis_sentinel) ->
|
||||
authz_common_fields(redis) ++
|
||||
connector_fields(redis, sentinel) ++
|
||||
[{cmd, query()}];
|
||||
[{cmd, cmd()}];
|
||||
fields(redis_cluster) ->
|
||||
authz_common_fields(redis) ++
|
||||
connector_fields(redis, cluster) ++
|
||||
[{cmd, query()}].
|
||||
[{cmd, cmd()}].
|
||||
|
||||
desc("authorization") ->
|
||||
"Configuration related to the client authorization.";
|
||||
desc(?CONF_NS) ->
|
||||
?DESC(?CONF_NS);
|
||||
desc(file) ->
|
||||
"Authorization using a static file.";
|
||||
?DESC(file);
|
||||
desc(http_get) ->
|
||||
"Authorization using an external HTTP server (via GET requests).";
|
||||
?DESC(http_get);
|
||||
desc(http_post) ->
|
||||
"Authorization using an external HTTP server (via POST requests).";
|
||||
?DESC(http_post);
|
||||
desc(mnesia) ->
|
||||
"Authorization using a built-in database (mnesia).";
|
||||
?DESC(mnesia);
|
||||
desc(mongo_single) ->
|
||||
"Authorization using a single MongoDB instance.";
|
||||
?DESC(mongo_single);
|
||||
desc(mongo_rs) ->
|
||||
"Authorization using a MongoDB replica set.";
|
||||
?DESC(mongo_rs);
|
||||
desc(mongo_sharded) ->
|
||||
"Authorization using a sharded MongoDB cluster.";
|
||||
?DESC(mongo_sharded);
|
||||
desc(mysql) ->
|
||||
"Authorization using a MySQL database.";
|
||||
?DESC(mysql);
|
||||
desc(postgresql) ->
|
||||
"Authorization using a PostgreSQL database.";
|
||||
?DESC(postgresql);
|
||||
desc(redis_single) ->
|
||||
"Authorization using a single Redis instance.";
|
||||
?DESC(redis_single);
|
||||
desc(redis_sentinel) ->
|
||||
"Authorization using a Redis Sentinel.";
|
||||
?DESC(redis_sentinel);
|
||||
desc(redis_cluster) ->
|
||||
"Authorization using a Redis cluster.";
|
||||
?DESC(redis_cluster);
|
||||
desc(_) ->
|
||||
undefined.
|
||||
|
||||
authz_common_fields(Type) ->
|
||||
[
|
||||
{type, #{type => Type, required => true, desc => ?DESC(type)}},
|
||||
{enable, #{type => boolean(), default => true, desc => ?DESC(enable)}}
|
||||
].
|
||||
|
||||
http_common_fields() ->
|
||||
[
|
||||
{url, fun url/1},
|
||||
{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:without(
|
||||
|
@ -215,18 +185,12 @@ mongo_common_fields() ->
|
|||
{collection, #{
|
||||
type => atom(),
|
||||
required => true,
|
||||
desc => "`MongoDB` collection containing the authorization data."
|
||||
desc => ?DESC(collection)
|
||||
}},
|
||||
{selector, #{
|
||||
type => map(),
|
||||
required => true,
|
||||
desc => "MQL query used to select the authorization record."
|
||||
}},
|
||||
{type, #{type => mongodb, required => true, desc => "Database backend."}},
|
||||
{enable, #{
|
||||
type => boolean(),
|
||||
default => true,
|
||||
desc => "Enable or disable the backend."
|
||||
desc => ?DESC(selector)
|
||||
}}
|
||||
].
|
||||
|
||||
|
@ -238,7 +202,7 @@ validations() ->
|
|||
headers(type) ->
|
||||
list({binary(), binary()});
|
||||
headers(desc) ->
|
||||
"List of HTTP headers.";
|
||||
?DESC(?FUNCTION_NAME);
|
||||
headers(converter) ->
|
||||
fun(Headers) ->
|
||||
maps:to_list(maps:merge(default_headers(), transform_header_name(Headers)))
|
||||
|
@ -251,7 +215,7 @@ headers(_) ->
|
|||
headers_no_content_type(type) ->
|
||||
list({binary(), binary()});
|
||||
headers_no_content_type(desc) ->
|
||||
"List of HTTP headers.";
|
||||
?DESC(?FUNCTION_NAME);
|
||||
headers_no_content_type(converter) ->
|
||||
fun(Headers) ->
|
||||
maps:to_list(maps:merge(default_headers_no_content_type(), transform_header_name(Headers)))
|
||||
|
@ -269,7 +233,7 @@ headers_no_content_type(_) ->
|
|||
undefined.
|
||||
|
||||
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(required) -> true;
|
||||
url(_) -> undefined.
|
||||
|
@ -328,7 +292,20 @@ union_array(Item) when is_list(Item) ->
|
|||
query() ->
|
||||
#{
|
||||
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,
|
||||
validator => fun(S) ->
|
||||
case size(S) > 0 of
|
||||
|
@ -351,14 +328,7 @@ connector_fields(DB, Fields) ->
|
|||
error:Reason ->
|
||||
erlang:error(Reason)
|
||||
end,
|
||||
[
|
||||
{type, #{type => DB, desc => "Database backend."}},
|
||||
{enable, #{
|
||||
type => boolean(),
|
||||
default => true,
|
||||
desc => "Enable or disable the backend."
|
||||
}}
|
||||
] ++ erlang:apply(Mod, fields, [Fields]).
|
||||
erlang:apply(Mod, fields, [Fields]).
|
||||
|
||||
to_list(A) when is_atom(A) ->
|
||||
atom_to_list(A);
|
||||
|
|
Loading…
Reference in New Issue