Ejemplo n.º 1
0
func OAuthHandleWrapper(handler http.HandlerFunc, groups []string, pri []string) http.HandlerFunc {
	return func(rw http.ResponseWriter, req *http.Request) {
		userMngr, err := Provider().OpenUserMngr(req)
		if err != nil {
			response.InternalErrorResponse(rw, &response.JSONErr{Message: err.Error()})
		}
		defer userMngr.Close()

		token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
		user, err := userMngr.GetUser(token)
		if err != nil {
			if err == ErrNotLogged {
				response.ForbiddenResponse(rw, &response.JSONErr{
					Code:        response.ErrCodeNotLogged,
					Message:     err.Error(),
					Description: "User need to be logged in to perform this action.",
				})
				return
			}
			response.InternalErrorResponse(rw, &response.JSONErr{Message: err.Error()})
			return
		}

		if len(groups) > 0 {
			for _, bg := range user.BriefGroups {
				for _, g2 := range groups {
					if bg.Name == g2 {
						handler(rw, req)
						return
					}
				}
			}
		}

		var (
			cannot   bool
			cannotDo string
		)
		for _, do := range pri {
			if !userMngr.Can(user, do) {
				cannotDo += do + ","
			}
		}

		if cannot {
			response.ForbiddenResponse(rw, &response.JSONErr{
				Code:        response.ErrNoPermission,
				Message:     "User doesn't have valid permission.",
				Description: "User doesn't have " + cannotDo + " permission.",
			})
			return
		}

		// run user defined handler
		handler(rw, req)
	}
}
Ejemplo n.º 2
0
func OAuthOwnerPrivilegeWrapper(handler http.HandlerFunc, userIdField string) http.HandlerFunc {
	return func(rw http.ResponseWriter, req *http.Request) {
		userMngr, err := Provider().OpenUserMngr(req)
		if err != nil {
			response.InternalErrorResponse(rw, &response.JSONErr{Message: err.Error()})
		}
		defer userMngr.Close()

		token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
		user, err := userMngr.GetUser(token)
		if err != nil {
			if err == ErrNotLogged {
				response.ForbiddenResponse(rw, &response.JSONErr{
					Code:        response.ErrCodeNotLogged,
					Message:     err.Error(),
					Description: "User need to be logged in to perform this action.",
				})
				return
			}
			response.InternalErrorResponse(rw, &response.JSONErr{Message: err.Error()})
			return
		}

		vars := mux.Vars(req)
		idStr := vars[userIdField]
		if len(idStr) == 0 {
			response.BadRequestResponse(rw, &response.JSONErr{
				Message:     "Missing " + userIdField + " from request URL",
				Description: "OAuthOwnerPrivilegeWrapper require " + userIdField + " defiend by 'userIdField' to be exist in handle pattern.",
			})
			return
		}

		u, err := userMngr.FindUser(idStr)
		if err != nil {
			response.InternalErrorResponse(rw, &response.JSONErr{Message: err.Error()})
			return
		}

		if u.Id != user.Id {
			response.ForbiddenResponse(rw, &response.JSONErr{
				Code:        response.ErrNoPermission,
				Message:     "Current user must be the owner of profile.",
				Description: "Current user must be the owner of the profile defined by " + userIdField + " field.",
			})
			return
		}

		handler(rw, req)
	}
}
Ejemplo n.º 3
0
/*
UserInfoDetail handle the request for getting user account info.

Example Request Body:
  GET /profile/some-kind-of-ID/info
Example Success Response
  {
    "FirstName": "Cao Nguyên"
    ...//other feilds of auth,UserInfo struct
  }
*/
func UserInfoDetail(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
	}

	if currentUser.Id != u.Id {
		if !userMngr.Can(currentUser, "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
		}
	}

	json.NewEncoder(rw).Encode(u.Info)
}
Ejemplo n.º 4
0
/*
UserInfoUpdate handle the reuqest for update user infomation. Its require 'manage_user'
to change other's infomation.

Example Request Body:
  PUT /profile/some-kind-of-ID/info
  {
    "FirstName": "Cao Nguyên"
    ...//other feilds of auth,UserInfo struct
  }
*/
func UserInfoUpdate(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
	}

	if currentUser.Id != u.Id {
		if !userMngr.Can(currentUser, "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
		}
	}

	var inf auth.UserInfo
	err = json.NewDecoder(req.Body).Decode(&inf)
	if err != nil {
		response.BadRequestResponse(rw, &response.JSONErr{
			Code:        ErrCodeInvalidInput,
			Message:     err.Error(),
			Description: "The request body must be a valid response.UserInfo JSON object",
		})
		return
	}
	defer req.Body.Close()

	u.Info = inf
	err = userMngr.UpdateUserDetail(u)
	if err != nil {
		response.InternalErrorResponse(rw, &response.JSONErr{
			Message:     err.Error(),
			Description: "Error when saving user object to database.",
		})
		return
	}

}
Ejemplo n.º 5
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."}`))
}