feat: (rbac) core response

This commit is contained in:
xushuhui 2022-04-20 15:25:54 +08:00
parent e16ca50773
commit 16821ed736
9 changed files with 103 additions and 61 deletions

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/golang-jwt/jwt" "github.com/golang-jwt/jwt"
"github.com/mitchellh/mapstructure"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"infini.sh/console/internal/dto" "infini.sh/console/internal/dto"
"infini.sh/console/model/rbac" "infini.sh/console/model/rbac"
@ -11,6 +12,7 @@ import (
"infini.sh/framework/core/global" "infini.sh/framework/core/global"
"infini.sh/framework/core/orm" "infini.sh/framework/core/orm"
"infini.sh/framework/core/util" "infini.sh/framework/core/util"
"strings" "strings"
"time" "time"
) )
@ -24,10 +26,21 @@ type User struct {
UserId string `json:"user_id"` UserId string `json:"user_id"`
Roles []string `json:"roles"` 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}"`
}
const Secret = "console" const Secret = "console"
func authenticateUser(username string, password string) (user rbac.User, err error) { func authenticateUser(username string, password string) (user Account, err error) {
err, result := orm.GetBy("username", username, rbac.User{}) err, result := orm.GetBy("username", username, rbac.User{})
if err != nil { if err != nil {
@ -38,7 +51,11 @@ func authenticateUser(username string, password string) (user rbac.User, err err
err = errors.New("user not found") err = errors.New("user not found")
return return
} }
user = result.Result[0].(rbac.User)
err = mapstructure.Decode(result.Result[0], &user)
if err != nil {
return
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
if err == bcrypt.ErrMismatchedHashAndPassword { if err == bcrypt.ErrMismatchedHashAndPassword {
err = errors.New("password incorrect") err = errors.New("password incorrect")
@ -47,7 +64,7 @@ func authenticateUser(username string, password string) (user rbac.User, err err
return return
} }
func authenticateAdmin(username string, password string) (user rbac.User, err error) { func authenticateAdmin(username string, password string) (user Account, err error) {
u, _ := global.Env().GetConfig("bootstrap.username", "admin") u, _ := global.Env().GetConfig("bootstrap.username", "admin")
p, _ := global.Env().GetConfig("bootstrap.password", "admin") p, _ := global.Env().GetConfig("bootstrap.password", "admin")
@ -60,7 +77,7 @@ func authenticateAdmin(username string, password string) (user rbac.User, err er
user.Username = username user.Username = username
return user, nil return user, nil
} }
func authorize(user rbac.User) (m map[string]interface{}, err error) { func authorize(user Account) (m map[string]interface{}, err error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserClaims{ token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserClaims{
User: &User{ User: &User{
Username: user.Username, Username: user.Username,
@ -86,7 +103,7 @@ func authorize(user rbac.User) (m map[string]interface{}, err error) {
return return
} }
func Login(username string, password string) (m map[string]interface{}, err error) { func Login(username string, password string) (m map[string]interface{}, err error) {
var user rbac.User var user Account
if username == "admin" { if username == "admin" {
user, err = authenticateAdmin(username, password) user, err = authenticateAdmin(username, password)
if err != nil { if err != nil {
@ -128,7 +145,7 @@ func UpdatePassword(localUser *User, req dto.UpdatePassword) (err error) {
err = ErrNotFound err = ErrNotFound
return return
} }
err = bcrypt.CompareHashAndPassword([]byte(req.OldPassword), []byte(user.Password)) err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.OldPassword))
if err == bcrypt.ErrMismatchedHashAndPassword { if err == bcrypt.ErrMismatchedHashAndPassword {
err = errors.New("old password is not correct") err = errors.New("old password is not correct")
return return

View File

@ -135,7 +135,7 @@ func UpdateUser(localUser *User, id string, req dto.UpdateUser) (err error) {
user.Phone = req.Phone user.Phone = req.Phone
user.Tags = req.Tags user.Tags = req.Tags
user.Updated = time.Now() user.Updated = time.Now()
err = orm.Save(user) err = orm.Save(&user)
if err != nil { if err != nil {
return return
} }
@ -177,7 +177,7 @@ func UpdateUserRole(localUser *User, id string, req dto.UpdateUserRole) (err err
} }
user.Roles = roles user.Roles = roles
user.Updated = time.Now() user.Updated = time.Now()
err = orm.Save(user) err = orm.Save(&user)
if err != nil { if err != nil {
return return
} }

45
internal/core/response.go Normal file
View File

@ -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,
}
}

View File

@ -5,6 +5,6 @@ type Login struct {
Password string `json:"password"` Password string `json:"password"`
} }
type UpdatePassword struct { type UpdatePassword struct {
OldPassword string `json:"oldPassword"` OldPassword string `json:"old_password"`
NewPassword string `json:"newPassword"` NewPassword string `json:"new_password"`
} }

View File

@ -2,6 +2,7 @@ package account
import ( import (
"infini.sh/console/internal/biz" "infini.sh/console/internal/biz"
"infini.sh/console/internal/core"
"infini.sh/console/internal/dto" "infini.sh/console/internal/dto"
m "infini.sh/console/internal/middleware" m "infini.sh/console/internal/middleware"
"infini.sh/framework/core/api" "infini.sh/framework/core/api"
@ -99,7 +100,19 @@ func (h Account) Profile(w http.ResponseWriter, r *http.Request, ps httprouter.P
h.Error(w, err) h.Error(w, err)
return return
} }
h.WriteJSON(w, reqUser, 200) user, err := biz.GetUser(reqUser.UserId)
if err != nil {
h.Error(w, err)
return
}
u := util.MapStr{
"id": user.ID,
"username": user.Username,
"email": user.Email,
"phone": user.Phone,
"name": user.Name,
}
h.WriteOKJSON(w, core.FoundResponse(reqUser.UserId, u))
return return
} }
func (h Account) UpdatePassword(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func (h Account) UpdatePassword(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {

View File

@ -65,39 +65,3 @@ func init() {
loadJsonConfig() loadJsonConfig()
loadRolePermission() loadRolePermission()
} }
type Response struct {
Total int64 `json:"total,omitempty"`
Hit interface{} `json:"hit,omitempty"`
Id string `json:"_id,omitempty"`
Result string `json:"result,omitempty"`
}
type NotFoundResp struct {
Found bool `json:"found"`
Id string `json:"_id,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) NotFoundResp {
return NotFoundResp{
Id: id,
Found: false,
}
}

View File

@ -3,6 +3,7 @@ package rbac
import ( import (
log "github.com/cihub/seelog" log "github.com/cihub/seelog"
"infini.sh/console/internal/biz" "infini.sh/console/internal/biz"
"infini.sh/console/internal/core"
httprouter "infini.sh/framework/core/api/router" httprouter "infini.sh/framework/core/api/router"
"net/http" "net/http"
@ -18,7 +19,7 @@ func (h Rbac) ListPermission(w http.ResponseWriter, r *http.Request, ps httprout
return return
} }
permissions := role.ListPermission() permissions := role.ListPermission()
h.WriteOKJSON(w, Response{ h.WriteOKJSON(w, core.Response{
Hit: permissions, Hit: permissions,
}) })
return return

View File

@ -4,6 +4,7 @@ import (
log "github.com/cihub/seelog" log "github.com/cihub/seelog"
"infini.sh/console/internal/biz" "infini.sh/console/internal/biz"
"infini.sh/console/internal/biz/enum" "infini.sh/console/internal/biz/enum"
"infini.sh/console/internal/core"
"infini.sh/console/internal/dto" "infini.sh/console/internal/dto"
httprouter "infini.sh/framework/core/api/router" httprouter "infini.sh/framework/core/api/router"
"net/http" "net/http"
@ -35,7 +36,7 @@ func (h Rbac) CreateRole(w http.ResponseWriter, r *http.Request, ps httprouter.P
return return
} }
_ = h.WriteOKJSON(w, CreateResponse(id)) _ = h.WriteOKJSON(w, core.CreateResponse(id))
return return
} }
@ -62,7 +63,7 @@ func (h Rbac) SearchRole(w http.ResponseWriter, r *http.Request, ps httprouter.P
roles = append(roles, v) roles = append(roles, v)
} }
h.WriteOKJSON(w, Response{Hit: roles, Total: res.Total + int64(len(enum.BuildRoles))}) h.WriteOKJSON(w, core.Response{Hit: roles, Total: res.Total + int64(len(enum.BuildRoles))})
return return
} }
@ -76,7 +77,7 @@ func (h Rbac) GetRole(w http.ResponseWriter, r *http.Request, ps httprouter.Para
h.Error(w, err) h.Error(w, err)
return return
} }
h.WriteOKJSON(w, Response{Hit: role}) h.WriteOKJSON(w, core.Response{Hit: role})
return return
} }
@ -96,7 +97,7 @@ func (h Rbac) DeleteRole(w http.ResponseWriter, r *http.Request, ps httprouter.P
h.Error(w, err) h.Error(w, err)
return return
} }
_ = h.WriteOKJSON(w, DeleteResponse(id)) _ = h.WriteOKJSON(w, core.DeleteResponse(id))
return return
} }
@ -122,6 +123,6 @@ func (h Rbac) UpdateRole(w http.ResponseWriter, r *http.Request, ps httprouter.P
h.Error(w, err) h.Error(w, err)
return return
} }
_ = h.WriteOKJSON(w, UpdateResponse(id)) _ = h.WriteOKJSON(w, core.UpdateResponse(id))
return return
} }

View File

@ -3,6 +3,7 @@ package rbac
import ( import (
"errors" "errors"
"infini.sh/console/internal/biz" "infini.sh/console/internal/biz"
"infini.sh/console/internal/core"
"infini.sh/console/internal/dto" "infini.sh/console/internal/dto"
httprouter "infini.sh/framework/core/api/router" httprouter "infini.sh/framework/core/api/router"
"infini.sh/framework/modules/elastic" "infini.sh/framework/modules/elastic"
@ -39,7 +40,7 @@ func (h Rbac) CreateUser(w http.ResponseWriter, r *http.Request, ps httprouter.P
h.Error(w, err) h.Error(w, err)
return return
} }
_ = h.WriteOKJSON(w, CreateResponse(id)) _ = h.WriteOKJSON(w, core.CreateResponse(id))
return return
} }
@ -48,7 +49,7 @@ func (h Rbac) GetUser(w http.ResponseWriter, r *http.Request, ps httprouter.Para
id := ps.MustGetParameter("id") id := ps.MustGetParameter("id")
user, err := biz.GetUser(id) user, err := biz.GetUser(id)
if errors.Is(err, elastic.ErrNotFound) { if errors.Is(err, elastic.ErrNotFound) {
h.WriteJSON(w, NotFoundResponse(id), http.StatusNotFound) h.WriteJSON(w, core.NotFoundResponse(id), http.StatusNotFound)
return return
} }
@ -57,7 +58,7 @@ func (h Rbac) GetUser(w http.ResponseWriter, r *http.Request, ps httprouter.Para
h.Error(w, err) h.Error(w, err)
return return
} }
h.WriteOKJSON(w, Response{Hit: user}) h.WriteOKJSON(w, core.FoundResponse(id, user))
return return
} }
@ -83,7 +84,7 @@ func (h Rbac) UpdateUser(w http.ResponseWriter, r *http.Request, ps httprouter.P
h.Error(w, err) h.Error(w, err)
return return
} }
_ = h.WriteOKJSON(w, UpdateResponse(id)) _ = h.WriteOKJSON(w, core.UpdateResponse(id))
return return
} }
@ -109,7 +110,7 @@ func (h Rbac) UpdateUserRole(w http.ResponseWriter, r *http.Request, ps httprout
h.Error(w, err) h.Error(w, err)
return return
} }
_ = h.WriteOKJSON(w, UpdateResponse(id)) _ = h.WriteOKJSON(w, core.UpdateResponse(id))
return return
} }
@ -123,7 +124,7 @@ func (h Rbac) DeleteUser(w http.ResponseWriter, r *http.Request, ps httprouter.P
} }
err = biz.DeleteUser(localUser, id) err = biz.DeleteUser(localUser, id)
if errors.Is(err, elastic.ErrNotFound) { if errors.Is(err, elastic.ErrNotFound) {
h.WriteJSON(w, NotFoundResponse(id), http.StatusNotFound) h.WriteJSON(w, core.NotFoundResponse(id), http.StatusNotFound)
return return
} }
if err != nil { if err != nil {
@ -131,7 +132,7 @@ func (h Rbac) DeleteUser(w http.ResponseWriter, r *http.Request, ps httprouter.P
h.Error(w, err) h.Error(w, err)
return return
} }
_ = h.WriteOKJSON(w, DeleteResponse(id)) _ = h.WriteOKJSON(w, core.DeleteResponse(id))
return return
} }
@ -149,7 +150,7 @@ func (h Rbac) SearchUser(w http.ResponseWriter, r *http.Request, ps httprouter.P
return return
} }
h.WriteOKJSON(w, Response{Hit: res.Result, Total: res.Total}) h.WriteOKJSON(w, core.Response{Hit: res.Result, Total: res.Total})
return return
} }