示例#1
0
func ChangeUserPassword(c *middleware.Context, cmd m.ChangeUserPasswordCommand) Response {
	userQuery := m.GetUserByIdQuery{Id: c.UserId}

	if err := bus.Dispatch(&userQuery); err != nil {
		return ApiError(500, "Could not read user from database", err)
	}

	passwordHashed := util.EncodePassword(cmd.OldPassword, userQuery.Result.Salt)
	if passwordHashed != userQuery.Result.Password {
		return ApiError(401, "Invalid old password", nil)
	}

	if len(cmd.NewPassword) < 4 {
		return ApiError(400, "New password too short", nil)
	}

	cmd.UserId = c.UserId
	cmd.NewPassword = util.EncodePassword(cmd.NewPassword, userQuery.Result.Salt)

	if err := bus.Dispatch(&cmd); err != nil {
		return ApiError(500, "Failed to change user password", err)
	}

	return ApiSuccess("User password changed")
}
示例#2
0
func AdminUpdateUserPassword(c *middleware.Context, form dtos.AdminUpdateUserPasswordForm) {
	userId := c.ParamsInt64(":id")

	if len(form.Password) < 4 {
		c.JsonApiErr(400, "New password too short", nil)
		return
	}

	userQuery := m.GetUserByIdQuery{Id: userId}

	if err := bus.Dispatch(&userQuery); err != nil {
		c.JsonApiErr(500, "Could not read user from database", err)
		return
	}

	passwordHashed := util.EncodePassword(form.Password, userQuery.Result.Salt)

	cmd := m.ChangeUserPasswordCommand{
		UserId:      userId,
		NewPassword: passwordHashed,
	}

	if err := bus.Dispatch(&cmd); err != nil {
		c.JsonApiErr(500, "Failed to update user password", err)
		return
	}

	c.JsonOK("User password updated")
}
示例#3
0
func CreateUser(cmd *m.CreateUserCommand) error {
	return inTransaction2(func(sess *session) error {
		orgId, err := getOrgIdForNewUser(cmd.Email, sess)
		if err != nil {
			return err
		}

		// create user
		user := m.User{
			Email:   cmd.Email,
			Name:    cmd.Name,
			Login:   cmd.Login,
			Company: cmd.Company,
			IsAdmin: cmd.IsAdmin,
			OrgId:   orgId,
			Created: time.Now(),
			Updated: time.Now(),
		}

		if len(cmd.Password) > 0 {
			user.Salt = util.GetRandomString(10)
			user.Rands = util.GetRandomString(10)
			user.Password = util.EncodePassword(cmd.Password, user.Salt)
		}

		sess.UseBool("is_admin")

		if _, err := sess.Insert(&user); err != nil {
			return err
		}

		// create org user link
		orgUser := m.OrgUser{
			OrgId:   orgId,
			UserId:  user.Id,
			Role:    m.ROLE_ADMIN,
			Created: time.Now(),
			Updated: time.Now(),
		}

		if setting.AutoAssignOrg && !user.IsAdmin {
			orgUser.Role = m.RoleType(setting.AutoAssignOrgRole)
		}

		if _, err = sess.Insert(&orgUser); err != nil {
			return err
		}

		sess.publishAfterCommit(&events.UserCreated{
			Timestamp: user.Created,
			Id:        user.Id,
			Name:      user.Name,
			Login:     user.Login,
			Email:     user.Email,
		})

		cmd.Result = user
		return nil
	})
}
示例#4
0
func LoginPost(c *middleware.Context, cmd dtos.LoginCommand) {
	userQuery := m.GetUserByLoginQuery{LoginOrEmail: cmd.User}
	err := bus.Dispatch(&userQuery)

	if err != nil {
		c.JsonApiErr(401, "Invalid username or password", err)
		return
	}

	user := userQuery.Result

	passwordHashed := util.EncodePassword(cmd.Password, user.Salt)
	if passwordHashed != user.Password {
		c.JsonApiErr(401, "Invalid username or password", err)
		return
	}

	loginUserWithUser(user, c)

	result := map[string]interface{}{
		"message": "Logged in",
	}

	if redirectTo, _ := url.QueryUnescape(c.GetCookie("redirect_to")); len(redirectTo) > 0 {
		result["redirectUrl"] = redirectTo
		c.SetCookie("redirect_to", "", -1, setting.AppSubUrl+"/")
	}

	metrics.M_Api_Login_Post.Inc(1)

	c.JSON(200, result)
}
示例#5
0
func New(orgId int64, name string) KeyGenResult {
	jsonKey := ApiKeyJson{}

	jsonKey.OrgId = orgId
	jsonKey.Name = name
	jsonKey.Key = util.GetRandomString(32)

	result := KeyGenResult{}
	result.HashedKey = util.EncodePassword(jsonKey.Key, name)

	jsonString, _ := json.Marshal(jsonKey)

	result.ClientSecret = base64.StdEncoding.EncodeToString([]byte(jsonString))
	return result
}
示例#6
0
func TestApiKeyGen(t *testing.T) {

	Convey("When generating new api key", t, func() {
		result := New(12, "Cool key")

		So(result.ClientSecret, ShouldNotBeEmpty)
		So(result.HashedKey, ShouldNotBeEmpty)

		Convey("can decode key", func() {
			keyInfo, err := Decode(result.ClientSecret)
			So(err, ShouldBeNil)

			keyHashed := util.EncodePassword(keyInfo.Key, keyInfo.Name)
			So(keyHashed, ShouldEqual, result.HashedKey)
		})
	})
}
示例#7
0
func initContextWithBasicAuth(ctx *Context) bool {
	if !setting.BasicAuthEnabled {
		return false
	}

	header := ctx.Req.Header.Get("Authorization")
	if header == "" {
		return false
	}

	username, password, err := util.DecodeBasicAuthHeader(header)
	if err != nil {
		ctx.JsonApiErr(401, "Invalid Basic Auth Header", err)
		return true
	}

	loginQuery := m.GetUserByLoginQuery{LoginOrEmail: username}
	if err := bus.Dispatch(&loginQuery); err != nil {
		ctx.JsonApiErr(401, "Basic auth failed", err)
		return true
	}

	user := loginQuery.Result

	// validate password
	if util.EncodePassword(password, user.Salt) != user.Password {
		ctx.JsonApiErr(401, "Invalid username or password", nil)
		return true
	}

	query := m.GetSignedInUserQuery{UserId: user.Id}
	if err := bus.Dispatch(&query); err != nil {
		ctx.JsonApiErr(401, "Authentication error", err)
		return true
	} else {
		ctx.SignedInUser = query.Result
		ctx.IsSignedIn = true
		return true
	}
}
示例#8
0
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")
}
示例#9
0
func TestMiddlewareContext(t *testing.T) {

	Convey("Given the grafana middleware", t, func() {
		middlewareScenario("middleware should add context to injector", func(sc *scenarioContext) {
			sc.fakeReq("GET", "/").exec()
			So(sc.context, ShouldNotBeNil)
		})

		middlewareScenario("Default middleware should allow get request", func(sc *scenarioContext) {
			sc.fakeReq("GET", "/").exec()
			So(sc.resp.Code, ShouldEqual, 200)
		})

		middlewareScenario("Non api request should init session", func(sc *scenarioContext) {
			sc.fakeReq("GET", "/").exec()
			So(sc.resp.Header().Get("Set-Cookie"), ShouldContainSubstring, "grafana_sess")
		})

		middlewareScenario("Invalid api key", func(sc *scenarioContext) {
			sc.apiKey = "invalid_key_test"
			sc.fakeReq("GET", "/").exec()

			Convey("Should not init session", func() {
				So(sc.resp.Header().Get("Set-Cookie"), ShouldBeEmpty)
			})

			Convey("Should return 401", func() {
				So(sc.resp.Code, ShouldEqual, 401)
				So(sc.respJson["message"], ShouldEqual, "Invalid API key")
			})
		})

		middlewareScenario("Using basic auth", func(sc *scenarioContext) {

			bus.AddHandler("test", func(query *m.GetUserByLoginQuery) error {
				query.Result = &m.User{
					Password: util.EncodePassword("myPass", "salt"),
					Salt:     "salt",
				}
				return nil
			})

			bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error {
				query.Result = &m.SignedInUser{OrgId: 2, UserId: 12}
				return nil
			})

			setting.BasicAuthEnabled = true
			authHeader := util.GetBasicAuthHeader("myUser", "myPass")
			sc.fakeReq("GET", "/").withAuthoriziationHeader(authHeader).exec()

			Convey("Should init middleware context with user", func() {
				So(sc.context.IsSignedIn, ShouldEqual, true)
				So(sc.context.OrgId, ShouldEqual, 2)
				So(sc.context.UserId, ShouldEqual, 12)
			})
		})

		middlewareScenario("Valid api key", func(sc *scenarioContext) {
			keyhash := util.EncodePassword("v5nAwpMafFP6znaS4urhdWDLS5511M42", "asd")

			bus.AddHandler("test", func(query *m.GetApiKeyByNameQuery) error {
				query.Result = &m.ApiKey{OrgId: 12, Role: m.ROLE_EDITOR, Key: keyhash}
				return nil
			})

			sc.fakeReq("GET", "/").withValidApiKey().exec()

			Convey("Should return 200", func() {
				So(sc.resp.Code, ShouldEqual, 200)
			})

			Convey("Should init middleware context", func() {
				So(sc.context.IsSignedIn, ShouldEqual, true)
				So(sc.context.OrgId, ShouldEqual, 12)
				So(sc.context.OrgRole, ShouldEqual, m.ROLE_EDITOR)
			})
		})

		middlewareScenario("Valid api key, but does not match db hash", func(sc *scenarioContext) {
			keyhash := "something_not_matching"

			bus.AddHandler("test", func(query *m.GetApiKeyByNameQuery) error {
				query.Result = &m.ApiKey{OrgId: 12, Role: m.ROLE_EDITOR, Key: keyhash}
				return nil
			})

			sc.fakeReq("GET", "/").withValidApiKey().exec()

			Convey("Should return api key invalid", func() {
				So(sc.resp.Code, ShouldEqual, 401)
				So(sc.respJson["message"], ShouldEqual, "Invalid API key")
			})
		})

		middlewareScenario("UserId in session", func(sc *scenarioContext) {

			sc.fakeReq("GET", "/").handler(func(c *Context) {
				c.Session.Set(SESS_KEY_USERID, int64(12))
			}).exec()

			bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error {
				query.Result = &m.SignedInUser{OrgId: 2, UserId: 12}
				return nil
			})

			sc.fakeReq("GET", "/").exec()

			Convey("should init context with user info", func() {
				So(sc.context.IsSignedIn, ShouldBeTrue)
				So(sc.context.UserId, ShouldEqual, 12)
			})
		})

		middlewareScenario("When anonymous access is enabled", func(sc *scenarioContext) {
			setting.AnonymousEnabled = true
			setting.AnonymousOrgName = "test"
			setting.AnonymousOrgRole = string(m.ROLE_EDITOR)

			bus.AddHandler("test", func(query *m.GetOrgByNameQuery) error {
				So(query.Name, ShouldEqual, "test")

				query.Result = &m.Org{Id: 2, Name: "test"}
				return nil
			})

			sc.fakeReq("GET", "/").exec()

			Convey("should init context with org info", func() {
				So(sc.context.UserId, ShouldEqual, 0)
				So(sc.context.OrgId, ShouldEqual, 2)
				So(sc.context.OrgRole, ShouldEqual, m.ROLE_EDITOR)
			})

			Convey("context signed in should be false", func() {
				So(sc.context.IsSignedIn, ShouldBeFalse)
			})
		})

		middlewareScenario("When auth_proxy is enabled enabled and user exists", func(sc *scenarioContext) {
			setting.AuthProxyEnabled = true
			setting.AuthProxyHeaderName = "X-WEBAUTH-USER"
			setting.AuthProxyHeaderProperty = "username"

			bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error {
				query.Result = &m.SignedInUser{OrgId: 2, UserId: 12}
				return nil
			})

			sc.fakeReq("GET", "/")
			sc.req.Header.Add("X-WEBAUTH-USER", "torkelo")
			sc.exec()

			Convey("should init context with user info", func() {
				So(sc.context.IsSignedIn, ShouldBeTrue)
				So(sc.context.UserId, ShouldEqual, 12)
				So(sc.context.OrgId, ShouldEqual, 2)
			})
		})

		middlewareScenario("When auth_proxy is enabled enabled and user does not exists", func(sc *scenarioContext) {
			setting.AuthProxyEnabled = true
			setting.AuthProxyHeaderName = "X-WEBAUTH-USER"
			setting.AuthProxyHeaderProperty = "username"
			setting.AuthProxyAutoSignUp = true

			bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error {
				if query.UserId > 0 {
					query.Result = &m.SignedInUser{OrgId: 4, UserId: 33}
					return nil
				} else {
					return m.ErrUserNotFound
				}
			})

			var createUserCmd *m.CreateUserCommand
			bus.AddHandler("test", func(cmd *m.CreateUserCommand) error {
				createUserCmd = cmd
				cmd.Result = m.User{Id: 33}
				return nil
			})

			sc.fakeReq("GET", "/")
			sc.req.Header.Add("X-WEBAUTH-USER", "torkelo")
			sc.exec()

			Convey("Should create user if auto sign up is enabled", func() {
				So(sc.context.IsSignedIn, ShouldBeTrue)
				So(sc.context.UserId, ShouldEqual, 33)
				So(sc.context.OrgId, ShouldEqual, 4)

			})
		})

	})
}
示例#10
0
func IsValid(key *ApiKeyJson, hashedKey string) bool {
	check := util.EncodePassword(key.Key, key.Name)
	return check == hashedKey
}