Started work on LDAP again, #1450

This commit is contained in:
Torkel Ödegaard
2015-07-10 11:10:48 +02:00
376 changed files with 32968 additions and 8624 deletions

View File

@@ -26,6 +26,7 @@ func Register(r *macaron.Macaron) {
// authed views
r.Get("/profile/", reqSignedIn, Index)
r.Get("/org/", reqSignedIn, Index)
r.Get("/org/new", reqSignedIn, Index)
r.Get("/datasources/", reqSignedIn, Index)
r.Get("/datasources/edit/*", reqSignedIn, Index)
r.Get("/org/users/", reqSignedIn, Index)
@@ -39,7 +40,14 @@ func Register(r *macaron.Macaron) {
// sign up
r.Get("/signup", Index)
r.Post("/api/user/signup", bind(m.CreateUserCommand{}), SignUp)
r.Post("/api/user/signup", bind(m.CreateUserCommand{}), wrap(SignUp))
// reset password
r.Get("/user/password/send-reset-email", Index)
r.Get("/user/password/reset", Index)
r.Post("/api/user/password/send-reset-email", bind(dtos.SendResetPasswordEmailForm{}), wrap(SendResetPasswordEmail))
r.Post("/api/user/password/reset", bind(dtos.ResetUserPasswordForm{}), wrap(ResetPassword))
// dashboard snapshots
r.Post("/api/snapshots/", bind(m.CreateDashboardSnapshotCommand{}), CreateDashboardSnapshot)

View File

@@ -87,10 +87,10 @@ func ApiError(status int, message string, err error) *NormalResponse {
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"] = "Not Found"
case 500:
metrics.M_Api_Status_500.Inc(1)
resp["message"] = "Internal Server Error"
}

View File

@@ -4,13 +4,14 @@ import (
"encoding/json"
"os"
"path"
"strings"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/search"
"github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
@@ -31,7 +32,7 @@ func isDasboardStarredByUser(c *middleware.Context, dashId int64) (bool, error)
func GetDashboard(c *middleware.Context) {
metrics.M_Api_Dashboard_Get.Inc(1)
slug := c.Params(":slug")
slug := strings.ToLower(c.Params(":slug"))
query := m.GetDashboardQuery{Slug: slug, OrgId: c.OrgId}
err := bus.Dispatch(&query)

View File

@@ -59,7 +59,7 @@ func GetDashboardSnapshot(c *middleware.Context) {
// expired snapshots should also be removed from db
if snapshot.Expires.Before(time.Now()) {
c.JsonApiErr(404, "Snapshot not found", err)
c.JsonApiErr(404, "Dashboard snapshot not found", err)
return
}

View File

@@ -18,7 +18,7 @@ type AdminUpdateUserPasswordForm struct {
}
type AdminUpdateUserPermissionsForm struct {
IsGrafanaAdmin bool `json:"IsGrafanaAdmin" binding:"Required"`
IsGrafanaAdmin bool `json:"IsGrafanaAdmin"`
}
type AdminUserListItem struct {
@@ -27,3 +27,13 @@ type AdminUserListItem struct {
Login string `json:"login"`
IsGrafanaAdmin bool `json:"isGrafanaAdmin"`
}
type SendResetPasswordEmailForm struct {
UserOrEmail string `json:"userOrEmail" binding:"Required"`
}
type ResetUserPasswordForm struct {
Code string `json:"code"`
NewPassword string `json:"newPassword"`
ConfirmPassword string `json:"confirmPassword"`
}

View File

@@ -99,7 +99,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
"defaultDatasource": defaultDatasource,
"datasources": datasources,
"appSubUrl": setting.AppSubUrl,
"viewerRoleMode": setting.ViewerRoleMode,
"allowOrgCreate": (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin,
"buildInfo": map[string]interface{}{
"version": setting.BuildVersion,
"commit": setting.BuildCommit,

View File

@@ -5,7 +5,7 @@ import (
"fmt"
"net/url"
"github.com/gogits/gogs/modules/ldap"
"github.com/go-ldap/ldap"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/setting"
)
@@ -15,7 +15,7 @@ var (
)
func Login(username, password string) error {
url, err := url.Parse(setting.LdapUrls[0])
url, err := url.Parse(setting.LdapHosts[0])
if err != nil {
return err
}

View File

@@ -4,7 +4,6 @@ import (
"net/url"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/ldapauth"
"github.com/grafana/grafana/pkg/auth"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
@@ -89,28 +88,20 @@ func LoginApiPing(c *middleware.Context) {
}
func LoginPost(c *middleware.Context, cmd dtos.LoginCommand) Response {
sourcesQuery := auth.GetAuthSourcesQuery{}
if err := bus.Dispatch(&sourcesQuery); err != nil {
return ApiError(500, "Could not get login sources", err)
authQuery := auth.AuthenticateUserQuery{
Username: cmd.User,
Password: cmd.Password,
}
var err error
var user *m.User
for _, authSource := range sourcesQuery.Sources {
user, err = authSource.AuthenticateUser(cmd.User, cmd.Password)
if err == nil {
break
}
// handle non invalid credentials error, otherwise try next auth source
if err != auth.ErrInvalidCredentials {
return ApiError(500, "Error while trying to authenticate user", err)
if err := bus.Dispatch(&authQuery); err != nil {
if err == auth.ErrInvalidCredentials {
return ApiError(401, "Invalid username or password", err)
}
return ApiError(500, "Error while trying to authenticate user", err)
}
if err != nil {
return ApiError(401, "Invalid username or password", err)
}
user := authQuery.User
loginUserWithUser(user, c)
@@ -128,19 +119,6 @@ func LoginPost(c *middleware.Context, cmd dtos.LoginCommand) Response {
return Json(200, result)
}
func LoginUsingLdap(c *middleware.Context, cmd dtos.LoginCommand) Response {
err := ldapauth.Login(cmd.User, cmd.Password)
if err != nil {
if err == ldapauth.ErrInvalidCredentials {
return ApiError(401, "Invalid username or password", err)
}
return ApiError(500, "Ldap login failed", err)
}
return Empty(401)
}
func loginUserWithUser(user *m.User, c *middleware.Context) {
if user == nil {
log.Error(3, "User login with nil user")

View File

@@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
// GET /api/org
@@ -39,7 +40,7 @@ func getOrgHelper(orgId int64) Response {
// POST /api/orgs
func CreateOrg(c *middleware.Context, cmd m.CreateOrgCommand) Response {
if !setting.AllowUserOrgCreate && !c.IsGrafanaAdmin {
if !c.IsSignedIn || (!setting.AllowUserOrgCreate && !c.IsGrafanaAdmin) {
return ApiError(401, "Access denied", nil)
}
@@ -50,7 +51,10 @@ func CreateOrg(c *middleware.Context, cmd m.CreateOrgCommand) Response {
metrics.M_Api_Org_Create.Inc(1)
return ApiSuccess("Organization created")
return Json(200, &util.DynMap{
"orgId": cmd.Result.Id,
"message": "Organization created",
})
}
// PUT /api/org

49
pkg/api/password.go Normal file
View File

@@ -0,0 +1,49 @@
package api
import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/util"
)
func SendResetPasswordEmail(c *middleware.Context, form dtos.SendResetPasswordEmailForm) Response {
userQuery := m.GetUserByLoginQuery{LoginOrEmail: form.UserOrEmail}
if err := bus.Dispatch(&userQuery); err != nil {
return ApiError(404, "User does not exist", err)
}
emailCmd := m.SendResetPasswordEmailCommand{User: userQuery.Result}
if err := bus.Dispatch(&emailCmd); err != nil {
return ApiError(500, "Failed to send email", err)
}
return ApiSuccess("Email sent")
}
func ResetPassword(c *middleware.Context, form dtos.ResetUserPasswordForm) Response {
query := m.ValidateResetPasswordCodeQuery{Code: form.Code}
if err := bus.Dispatch(&query); err != nil {
if err == m.ErrInvalidEmailCode {
return ApiError(400, "Invalid or expired reset password code", nil)
}
return ApiError(500, "Unknown error validating email code", err)
}
if form.NewPassword != form.ConfirmPassword {
return ApiError(400, "Passwords do not match", nil)
}
cmd := m.ChangeUserPasswordCommand{}
cmd.UserId = query.Result.Id
cmd.NewPassword = util.EncodePassword(form.NewPassword, query.Result.Salt)
if err := bus.Dispatch(&cmd); err != nil {
return ApiError(500, "Failed to change user password", err)
}
return ApiSuccess("User password changed")
}

View File

@@ -3,7 +3,7 @@ package api
import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/search"
"github.com/grafana/grafana/pkg/services/search"
)
func Search(c *middleware.Context) {

View File

@@ -2,6 +2,7 @@ package api
import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models"
@@ -9,24 +10,29 @@ import (
)
// POST /api/user/signup
func SignUp(c *middleware.Context, cmd m.CreateUserCommand) {
func SignUp(c *middleware.Context, cmd m.CreateUserCommand) Response {
if !setting.AllowUserSignUp {
c.JsonApiErr(401, "User signup is disabled", nil)
return
return ApiError(401, "User signup is disabled", nil)
}
cmd.Login = cmd.Email
if err := bus.Dispatch(&cmd); err != nil {
c.JsonApiErr(500, "failed to create user", err)
return
return ApiError(500, "failed to create user", err)
}
user := cmd.Result
bus.Publish(&events.UserSignedUp{
Id: user.Id,
Name: user.Name,
Email: user.Email,
Login: user.Login,
})
loginUserWithUser(&user, c)
c.JsonOK("User created and logged in")
metrics.M_Api_User_SignUp.Inc(1)
return ApiSuccess("User created and logged in")
}