Commit 5270c4bc by Torkel Ödegaard

refactorin api code for user routes, preparation for admin improvements, #2014

parent a993bc13
......@@ -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)
}
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)
}
if err := bus.Dispatch(&query); err != nil {
c.JsonApiErr(500, "Failed to get user organizations", err)
return
}
// GET /api/user/:id/orgs
func GetUserOrgList(c *middleware.Context) Response {
return getUserOrgList(c.ParamsInt64(":id"))
}
for _, ac := range query.Result {
if ac.OrgId == c.OrgId {
ac.IsUsing = true
break
}
func getUserOrgList(userId int64) Response {
query := m.GetUserOrgListQuery{UserId: userId}
if err := bus.Dispatch(&query); err != nil {
return ApiError(500, "Faile to get user organziations", err)
}
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>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment