mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactorin api code for user routes, preparation for admin improvements, #2014
This commit is contained in:
parent
a993bc1331
commit
5270c4bc74
@ -55,15 +55,21 @@ func Register(r *macaron.Macaron) {
|
||||
r.Group("/api", func() {
|
||||
// user
|
||||
r.Group("/user", func() {
|
||||
r.Get("/", GetUser)
|
||||
r.Get("/", wrap(GetSignedInUser))
|
||||
r.Put("/", bind(m.UpdateUserCommand{}), UpdateUser)
|
||||
r.Post("/using/:id", UserSetUsingOrg)
|
||||
r.Get("/orgs", GetUserOrgList)
|
||||
r.Get("/orgs", wrap(GetSignedInUserOrgList))
|
||||
r.Post("/stars/dashboard/:id", StarDashboard)
|
||||
r.Delete("/stars/dashboard/:id", UnstarDashboard)
|
||||
r.Put("/password", bind(m.ChangeUserPasswordCommand{}), ChangeUserPassword)
|
||||
})
|
||||
|
||||
// users
|
||||
r.Group("/users", func() {
|
||||
r.Get("/:id/", wrap(GetUserById))
|
||||
r.Get("/:id/org", wrap(GetUserOrgList))
|
||||
}, reqGrafanaAdmin)
|
||||
|
||||
// account
|
||||
r.Group("/org", func() {
|
||||
r.Get("/", GetOrg)
|
||||
@ -127,5 +133,5 @@ func Register(r *macaron.Macaron) {
|
||||
// rendering
|
||||
r.Get("/render/*", reqSignedIn, RenderToPng)
|
||||
|
||||
r.NotFound(NotFound)
|
||||
r.NotFound(NotFoundHandler)
|
||||
}
|
||||
|
111
pkg/api/common.go
Normal file
111
pkg/api/common.go
Normal file
@ -0,0 +1,111 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/Unknwon/macaron"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
var (
|
||||
NotFound = ApiError(404, "Not found", nil)
|
||||
ServerError = ApiError(500, "Server error", nil)
|
||||
)
|
||||
|
||||
type Response interface {
|
||||
WriteTo(out http.ResponseWriter)
|
||||
}
|
||||
|
||||
type NormalResponse struct {
|
||||
status int
|
||||
body []byte
|
||||
header http.Header
|
||||
}
|
||||
|
||||
func wrap(action func(c *middleware.Context) Response) macaron.Handler {
|
||||
return func(c *middleware.Context) {
|
||||
res := action(c)
|
||||
if res == nil {
|
||||
res = ServerError
|
||||
}
|
||||
res.WriteTo(c.Resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *NormalResponse) WriteTo(out http.ResponseWriter) {
|
||||
header := out.Header()
|
||||
for k, v := range r.header {
|
||||
header[k] = v
|
||||
}
|
||||
out.WriteHeader(r.status)
|
||||
out.Write(r.body)
|
||||
}
|
||||
|
||||
func (r *NormalResponse) Cache(ttl string) *NormalResponse {
|
||||
return r.Header("Cache-Control", "public,max-age="+ttl)
|
||||
}
|
||||
|
||||
func (r *NormalResponse) Header(key, value string) *NormalResponse {
|
||||
r.header.Set(key, value)
|
||||
return r
|
||||
}
|
||||
|
||||
// functions to create responses
|
||||
|
||||
func Empty(status int) *NormalResponse {
|
||||
return Respond(status, nil)
|
||||
}
|
||||
|
||||
func Json(status int, body interface{}) *NormalResponse {
|
||||
return Respond(status, body).Header("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
func ApiError(status int, message string, err error) *NormalResponse {
|
||||
resp := make(map[string]interface{})
|
||||
|
||||
if err != nil {
|
||||
log.Error(4, "%s: %v", message, err)
|
||||
if setting.Env != setting.PROD {
|
||||
resp["error"] = err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
switch status {
|
||||
case 404:
|
||||
resp["message"] = "Not Found"
|
||||
metrics.M_Api_Status_500.Inc(1)
|
||||
case 500:
|
||||
metrics.M_Api_Status_404.Inc(1)
|
||||
resp["message"] = "Internal Server Error"
|
||||
}
|
||||
|
||||
if message != "" {
|
||||
resp["message"] = message
|
||||
}
|
||||
|
||||
return Json(status, resp)
|
||||
}
|
||||
|
||||
func Respond(status int, body interface{}) *NormalResponse {
|
||||
var b []byte
|
||||
var err error
|
||||
switch t := body.(type) {
|
||||
case []byte:
|
||||
b = t
|
||||
case string:
|
||||
b = []byte(t)
|
||||
default:
|
||||
if b, err = json.Marshal(body); err != nil {
|
||||
return ApiError(500, "body json marshal", err)
|
||||
}
|
||||
}
|
||||
return &NormalResponse{
|
||||
body: b,
|
||||
status: status,
|
||||
header: make(http.Header),
|
||||
}
|
||||
}
|
@ -59,7 +59,7 @@ func Index(c *middleware.Context) {
|
||||
c.HTML(200, "index")
|
||||
}
|
||||
|
||||
func NotFound(c *middleware.Context) {
|
||||
func NotFoundHandler(c *middleware.Context) {
|
||||
if c.IsApiRequest() {
|
||||
c.JsonApiErr(404, "Not found", nil)
|
||||
return
|
||||
|
@ -7,15 +7,24 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func GetUser(c *middleware.Context) {
|
||||
query := m.GetUserProfileQuery{UserId: c.UserId}
|
||||
// GET /api/user (current authenticated user)
|
||||
func GetSignedInUser(c *middleware.Context) Response {
|
||||
return getUserUserProfile(c.UserId)
|
||||
}
|
||||
|
||||
// GET /api/user/:id
|
||||
func GetUserById(c *middleware.Context) Response {
|
||||
return getUserUserProfile(c.ParamsInt64(":id"))
|
||||
}
|
||||
|
||||
func getUserUserProfile(userId int64) Response {
|
||||
query := m.GetUserProfileQuery{UserId: userId}
|
||||
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
c.JsonApiErr(500, "Failed to get user", err)
|
||||
return
|
||||
return ApiError(500, "Failed to get user", err)
|
||||
}
|
||||
|
||||
c.JSON(200, query.Result)
|
||||
return Json(200, query.Result)
|
||||
}
|
||||
|
||||
func UpdateUser(c *middleware.Context, cmd m.UpdateUserCommand) {
|
||||
@ -29,22 +38,24 @@ func UpdateUser(c *middleware.Context, cmd m.UpdateUserCommand) {
|
||||
c.JsonOK("User updated")
|
||||
}
|
||||
|
||||
func GetUserOrgList(c *middleware.Context) {
|
||||
query := m.GetUserOrgListQuery{UserId: c.UserId}
|
||||
// GET /api/user/orgs
|
||||
func GetSignedInUserOrgList(c *middleware.Context) Response {
|
||||
return getUserOrgList(c.UserId)
|
||||
}
|
||||
|
||||
// GET /api/user/:id/orgs
|
||||
func GetUserOrgList(c *middleware.Context) Response {
|
||||
return getUserOrgList(c.ParamsInt64(":id"))
|
||||
}
|
||||
|
||||
func getUserOrgList(userId int64) Response {
|
||||
query := m.GetUserOrgListQuery{UserId: userId}
|
||||
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
c.JsonApiErr(500, "Failed to get user organizations", err)
|
||||
return
|
||||
return ApiError(500, "Faile to get user organziations", err)
|
||||
}
|
||||
|
||||
for _, ac := range query.Result {
|
||||
if ac.OrgId == c.OrgId {
|
||||
ac.IsUsing = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, query.Result)
|
||||
return Json(200, query.Result)
|
||||
}
|
||||
|
||||
func validateUsingOrg(userId int64, orgId int64) bool {
|
||||
|
@ -58,8 +58,7 @@ type OrgDTO struct {
|
||||
}
|
||||
|
||||
type UserOrgDTO struct {
|
||||
OrgId int64 `json:"orgId"`
|
||||
Name string `json:"name"`
|
||||
Role RoleType `json:"role"`
|
||||
IsUsing bool `json:"isUsing"`
|
||||
OrgId int64 `json:"orgId"`
|
||||
Name string `json:"name"`
|
||||
Role RoleType `json:"role"`
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form" style="margin-top: 5px">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Email</strong>
|
||||
@ -36,7 +36,7 @@
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form" style="margin-top: 5px">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Username</strong>
|
||||
|
@ -24,7 +24,7 @@
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form" style="margin-top: 5px">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Email</strong>
|
||||
@ -35,7 +35,7 @@
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form" style="margin-top: 5px">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Username</strong>
|
||||
@ -46,7 +46,7 @@
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form" style="margin-top: 5px">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Password</strong>
|
||||
|
@ -71,10 +71,10 @@
|
||||
<td style="width: 98%"><strong>Name: </strong> {{org.name}}</td>
|
||||
<td><strong>Role: </strong> {{org.role}}</td>
|
||||
<td class="nobg max-width-btns">
|
||||
<span class="btn btn-primary btn-mini" ng-show="org.isUsing">
|
||||
<span class="btn btn-primary btn-mini" ng-show="org.orgId === contextSrv.user.orgId">
|
||||
Current
|
||||
</span>
|
||||
<a ng-click="setUsingOrg(org)" class="btn btn-inverse btn-mini" ng-show="!org.isUsing">
|
||||
<a ng-click="setUsingOrg(org)" class="btn btn-inverse btn-mini" ng-show="org.orgId !== contextSrv.user.orgId">
|
||||
Select
|
||||
</a>
|
||||
</td>
|
||||
|
Loading…
Reference in New Issue
Block a user