예제 #1
0
// http DELETE localhost:5025/admin/remove-users userIds:='["56bf19d65a1d18b704000001", "56be731d5a1d18accd000001"]' X-Diskette-Session-Token:<session_token>
func (service *serviceImpl) RemoveUsers(c echo.Context) error {
	var request struct {
		UserIds []string `json:"userIds"`
	}
	c.Bind(&request)

	if request.UserIds == nil {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'userIds'")))
	}

	objectIds := []bson.ObjectId{}
	for _, userId := range request.UserIds {
		objectIds = append(objectIds, bson.ObjectIdHex(userId))
	}

	info, err := service.userCollection.RemoveAll(bson.M{
		"_id": bson.M{
			"$in": objectIds,
		},
	})
	if err != nil {
		err = errors.New("No such user.")
		c.JSON(http.StatusNotFound, util.CreateErrResponse(err))
		return err
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(info.Removed))
}
예제 #2
0
// http POST localhost:5025/user/forgot-password [email protected]
func (service *serviceImpl) ForgotPassword(c echo.Context) error {
	var request struct {
		Email string `json:"email"`
	}
	c.Bind(&request)

	if request.Email == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'email'")))
	}

	resetKey := uuid.NewV4().String()

	err := service.userCollection.Update(
		bson.M{"email": request.Email},
		bson.M{
			"$set": bson.M{
				"resetKey":         resetKey,
				"requestedResetAt": time.Now(),
			},
		},
	)
	if err != nil {
		return c.JSON(http.StatusNotFound, util.CreateErrResponse(errors.New("The user doesn't exist.")))
	}

	token := tokens.ResetToken{Key: resetKey}
	tokenStr, err := token.ToString(service.jwtKey)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(bson.M{"ResetToken": tokenStr}))
}
// http DELETE localhost:5025/admin/remove-unconfirmed-users X-Diskette-Session-Token:<session_token>
func (service *serviceImpl) RemoveUnconfirmedUsers(c echo.Context) error {

	d, err := time.ParseDuration("12h")
	if err != nil {
		return err
	}

	objectIds := []bson.ObjectId{}
	iter := service.userCollection.Find(nil).Iter()
	var userDoc collections.UserDocument
	for iter.Next(&userDoc) {
		isAccountOld := userDoc.CreatedAt.Before(time.Now().Add(-1 * d))
		if isAccountOld && !userDoc.IsConfirmed {
			objectIds = append(objectIds, userDoc.Id)
		}
	}
	if err := iter.Close(); err != nil {
		return err
	}

	info, err := service.userCollection.RemoveAll(bson.M{
		"_id": bson.M{
			"$in": objectIds,
		},
	})
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(info.Updated))
}
예제 #4
0
// http POST localhost:5025/admin/suspend-users userIds:='["56bf19d65a1d18b704000001", "56be731d5a1d18accd000001"]' X-Diskette-Session-Token:<session_token>
func (service *serviceImpl) SuspendUsers(c echo.Context) error {
	var request struct {
		UserIds []string `json:"userIds"`
	}
	c.Bind(&request)

	if request.UserIds == nil {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'userIds'")))
	}

	objectIds := []bson.ObjectId{}
	for _, userId := range request.UserIds {
		objectIds = append(objectIds, bson.ObjectIdHex(userId))
	}

	info, err := service.userCollection.UpdateAll(
		bson.M{
			"_id": bson.M{
				"$in": objectIds,
			},
		},
		bson.M{
			"$set": bson.M{
				"isSuspended": true,
			},
		},
	)

	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(info.Updated))
}
예제 #5
0
// http POST localhost:5025/session/set-profile?st=<session_token> profile:='{"profession": "Software Developer"}'
func (service *serviceImpl) SetProfile(c echo.Context) error {
	sessionToken := c.Get("sessionToken").(tokens.SessionToken)

	var request struct {
		Profile map[string]interface{} `json:"profile"`
	}
	c.Bind(&request)

	if request.Profile == nil {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'profile'")))
	}

	err := service.userCollection.UpdateId(
		bson.ObjectIdHex(sessionToken.UserId),
		bson.M{
			"$set": bson.M{
				"profile": request.Profile,
			},
		},
	)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(nil))
}
예제 #6
0
// http POST localhost:5025/user/confirm token=<confirmation_token>
func (service *serviceImpl) ConfirmSignup(c echo.Context) error {
	var request struct {
		Token string `json:"token"`
	}
	c.Bind(&request)

	if request.Token == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'token'")))
	}

	token, err := tokens.ParseConfirmationToken(service.jwtKey, request.Token)
	if err != nil || token.Key == "" {
		return c.JSON(http.StatusForbidden, util.CreateErrResponse(err))
	}

	err = service.userCollection.Update(
		bson.M{"confirmationKey": token.Key},
		bson.M{
			"$set": bson.M{
				"isConfirmed": true,
			},
		},
	)

	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(nil))
}
예제 #7
0
// http POST localhost:5025/user/signup [email protected] password=abc profile:='{"name": "Joe Doe", "language": "en" }'
func (service *serviceImpl) Signup(c echo.Context) error {
	var request struct {
		Email    string                 `json:"email"`
		Password string                 `json:"password"`
		Profile  map[string]interface{} `json:"profile"`
	}
	c.Bind(&request)

	if request.Email == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'email'")))
	}

	if request.Password == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'password'")))
	}

	if request.Profile == nil {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'profile'")))
	}

	count, err := service.userCollection.Find(bson.M{"email": request.Email}).Count()
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	if count > 0 {
		return c.JSON(http.StatusConflict, util.CreateErrResponse(errors.New("This email address is already being used.")))
	}

	hashedPass, err := bcrypt.GenerateFromPassword([]byte(request.Password), bcrypt.DefaultCost)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	userDoc := collections.UserDocument{
		Id:          bson.NewObjectId(),
		Email:       request.Email,
		HashedPass:  hashedPass,
		Profile:     request.Profile,
		CreatedAt:   time.Now(),
		IsSuspended: false,
	}

	userDoc.ConfirmationKey = uuid.NewV4().String()

	token := tokens.ConfirmationToken{Key: userDoc.ConfirmationKey}

	tokenStr, err := token.ToString(service.jwtKey)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	err = service.userCollection.Insert(userDoc)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(bson.M{"ConfirmationToken": tokenStr}))
}
예제 #8
0
// POST /collection?st={sessionToken} BODY={doc}
// examples:
// http POST localhost:5025/collection/user name=dfreire [email protected]
func (service *serviceImpl) Post(c echo.Context) error {
	collection := c.Param("collection")
	// sessionToken := c.Query("st")

	var document map[string]interface{}
	c.Bind(&document)

	err := service.db.C(collection).Insert(document)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(document))
}
예제 #9
0
// http localhost:5025/admin/get-users?q=<query> X-Diskette-Session-Token:<session_token>
func (service *serviceImpl) GetUsers(c echo.Context) error {
	var query map[string]interface{}
	queryStr := c.QueryParam("q")
	if queryStr != "" {
		if err := json.Unmarshal([]byte(queryStr), &query); err != nil {
			return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
		}
	}

	var documents []interface{}
	err := service.userCollection.Find(query).All(&documents)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(documents))
}
예제 #10
0
// http POST localhost:5025/user/signin [email protected] password=abc
func (service *serviceImpl) Signin(c echo.Context) error {
	var request struct {
		Email    string `json:"email"`
		Password string `json:"password"`
	}
	c.Bind(&request)

	if request.Email == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'email'")))
	}

	if request.Password == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'password'")))
	}

	var userDoc collections.UserDocument
	err := service.userCollection.Find(bson.M{"email": request.Email}).One(&userDoc)
	if err != nil {
		return c.JSON(http.StatusNotFound, util.CreateErrResponse(errors.New("The user doesn't exist.")))
	}

	if !userDoc.IsConfirmed {
		return c.JSON(http.StatusUnauthorized, util.CreateErrResponse(errors.New("The user has not confirmed the account.")))
	}

	if userDoc.IsSuspended {
		return c.JSON(http.StatusUnauthorized, util.CreateErrResponse(errors.New("The user is suspended.")))
	}

	if err = bcrypt.CompareHashAndPassword([]byte(userDoc.HashedPass), []byte(request.Password)); err != nil {
		return c.JSON(http.StatusUnauthorized, util.CreateErrResponse(errors.New("The password didn't match.")))
	}

	token := tokens.SessionToken{
		UserId:    userDoc.Id.Hex(),
		CreatedAt: time.Now(),
	}

	tokenStr, err := token.ToString(service.jwtKey)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(bson.M{"sessionToken": tokenStr}))
}
예제 #11
0
// http POST localhost:5025/session/signout?st=<session_token>
func (service *serviceImpl) Signout(c echo.Context) error {
	sessionToken := c.Get("sessionToken").(tokens.SessionToken)

	err := service.userCollection.UpdateId(
		bson.ObjectIdHex(sessionToken.UserId),
		bson.M{
			"$set": bson.M{
				"signedOutAt": time.Now(),
			},
		},
	)

	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(nil))
}
예제 #12
0
// http POST localhost:5025/admin/change-user-password userId=<user_id> newPassword="******" X-Diskette-Session-Token:<session_token>
func (service *serviceImpl) ChangeUserPassword(c echo.Context) error {
	var request struct {
		UserId      string `json:"userId"`
		NewPassword string `json:"newPassword"`
	}
	c.Bind(&request)

	if request.UserId == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'userId'")))
	}

	if request.NewPassword == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'newPassword'")))
	}

	var userDoc collections.UserDocument
	err := service.userCollection.FindId(bson.ObjectIdHex(request.UserId)).One(&userDoc)
	if err != nil {
		err = errors.New("No such user.")
		c.JSON(http.StatusNotFound, util.CreateErrResponse(err))
		return err
	}

	hashedPass, err := bcrypt.GenerateFromPassword([]byte(request.NewPassword), bcrypt.DefaultCost)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	err = service.userCollection.UpdateId(
		bson.ObjectIdHex(request.UserId),
		bson.M{
			"$set": bson.M{
				"hashedPass": hashedPass,
			},
		},
	)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(nil))
}
예제 #13
0
// http POST localhost:5025/user/reset-password token=<reset_token> password=123
func (service *serviceImpl) ResetPassword(c echo.Context) error {
	var request struct {
		Token    string `json:"token"`
		Password string `json:"password"`
	}
	c.Bind(&request)

	if request.Token == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'token'")))
	}

	if request.Password == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'password'")))
	}

	token, err := tokens.ParseResetToken(service.jwtKey, request.Token)
	if err != nil || token.Key == "" {
		return c.JSON(http.StatusForbidden, util.CreateErrResponse(err))
	}

	hashedPass, err := bcrypt.GenerateFromPassword([]byte(request.Password), bcrypt.DefaultCost)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	err = service.userCollection.Update(
		bson.M{"resetKey": token.Key},
		bson.M{
			"$set": bson.M{
				"resetKey":         "",
				"requestedResetAt": time.Unix(0, 0),
				"hashedPass":       hashedPass,
			},
		},
	)
	if err != nil {
		return c.JSON(http.StatusNotFound, util.CreateErrResponse(errors.New("The token doesn't exist.")))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(nil))
}
예제 #14
0
// http POST localhost:5025/session/change-password?st=<session_token> oldPassword=<old_password> newPassword=<new_password>
func (service *serviceImpl) ChangePassword(c echo.Context) error {
	sessionToken := c.Get("sessionToken").(tokens.SessionToken)
	userDoc := c.Get("userDoc").(collections.UserDocument)

	var request struct {
		OldPassword string `json:"oldPassword"`
		NewPassword string `json:"newPassword"`
	}
	c.Bind(&request)

	if request.OldPassword == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'oldPassword'")))
	}

	if request.NewPassword == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'newPassword'")))
	}

	if err := bcrypt.CompareHashAndPassword([]byte(userDoc.HashedPass), []byte(request.OldPassword)); err != nil {
		return c.JSON(http.StatusUnauthorized, util.CreateErrResponse(errors.New("The old password didn't match.")))
	}

	newHashedPass, err := bcrypt.GenerateFromPassword([]byte(request.NewPassword), bcrypt.DefaultCost)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	err = service.userCollection.UpdateId(
		bson.ObjectIdHex(sessionToken.UserId),
		bson.M{
			"$set": bson.M{
				"hashedPass": newHashedPass,
			},
		},
	)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(nil))
}
예제 #15
0
// examples:
// http DELETE localhost:5025/collection/user?q='{"name":"dfreire"}'
func (service *serviceImpl) Delete(c echo.Context) error {
	collection := c.Param("collection")

	queryStr := c.QueryParam("q")
	if queryStr == "" {

		return c.JSON(http.StatusForbidden, util.CreateErrResponse(errors.New("Missing parameter 'q' (for query)")))
	}

	var query map[string]interface{}
	if err := json.Unmarshal([]byte(queryStr), &query); err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	_, err := service.db.C(collection).RemoveAll(query)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(nil))
}
예제 #16
0
// http POST localhost:5025/admin/remove-expired-reset-keys X-Diskette-Session-Token:<session_token>
func (service *serviceImpl) RemoveExpiredResetKeys(c echo.Context) error {

	d, err := time.ParseDuration("12h")
	if err != nil {
		return err
	}

	objectIds := []bson.ObjectId{}
	iter := service.userCollection.Find(nil).Iter()
	var userDoc collections.UserDocument
	for iter.Next(&userDoc) {
		hasResetKey := userDoc.ResetKey != ""
		hasResetKeyExpired := userDoc.RequestedResetAt.Before(time.Now().Add(-1 * d))
		if hasResetKey && hasResetKeyExpired {
			objectIds = append(objectIds, userDoc.Id)
		}
	}
	if err := iter.Close(); err != nil {
		return err
	}

	info, err := service.userCollection.UpdateAll(
		bson.M{
			"_id": bson.M{
				"$in": objectIds,
			},
		},
		bson.M{
			"$set": bson.M{
				"resetKey": "",
			},
		},
	)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(info.Updated))
}
예제 #17
0
// http POST localhost:5025/admin/set-user-roles userId=<user_id> newRoles:='["admin"]' X-Diskette-Session-Token:<session_token>
func (service *serviceImpl) SetUserRoles(c echo.Context) error {
	var request struct {
		UserId   string   `json:"userId"`
		NewRoles []string `json:"newRoles"`
	}
	c.Bind(&request)

	if request.UserId == "" {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'userId'")))
	}

	if request.NewRoles == nil {
		return c.JSON(http.StatusBadRequest, util.CreateErrResponse(errors.New("Missing parameter 'newRoles'")))
	}

	var userDoc collections.UserDocument
	err := service.userCollection.FindId(bson.ObjectIdHex(request.UserId)).One(&userDoc)
	if err != nil {
		err = errors.New("No such user.")
		c.JSON(http.StatusNotFound, util.CreateErrResponse(err))
		return err
	}

	err = service.userCollection.UpdateId(
		bson.ObjectIdHex(request.UserId),
		bson.M{
			"$set": bson.M{
				"roles": request.NewRoles,
			},
		},
	)
	if err != nil {
		return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err))
	}

	return c.JSON(http.StatusOK, util.CreateOkResponse(nil))
}