// 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)) }
// 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)) }
// 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)) }
// 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)) }
// 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)) }
// 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})) }
// 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)) }
// 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)) }
// 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})) }
// 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)) }
// 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)) }
// 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)) }
// 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)) }
// 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)) }
// 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)) }
// 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)) }