Exemple #1
0
/*
PasswordUpdate handle the request for changin user password. its require 'manage_user' permission to
change other's password.

Example Request Body:
  POST /profile/some-kind-of-ID/change-password
  {
    "Pwd": "xxxxxxxxx",
    "NewPwd": "yyyyyyyyy",
    "NewPwdRepeat": "yyyyyyyyy"
  }
Example Success Response:
{
  "Message":"Password for user  has been updated."
}
*/
func PasswordUpdate(rw http.ResponseWriter, req *http.Request) {
	rw.Header().Set("Content-Type", "application/json; charset=utf-8")

	u, userMngr, err := getUserByIdAndWriteIfError(rw, req)
	if err != nil {
		return
	}
	defer userMngr.Close()

	token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
	currentUser, err := userMngr.GetUser(token)
	if err != nil {
		response.InternalErrorResponse(rw, &response.JSONErr{
			Message:     err.Error(),
			Description: "Error when loading current user.",
		})
		return
	}

	var can_manage_user bool

	if currentUser.Id != u.Id {
		if can_manage_user = userMngr.Can(currentUser, "manage_user"); !can_manage_user {
			response.ForbiddenResponse(rw, &response.JSONErr{
				Code:        response.ErrNoPermission,
				Message:     "Current user doesn't have valid permission.",
				Description: "Current user need 'manage_user' permission to perform this action.",
			})
			return
		}
	}

	pwdChange := struct {
		Pwd          string
		NewPwd       string
		NewPwdRepeat string
	}{}

	err = json.NewDecoder(req.Body).Decode(&pwdChange)
	if err != nil {
		response.BadRequestResponse(rw, &response.JSONErr{
			Code:        ErrCodeInvalidInput,
			Message:     err.Error(),
			Description: "The request body mus contain an JSON object with valid Pwd, NewPwd and NewPwdRepeat field.",
		})
		return
	}

	if pwdChange.NewPwd != pwdChange.NewPwdRepeat {
		response.BadRequestResponse(rw, &response.JSONErr{
			Code:    ErrCodePwdMismatch,
			Message: "NewPwd doesn't match.",
		})
		return
	}

	if !can_manage_user {
		if u.ComparePassword(pwdChange.Pwd) != nil {
			response.ForbiddenResponse(rw, &response.JSONErr{
				Code:        ErrCodeInvlaidPwd,
				Message:     "Invalid passsword",
				Description: "Your provied password are invlaid.",
			})
			return
		}
	}

	err = u.ChangePassword(pwdChange.NewPwd)
	if err != nil {
		response.InternalErrorResponse(rw, &response.JSONErr{
			Message:     err.Error(),
			Description: "Error when update user password.",
		})
		return
	}

	if !can_manage_user {
		rw.WriteHeader(http.StatusAccepted)
		go func() {
			var logger *log.Logger
			logdbw, err := dblog.Provider().OpenLogger(req)
			if err != nil {
				// use std log... :(
				// mostly never be in appengine env
				logger = log.New(os.Stdout, "", log.LstdFlags)
				logger.Println("rest: cannot OpenLogger")
			} else {
				logger = log.New(logdbw, "", 4)
			}

			conf, err := config.Provider().OpenConfigurator(req)
			if err != nil {
				logger.Println("rest: OpenConfigurator", err)
				return
			}
			defer conf.Close()

			mess, err := conf.Get("pwd_change_message")
			if err != nil {
				logger.Println("rest: Configurator can't load 'pwd_change_message'", err)
			}

			err = util.SendSimpleMail(conf, u.Email, "Password changed", mess)
			if err != nil {
				logger.Println("rest: SendSimpleMail", err)
			}
		}()
	}

	rw.Write([]byte(`{"Message":"Password for user ` + u.Email + ` has been updated."}`))
}
Exemple #2
0
/*
SignUp handle the request for account sign-up. The handler will
check the email and password format. If success it will send an
email and immediately return a 202 status code.

Example Request Body:
  POST /signup
  {
    "Email": "*****@*****.**",
    "Pwd": "xxxxxxxxx",
    "PwdRepeat": "xxxxxxxxx"
  }
Example Success Response:
  {
    "Message":"email sent to [email protected]"
  }
*/
func SignUp(rw http.ResponseWriter, req *http.Request) {
	rw.Header().Set("Content-Type", "application/json; charset=utf-8")

	userMngr, err := auth.Provider().OpenUserMngr(req)
	if err != nil {
		response.InternalErrorResponse(rw, &response.JSONErr{Message: err.Error()})
		return
	}
	defer userMngr.Close()

	credential := struct {
		Email     string
		Pwd       string
		PwdRepeat string
	}{}

	err = json.NewDecoder(req.Body).Decode(&credential)
	if err != nil {
		response.BadRequestResponse(rw, &response.JSONErr{
			Code:        ErrCodeInvalidCredential,
			Message:     err.Error(),
			Description: "Credential must be an valid json object contain Email, Pwd and PwdRepeat.",
		})
		return
	}

	if credential.Pwd != credential.PwdRepeat {
		response.BadRequestResponse(rw, &response.JSONErr{
			Code:    ErrCodePwdMismatch,
			Message: "Pwd and PwdRepeat doesn't match",
		})
		return
	}

	var app bool

	u, err := userMngr.AddUser(credential.Email, credential.PwdRepeat, app)
	if err != nil {
		switch err {
		case auth.ErrInvalidEmail:
			response.ErrorResponse(rw, http.StatusPreconditionFailed, &response.JSONErr{
				Code:    ErrCodeInvalidEmail,
				Message: err.Error(),
			})
		case auth.ErrInvalidPassword:
			response.ErrorResponse(rw, http.StatusPreconditionFailed, &response.JSONErr{
				Code:    ErrCodeInvlaidPwd,
				Message: err.Error(),
			})
		case auth.ErrDuplicateEmail:
			response.ErrorResponse(rw, http.StatusPreconditionFailed, &response.JSONErr{
				Code:    ErrCodeDupEmail,
				Message: err.Error(),
			})
		default:
			response.InternalErrorResponse(rw, &response.JSONErr{Message: err.Error()})
		}
		return
	}

	conf, err := config.Provider().OpenConfigurator(req)
	if err != nil {
		response.InternalErrorResponse(rw, &response.JSONErr{Message: err.Error()})
		return
	}

	if !app {
		// TODO(!)
		// time out control for mail send
		go func() {
			err = util.SendSimpleMail(conf, u.Email, "Email confirm", u.ConfirmCodes["activate"])
			if err != nil {
				log.Println("rest: SendSimpleMail", err)
			}
			conf.Close()
		}()
	}

	rw.WriteHeader(http.StatusAccepted)
	rw.Write([]byte(`{"Message":"email sent to ` + u.Email + `"}`))
}