Merge branch 'rbac' of ssh://git.infini.ltd:64221/infini/console into rbac
This commit is contained in:
commit
99433c0fc4
|
@ -0,0 +1,274 @@
|
|||
{
|
||||
"DELETE-/_ingest/pipeline/:id": "ingest.delete_pipeline",
|
||||
"DELETE-/_scripts/:id": "script.delete",
|
||||
"DELETE-/_search/scroll": "scroll.delete",
|
||||
"DELETE-/_search/scroll/:scroll_id":"scroll.delete",
|
||||
"DELETE-/_snapshot/:repository": "snapshot.delete_repository",
|
||||
"DELETE-/_snapshot/:repository/:snapshot": "snapshot.delete",
|
||||
"DELETE-/_template/:name": "indices.delete_template",
|
||||
"DELETE-/:index": "indices.delete",
|
||||
"DELETE-/:index/_alias/:name": "indices.delete_alias",
|
||||
"DELETE-/:index/_aliases/:name": "indices.delete_alias",
|
||||
"DELETE-/:index/_doc/:id": "doc.delete",
|
||||
|
||||
"GET-/": "cluster.info",
|
||||
"GET-/_alias": "indices.get_alias",
|
||||
"GET-/_alias/:name": "indices.get_alias",
|
||||
"GET-/_analyze": "indices.analyze",
|
||||
"GET-/_cat": "cat.help",
|
||||
"GET-/_cat/aliases": "cat.aliases",
|
||||
"GET-/_cat/aliases/:name": "cat.aliases",
|
||||
"GET-/_cat/allocation": "cat.allocation",
|
||||
"GET-/_cat/allocation/:node_id": "cat.allocation",
|
||||
"GET-/_cat/count": "cat.count",
|
||||
"GET-/_cat/count/:index": "cat.count",
|
||||
"GET-/_cat/fielddata": "cat.fielddata",
|
||||
"GET-/_cat/fielddata/:fields": "cat.fielddata",
|
||||
"GET-/_cat/health": "cat.health",
|
||||
"GET-/_cat/indices": "cat.indices",
|
||||
"GET-/_cat/indices/:index": "cat.indices",
|
||||
"GET-/_cat/master": "cat.master",
|
||||
"GET-/_cat/nodeattrs": "cat.nodeattrs",
|
||||
"GET-/_cat/nodes": "cat.nodes",
|
||||
"GET-/_cat/pending_tasks": "cat.pending_tasks",
|
||||
"GET-/_cat/plugins": "cat.plugins",
|
||||
"GET-/_cat/recovery": "cat.recovery",
|
||||
"GET-/_cat/recovery/:index": "cat.recovery",
|
||||
"GET-/_cat/repositories": "cat.repositories",
|
||||
"GET-/_cat/segments": "cat.segments",
|
||||
"GET-/_cat/segments/:index": "cat.segments",
|
||||
"GET-/_cat/shards": "cat.shards",
|
||||
"GET-/_cat/shards/:index": "cat.shards",
|
||||
"GET-/_cat/snapshots": "cat.snapshots",
|
||||
"GET-/_cat/snapshots/:repository": "cat.snapshots",
|
||||
"GET-/_cat/tasks": "cat.tasks",
|
||||
"GET-/_cat/templates": "cat.templates",
|
||||
"GET-/_cat/templates/:name": "cat.templates",
|
||||
"GET-/_cat/thread_pool": "cat.thread_pool",
|
||||
"GET-/_cat/thread_pool/:thread_pool_patterns": "cat.thread_pool",
|
||||
"GET-/_cluster/allocation/explain": "cluster.allocation_explain",
|
||||
"GET-/_cluster/health": "cluster.health",
|
||||
"GET-/_cluster/health/:index": "cluster.health",
|
||||
"GET-/_cluster/nodes/hot_threads": "nodes.hot_threads",
|
||||
"GET-/_cluster/nodes/hotthreads": "nodes.hot_threads",
|
||||
"GET-/_cluster/nodes/:node_id/hot_threads": "nodes.hot_threads",
|
||||
"GET-/_cluster/nodes/:node_id/hotthreads": "nodes.hot_threads",
|
||||
"GET-/_cluster/pending_tasks": "cluster.pending_tasks",
|
||||
"GET-/_cluster/settings": "cluster.get_settings",
|
||||
"GET-/_cluster/state": "cluster.state",
|
||||
"GET-/_cluster/state/:metric": "cluster.state",
|
||||
"GET-/_cluster/state/:metric/:index": "cluster.state",
|
||||
"GET-/_cluster/stats": "cluster.stats",
|
||||
"GET-/_cluster/stats/nodes/:node_id": "cluster.stats",
|
||||
"GET-/_count": "cluster.count",
|
||||
|
||||
"GET-/_flush": "indices.flush",
|
||||
"GET-/_flush/synced": "indices.flush_synced",
|
||||
"GET-/_ingest/pipeline": "ingest.get_pipeline",
|
||||
"GET-/_ingest/pipeline/_simulate": "ingest.simulate",
|
||||
"GET-/_ingest/pipeline/:id": "ingest.get_pipeline",
|
||||
"GET-/_ingest/pipeline/:id/_simulate": "ingest.simulate",
|
||||
"GET-/_ingest/processor/grok": "ingest.processor_grok",
|
||||
"GET-/_mapping": "indices.get_mapping",
|
||||
|
||||
"GET-/_mget": "cluster.mget",
|
||||
"GET-/_msearch": "cluster.msearch",
|
||||
"GET-/_msearch/template": "cluster.msearch_template",
|
||||
"GET-/_mtermvectors": "cluster.mtermvectors",
|
||||
"GET-/_nodes": "nodes.info",
|
||||
"GET-/_nodes/hot_threads": "nodes.hot_threads",
|
||||
"GET-/_nodes/hotthreads": "nodes.hot_threads",
|
||||
"GET-/_nodes/stats": "nodes.stats",
|
||||
"GET-/_nodes/stats/:metric": "nodes.stats",
|
||||
"GET-/_nodes/stats/:metric/:index_metric": "nodes.stats",
|
||||
"GET-/_nodes/usage": "nodes.usage",
|
||||
"GET-/_nodes/usage/:metric": "nodes.usage",
|
||||
"GET-/_nodes/:metric": "nodes.info",
|
||||
"GET-/_nodes/:node_id": "nodes.info",
|
||||
"GET-/_nodes/:node_id/hot_threads": "nodes.hot_threads",
|
||||
"GET-/_nodes/:node_id/hotthreads": "nodes.hot_threads",
|
||||
"GET-/_nodes/:node_id/stats": "nodes.stats",
|
||||
"GET-/_nodes/:node_id/stats/:metric": "nodes.stats",
|
||||
"GET-/_nodes/:node_id/stats/:metric/:index_metric": "nodes.stats",
|
||||
"GET-/_nodes/:node_id/usage": "nodes.usage",
|
||||
"GET-/_nodes/:node_id/usage/:metric": "nodes.usage",
|
||||
"GET-/_nodes/:node_id/:metric": "nodes.info",
|
||||
"GET-/_rank_eval": "cluster.rank_eval",
|
||||
"GET-/_recovery": "indices.recovery",
|
||||
"GET-/_refresh": "indices.refresh",
|
||||
"GET-/_remote/info": "cluster.remote_info",
|
||||
"GET-/_render/template": "render_search_template",
|
||||
"GET-/_render/template/:id": "render_search_template",
|
||||
"GET-/_scripts/painless/_execute": "scripts.painless_execute",
|
||||
"GET-/_scripts/:id": "scripts.get",
|
||||
"GET-/_search": "cluster.search",
|
||||
"GET-/_search/scroll": "scroll.get",
|
||||
"GET-/_search/scroll/:scroll_id": "scroll.get",
|
||||
"GET-/_search/template": "search_template",
|
||||
"GET-/_search_shards": "cluster.search_shards",
|
||||
"GET-/_segments": "indices.segments",
|
||||
"GET-/_settings": "indices.get_settings",
|
||||
"GET-/_settings/:name": "indices.get_settings",
|
||||
"GET-/_shard_stores": "indices.shard_stores",
|
||||
"GET-/_snapshot": "snapshot.get_repository",
|
||||
"GET-/_snapshot/_status": "snapshot.status",
|
||||
"GET-/_snapshot/:repository": "snapshot.get_repository",
|
||||
"GET-/_snapshot/:repository/_status": "snapshot.status",
|
||||
"GET-/_snapshot/:repository/:snapshot": "snapshot.get",
|
||||
"GET-/_snapshot/:repository/:snapshot/_status": "snapshot.status",
|
||||
"GET-/_stats": "indices.stats",
|
||||
"GET-/_stats/:metric": "indices.stats",
|
||||
"GET-/_tasks": "tasks.list",
|
||||
"GET-/_tasks/:task_id": "tasks.get",
|
||||
"GET-/_template": "indices.get_template",
|
||||
"GET-/_template/:name": "indices.get_template",
|
||||
"GET-/_upgrade": "indices.get_upgrade",
|
||||
"GET-/_validate/query": "indices.validate_query",
|
||||
"GET-/:index": "indices.get",
|
||||
"GET-/:index/_alias": "indices.get_alias",
|
||||
"GET-/:index/_alias/:name": "indices.get_alias",
|
||||
"GET-/:index/_analyze": "indices.analyze",
|
||||
"GET-/:index/_count": "indices.count",
|
||||
"GET-/:index/_doc/:id": "doc.get",
|
||||
"GET-/:index/_field_caps": "indices.field_caps",
|
||||
"GET-/:index/_flush": "indices.flush",
|
||||
"GET-/:index/_flush/synced": "indices.flush_synced",
|
||||
"GET-/:index/_mapping": "indices.get_mapping",
|
||||
"GET-/:index/_mappings": "indices.get_mapping",
|
||||
"GET-/:index/_mapping/field/:fields": "indices.get_field_mapping",
|
||||
|
||||
"GET-/:index/_mget": "indices.mget",
|
||||
"GET-/:index/_msearch": "indices.msearch",
|
||||
"GET-/:index/_msearch/template": "indices.msearch_template",
|
||||
"GET-/:index/_mtermvectors": "indices.mtermvectors",
|
||||
"GET-/:index/_rank_eval": "indices.rank_eval",
|
||||
"GET-/:index/_recovery": "indices.recovery",
|
||||
"GET-/:index/_refresh": "indices.refresh",
|
||||
"GET-/:index/_search": "indices.search",
|
||||
"GET-/:index/_search/template": "indices.search_template",
|
||||
"GET-/:index/_search_shards": "indices.search_shards",
|
||||
"GET-/:index/_segments": "indices.segments",
|
||||
"GET-/:index/_settings": "indices.get_settings",
|
||||
"GET-/:index/_settings/:name": "indices.get_settings",
|
||||
"GET-/:index/_shard_stores": "indices.shard_stores",
|
||||
"GET-/:index/_stats": "indices.stats",
|
||||
"GET-/:index/_stats/:metric": "indices.stats",
|
||||
"GET-/:index/_upgrade": "indices.get_upgrade",
|
||||
"GET-/:index/_validate/query": "indices.validate_query",
|
||||
|
||||
"HEAD-/": "cluster.info",
|
||||
"HEAD-/_alias/:name": "indices.exists_alias",
|
||||
"HEAD-/_template/:name": "indices.exists_template",
|
||||
"HEAD-/:index": "indices.exists",
|
||||
"HEAD-/:index/_alias/:name": "indices.exists_alias",
|
||||
"HEAD-/:index/_analyze": "indices.analyze",
|
||||
"HEAD-/:index/_mapping/{type}": "indices.exists_type",
|
||||
|
||||
"HEAD-/:index/_doc/{id}": "doc.exists",
|
||||
"HEAD-/:index/_doc/{id}/_source": "doc.exists_source",
|
||||
|
||||
"POST-/_aliases": "indices.update_aliases",
|
||||
"POST-/_analyze": "indices.analyze",
|
||||
"POST-/_bulk": "cluster.bulk",
|
||||
"POST-/_cache/clear": "indices.clear_cache",
|
||||
"POST-/_cluster/allocation/explain": "cluster.allocation_explain",
|
||||
"POST-/_cluster/reroute": "cluster.reroute",
|
||||
"POST-/_count": "cluster.count",
|
||||
"POST-/_delete_by_query/:task_id/_rethrottle": "reindex_rethrottle",
|
||||
"POST-/_field_caps": "cluster.field_caps",
|
||||
"POST-/_flush": "indices.flush",
|
||||
"POST-/_flush/synced": "indices.flush_synced",
|
||||
"POST-/_forcemerge": "indices.forcemerge",
|
||||
"POST-/_ingest/pipeline/_simulate": "ingest.simulate",
|
||||
"POST-/_ingest/pipeline/:id/_simulate": "ingest.simulate",
|
||||
|
||||
"POST-/_mget": "cluster.mget",
|
||||
"POST-/_msearch": "cluster.msearch",
|
||||
"POST-/_msearch/template": "cluster.msearch_template",
|
||||
"POST-/_mtermvectors": "cluster.mtermvectors",
|
||||
"POST-/_nodes/reload_secure_settings": "nodes.reload_secure_settings",
|
||||
"POST-/_nodes/:node_id/reload_secure_settings": "nodes.reload_secure_settings",
|
||||
"POST-/_rank_eval": "cluster.rank_eval",
|
||||
"POST-/_refresh": "indices.refresh",
|
||||
"POST-/_reindex": "reindex",
|
||||
"POST-/_reindex/:task_id/_rethrottle": "reindex_rethrottle",
|
||||
"POST-/_render/template": "render_search_template.create",
|
||||
"POST-/_render/template/:id": "render_search_template.get",
|
||||
"POST-/_scripts/painless/_execute": "scripts_painless_execute",
|
||||
"POST-/_scripts/:id": "scripts.put",
|
||||
"POST-/_scripts/:id/:context": "scripts.put",
|
||||
|
||||
"POST-/_search/scroll": "scroll.create",
|
||||
"POST-/_search/scroll/:scroll_id": "scroll.create",
|
||||
"POST-/_search/template": "search_template",
|
||||
|
||||
"POST-/_snapshot/:repository": "snapshot.create_repository",
|
||||
"POST-/_snapshot/:repository/_verify": "snapshot.verify_repository",
|
||||
"POST-/_snapshot/:repository/:snapshot": "snapshot.create",
|
||||
"POST-/_snapshot/:repository/:snapshot/_restore": "snapshot.restore",
|
||||
"POST-/_tasks/_cancel": "tasks.cancel",
|
||||
"POST-/_tasks/:task_id/_cancel": "tasks.cancel",
|
||||
"POST-/_template/:name": "indices.put_template",
|
||||
"POST-/_update_by_query/:task_id/_rethrottle": "reindex_rethrottle",
|
||||
"POST-/_upgrade": "indices.upgrade",
|
||||
"POST-/_validate/query": "indices.validate_query",
|
||||
"POST-/:alias/_rollover": "indices.rollover",
|
||||
"POST-/:alias/_rollover/:new_index": "indices.rollover",
|
||||
"POST-/:index/_alias/:name": "indices.put_alias",
|
||||
"POST-/:index/_aliases/:name": "indices.put_alias",
|
||||
"POST-/:index/_analyze": "indices.analyze",
|
||||
"POST-/:index/_bulk": "indices.bulk",
|
||||
"POST-/:index/_cache/clear": "indices.clear_cache",
|
||||
"POST-/:index/_close": "indices.close",
|
||||
"POST-/:index/_count": "indices.count",
|
||||
"POST-/:index/_delete_by_query": "indices.delete_by_query",
|
||||
"POST-/:index/_doc": "doc.create",
|
||||
"POST-/:index/_doc/:id": "doc.update",
|
||||
"POST-/:index/_doc/:id/_update": "doc.update",
|
||||
"POST-/:index/_field_caps": "indices.field_caps",
|
||||
"POST-/:index/_flush": "indices.flush",
|
||||
"POST-/:index/_flush/synced": "indices.flush_synced",
|
||||
"POST-/:index/_forcemerge": "indices.forcemerge",
|
||||
|
||||
"POST-/:index/_mget": "indices.mget",
|
||||
"POST-/:index/_msearch": "indices.msearch",
|
||||
"POST-/:index/_msearch/template": "indices.msearch_template",
|
||||
"POST-/:index/_mtermvectors": "indices.mtermvectors",
|
||||
"POST-/:index/_open": "indices.open",
|
||||
"POST-/:index/_rank_eval": "indices.rank_eval",
|
||||
"POST-/:index/_refresh": "indices.refresh",
|
||||
"POST-/:index/_search": "indices.search",
|
||||
"POST-/:index/_search/template": "indices.search_template",
|
||||
"POST-/:index/_search_shards": "indices.search_shards",
|
||||
"POST-/:index/_shrink/:target": "indices.shrink",
|
||||
"POST-/:index/_split/:target": "indices.split",
|
||||
"POST-/:index/_update_by_query": "indices.update_by_query",
|
||||
"POST-/:index/_upgrade": "indices.upgrade",
|
||||
"POST-/:index/_validate/query": "indices.validate_query",
|
||||
|
||||
"POST-/:index/_mapping": "indices.put_mapping",
|
||||
"POST-/:index/_mappings": "indices.put_mapping",
|
||||
"PUT-/_bulk": "cluster.bulk",
|
||||
"PUT-/_cluster/settings": "cluster.put_settings",
|
||||
"PUT-/_ingest/pipeline/:id": "ingest.put_pipeline",
|
||||
|
||||
"PUT-/_scripts/:id": "scripts.put",
|
||||
"PUT-/_scripts/:id/:context": "scripts.put",
|
||||
"PUT-/_settings": "cluster.settings_put",
|
||||
"PUT-/_snapshot/:repository": "snapshot.create_repository",
|
||||
"PUT-/_snapshot/:repository/:snapshot": "snapshot.create",
|
||||
"PUT-/_template/:name": "indices.put_template",
|
||||
"PUT-/:index": "indices.put",
|
||||
"PUT-/:index/_alias/:name": "indices.put_alias",
|
||||
"PUT-/:index/_aliases/:name": "indices.put_alias",
|
||||
"PUT-/:index/_bulk": "indices.put_bulk",
|
||||
|
||||
"PUT-/:index/_doc/:id": "doc.put",
|
||||
|
||||
"PUT-/:index/_settings": "indices.put_settings",
|
||||
"PUT-/:index/_shrink/:target": "indices.shrink",
|
||||
"PUT-/:index/_split/:target": "indices.split",
|
||||
|
||||
"PUT-/:index/_mapping": "indices.put_mapping",
|
||||
"PUT-/:index/_mappings": "indices.put_mapping"
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
{
|
||||
|
||||
"cat": [
|
||||
"cat.*",
|
||||
"cat.indices",
|
||||
"cat.help",
|
||||
"cat.repositories",
|
||||
"cat.pending_tasks",
|
||||
"cat.tasks",
|
||||
"cat.allocation",
|
||||
"cat.count",
|
||||
"cat.shards",
|
||||
"cat.aliases",
|
||||
"cat.nodeattrs",
|
||||
"cat.templates",
|
||||
"cat.thread_pool",
|
||||
"cat.health",
|
||||
"cat.recovery",
|
||||
"cat.fielddata",
|
||||
"cat.nodes",
|
||||
"cat.plugins",
|
||||
"cat.segments",
|
||||
"cat.snapshots",
|
||||
"cat.master"
|
||||
],
|
||||
"cluster": [
|
||||
"cluster.*",
|
||||
"cluster.health",
|
||||
"cluster.get_settings",
|
||||
"cluster.pending_tasks",
|
||||
"cluster.stats",
|
||||
"cluster.remote_info",
|
||||
"cluster.allocation_explain",
|
||||
"cluster.put_settings",
|
||||
"cluster.reroute",
|
||||
"cluster.count",
|
||||
"cluster.state",
|
||||
"cluster.info",
|
||||
"cluster.bulk",
|
||||
"cluster.mget",
|
||||
"cluster.ping",
|
||||
"cluster.msearch",
|
||||
"cluster.msearch_template",
|
||||
"cluster.mtermvectors",
|
||||
"cluster.rank_eval",
|
||||
"cluster.search",
|
||||
"cluster.search_shards"
|
||||
],
|
||||
|
||||
"doc": [
|
||||
"doc.*",
|
||||
"doc.update",
|
||||
|
||||
"doc.create",
|
||||
"doc.delete",
|
||||
"doc.get",
|
||||
"doc.exists",
|
||||
"doc.count",
|
||||
"doc.exists_source",
|
||||
"doc.bulk",
|
||||
"doc.explain",
|
||||
"doc.mget",
|
||||
"doc.msearch",
|
||||
"doc.msearch_template",
|
||||
"doc.mtermvectors",
|
||||
"doc.search"
|
||||
],
|
||||
|
||||
"indices": [
|
||||
"indices.*",
|
||||
"indices.exists_alias",
|
||||
"indices.get_alias",
|
||||
"indices.recovery",
|
||||
"indices.delete",
|
||||
"indices.put",
|
||||
"indices.clear_cache",
|
||||
"indices.update_by_query",
|
||||
"indices.shrink",
|
||||
"indices.forcemerge",
|
||||
"indices.put_alias",
|
||||
"indices.create",
|
||||
"indices.split",
|
||||
"indices.flush",
|
||||
"indices.get_mapping",
|
||||
"indices.upgrade",
|
||||
"indices.validate_query",
|
||||
"indices.exists_template",
|
||||
"indices.get_upgrade",
|
||||
"indices.update_aliases",
|
||||
"indices.analyze",
|
||||
"indices.exists",
|
||||
"indices.close",
|
||||
"indices.delete_template",
|
||||
"indices.get_field_mapping",
|
||||
"indices.delete_alias",
|
||||
"indices.exists_type",
|
||||
"indices.get_template",
|
||||
"indices.put_template",
|
||||
"indices.refresh",
|
||||
"indices.segments",
|
||||
"indices.termvectors",
|
||||
"indices.flush_synced",
|
||||
"indices.put_mapping",
|
||||
"indices.get",
|
||||
"indices.get_settings",
|
||||
"indices.open",
|
||||
"indices.put_settings",
|
||||
"indices.stats",
|
||||
"indices.delete_by_query",
|
||||
"indices.rollover",
|
||||
"indices.count",
|
||||
"indices.shard_stores",
|
||||
"indices.bulk",
|
||||
"indices.mget",
|
||||
"indices.msearch",
|
||||
"indices.msearch_template",
|
||||
"indices.mtermvectors",
|
||||
"indices.rank_eval",
|
||||
"indices.search",
|
||||
"indices.search_shards",
|
||||
"indices.field_caps"
|
||||
],
|
||||
|
||||
"ingest": [
|
||||
"ingest.*",
|
||||
"ingest.delete_pipeline",
|
||||
"ingest.put_pipeline",
|
||||
"ingest.simulate",
|
||||
"ingest.get_pipeline",
|
||||
"ingest.processor_grok"
|
||||
],
|
||||
|
||||
"nodes": [
|
||||
"nodes.*",
|
||||
"nodes.info",
|
||||
"nodes.stats",
|
||||
"nodes.reload_secure_settings",
|
||||
"nodes.usage",
|
||||
"nodes.hot_threads"
|
||||
],
|
||||
|
||||
"reindex": [
|
||||
"reindex.*",
|
||||
"reindex.rethrottle"
|
||||
],
|
||||
|
||||
"render_search_template": [
|
||||
"render_search_template.*",
|
||||
"render_search_template.create",
|
||||
"render_search_template.*"
|
||||
],
|
||||
"scripts": [
|
||||
"scripts.*",
|
||||
"scripts.get",
|
||||
"scripts.put",
|
||||
"scripts.delete",
|
||||
"scripts.painless_execute"
|
||||
],
|
||||
|
||||
"scroll": [
|
||||
"scroll.*",
|
||||
"scroll.delete",
|
||||
"scroll.get",
|
||||
"scroll.create"
|
||||
],
|
||||
|
||||
"snapshot": [
|
||||
"snapshot.*",
|
||||
"snapshot.get_repository",
|
||||
"snapshot.create_repository",
|
||||
"snapshot.create",
|
||||
"snapshot.restore",
|
||||
"snapshot.status",
|
||||
"snapshot.delete",
|
||||
"snapshot.delete_repository",
|
||||
"snapshot.verify_repository",
|
||||
"snapshot.get"
|
||||
],
|
||||
|
||||
"tasks": [
|
||||
"tasks.*",
|
||||
"tasks.list",
|
||||
"tasks.cancel",
|
||||
"tasks.get"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"infini.sh/console/internal/dto"
|
||||
"infini.sh/console/model/rbac"
|
||||
"infini.sh/framework/core/event"
|
||||
"infini.sh/framework/core/global"
|
||||
"infini.sh/framework/core/orm"
|
||||
"infini.sh/framework/core/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserClaims struct {
|
||||
*jwt.RegisteredClaims
|
||||
*User
|
||||
}
|
||||
type User struct {
|
||||
Username string `json:"username"`
|
||||
UserId string `json:"user_id"`
|
||||
Roles []string `json:"roles"`
|
||||
}
|
||||
type Account struct {
|
||||
ID string `json:"id,omitempty" `
|
||||
Created string `json:"created,omitempty" `
|
||||
Updated string `json:"updated,omitempty" `
|
||||
Username string `json:"username" elastic_mapping:"username:{type:keyword}"`
|
||||
Password string `json:"password" elastic_mapping:"password:{type:text}"`
|
||||
Name string `json:"name" elastic_mapping:"name:{type:keyword}"`
|
||||
Phone string `json:"phone" elastic_mapping:"phone:{type:keyword}"`
|
||||
Email string `json:"email" elastic_mapping:"email:{type:keyword}"`
|
||||
Tags []string `json:"tags" elastic_mapping:"tags:{type:text}"`
|
||||
Roles []rbac.UserRole `json:"roles"`
|
||||
}
|
||||
|
||||
const Secret = "console"
|
||||
|
||||
func authenticateUser(username string, password string) (user Account, err error) {
|
||||
|
||||
err, result := orm.GetBy("name", username, rbac.User{})
|
||||
if err != nil {
|
||||
err = ErrNotFound
|
||||
return
|
||||
}
|
||||
if result.Total == 0 {
|
||||
err = errors.New("user not found")
|
||||
return
|
||||
}
|
||||
|
||||
err = mapstructure.Decode(result.Result[0], &user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
err = errors.New("password incorrect")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
func authenticateAdmin(username string, password string) (user Account, err error) {
|
||||
|
||||
u, _ := global.Env().GetConfig("bootstrap.username", "admin")
|
||||
p, _ := global.Env().GetConfig("bootstrap.password", "admin")
|
||||
|
||||
if u != username || p != password {
|
||||
err = errors.New("invalid username or password")
|
||||
return
|
||||
}
|
||||
user.ID = username
|
||||
user.Username = username
|
||||
user.Roles = []rbac.UserRole{{
|
||||
ID: "admin", Name: "admin",
|
||||
}}
|
||||
return user, nil
|
||||
}
|
||||
func authorize(user Account) (m map[string]interface{}, err error) {
|
||||
|
||||
var roles, privilege []string
|
||||
for _, v := range user.Roles {
|
||||
role := RoleMap[v.Name]
|
||||
roles = append(roles, v.Name)
|
||||
privilege = append(privilege, role.Privilege.Platform...)
|
||||
}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserClaims{
|
||||
User: &User{
|
||||
Username: user.Username,
|
||||
UserId: user.ID,
|
||||
Roles: roles,
|
||||
},
|
||||
RegisteredClaims: &jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
||||
},
|
||||
})
|
||||
|
||||
tokenString, err := token.SignedString([]byte(Secret))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m = util.MapStr{
|
||||
"access_token": tokenString,
|
||||
"username": user.Username,
|
||||
"id": user.ID,
|
||||
"expire_in": 86400,
|
||||
"roles": roles,
|
||||
"privilege": privilege,
|
||||
}
|
||||
return
|
||||
}
|
||||
func Login(username string, password string) (m map[string]interface{}, err error) {
|
||||
var user Account
|
||||
if username == "admin" {
|
||||
user, err = authenticateAdmin(username, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
user, err = authenticateUser(username, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
m, err = authorize(user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
TokenMap[user.ID] = Token{ExpireIn: time.Now().Unix() + 86400}
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "login",
|
||||
Type: "create",
|
||||
Labels: util.MapStr{
|
||||
"username": username,
|
||||
"password": password,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"id": user.ID,
|
||||
"name": user.Username,
|
||||
},
|
||||
}, nil, nil))
|
||||
return
|
||||
}
|
||||
func UpdatePassword(localUser *User, req dto.UpdatePassword) (err error) {
|
||||
user := rbac.User{}
|
||||
user.ID = localUser.UserId
|
||||
_, err = orm.Get(&user)
|
||||
if err != nil {
|
||||
|
||||
return
|
||||
}
|
||||
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.OldPassword))
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
err = errors.New("old password is not correct")
|
||||
return
|
||||
}
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
user.Password = string(hash)
|
||||
err = orm.Save(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "user",
|
||||
Type: "update",
|
||||
Labels: util.MapStr{
|
||||
"old_password": req.OldPassword,
|
||||
"new_password": req.NewPassword,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"id": user.ID,
|
||||
"name": user.Name,
|
||||
},
|
||||
}, nil, nil))
|
||||
return
|
||||
}
|
||||
func UpdateProfile(localUser *User, req dto.UpdateProfile) (err error) {
|
||||
user := rbac.User{}
|
||||
user.ID = localUser.UserId
|
||||
_, err = orm.Get(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
user.Name = req.Name
|
||||
user.Email = req.Email
|
||||
user.Phone = req.Phone
|
||||
err = orm.Save(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "user",
|
||||
Type: "update",
|
||||
Labels: util.MapStr{
|
||||
"name": req.Name,
|
||||
"email": req.Email,
|
||||
"phone": req.Phone,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"id": user.ID,
|
||||
"name": user.Name,
|
||||
},
|
||||
}, nil, nil))
|
||||
return
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
)
|
||||
|
||||
const ctxUserKey = "user"
|
||||
|
||||
func NewUserContext(ctx context.Context, clam *UserClaims) context.Context {
|
||||
return context.WithValue(ctx, ctxUserKey, clam)
|
||||
}
|
||||
func FromUserContext(ctx context.Context) (*User, error) {
|
||||
ctxUser := ctx.Value(ctxUserKey)
|
||||
if ctxUser == nil {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
reqUser, ok := ctxUser.(*UserClaims)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid context user")
|
||||
}
|
||||
return reqUser.User, nil
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package enum
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var PermissionMap = make(map[string][]string)
|
||||
|
||||
const (
|
||||
UserRead = "system.user:read"
|
||||
UserAll = "system.user:all"
|
||||
RoleRead = "system.role:read"
|
||||
RoleAll = "system.role:all"
|
||||
ClusterAll = "system.cluster:all"
|
||||
ClusterRead = "system.cluster:read"
|
||||
CommandAll = "system.command:all"
|
||||
CommandRead = "system.command:read"
|
||||
|
||||
InstanceRead = "gateway.instance:read"
|
||||
InstanceAll = "gateway.instance:all"
|
||||
EntryAll = "gateway.entry:all"
|
||||
EntryRead = "gateway.entry:read"
|
||||
RouterRead = "gateway.router:read"
|
||||
RouterAll = "gateway.router:all"
|
||||
FlowRead = "gateway.flow:read"
|
||||
FlowAll = "gateway.flow:all"
|
||||
|
||||
IndexAll = "data.index:all"
|
||||
IndexRead = "data.index:read"
|
||||
ViewsAll = "data.view:all"
|
||||
ViewsRead = "data.view:read"
|
||||
DiscoverAll = "data.discover:all"
|
||||
DiscoverRead = "data.discover:read"
|
||||
|
||||
RuleRead = "alerting.rule:read"
|
||||
RuleAll = "alerting.rule:all"
|
||||
AlertRead = "alerting.alert:read"
|
||||
AlertAll = "alerting.alert:all"
|
||||
ChannelRead = "alerting.channel:read"
|
||||
ChannelAll = "alerting.channel:all"
|
||||
|
||||
ClusterOverviewRead = "cluster.overview:read"
|
||||
ClusterOverviewAll = "cluster.overview:all"
|
||||
MonitoringRead = "cluster.monitoring:read"
|
||||
MonitoringAll = "cluster.monitoring:all"
|
||||
ActivitiesRead = "cluster.activities:read"
|
||||
ActivitiesAll = "cluster.activities:all"
|
||||
)
|
||||
|
||||
const (
|
||||
PermissionUserRead string = "user:read"
|
||||
PermissionUserWrite = "user:write"
|
||||
PermissionRoleRead = "role:read"
|
||||
PermissionRoleWrite = "role:write"
|
||||
PermissionCommandRead = "command:read"
|
||||
PermissionCommandWrite = "command:write"
|
||||
PermissionElasticsearchClusterRead = "es.cluster:read"
|
||||
PermissionElasticsearchClusterWrite = "es.cluster:write" // es cluster
|
||||
PermissionElasticsearchIndexRead = "es.index:read"
|
||||
PermissionElasticsearchIndexWrite = "es.index:write" // es index metadata
|
||||
PermissionElasticsearchNodeRead = "es.node:read" //es node metadata
|
||||
PermissionActivityRead = "activity:read"
|
||||
PermissionActivityWrite = "activity:write"
|
||||
PermissionAlertRuleRead = "alert.rule:read"
|
||||
PermissionAlertRuleWrite = "alert.rule:write"
|
||||
PermissionAlertHistoryRead = "alert.history:read"
|
||||
PermissionAlertHistoryWrite = "alert.history:write"
|
||||
PermissionAlertChannelRead = "alert.channel:read"
|
||||
PermissionAlertChannelWrite = "alert.channel:write"
|
||||
PermissionViewRead = "view:read"
|
||||
PermissionViewWrite = "view:write"
|
||||
PermissionGatewayInstanceRead = "gateway.instance:read"
|
||||
PermissionGatewayInstanceWrite = "gateway.instance:write"
|
||||
PermissionGatewayEntryRead = "gateway.entry:read"
|
||||
PermissionGatewayEntryWrite = "gateway.entry:write"
|
||||
PermissionGatewayRouterRead = "gateway.router:read"
|
||||
PermissionGatewayRouterWrite = "gateway.router:write"
|
||||
PermissionGatewayFlowRead = "gateway.flow:read"
|
||||
PermissionGatewayFlowWrite = "gateway.flow:write"
|
||||
PermissionElasticsearchMetricRead = "es.metric:read"
|
||||
)
|
||||
|
||||
var (
|
||||
UserReadPermission = []string{PermissionUserRead}
|
||||
UserAllPermission = []string{PermissionUserRead, PermissionUserWrite,PermissionRoleRead}
|
||||
|
||||
RoleReadPermission = []string{PermissionRoleRead}
|
||||
RoleAllPermission = []string{PermissionRoleRead, PermissionRoleWrite}
|
||||
|
||||
ClusterReadPermission = []string{PermissionElasticsearchClusterRead}
|
||||
ClusterAllPermission = []string{PermissionElasticsearchClusterRead, PermissionElasticsearchClusterWrite}
|
||||
|
||||
CommandReadPermission = []string{PermissionCommandRead}
|
||||
CommandAllPermission = []string{PermissionCommandRead, PermissionCommandWrite}
|
||||
|
||||
InstanceReadPermission = []string{PermissionGatewayInstanceRead}
|
||||
InstanceAllPermission = []string{PermissionGatewayInstanceRead,PermissionGatewayInstanceWrite}
|
||||
|
||||
EntryReadPermission = []string{PermissionGatewayEntryRead}
|
||||
EntryAllPermission = []string{PermissionGatewayEntryRead, PermissionGatewayEntryWrite}
|
||||
|
||||
RouterReadPermission = []string{PermissionGatewayRouterRead}
|
||||
RouterAllPermission = []string{PermissionGatewayRouterRead, PermissionGatewayRouterWrite}
|
||||
|
||||
FlowReadPermission = []string{PermissionGatewayFlowRead}
|
||||
FlowAllPermission = []string{PermissionGatewayFlowRead, PermissionGatewayFlowWrite}
|
||||
|
||||
IndexAllPermission = []string{"index:read"}
|
||||
IndexReadPermission = []string{"index:read", "index:write"}
|
||||
ViewsAllPermission = []string{PermissionViewRead}
|
||||
ViewsReadPermission = []string{PermissionViewRead, PermissionViewWrite}
|
||||
DiscoverReadPermission = []string{PermissionViewRead}
|
||||
DiscoverAllPermission = []string{PermissionViewRead}
|
||||
|
||||
RuleReadPermission = []string{PermissionAlertRuleRead}
|
||||
RuleAllPermission = []string{PermissionAlertRuleRead, PermissionAlertRuleWrite}
|
||||
AlertReadPermission = []string{PermissionAlertHistoryRead}
|
||||
AlertAllPermission = []string{PermissionAlertHistoryRead, PermissionAlertHistoryWrite}
|
||||
ChannelReadPermission = []string{PermissionAlertChannelRead}
|
||||
ChannelAllPermission = []string{PermissionAlertChannelRead, PermissionAlertChannelWrite}
|
||||
|
||||
ClusterOverviewReadPermission = []string{PermissionElasticsearchClusterRead, PermissionElasticsearchIndexRead, PermissionElasticsearchNodeRead, PermissionElasticsearchMetricRead}
|
||||
ClusterOverviewAllPermission = ClusterOverviewReadPermission
|
||||
MonitoringReadPermission = ClusterOverviewAllPermission
|
||||
|
||||
ActivitiesReadPermission = []string{PermissionActivityRead}
|
||||
ActivitiesAllPermission = []string{PermissionActivityRead, PermissionActivityWrite}
|
||||
)
|
||||
|
||||
var AdminPrivilege = []string{
|
||||
UserAll, RoleAll, ClusterAll, CommandAll,
|
||||
InstanceAll, EntryAll, RouterAll, FlowAll,
|
||||
IndexAll, ViewsAll, DiscoverAll,
|
||||
RuleAll, AlertAll, ChannelAll,
|
||||
ClusterOverviewAll, MonitoringAll, ActivitiesAll,
|
||||
}
|
||||
|
||||
var BuildRoles = make(map[string]map[string]interface{}, 0)
|
||||
|
||||
func init() {
|
||||
|
||||
BuildRoles["admin"] = map[string]interface{}{
|
||||
"id": "admin",
|
||||
"name": "管理员",
|
||||
"type": "platform",
|
||||
"platform": AdminPrivilege,
|
||||
"builtin": true,
|
||||
"description": "is admin",
|
||||
"created": time.Now(),
|
||||
}
|
||||
PermissionMap = map[string][]string{
|
||||
UserRead: UserReadPermission,
|
||||
UserAll: UserAllPermission,
|
||||
RoleRead: RoleReadPermission,
|
||||
RoleAll: RoleAllPermission,
|
||||
ClusterRead: ClusterReadPermission,
|
||||
ClusterAll: ClusterAllPermission,
|
||||
CommandRead: CommandReadPermission,
|
||||
CommandAll: CommandAllPermission,
|
||||
|
||||
InstanceRead: InstanceReadPermission,
|
||||
InstanceAll: InstanceAllPermission,
|
||||
EntryRead: EntryReadPermission,
|
||||
EntryAll: EntryAllPermission,
|
||||
RouterRead: RouterReadPermission,
|
||||
RouterAll: RouterAllPermission,
|
||||
FlowRead: FlowReadPermission,
|
||||
FlowAll: FlowAllPermission,
|
||||
|
||||
IndexAll: IndexAllPermission,
|
||||
IndexRead: IndexReadPermission,
|
||||
ViewsAll: ViewsAllPermission,
|
||||
ViewsRead: ViewsReadPermission,
|
||||
DiscoverRead: DiscoverReadPermission,
|
||||
DiscoverAll: DiscoverAllPermission,
|
||||
|
||||
RuleRead: RuleReadPermission,
|
||||
RuleAll: RuleAllPermission,
|
||||
AlertRead: AlertReadPermission,
|
||||
AlertAll: AlertAllPermission,
|
||||
ChannelRead: ChannelReadPermission,
|
||||
ChannelAll: ChannelAllPermission,
|
||||
|
||||
ClusterOverviewRead: ClusterOverviewReadPermission,
|
||||
ClusterOverviewAll: ClusterOverviewAllPermission,
|
||||
MonitoringAll: MonitoringReadPermission,
|
||||
MonitoringRead: MonitoringReadPermission,
|
||||
ActivitiesAll: ActivitiesAllPermission,
|
||||
ActivitiesRead: ActivitiesReadPermission,
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"infini.sh/framework/core/event"
|
||||
"infini.sh/framework/core/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GenerateEvent(metadata event.ActivityMetadata, fields util.MapStr, changeLog interface{}) *event.Activity {
|
||||
return &event.Activity{
|
||||
ID: util.GetUUID(),
|
||||
Timestamp: time.Now(),
|
||||
Metadata: metadata,
|
||||
Fields: fields,
|
||||
Changelog: changeLog,
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"infini.sh/console/model/rbac"
|
||||
)
|
||||
|
||||
var ClusterApis = make(map[string][]string)
|
||||
var IndexApis = make([]string, 50)
|
||||
|
||||
var RoleMap = make(map[string]rbac.Role)
|
||||
|
||||
type Token struct {
|
||||
JwtStr string `json:"jwt_str"`
|
||||
Value string `json:"value"`
|
||||
ExpireIn int64 `json:"expire_in"`
|
||||
}
|
||||
|
||||
var TokenMap = make(map[string]Token)
|
||||
|
||||
|
||||
type RolePermission struct {
|
||||
Platform []string `json:"platform,omitempty"`
|
||||
Cluster []string `json:"cluster"`
|
||||
ClusterPrivilege []string `json:"cluster_privilege"`
|
||||
|
||||
IndexPrivilege map[string][]string `json:"index_privilege"`
|
||||
}
|
||||
|
||||
func ListElasticsearchPermission() interface{} {
|
||||
list := ElasticsearchPermission{
|
||||
ClusterPrivileges: ClusterApis,
|
||||
IndexPrivileges: IndexApis,
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
type ElasticsearchPermission struct {
|
||||
IndexPrivileges []string `json:"index_privileges"`
|
||||
ClusterPrivileges map[string][]string `json:"cluster_privileges"`
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"infini.sh/console/internal/biz/enum"
|
||||
"infini.sh/console/model/rbac"
|
||||
"infini.sh/framework/core/event"
|
||||
"infini.sh/framework/core/orm"
|
||||
"infini.sh/framework/core/util"
|
||||
log "src/github.com/cihub/seelog"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RoleType = string
|
||||
|
||||
const (
|
||||
Platform RoleType = "platform"
|
||||
Elastisearch RoleType = "elasticsearch"
|
||||
)
|
||||
|
||||
func UpdateRole(localUser *User, role *rbac.Role) (err error) {
|
||||
model, err := GetRole(role.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
role.Type = model.Type
|
||||
role.Created = model.Created
|
||||
changeLog, _ := util.DiffTwoObject(model, role)
|
||||
role.Updated = time.Now()
|
||||
err = orm.Save(role)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
RoleMap[model.Name] = model
|
||||
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "role",
|
||||
Type: "update",
|
||||
Labels: util.MapStr{
|
||||
"id": model.ID,
|
||||
"description": model.Description,
|
||||
"privilege": role.Privilege,
|
||||
"updated": model.Updated,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"userid": localUser.UserId,
|
||||
"username": localUser.Username,
|
||||
},
|
||||
}, nil, changeLog))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func CreateRole(localUser *User, role *rbac.Role) (id string, err error) {
|
||||
if role.Name == "" {
|
||||
err = errors.New("role name is require")
|
||||
return
|
||||
}
|
||||
if _, ok := enum.BuildRoles[role.Name]; ok {
|
||||
err = fmt.Errorf("role name %s already exists", role.Name)
|
||||
return
|
||||
}
|
||||
q := orm.Query{Size: 1}
|
||||
q.Conds = orm.And(orm.Eq("name", role.Name))
|
||||
|
||||
err, result := orm.Search(rbac.Role{}, &q)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if result.Total > 0 {
|
||||
err = fmt.Errorf("role name %s already exists", role.Name)
|
||||
return
|
||||
}
|
||||
|
||||
role.ID = util.GetUUID()
|
||||
role.Created = time.Now()
|
||||
role.Updated = time.Now()
|
||||
err = orm.Save(role)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
id = role.ID
|
||||
RoleMap[role.Name] = *role
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "role",
|
||||
Type: "create",
|
||||
Labels: util.MapStr{
|
||||
"id": id,
|
||||
"name": role.Name,
|
||||
"description": role.Description,
|
||||
"privilege": role.Privilege,
|
||||
"type": role.Type,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"userid": localUser.UserId,
|
||||
"username": localUser.Username,
|
||||
},
|
||||
}, nil, nil))
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
func DeleteRole(localUser *User, id string) (err error) {
|
||||
role := rbac.Role{}
|
||||
role.ID = id
|
||||
roleName := role.Name
|
||||
_, err = orm.Get(&role)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = orm.Delete(&role)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
delete(RoleMap, roleName)
|
||||
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "role",
|
||||
Type: "delete",
|
||||
Labels: util.MapStr{
|
||||
"id": id,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"userid": localUser.UserId,
|
||||
"username": localUser.Username,
|
||||
},
|
||||
}, util.MapStr{
|
||||
"id": id,
|
||||
"name": role.Name,
|
||||
"description": role.Description,
|
||||
"type": role.Type,
|
||||
"created": role.Created.Format("2006-01-02 15:04:05"),
|
||||
"updated": role.Updated.Format("2006-01-02 15:04:05"),
|
||||
}, nil))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func GetRole(id string) (role rbac.Role, err error) {
|
||||
|
||||
role.ID = id
|
||||
_, err = orm.Get(&role)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SearchRole(keyword string, from, size int) (roles orm.Result, err error) {
|
||||
|
||||
query := orm.Query{}
|
||||
|
||||
queryDSL := `{"query":{"bool":{"must":[%s]}}, "from": %d,"size": %d}`
|
||||
mustBuilder := &strings.Builder{}
|
||||
|
||||
if keyword != "" {
|
||||
mustBuilder.WriteString(fmt.Sprintf(`{"query_string":{"default_field":"*","query": "%s"}}`, keyword))
|
||||
}
|
||||
queryDSL = fmt.Sprintf(queryDSL, mustBuilder.String(), from, size)
|
||||
query.RawQuery = []byte(queryDSL)
|
||||
|
||||
err, roles = orm.Search(rbac.Role{}, &query)
|
||||
|
||||
return
|
||||
}
|
||||
func IsAllowRoleType(roleType string) (err error) {
|
||||
if roleType != Platform && roleType != Elastisearch {
|
||||
err = fmt.Errorf("invalid role type %s ", roleType)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
|
@ -0,0 +1,279 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"infini.sh/console/internal/dto"
|
||||
"infini.sh/console/model/rbac"
|
||||
"infini.sh/framework/core/event"
|
||||
|
||||
"infini.sh/framework/core/orm"
|
||||
"infini.sh/framework/core/util"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var ErrNotFound = fmt.Errorf("not found")
|
||||
|
||||
func DeleteUser(localUser *User, id string) (err error) {
|
||||
|
||||
user := rbac.User{}
|
||||
user.ID = id
|
||||
_, err = orm.Get(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = orm.Delete(user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
delete(TokenMap, id)
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "user",
|
||||
Type: "delete",
|
||||
Labels: util.MapStr{
|
||||
"id": id,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"userid": localUser.UserId,
|
||||
"username": localUser.Username,
|
||||
},
|
||||
}, util.MapStr{
|
||||
"id": id,
|
||||
"name": user.Name,
|
||||
"email": user.Email,
|
||||
"phone": user.Phone,
|
||||
"password": user.Password,
|
||||
"nickname": user.NickName,
|
||||
"tags": user.Tags,
|
||||
"roles": user.Roles,
|
||||
"created": user.Created,
|
||||
"updated": user.Updated,
|
||||
}, nil))
|
||||
return
|
||||
}
|
||||
func CreateUser(localUser *User, req dto.CreateUser) (id string, password string, err error) {
|
||||
q := orm.Query{Size: 1000}
|
||||
q.Conds = orm.And(orm.Eq("name", req.Name))
|
||||
|
||||
err, result := orm.Search(rbac.User{}, &q)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if result.Total > 0 {
|
||||
err = fmt.Errorf("user name %s already exists", req.Name)
|
||||
return
|
||||
}
|
||||
|
||||
roles := make([]rbac.UserRole, 0)
|
||||
for _, v := range req.Roles {
|
||||
roles = append(roles, rbac.UserRole{
|
||||
ID: v.Id,
|
||||
Name: v.Name,
|
||||
})
|
||||
}
|
||||
randStr := util.GenerateRandomString(8)
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(randStr), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
user := rbac.User{
|
||||
Name: req.Name,
|
||||
NickName: req.NickName,
|
||||
Password: string(hash),
|
||||
Email: req.Email,
|
||||
Phone: req.Phone,
|
||||
Roles: roles,
|
||||
Tags: req.Tags,
|
||||
}
|
||||
user.ID = util.GetUUID()
|
||||
user.Created = time.Now()
|
||||
user.Updated = time.Now()
|
||||
err = orm.Save(&user)
|
||||
if err != nil {
|
||||
|
||||
return
|
||||
}
|
||||
id = user.ID
|
||||
password = randStr
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "user",
|
||||
Type: "create",
|
||||
Labels: util.MapStr{
|
||||
"id": id,
|
||||
"name": user.Name,
|
||||
"email": user.Email,
|
||||
"phone": user.Phone,
|
||||
"password": user.Password,
|
||||
"nick_name": user.NickName,
|
||||
"tags": user.Tags,
|
||||
"roles": user.Roles,
|
||||
"created": user.Created,
|
||||
"updated": user.Updated,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"userid": localUser.UserId,
|
||||
"username": localUser.Username,
|
||||
},
|
||||
}, nil, nil))
|
||||
return
|
||||
}
|
||||
func UpdateUser(localUser *User, id string, req dto.UpdateUser) (err error) {
|
||||
user := rbac.User{}
|
||||
user.ID = id
|
||||
_, err = orm.Get(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
roles := make([]rbac.UserRole, 0)
|
||||
for _, v := range req.Roles {
|
||||
roles = append(roles, rbac.UserRole{
|
||||
ID: v.Id,
|
||||
Name: v.Name,
|
||||
})
|
||||
}
|
||||
changeLog, _ := util.DiffTwoObject(user, req)
|
||||
user.Name = req.Name
|
||||
user.Email = req.Email
|
||||
user.Phone = req.Phone
|
||||
user.Tags = req.Tags
|
||||
user.Roles = roles
|
||||
user.Updated = time.Now()
|
||||
err = orm.Save(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
delete(TokenMap, id)
|
||||
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "user",
|
||||
Type: "update",
|
||||
Labels: util.MapStr{
|
||||
"id": id,
|
||||
"email": user.Email,
|
||||
"phone": user.Phone,
|
||||
"name": user.Name,
|
||||
"tags": user.Tags,
|
||||
"roles": roles,
|
||||
"updated": user.Updated,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"userid": localUser.UserId,
|
||||
"username": localUser.Username,
|
||||
},
|
||||
}, nil, changeLog))
|
||||
return
|
||||
}
|
||||
func UpdateUserRole(localUser *User, id string, req dto.UpdateUserRole) (err error) {
|
||||
user := rbac.User{}
|
||||
user.ID = id
|
||||
_, err = orm.Get(&user)
|
||||
if err != nil {
|
||||
|
||||
return
|
||||
}
|
||||
changeLog, _ := util.DiffTwoObject(user, req)
|
||||
roles := make([]rbac.UserRole, 0)
|
||||
for _, v := range req.Roles {
|
||||
roles = append(roles, rbac.UserRole{
|
||||
ID: v.Id,
|
||||
Name: v.Name,
|
||||
})
|
||||
}
|
||||
user.Roles = roles
|
||||
user.Updated = time.Now()
|
||||
err = orm.Save(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
delete(TokenMap, id)
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "user",
|
||||
Type: "update",
|
||||
Labels: util.MapStr{
|
||||
"id": id,
|
||||
"roles": user.Roles,
|
||||
"updated": user.Updated,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"userid": localUser.UserId,
|
||||
"username": localUser.Username,
|
||||
},
|
||||
}, nil, changeLog))
|
||||
return
|
||||
|
||||
}
|
||||
func GetUser(id string) (user rbac.User, err error) {
|
||||
|
||||
user.ID = id
|
||||
_, err = orm.Get(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
func SearchUser(keyword string, from, size int) (users orm.Result, err error) {
|
||||
query := orm.Query{}
|
||||
|
||||
queryDSL := `{"query":{"bool":{"must":[%s]}}, "from": %d,"size": %d}`
|
||||
mustBuilder := &strings.Builder{}
|
||||
|
||||
if keyword != "" {
|
||||
mustBuilder.WriteString(fmt.Sprintf(`{"query_string":{"default_field":"*","query": "%s"}}`, keyword))
|
||||
}
|
||||
queryDSL = fmt.Sprintf(queryDSL, mustBuilder.String(), from, size)
|
||||
query.RawQuery = []byte(queryDSL)
|
||||
|
||||
err, users = orm.Search(rbac.User{}, &query)
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
func UpdateUserPassword(localUser *User, id string, password string) (err error) {
|
||||
user := rbac.User{}
|
||||
user.ID = id
|
||||
_, err = orm.Get(&user)
|
||||
if err != nil {
|
||||
|
||||
return
|
||||
}
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
user.Password = string(hash)
|
||||
user.Updated = time.Now()
|
||||
err = orm.Save(&user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if localUser.UserId == id {
|
||||
delete(TokenMap, localUser.UserId)
|
||||
}
|
||||
err = orm.Save(GenerateEvent(event.ActivityMetadata{
|
||||
Category: "platform",
|
||||
Group: "rbac",
|
||||
Name: "user",
|
||||
Type: "update",
|
||||
Labels: util.MapStr{
|
||||
"id": id,
|
||||
"password": password,
|
||||
"updated": user.Updated,
|
||||
},
|
||||
User: util.MapStr{
|
||||
"userid": localUser.UserId,
|
||||
"username": localUser.Username,
|
||||
},
|
||||
}, nil, nil))
|
||||
return
|
||||
}
|
|
@ -0,0 +1,273 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"infini.sh/console/internal/biz/enum"
|
||||
"infini.sh/console/model/rbac"
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"infini.sh/framework/core/util"
|
||||
"src/github.com/golang-jwt/jwt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type EsRequest struct {
|
||||
Doc string `json:"doc"`
|
||||
Privilege string `json:"privilege"`
|
||||
ClusterRequest
|
||||
IndexRequest
|
||||
}
|
||||
type ClusterRequest struct {
|
||||
Cluster []string `json:"cluster"`
|
||||
Privilege []string `json:"privilege"`
|
||||
}
|
||||
type IndexRequest struct {
|
||||
Cluster []string `json:"cluster"`
|
||||
Index []string `json:"index"`
|
||||
Privilege []string `json:"privilege"`
|
||||
}
|
||||
|
||||
func NewIndexRequest(ps httprouter.Params, privilege []string) IndexRequest {
|
||||
index := ps.ByName("index")
|
||||
clusterId := ps.ByName("id")
|
||||
return IndexRequest{
|
||||
Cluster: []string{clusterId},
|
||||
Index: []string{index},
|
||||
Privilege: privilege,
|
||||
}
|
||||
}
|
||||
func NewClusterRequest(ps httprouter.Params, privilege []string) ClusterRequest {
|
||||
clusterId := ps.ByName("id")
|
||||
return ClusterRequest{
|
||||
Cluster: []string{clusterId},
|
||||
Privilege: privilege,
|
||||
}
|
||||
}
|
||||
|
||||
func ValidateElasticsearch(req rbac.ElasticsearchPrivilege, roleNames []string) (err error) {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateIndex(req IndexRequest, userRole RolePermission) (err error) {
|
||||
|
||||
userClusterMap := make(map[string]struct{})
|
||||
for _, v := range userRole.Cluster {
|
||||
userClusterMap[v] = struct{}{}
|
||||
}
|
||||
for _, v := range req.Cluster {
|
||||
if _, ok := userClusterMap[v]; !ok {
|
||||
err = errors.New("no cluster permission")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, val := range req.Privilege {
|
||||
position := strings.Index(val, ".")
|
||||
if position == -1 {
|
||||
err = errors.New("invalid privilege parameter")
|
||||
return err
|
||||
}
|
||||
prefix := val[:position]
|
||||
for _, v := range req.Index {
|
||||
privilege, ok := userRole.IndexPrivilege[v]
|
||||
if !ok {
|
||||
err = errors.New("no index permission")
|
||||
return err
|
||||
}
|
||||
if util.StringInArray(privilege, prefix+".*") {
|
||||
continue
|
||||
}
|
||||
if util.StringInArray(privilege, val) {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("no index api permission: %s", val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func ValidateCluster(req ClusterRequest, roleNames []string) (err error) {
|
||||
userClusterMap := GetRoleClusterMap(roleNames)
|
||||
for _, v := range req.Cluster {
|
||||
userClusterPermissions, ok := userClusterMap[v]
|
||||
if !ok && userClusterMap["*"] == nil{
|
||||
err = fmt.Errorf("no cluster[%s] permission", v)
|
||||
return
|
||||
}
|
||||
if util.StringInArray(userClusterPermissions, "*") {
|
||||
continue
|
||||
}
|
||||
// if include api.* for example: cat.* , return nil
|
||||
for _, privilege := range req.Privilege {
|
||||
prefix := privilege[:strings.Index(privilege, ".")]
|
||||
|
||||
if util.StringInArray(userClusterPermissions, prefix+".*") {
|
||||
continue
|
||||
}
|
||||
if util.StringInArray(userClusterPermissions, privilege) {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("no cluster api permission: %s", privilege)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func CombineUserRoles(roleNames []string) RolePermission {
|
||||
newRole := RolePermission{}
|
||||
m := make(map[string][]string)
|
||||
for _, val := range roleNames {
|
||||
role := RoleMap[val]
|
||||
for _, v := range role.Privilege.Elasticsearch.Cluster.Resources {
|
||||
newRole.Cluster = append(newRole.Cluster, v.ID)
|
||||
}
|
||||
for _, v := range role.Privilege.Elasticsearch.Cluster.Permissions {
|
||||
newRole.ClusterPrivilege = append(newRole.ClusterPrivilege, v)
|
||||
}
|
||||
for _, v := range role.Privilege.Platform {
|
||||
newRole.Platform = append(newRole.Platform, v)
|
||||
}
|
||||
for _, v := range role.Privilege.Elasticsearch.Index {
|
||||
|
||||
for _, name := range v.Name {
|
||||
if _, ok := m[name]; ok {
|
||||
m[name] = append(m[name], v.Permissions...)
|
||||
} else {
|
||||
m[name] = v.Permissions
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
newRole.IndexPrivilege = m
|
||||
return newRole
|
||||
}
|
||||
func GetRoleClusterMap(roles []string) map[string][]string {
|
||||
userClusterMap := make(map[string][]string, 0)
|
||||
for _, roleName := range roles {
|
||||
role, ok := RoleMap[roleName]
|
||||
if ok {
|
||||
for _, ic := range role.Privilege.Elasticsearch.Cluster.Resources {
|
||||
userClusterMap[ic.ID] = append(userClusterMap[ic.ID], role.Privilege.Elasticsearch.Cluster.Permissions...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return userClusterMap
|
||||
}
|
||||
func GetRoleCluster(roles []string) []string {
|
||||
userClusterMap := GetRoleClusterMap(roles)
|
||||
realCluster := make([]string, 0, len(userClusterMap))
|
||||
for k, _ := range userClusterMap {
|
||||
realCluster = append(realCluster, k)
|
||||
}
|
||||
return realCluster
|
||||
}
|
||||
func GetRoleIndex(roles, clusterIDs []string) map[string][]string {
|
||||
userClusterMap := make(map[string]struct{}, len(clusterIDs))
|
||||
for _, clusterID := range clusterIDs {
|
||||
userClusterMap[clusterID] = struct{}{}
|
||||
}
|
||||
realIndex := map[string][]string{}
|
||||
for _, roleName := range roles {
|
||||
role, ok := RoleMap[roleName]
|
||||
if ok {
|
||||
for _, ic := range role.Privilege.Elasticsearch.Cluster.Resources {
|
||||
if _, ok = userClusterMap[ic.ID]; !ok {
|
||||
continue
|
||||
}
|
||||
for _, ip := range role.Privilege.Elasticsearch.Index {
|
||||
realIndex[ic.ID] = append(realIndex[ic.ID], ip.Name...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return realIndex
|
||||
}
|
||||
func ValidateLogin(authorizationHeader string) (clams *UserClaims, err error) {
|
||||
|
||||
if authorizationHeader == "" {
|
||||
err = errors.New("authorization header is empty")
|
||||
return
|
||||
}
|
||||
fields := strings.Fields(authorizationHeader)
|
||||
if fields[0] != "Bearer" || len(fields) != 2 {
|
||||
err = errors.New("authorization header is invalid")
|
||||
return
|
||||
}
|
||||
tokenString := fields[1]
|
||||
|
||||
token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return []byte(Secret), nil
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
clams, ok := token.Claims.(*UserClaims)
|
||||
|
||||
if clams.UserId == "" {
|
||||
err = errors.New("user id is empty")
|
||||
return
|
||||
}
|
||||
//fmt.Println("user token", clams.UserId, TokenMap[clams.UserId])
|
||||
tokenVal, ok := TokenMap[clams.UserId]
|
||||
if !ok {
|
||||
err = errors.New("token is invalid")
|
||||
return
|
||||
}
|
||||
if tokenVal.ExpireIn < time.Now().Unix() {
|
||||
err = errors.New("token is expire in")
|
||||
delete(TokenMap, clams.UserId)
|
||||
return
|
||||
}
|
||||
if ok && token.Valid {
|
||||
return clams, nil
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
func ValidatePermission(claims *UserClaims, permissions []string) (err error) {
|
||||
|
||||
user := claims.User
|
||||
|
||||
if user.UserId == "" {
|
||||
err = errors.New("user id is empty")
|
||||
return
|
||||
}
|
||||
if user.Roles == nil {
|
||||
err = errors.New("api permission is empty")
|
||||
return
|
||||
}
|
||||
|
||||
// 权限校验
|
||||
userPermissions := make([]string, 0)
|
||||
for _, role := range user.Roles {
|
||||
if _, ok := RoleMap[role]; ok {
|
||||
for _, v := range RoleMap[role].Privilege.Platform {
|
||||
userPermissions = append(userPermissions, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
userPermissionMap := make(map[string]struct{})
|
||||
for _, val := range userPermissions {
|
||||
for _, v := range enum.PermissionMap[val] {
|
||||
userPermissionMap[v] = struct{}{}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for _, v := range permissions {
|
||||
if _, ok := userPermissionMap[v]; !ok {
|
||||
err = errors.New("permission denied")
|
||||
return
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"infini.sh/framework/core/util"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_validateIndex(t *testing.T) {
|
||||
type args struct {
|
||||
req IndexRequest
|
||||
userRole RolePermission
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{"no index permission",
|
||||
args{
|
||||
req: IndexRequest{
|
||||
|
||||
Cluster: []string{"cluster1"},
|
||||
Index: []string{"index2"},
|
||||
Privilege: []string{"indices.mapping"},
|
||||
},
|
||||
userRole: RolePermission{
|
||||
Cluster: []string{
|
||||
"cluster1",
|
||||
},
|
||||
|
||||
ClusterPrivilege: []string{
|
||||
"cat.*",
|
||||
},
|
||||
IndexPrivilege: map[string][]string{
|
||||
"index1": []string{"indices.delete"},
|
||||
},
|
||||
},
|
||||
}, "no index permission",
|
||||
},
|
||||
{"no index api permission",
|
||||
args{
|
||||
req: IndexRequest{
|
||||
|
||||
Cluster: []string{"cluster1"},
|
||||
Index: []string{"index1"},
|
||||
Privilege: []string{"indices.mapping"},
|
||||
},
|
||||
userRole: RolePermission{
|
||||
Cluster: []string{
|
||||
"cluster1",
|
||||
},
|
||||
|
||||
ClusterPrivilege: []string{
|
||||
"cat.*",
|
||||
},
|
||||
IndexPrivilege: map[string][]string{
|
||||
"index1": []string{"indices.delete"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"no index api permission",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
got := ValidateIndex(tt.args.req, tt.args.userRole)
|
||||
|
||||
assert.EqualError(t, got, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
func Test_validateCluster(t *testing.T) {
|
||||
type args struct {
|
||||
req ClusterRequest
|
||||
userRole RolePermission
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{"no cluster",
|
||||
args{
|
||||
req: ClusterRequest{
|
||||
|
||||
Cluster: []string{"cluster1"},
|
||||
Privilege: []string{"indices.get_mapping"},
|
||||
},
|
||||
userRole: RolePermission{
|
||||
Cluster: []string{
|
||||
"cluster2",
|
||||
},
|
||||
|
||||
ClusterPrivilege: []string{
|
||||
"cat.*",
|
||||
},
|
||||
},
|
||||
}, "no cluster permission",
|
||||
},
|
||||
{"no cluster",
|
||||
args{
|
||||
req: ClusterRequest{
|
||||
Cluster: []string{"cluster1"},
|
||||
Privilege: []string{"indices.get_mapping"},
|
||||
},
|
||||
userRole: RolePermission{
|
||||
Cluster: []string{},
|
||||
ClusterPrivilege: []string{},
|
||||
},
|
||||
}, "no cluster permission",
|
||||
},
|
||||
{"no cluster api",
|
||||
args{
|
||||
req: ClusterRequest{
|
||||
|
||||
Cluster: []string{"cluster1"},
|
||||
Privilege: []string{"indices.get_mapping"},
|
||||
},
|
||||
userRole: RolePermission{
|
||||
Cluster: []string{
|
||||
"cluster1",
|
||||
},
|
||||
|
||||
ClusterPrivilege: []string{
|
||||
"cat.*",
|
||||
},
|
||||
},
|
||||
},
|
||||
"no cluster api permission",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := ValidateCluster(tt.args.req, tt.args.userRole)
|
||||
assert.EqualError(t, got, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestStringInArray(t *testing.T) {
|
||||
array := []string{"a", "b", "c", "d", "e"}
|
||||
assert.Equal(t, true, util.StringInArray(array, "c"))
|
||||
assert.Equal(t, false, util.StringInArray(array, "h"))
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package core
|
||||
|
||||
type Response struct {
|
||||
Total int64 `json:"total,omitempty"`
|
||||
Hit interface{} `json:"hit,omitempty"`
|
||||
Id string `json:"_id,omitempty"`
|
||||
Result string `json:"result,omitempty"`
|
||||
}
|
||||
type FoundResp struct {
|
||||
Found bool `json:"found"`
|
||||
Id string `json:"_id,omitempty"`
|
||||
Source interface{} `json:"_source,omitempty"`
|
||||
}
|
||||
|
||||
func CreateResponse(id string) Response {
|
||||
return Response{
|
||||
Id: id,
|
||||
Result: "created",
|
||||
}
|
||||
}
|
||||
func UpdateResponse(id string) Response {
|
||||
return Response{
|
||||
Id: id,
|
||||
Result: "updated",
|
||||
}
|
||||
}
|
||||
func DeleteResponse(id string) Response {
|
||||
return Response{
|
||||
Id: id,
|
||||
Result: "deleted",
|
||||
}
|
||||
}
|
||||
func NotFoundResponse(id string) FoundResp {
|
||||
return FoundResp{
|
||||
Id: id,
|
||||
Found: false,
|
||||
}
|
||||
}
|
||||
func FoundResponse(id string, data interface{}) FoundResp {
|
||||
return FoundResp{
|
||||
Id: id,
|
||||
Found: true,
|
||||
Source: data,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package dto
|
||||
|
||||
type CreateUser struct {
|
||||
NickName string `json:"nick_name"`
|
||||
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Roles []Role `json:"roles"`
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
type Role struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
type UpdateUser struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Tags []string `json:"tags"`
|
||||
Roles []Role `json:"roles"`
|
||||
}
|
||||
type UpdateUserRole struct {
|
||||
Roles []Role `json:"roles"`
|
||||
}
|
||||
type UpdateUserPassword struct {
|
||||
Password string `json:"password"`
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package dto
|
||||
|
||||
type Login struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
type UpdatePassword struct {
|
||||
OldPassword string `json:"old_password"`
|
||||
NewPassword string `json:"new_password"`
|
||||
}
|
||||
type UpdateProfile struct {
|
||||
Name string `json:"name"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"infini.sh/console/internal/biz"
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func IndexRequired(h httprouter.Handle, route ...string) httprouter.Handle {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
claims, err := biz.ValidateLogin(r.Header.Get("Authorization"))
|
||||
if err != nil {
|
||||
w = handleError(w, http.StatusUnauthorized, err)
|
||||
return
|
||||
}
|
||||
newRole := biz.CombineUserRoles(claims.Roles)
|
||||
|
||||
indexReq := biz.NewIndexRequest(ps, route)
|
||||
|
||||
err = biz.ValidateIndex(indexReq, newRole)
|
||||
if err != nil {
|
||||
w = handleError(w, http.StatusForbidden, err)
|
||||
return
|
||||
}
|
||||
h(w, r, ps)
|
||||
}
|
||||
}
|
||||
func ClusterRequired(h httprouter.Handle, route ...string) httprouter.Handle {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
claims, err := biz.ValidateLogin(r.Header.Get("Authorization"))
|
||||
if err != nil {
|
||||
w = handleError(w, http.StatusUnauthorized, err)
|
||||
return
|
||||
}
|
||||
//newRole := biz.CombineUserRoles(claims.Roles)
|
||||
clusterReq := biz.NewClusterRequest(ps, route)
|
||||
|
||||
err = biz.ValidateCluster(clusterReq, claims.Roles)
|
||||
if err != nil {
|
||||
w = handleError(w, http.StatusForbidden, err)
|
||||
return
|
||||
}
|
||||
h(w, r, ps)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"infini.sh/console/internal/biz"
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"infini.sh/framework/core/util"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func LoginRequired(h httprouter.Handle) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
|
||||
claims, err := biz.ValidateLogin(r.Header.Get("Authorization"))
|
||||
if err != nil {
|
||||
w = handleError(w, http.StatusUnauthorized, err)
|
||||
return
|
||||
}
|
||||
r = r.WithContext(biz.NewUserContext(r.Context(), claims))
|
||||
h(w, r, ps)
|
||||
}
|
||||
}
|
||||
|
||||
func PermissionRequired(h httprouter.Handle, permissions ...string) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
claims, err := biz.ValidateLogin(r.Header.Get("Authorization"))
|
||||
if err != nil {
|
||||
|
||||
w = handleError(w, http.StatusUnauthorized, err)
|
||||
return
|
||||
}
|
||||
err = biz.ValidatePermission(claims, permissions)
|
||||
if err != nil {
|
||||
w = handleError(w, http.StatusForbidden, err)
|
||||
return
|
||||
}
|
||||
r = r.WithContext(biz.NewUserContext(r.Context(), claims))
|
||||
h(w, r, ps)
|
||||
}
|
||||
}
|
||||
func handleError(w http.ResponseWriter, statusCode int, err error) http.ResponseWriter {
|
||||
w.Header().Set("Content-type", util.ContentTypeJson)
|
||||
w.WriteHeader(statusCode)
|
||||
json := util.ToJson(util.MapStr{
|
||||
"error": util.MapStr{
|
||||
"status": statusCode,
|
||||
"reason": err.Error(),
|
||||
},
|
||||
}, true)
|
||||
w.Write([]byte(json))
|
||||
|
||||
return w
|
||||
}
|
19
main.go
19
main.go
|
@ -7,7 +7,9 @@ import (
|
|||
"infini.sh/console/model"
|
||||
"infini.sh/console/model/alerting"
|
||||
"infini.sh/console/model/gateway"
|
||||
"infini.sh/console/model/rbac"
|
||||
_ "infini.sh/console/plugin"
|
||||
rbacApi "infini.sh/console/plugin/api/rbac"
|
||||
alerting2 "infini.sh/console/service/alerting"
|
||||
"infini.sh/framework"
|
||||
"infini.sh/framework/core/elastic"
|
||||
|
@ -51,7 +53,7 @@ func main() {
|
|||
terminalFooter := ""
|
||||
|
||||
app := framework.NewApp("console", "INFINI Cloud Console, The easiest way to operate your own elasticsearch platform.",
|
||||
config.Version,config.BuildNumber, config.LastCommitLog, config.BuildDate, config.EOLDate, terminalHeader, terminalFooter)
|
||||
config.Version, config.BuildNumber, config.LastCommitLog, config.BuildDate, config.EOLDate, terminalHeader, terminalFooter)
|
||||
|
||||
app.Init(nil)
|
||||
defer app.Shutdown()
|
||||
|
@ -60,11 +62,10 @@ func main() {
|
|||
|
||||
if app.Setup(func() {
|
||||
err := bootstrapRequirementCheck()
|
||||
if err !=nil{
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
//load core modules first
|
||||
module.RegisterSystemModule(&elastic2.ElasticModule{})
|
||||
module.RegisterSystemModule(&filter.FilterModule{})
|
||||
|
@ -119,17 +120,17 @@ func main() {
|
|||
|
||||
module.Start()
|
||||
|
||||
|
||||
orm.RegisterSchemaWithIndexName(model.Dict{}, "dict")
|
||||
orm.RegisterSchemaWithIndexName(model.Reindex{}, "reindex")
|
||||
orm.RegisterSchemaWithIndexName(elastic.View{}, "view")
|
||||
orm.RegisterSchemaWithIndexName(alerting.Alert{}, "alerting-alerts")
|
||||
orm.RegisterSchemaWithIndexName(elastic.CommonCommand{}, "commands")
|
||||
orm.RegisterSchemaWithIndexName(elastic.TraceTemplate{}, "trace-template")
|
||||
orm.RegisterSchemaWithIndexName(gateway.Instance{} , "gateway-instance")
|
||||
orm.RegisterSchemaWithIndexName(alerting.Rule{} , "alert-rule")
|
||||
orm.RegisterSchemaWithIndexName(alerting.Alert{} , "alert-history")
|
||||
|
||||
orm.RegisterSchemaWithIndexName(gateway.Instance{}, "gateway-instance")
|
||||
orm.RegisterSchemaWithIndexName(alerting.Rule{}, "alert-rule")
|
||||
orm.RegisterSchemaWithIndexName(alerting.Alert{}, "alert-history")
|
||||
orm.RegisterSchemaWithIndexName(rbac.Role{}, "rbac-role")
|
||||
orm.RegisterSchemaWithIndexName(rbac.User{}, "rbac-user")
|
||||
api.RegisterSchema()
|
||||
|
||||
go func() {
|
||||
|
@ -138,6 +139,8 @@ func main() {
|
|||
log.Errorf("init alerting task error: %v", err)
|
||||
}
|
||||
}()
|
||||
go rbacApi.Init()
|
||||
|
||||
}, nil) {
|
||||
app.Run()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package rbac
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Role struct {
|
||||
ID string `json:"id,omitempty" elastic_meta:"_id" elastic_mapping:"id: { type: keyword }"`
|
||||
Created time.Time `json:"created,omitempty" elastic_mapping:"created: { type: date }"`
|
||||
Updated time.Time `json:"updated,omitempty" elastic_mapping:"updated: { type: date }"`
|
||||
Name string `json:"name" elastic_mapping:"name: { type: keyword }"`
|
||||
Type string `json:"type" elastic_mapping:"type: { type: keyword }"`
|
||||
Description string `json:"description" elastic_mapping:"description: { type: text }"`
|
||||
Builtin bool `json:"builtin" elastic_mapping:"builtin: { type: boolean }"`
|
||||
Privilege RolePrivilege `json:"privilege" elastic_mapping:"privilege: { type: object }"`
|
||||
}
|
||||
|
||||
type RolePrivilege struct {
|
||||
Platform []string `json:"platform,omitempty" elastic_mapping:"platform: { type: keyword }"`
|
||||
Elasticsearch ElasticsearchPrivilege `json:"elasticsearch,omitempty" elastic_mapping:"elasticsearch: { type: object }"`
|
||||
}
|
||||
|
||||
type ElasticsearchPrivilege struct {
|
||||
Cluster ClusterPrivilege `json:"cluster,omitempty" elastic_mapping:"cluster: { type: object }"`
|
||||
Index []IndexPrivilege `json:"index,omitempty" elastic_mapping:"index: { type: object }"`
|
||||
}
|
||||
|
||||
type InnerCluster struct {
|
||||
ID string `json:"id" elastic_mapping:"id: { type: keyword }"`
|
||||
Name string `json:"name" elastic_mapping:"name: { type: keyword }"`
|
||||
}
|
||||
type ClusterPrivilege struct {
|
||||
Resources []InnerCluster `json:"resources,omitempty" elastic_mapping:"resources: { type: object }"`
|
||||
Permissions []string `json:"permissions,omitempty" elastic_mapping:"permissions: { type: keyword }"`
|
||||
}
|
||||
|
||||
type IndexPrivilege struct {
|
||||
Name []string `json:"name,omitempty" elastic_mapping:"name: { type: keyword }"`
|
||||
Permissions []string `json:"permissions,omitempty" elastic_mapping:"permissions: { type: keyword }"`
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package rbac
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id,omitempty" elastic_meta:"_id" elastic_mapping:"id: { type: keyword }"`
|
||||
Created time.Time `json:"created,omitempty" elastic_mapping:"created: { type: date }"`
|
||||
Updated time.Time `json:"updated,omitempty" elastic_mapping:"updated: { type: date }"`
|
||||
Name string `json:"name" elastic_mapping:"name: { type: keyword }"`
|
||||
NickName string `json:"nick_name" elastic_mapping:"nick_name: { type: keyword }"`
|
||||
Password string `json:"password" elastic_mapping:"password: { type: keyword }"`
|
||||
Email string `json:"email" elastic_mapping:"email: { type: keyword }"`
|
||||
Phone string `json:"phone" elastic_mapping:"phone: { type: keyword }"`
|
||||
Tags []string `json:"tags" elastic_mapping:"mobile: { type: keyword }"`
|
||||
Roles []UserRole `json:"roles" elastic_mapping:"roles: { type: object }"`
|
||||
}
|
||||
|
||||
type UserRole struct {
|
||||
ID string `json:"id" elastic_mapping:"id: { type: keyword }"`
|
||||
Name string `json:"name" elastic_mapping:"name: { type: keyword }"`
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
package account
|
||||
|
||||
import (
|
||||
"infini.sh/console/internal/biz"
|
||||
"infini.sh/console/internal/core"
|
||||
"infini.sh/console/internal/dto"
|
||||
m "infini.sh/console/internal/middleware"
|
||||
"infini.sh/framework/core/api"
|
||||
"infini.sh/framework/core/api/router"
|
||||
"infini.sh/framework/core/global"
|
||||
"infini.sh/framework/core/util"
|
||||
"net/http"
|
||||
)
|
||||
|
@ -13,59 +16,43 @@ type Account struct {
|
|||
}
|
||||
|
||||
func init() {
|
||||
account:=Account{}
|
||||
api.HandleAPIMethod(api.POST, "/account/login", account.AccountLogin)
|
||||
account := Account{}
|
||||
api.HandleAPIMethod(api.POST, "/account/login", account.Login)
|
||||
|
||||
api.HandleAPIMethod(api.GET, "/account/current_user", account.CurrentUser)
|
||||
|
||||
api.HandleAPIMethod(api.DELETE, "/account/logout", account.Logout)
|
||||
api.HandleAPIMethod(api.GET, "/account/profile", m.LoginRequired(account.Profile))
|
||||
api.HandleAPIMethod(api.PUT, "/account/password", m.LoginRequired(account.UpdatePassword))
|
||||
}
|
||||
|
||||
var userInSession string="user_in_session"
|
||||
const userInSession = "user_session:"
|
||||
|
||||
func (handler Account)AccountLogin(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
func (h Account) Login(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
|
||||
//{"userName":"admin","password":"111111","type":"account"}
|
||||
|
||||
json,err:=handler.GetJSON(req)
|
||||
if err!=nil{
|
||||
handler.Error(w,err)
|
||||
return
|
||||
}
|
||||
userName,err:=json.String("userName")
|
||||
if err!=nil{
|
||||
handler.Error(w,err)
|
||||
return
|
||||
}
|
||||
password,err:=json.String("password")
|
||||
if err!=nil{
|
||||
handler.Error(w,err)
|
||||
var req dto.Login
|
||||
err := h.DecodeJSON(r, &req)
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
u,_:=global.Env().GetConfig("bootstrap.username","admin")
|
||||
p,_:=global.Env().GetConfig("bootstrap.password","admin")
|
||||
if u==userName&&p==password{
|
||||
data := util.MapStr{
|
||||
"status": "ok",
|
||||
"type": "account",
|
||||
"currentAuthority": "admin",
|
||||
"userid": "10001",
|
||||
}
|
||||
api.SetSession(w,req, userInSession,userName)
|
||||
handler.WriteJSON(w, data, http.StatusOK)
|
||||
}else{
|
||||
data := util.MapStr{
|
||||
"status": "error",
|
||||
"type": "account",
|
||||
"currentAuthority": "guest",
|
||||
}
|
||||
handler.WriteJSON(w, data, http.StatusOK)
|
||||
data, err := biz.Login(req.Username, req.Password)
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
data["status"] = "ok"
|
||||
|
||||
//api.SetSession(w, r, userInSession+req.Username, req.Username)
|
||||
h.WriteOKJSON(w, data)
|
||||
}
|
||||
|
||||
func (handler Account)CurrentUser(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
func (h Account) CurrentUser(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
|
||||
exists,user:=api.GetSession(w,req, userInSession)
|
||||
if exists{
|
||||
data:=util.MapStr{
|
||||
exists, user := api.GetSession(w, req, userInSession)
|
||||
if exists {
|
||||
data := util.MapStr{
|
||||
"name": user,
|
||||
"avatar": "",
|
||||
"userid": "10001",
|
||||
|
@ -94,13 +81,96 @@ func (handler Account)CurrentUser(w http.ResponseWriter, req *http.Request, ps h
|
|||
"phone": "4001399200",
|
||||
}
|
||||
|
||||
handler.WriteJSON(w, data,200)
|
||||
}else{
|
||||
h.WriteJSON(w, data, 200)
|
||||
} else {
|
||||
data := util.MapStr{
|
||||
"status": "error",
|
||||
"type": "account",
|
||||
"currentAuthority": "guest",
|
||||
}
|
||||
handler.WriteJSON(w, data, 403)
|
||||
h.WriteJSON(w, data, 403)
|
||||
}
|
||||
}
|
||||
func (h Account) Logout(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
reqUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
delete(biz.TokenMap, reqUser.UserId)
|
||||
h.WriteOKJSON(w, util.MapStr{
|
||||
"status": "ok",
|
||||
})
|
||||
}
|
||||
func (h Account) Profile(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
reqUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if reqUser.UserId == "admin" {
|
||||
|
||||
u := util.MapStr{
|
||||
"user_id": "admin",
|
||||
"name": "admin",
|
||||
"email": "admin@infini.ltd",
|
||||
"nick_name": "admin",
|
||||
"phone": "13011111111",
|
||||
}
|
||||
h.WriteOKJSON(w, core.FoundResponse(reqUser.UserId, u))
|
||||
} else {
|
||||
user, err := biz.GetUser(reqUser.UserId)
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
u := util.MapStr{
|
||||
"user_id": user.ID,
|
||||
"name": user.Name,
|
||||
"email": user.Email,
|
||||
"nick_name": user.NickName,
|
||||
"phone": user.Phone,
|
||||
}
|
||||
h.WriteOKJSON(w, core.FoundResponse(reqUser.UserId, u))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
func (h Account) UpdatePassword(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
reqUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
var req dto.UpdatePassword
|
||||
err = h.DecodeJSON(r, &req)
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = biz.UpdatePassword(reqUser, req)
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
h.WriteOKJSON(w, core.UpdateResponse(reqUser.UserId))
|
||||
return
|
||||
}
|
||||
func (h Account) UpdateProfile(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
reqUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
var req dto.UpdateProfile
|
||||
err = h.DecodeJSON(r, &req)
|
||||
err = biz.UpdateProfile(reqUser, req)
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
h.WriteOKJSON(w, core.UpdateResponse(reqUser.UserId))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
package index_management
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"infini.sh/framework/core/elastic"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"infini.sh/console/config"
|
||||
model2 "infini.sh/console/model"
|
||||
"infini.sh/framework/core/api"
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"infini.sh/framework/core/orm"
|
||||
"infini.sh/framework/core/util"
|
||||
"infini.sh/console/config"
|
||||
model2 "infini.sh/console/model"
|
||||
)
|
||||
|
||||
type APIHandler struct {
|
||||
|
@ -116,3 +118,73 @@ func (handler APIHandler) UpdateDictItemAction(w http.ResponseWriter, req *http.
|
|||
handler.WriteJSON(w, resp, http.StatusOK)
|
||||
|
||||
}
|
||||
func (h APIHandler) ListIndex(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||
clusterIds := h.GetParameterOrDefault(req, "ids", "")
|
||||
keyword := h.GetParameterOrDefault(req, "keyword", "")
|
||||
ids := strings.Split(clusterIds, ",")
|
||||
for i := range ids {
|
||||
if i < len(ids)-1 {
|
||||
ids[i] = `"` + ids[i] + `",`
|
||||
} else {
|
||||
ids[i] = `"` + ids[i] + `"`
|
||||
}
|
||||
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
h.Error400(w, "id is required")
|
||||
return
|
||||
}
|
||||
var dsl = `{
|
||||
"_source": ["metadata.index_name"],
|
||||
"collapse": {
|
||||
"field": "metadata.index_name"
|
||||
},
|
||||
"size": 100,
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{
|
||||
"terms": {
|
||||
"metadata.cluster_id": %s
|
||||
}
|
||||
}%s
|
||||
],
|
||||
"must_not": [
|
||||
{
|
||||
"term": {
|
||||
"metadata.labels.state": {
|
||||
"value": "delete"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
str := &strings.Builder{}
|
||||
|
||||
if keyword != "" {
|
||||
str.WriteString(fmt.Sprintf(`,{"wildcard":{"metadata.index_name":{"value":"*%s*"}}}`, keyword))
|
||||
}
|
||||
dsl = fmt.Sprintf(dsl, ids, str)
|
||||
|
||||
esClient := elastic.GetClient(h.Config.Elasticsearch)
|
||||
resp, err := esClient.SearchWithRawQueryDSL(".infini_index", []byte(dsl))
|
||||
if err != nil {
|
||||
|
||||
return
|
||||
}
|
||||
list := resp.Hits.Hits
|
||||
var indexNames []string
|
||||
for _, v := range list {
|
||||
m := v.Source["metadata"].(map[string]interface{})
|
||||
indexNames = append(indexNames, m["index_name"].(string))
|
||||
|
||||
}
|
||||
m := make(map[string]interface{})
|
||||
m["indexnames"] = indexNames
|
||||
h.WriteOKJSON(w, m)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package api
|
|||
|
||||
import (
|
||||
"infini.sh/console/config"
|
||||
m "infini.sh/console/internal/middleware"
|
||||
"infini.sh/console/plugin/api/alerting"
|
||||
"infini.sh/console/plugin/api/index_management"
|
||||
"infini.sh/framework/core/api"
|
||||
|
@ -23,28 +24,29 @@ func Init(cfg *config.AppConfig) {
|
|||
//api.HandleAPIMethod(api.GET, "/api/dict/:id",handler.GetDictItemAction)
|
||||
api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix, "dict/:id"), handler.DeleteDictItemAction)
|
||||
api.HandleAPIMethod(api.PUT, path.Join(pathPrefix, "dict/:id"), handler.UpdateDictItemAction)
|
||||
api.HandleAPIMethod(api.POST, path.Join(esPrefix, "doc/:index/_search"), handler.HandleSearchDocumentAction)
|
||||
api.HandleAPIMethod(api.POST, path.Join(esPrefix, "doc/:index"), handler.HandleAddDocumentAction)
|
||||
api.HandleAPIMethod(api.PUT, path.Join(esPrefix, "doc/:index/:docId"), handler.HandleUpdateDocumentAction)
|
||||
api.HandleAPIMethod(api.DELETE, path.Join(esPrefix, "doc/:index/:docId"), handler.HandleDeleteDocumentAction)
|
||||
|
||||
api.HandleAPIMethod(api.POST, path.Join(esPrefix, "doc/:index/_search"), m.IndexRequired(handler.HandleSearchDocumentAction, "doc.search"))
|
||||
api.HandleAPIMethod(api.POST, path.Join(esPrefix, "doc/:index"), m.IndexRequired(handler.HandleAddDocumentAction, "doc.create"))
|
||||
api.HandleAPIMethod(api.PUT, path.Join(esPrefix, "doc/:index/:docId"), m.IndexRequired(handler.HandleUpdateDocumentAction, "doc.update"))
|
||||
api.HandleAPIMethod(api.DELETE, path.Join(esPrefix, "doc/:index/:docId"), m.IndexRequired(handler.HandleDeleteDocumentAction, "doc.delete"))
|
||||
api.HandleAPIMethod(api.GET, path.Join(esPrefix, "doc/_validate"), handler.ValidateDocIDAction)
|
||||
|
||||
api.HandleAPIMethod(api.POST, path.Join(pathPrefix, "rebuild/*id"), handler.HandleReindexAction)
|
||||
api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "rebuild/_search"), handler.HandleGetRebuildListAction)
|
||||
api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix, "rebuild/:id"), handler.HandleDeleteRebuildAction)
|
||||
|
||||
api.HandleAPIMethod(api.GET, path.Join(esPrefix, "_cat/indices"), handler.HandleGetIndicesAction)
|
||||
api.HandleAPIMethod(api.GET, path.Join(esPrefix, "index/:index/_mappings"), handler.HandleGetMappingsAction)
|
||||
api.HandleAPIMethod(api.GET, path.Join(esPrefix, "index/:index/_settings"), handler.HandleGetSettingsAction)
|
||||
api.HandleAPIMethod(api.PUT, path.Join(esPrefix, "index/:index/_settings"), handler.HandleUpdateSettingsAction)
|
||||
api.HandleAPIMethod(api.DELETE, path.Join(esPrefix, "index/:index"), handler.HandleDeleteIndexAction)
|
||||
api.HandleAPIMethod(api.POST, path.Join(esPrefix, "index/:index"), handler.HandleCreateIndexAction)
|
||||
api.HandleAPIMethod(api.GET, path.Join(esPrefix, "_cat/indices"), m.ClusterRequired(handler.HandleGetIndicesAction, "cat.indices"))
|
||||
api.HandleAPIMethod(api.GET, path.Join(esPrefix, "index/:index/_mappings"), m.IndexRequired(handler.HandleGetMappingsAction, "indices.get_mapping"))
|
||||
api.HandleAPIMethod(api.GET, path.Join(esPrefix, "index/:index/_settings"), m.IndexRequired(handler.HandleGetSettingsAction, "indices.get_settings"))
|
||||
api.HandleAPIMethod(api.PUT, path.Join(esPrefix, "index/:index/_settings"), m.IndexRequired(handler.HandleUpdateSettingsAction, "indices.put_mapping"))
|
||||
api.HandleAPIMethod(api.DELETE, path.Join(esPrefix, "index/:index"), m.IndexRequired(handler.HandleDeleteIndexAction, "indices.delete"))
|
||||
api.HandleAPIMethod(api.POST, path.Join(esPrefix, "index/:index"), m.IndexRequired(handler.HandleCreateIndexAction, "indices.create"))
|
||||
|
||||
api.HandleAPIMethod(api.POST, path.Join(pathPrefix, "elasticsearch/command"), handler.HandleAddCommonCommandAction)
|
||||
api.HandleAPIMethod(api.PUT, path.Join(pathPrefix, "elasticsearch/command/:cid"), handler.HandleSaveCommonCommandAction)
|
||||
api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/command"), handler.HandleQueryCommonCommandAction)
|
||||
api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix, "elasticsearch/command/:cid"), handler.HandleDeleteCommonCommandAction)
|
||||
|
||||
api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/indices"), handler.ListIndex)
|
||||
//task.RegisterScheduleTask(task.ScheduleTask{
|
||||
// Description: "sync reindex task result",
|
||||
// Task: func() {
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package rbac
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"infini.sh/console/internal/biz"
|
||||
"infini.sh/console/internal/biz/enum"
|
||||
m "infini.sh/console/internal/middleware"
|
||||
"infini.sh/console/model/rbac"
|
||||
"infini.sh/framework/core/api"
|
||||
"infini.sh/framework/core/elastic"
|
||||
"infini.sh/framework/core/util"
|
||||
"os"
|
||||
"path"
|
||||
log "github.com/cihub/seelog"
|
||||
)
|
||||
|
||||
type Rbac struct {
|
||||
api.Handler
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
r := Rbac{}
|
||||
api.HandleAPIMethod(api.GET, "/permission/:type", r.ListPermission)
|
||||
api.HandleAPIMethod(api.POST, "/role/:type", m.PermissionRequired(r.CreateRole, enum.RoleAllPermission...))
|
||||
api.HandleAPIMethod(api.GET, "/role/:id", m.PermissionRequired(r.GetRole, enum.RoleReadPermission...))
|
||||
api.HandleAPIMethod(api.DELETE, "/role/:id", m.PermissionRequired(r.DeleteRole, enum.RoleAllPermission...))
|
||||
api.HandleAPIMethod(api.PUT, "/role/:id", m.PermissionRequired(r.UpdateRole, enum.RoleAllPermission...))
|
||||
api.HandleAPIMethod(api.GET, "/role/_search", m.PermissionRequired(r.SearchRole, enum.RoleReadPermission...))
|
||||
|
||||
api.HandleAPIMethod(api.POST, "/user", m.PermissionRequired(r.CreateUser, enum.UserAllPermission...))
|
||||
api.HandleAPIMethod(api.GET, "/user/:id", m.PermissionRequired(r.GetUser, enum.UserReadPermission...))
|
||||
api.HandleAPIMethod(api.DELETE, "/user/:id", m.PermissionRequired(r.DeleteUser, enum.UserAllPermission...))
|
||||
api.HandleAPIMethod(api.PUT, "/user/:id", m.PermissionRequired(r.UpdateUser, enum.UserAllPermission...))
|
||||
api.HandleAPIMethod(api.PUT, "/user/:id/role", m.PermissionRequired(r.UpdateUserRole, enum.UserAllPermission...))
|
||||
api.HandleAPIMethod(api.GET, "/user/_search", m.PermissionRequired(r.SearchUser, enum.UserReadPermission...))
|
||||
api.HandleAPIMethod(api.PUT, "/user/:id/password", m.PermissionRequired(r.UpdateUserPassword, enum.UserAllPermission...))
|
||||
}
|
||||
|
||||
func loadJsonConfig() {
|
||||
pwd, _ := os.Getwd()
|
||||
|
||||
bytes, err := util.FileGetContent(path.Join(pwd, "/config/permission.json"))
|
||||
if err != nil {
|
||||
panic("load json file err " + err.Error())
|
||||
|
||||
}
|
||||
apis := make(map[string][]string)
|
||||
err = json.Unmarshal(bytes, &apis)
|
||||
if err != nil {
|
||||
panic("json config unmarshal err " + err.Error())
|
||||
}
|
||||
biz.IndexApis = apis["indices"]
|
||||
delete(apis, "indices")
|
||||
biz.ClusterApis = apis
|
||||
|
||||
//bytes, err = util.FileGetContent(path.Join(pwd, "/config/map.json"))
|
||||
//if err != nil {
|
||||
// panic("load json file err " + err.Error())
|
||||
//}
|
||||
//esapiMap := make(map[string]string)
|
||||
//err = json.Unmarshal(bytes, &esapiMap)
|
||||
//if err != nil {
|
||||
// panic("json config unmarshal err " + err.Error())
|
||||
//}
|
||||
//for k, v := range esapiMap {
|
||||
// s := strings.Split(k, "-")
|
||||
// biz.EsApiRoutes.AddRoute(s[0], s[1], v)
|
||||
//}
|
||||
|
||||
}
|
||||
func loadRolePermission() {
|
||||
biz.RoleMap = make(map[string]rbac.Role)
|
||||
|
||||
biz.RoleMap["admin"] = rbac.Role{
|
||||
Privilege: rbac.RolePrivilege{
|
||||
Platform: enum.AdminPrivilege,
|
||||
},
|
||||
}
|
||||
|
||||
res, err := biz.SearchRole("", 0, 1000)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
response := elastic.SearchResponse{}
|
||||
util.FromJSONBytes(res.Raw, &response)
|
||||
|
||||
for _, v := range response.Hits.Hits {
|
||||
var role rbac.Role
|
||||
delete(v.Source, "created")
|
||||
delete(v.Source, "updated")
|
||||
err = mapstructure.Decode(v.Source, &role)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
biz.RoleMap[role.Name] = role
|
||||
}
|
||||
|
||||
}
|
||||
func Init() {
|
||||
loadJsonConfig()
|
||||
loadRolePermission()
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package rbac
|
||||
|
||||
import (
|
||||
log "github.com/cihub/seelog"
|
||||
"infini.sh/console/internal/biz"
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (h Rbac) ListPermission(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
typ := ps.MustGetParameter("type")
|
||||
err := biz.IsAllowRoleType(typ)
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
var permissions interface{}
|
||||
if typ == biz.Elastisearch {
|
||||
permissions = biz.ListElasticsearchPermission()
|
||||
}
|
||||
h.WriteOKJSON(w, permissions)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
package rbac
|
||||
|
||||
import (
|
||||
log "github.com/cihub/seelog"
|
||||
"infini.sh/console/internal/biz"
|
||||
"infini.sh/console/internal/biz/enum"
|
||||
"infini.sh/console/internal/core"
|
||||
"infini.sh/console/model/rbac"
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"infini.sh/framework/core/elastic"
|
||||
"infini.sh/framework/core/util"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (h Rbac) CreateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
roleType := ps.MustGetParameter("type")
|
||||
|
||||
localUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = biz.IsAllowRoleType(roleType)
|
||||
if err != nil {
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
role := &rbac.Role{
|
||||
Type: roleType,
|
||||
}
|
||||
err = h.DecodeJSON(r, role)
|
||||
if err != nil {
|
||||
h.Error400(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var id string
|
||||
id, err = biz.CreateRole(localUser, role)
|
||||
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
_ = h.WriteOKJSON(w, core.CreateResponse(id))
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (h Rbac) SearchRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
|
||||
var (
|
||||
keyword = h.GetParameterOrDefault(r, "keyword", "")
|
||||
from = h.GetIntOrDefault(r, "from", 0)
|
||||
size = h.GetIntOrDefault(r, "size", 20)
|
||||
)
|
||||
|
||||
res, err := biz.SearchRole(keyword, from, size)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
response := elastic.SearchResponse{}
|
||||
util.FromJSONBytes(res.Raw, &response)
|
||||
|
||||
hits := response.Hits.Hits
|
||||
list := make([]elastic.IndexDocument, 0)
|
||||
total := response.GetTotal()
|
||||
var index string
|
||||
for _, v := range hits {
|
||||
index = v.Index
|
||||
}
|
||||
for k, v := range enum.BuildRoles {
|
||||
list = append(list, elastic.IndexDocument{
|
||||
ID: k,
|
||||
Index: index,
|
||||
Type: "_doc",
|
||||
Source: v,
|
||||
})
|
||||
total++
|
||||
}
|
||||
list = append(list, hits...)
|
||||
response.Hits.Hits = list
|
||||
response.Hits.Total = total
|
||||
|
||||
h.WriteOKJSON(w, response)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (h Rbac) GetRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
id := ps.MustGetParameter("id")
|
||||
role, err := biz.GetRole(id)
|
||||
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
h.WriteOKJSON(w, core.Response{Hit: role})
|
||||
return
|
||||
}
|
||||
|
||||
func (h Rbac) DeleteRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
id := ps.MustGetParameter("id")
|
||||
|
||||
localUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = biz.DeleteRole(localUser, id)
|
||||
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
_ = h.WriteOKJSON(w, core.DeleteResponse(id))
|
||||
return
|
||||
}
|
||||
|
||||
func (h Rbac) UpdateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
id := ps.MustGetParameter("id")
|
||||
localUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
role := &rbac.Role{}
|
||||
err = h.DecodeJSON(r, role)
|
||||
if err != nil {
|
||||
h.Error400(w, err.Error())
|
||||
return
|
||||
}
|
||||
role.ID = id
|
||||
err = biz.UpdateRole(localUser, role)
|
||||
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
_ = h.WriteOKJSON(w, core.UpdateResponse(id))
|
||||
return
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package rbac
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"infini.sh/console/internal/biz"
|
||||
"infini.sh/console/internal/core"
|
||||
"infini.sh/console/internal/dto"
|
||||
httprouter "infini.sh/framework/core/api/router"
|
||||
"infini.sh/framework/core/util"
|
||||
"infini.sh/framework/modules/elastic"
|
||||
"net/http"
|
||||
log "src/github.com/cihub/seelog"
|
||||
)
|
||||
|
||||
type CreateUserReq struct {
|
||||
Username string `json:"username" `
|
||||
Password string `json:"password" `
|
||||
Name string `json:"name" `
|
||||
Phone string `json:"phone" `
|
||||
Email string `json:"email" `
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
func (h Rbac) CreateUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
|
||||
var req dto.CreateUser
|
||||
err := h.DecodeJSON(r, &req)
|
||||
if err != nil {
|
||||
h.Error400(w, err.Error())
|
||||
return
|
||||
}
|
||||
if req.Name == "" {
|
||||
|
||||
h.Error400(w, "username and phone and email is require")
|
||||
return
|
||||
}
|
||||
localUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
id, pass, err := biz.CreateUser(localUser, req)
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
_ = h.WriteOKJSON(w, util.MapStr{
|
||||
"_id": id,
|
||||
"password": pass,
|
||||
"result": "created",
|
||||
})
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (h Rbac) GetUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
id := ps.MustGetParameter("id")
|
||||
user, err := biz.GetUser(id)
|
||||
if errors.Is(err, elastic.ErrNotFound) {
|
||||
h.WriteJSON(w, core.NotFoundResponse(id), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
h.WriteOKJSON(w, core.FoundResponse(id, user))
|
||||
return
|
||||
}
|
||||
|
||||
func (h Rbac) UpdateUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
id := ps.MustGetParameter("id")
|
||||
var req dto.UpdateUser
|
||||
err := h.DecodeJSON(r, &req)
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.Error400(w, err.Error())
|
||||
return
|
||||
}
|
||||
localUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = biz.UpdateUser(localUser, id, req)
|
||||
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
_ = h.WriteOKJSON(w, core.UpdateResponse(id))
|
||||
return
|
||||
}
|
||||
|
||||
func (h Rbac) UpdateUserRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
id := ps.MustGetParameter("id")
|
||||
var req dto.UpdateUserRole
|
||||
err := h.DecodeJSON(r, &req)
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.Error400(w, err.Error())
|
||||
return
|
||||
}
|
||||
localUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = biz.UpdateUserRole(localUser, id, req)
|
||||
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
_ = h.WriteOKJSON(w, core.UpdateResponse(id))
|
||||
return
|
||||
}
|
||||
|
||||
func (h Rbac) DeleteUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
id := ps.MustGetParameter("id")
|
||||
localUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = biz.DeleteUser(localUser, id)
|
||||
if errors.Is(err, elastic.ErrNotFound) {
|
||||
h.WriteJSON(w, core.NotFoundResponse(id), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
_ = h.WriteOKJSON(w, core.DeleteResponse(id))
|
||||
return
|
||||
}
|
||||
|
||||
func (h Rbac) SearchUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
var (
|
||||
keyword = h.GetParameterOrDefault(r, "keyword", "")
|
||||
from = h.GetIntOrDefault(r, "from", 0)
|
||||
size = h.GetIntOrDefault(r, "size", 20)
|
||||
)
|
||||
|
||||
res, err := biz.SearchUser(keyword, from, size)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.Write(w, res.Raw)
|
||||
return
|
||||
|
||||
}
|
||||
func (h Rbac) UpdateUserPassword(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
id := ps.MustGetParameter("id")
|
||||
var req dto.UpdateUserPassword
|
||||
err := h.DecodeJSON(r, &req)
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.Error400(w, err.Error())
|
||||
return
|
||||
}
|
||||
localUser, err := biz.FromUserContext(r.Context())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = biz.UpdateUserPassword(localUser, id, req.Password)
|
||||
if err != nil {
|
||||
_ = log.Error(err.Error())
|
||||
h.ErrorInternalServer(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
_ = h.WriteOKJSON(w, core.UpdateResponse(id))
|
||||
return
|
||||
|
||||
}
|
Loading…
Reference in New Issue