2020-05-04 14:58:02 +00:00
// Copyright or © or Copr. happyDNS (2020)
//
2022-01-10 13:06:19 +00:00
// contact@happydomain.org
2020-05-04 14:58:02 +00:00
//
// This software is a computer program whose purpose is to provide a modern
// interface to interact with DNS systems.
//
// This software is governed by the CeCILL license under French law and abiding
// by the rules of distribution of free software. You can use, modify and/or
// redistribute the software under the terms of the CeCILL license as
// circulated by CEA, CNRS and INRIA at the following URL
// "http://www.cecill.info".
//
// As a counterpart to the access to the source code and rights to copy, modify
// and redistribute granted by the license, users are provided only with a
// limited warranty and the software's author, the holder of the economic
// rights, and the successive licensors have only limited liability.
//
// In this respect, the user's attention is drawn to the risks associated with
// loading, using, modifying and/or developing or reproducing the software by
// the user in light of its specific status of free software, that may mean
// that it is complicated to manipulate, and that also therefore means that it
// is reserved for developers and experienced professionals having in-depth
// computer knowledge. Users are therefore encouraged to load and test the
// software's suitability as regards their requirements in conditions enabling
// the security of their systems and/or data to be ensured and, more generally,
// to use and operate it in the same conditions as regards security.
//
// The fact that you are presently reading this means that you have had
// knowledge of the CeCILL license and that you accept its terms.
2019-09-10 16:20:25 +00:00
package api
import (
2021-12-16 14:53:58 +00:00
"bytes"
2022-10-25 16:16:34 +00:00
"encoding/base64"
2020-05-23 16:47:09 +00:00
"fmt"
2020-09-10 12:44:25 +00:00
"log"
2020-05-23 16:47:09 +00:00
"net/http"
"strings"
2019-09-10 16:20:25 +00:00
2021-05-05 01:48:16 +00:00
"github.com/gin-gonic/gin"
2019-09-10 16:20:25 +00:00
2022-01-10 13:06:19 +00:00
"git.happydns.org/happydomain/actions"
"git.happydns.org/happydomain/config"
"git.happydns.org/happydomain/model"
"git.happydns.org/happydomain/storage"
2019-09-10 16:20:25 +00:00
)
2021-05-05 01:48:16 +00:00
func declareUsersRoutes ( opts * config . Options , router * gin . RouterGroup ) {
router . POST ( "/users" , func ( c * gin . Context ) {
registerUser ( opts , c )
} )
router . PATCH ( "/users" , func ( c * gin . Context ) {
specialUserOperations ( opts , c )
} )
apiUserRoutes := router . Group ( "/users/:uid" )
2021-12-16 14:53:58 +00:00
apiUserRoutes . Use ( userAuthHandler )
2021-05-05 01:48:16 +00:00
apiUserRoutes . POST ( "/email" , validateUserAddress )
apiUserRoutes . POST ( "/recovery" , recoverUserAccount )
}
func declareUsersAuthRoutes ( opts * config . Options , router * gin . RouterGroup ) {
router . GET ( "/session" , getSession )
router . DELETE ( "/session" , clearSession )
apiUserRoutes := router . Group ( "/users/:uid" )
apiUserRoutes . Use ( userHandler )
apiUserRoutes . Use ( SameUserHandler )
apiUserRoutes . GET ( "" , getUser )
apiUserRoutes . GET ( "/settings" , getUserSettings )
apiUserRoutes . POST ( "/settings" , changeUserSettings )
2021-12-16 14:53:58 +00:00
apiUserAuthRoutes := router . Group ( "/users/:uid" )
apiUserAuthRoutes . Use ( userAuthHandler )
apiUserAuthRoutes . POST ( "/delete" , func ( c * gin . Context ) {
2021-05-05 01:48:16 +00:00
deleteUser ( opts , c )
} )
2021-12-16 14:53:58 +00:00
apiUserAuthRoutes . POST ( "/new_password" , func ( c * gin . Context ) {
2021-05-05 01:48:16 +00:00
changePassword ( opts , c )
} )
}
func myUser ( c * gin . Context ) ( user * happydns . User ) {
if u , exists := c . Get ( "LoggedUser" ) ; exists {
user = u . ( * happydns . User )
} else if u , exists := c . Get ( "user" ) ; exists {
user = u . ( * happydns . User )
}
return
2019-09-10 16:20:25 +00:00
}
type UploadedUser struct {
2020-12-18 22:30:58 +00:00
Kind string
Email string
Password string
Language string ` json:"lang,omitempty" `
Newsletter bool ` json:"wantReceiveUpdate,omitempty" `
2019-09-10 16:20:25 +00:00
}
2021-05-05 01:48:16 +00:00
func registerUser ( opts * config . Options , c * gin . Context ) {
2019-09-10 16:20:25 +00:00
var uu UploadedUser
2021-05-05 01:48:16 +00:00
err := c . ShouldBindJSON ( & uu )
2019-09-10 16:20:25 +00:00
if err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s sends invalid User JSON: %s" , c . ClientIP ( ) , err . Error ( ) )
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : fmt . Sprintf ( "Something is wrong in received data: %s" , err . Error ( ) ) } )
2021-05-05 01:48:16 +00:00
return
2019-09-10 16:20:25 +00:00
}
2020-05-23 16:47:09 +00:00
if len ( uu . Email ) <= 3 || strings . Index ( uu . Email , "@" ) == - 1 {
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : "The given email is invalid." } )
return
2019-09-10 16:20:25 +00:00
}
2020-05-23 16:47:09 +00:00
if len ( uu . Password ) <= 7 {
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : "The given password is invalid." } )
return
2020-05-23 16:47:09 +00:00
}
2021-12-16 14:53:58 +00:00
if storage . MainStore . AuthUserExists ( uu . Email ) {
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : "An account already exists with the given address. Try login now." } )
return
2020-05-23 16:47:09 +00:00
}
2021-12-16 14:53:58 +00:00
user , err := happydns . NewUserAuth ( uu . Email , uu . Password )
2021-05-05 01:48:16 +00:00
if err != nil {
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : err . Error ( ) } )
return
}
2020-12-18 22:30:58 +00:00
2021-12-16 14:53:58 +00:00
user . AllowCommercials = uu . Newsletter
2021-05-05 01:48:16 +00:00
2021-12-16 14:53:58 +00:00
if err := storage . MainStore . CreateAuthUser ( user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to CreateUser in registerUser: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to create your account. Please try again later." } )
return
2019-09-10 16:20:25 +00:00
}
2021-05-05 01:48:16 +00:00
if actions . SendValidationLink ( opts , user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to SendValidationLink in registerUser: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to sent email validation link. Please try again later." } )
return
}
log . Printf ( "%s: registers new user: %s" , c . ClientIP ( ) , user . Email )
c . JSON ( http . StatusOK , user )
2019-09-10 16:20:25 +00:00
}
2020-05-23 16:47:09 +00:00
2021-05-05 01:48:16 +00:00
func specialUserOperations ( opts * config . Options , c * gin . Context ) {
2020-05-23 16:47:09 +00:00
var uu UploadedUser
2021-05-05 01:48:16 +00:00
err := c . ShouldBindJSON ( & uu )
2020-05-23 16:47:09 +00:00
if err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s sends invalid User JSON: %s" , c . ClientIP ( ) , err . Error ( ) )
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : fmt . Sprintf ( "Something is wrong in received data: %s" , err . Error ( ) ) } )
2021-05-05 01:48:16 +00:00
return
2020-05-23 16:47:09 +00:00
}
2021-05-05 01:48:16 +00:00
res := gin . H { "errmsg" : "If this address exists in our database, you'll receive a new e-mail." }
2020-05-23 21:16:41 +00:00
2021-12-16 14:53:58 +00:00
if user , err := storage . MainStore . GetAuthUserByEmail ( uu . Email ) ; err != nil {
2022-11-27 11:43:12 +00:00
log . Printf ( "%s: unable to retrieve user %q: %s" , c . ClientIP ( ) , uu . Email , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . JSON ( http . StatusOK , res )
return
2020-05-23 16:47:09 +00:00
} else {
2020-05-23 21:16:41 +00:00
if uu . Kind == "recovery" {
2021-12-16 14:53:58 +00:00
if user . EmailVerification == nil {
2021-04-20 16:04:44 +00:00
if err = actions . SendValidationLink ( opts , user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to SendValidationLink in specialUserOperations: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to sent email validation link. Please try again later." } )
return
2020-05-23 21:16:41 +00:00
}
2021-05-05 01:48:16 +00:00
log . Printf ( "%s: Sent validation link to: %s" , c . ClientIP ( ) , user . Email )
2020-05-23 21:16:41 +00:00
} else {
2021-04-20 16:04:44 +00:00
if err = actions . SendRecoveryLink ( opts , user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to SendRecoveryLink in specialUserOperations: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to sent accont recovery link. Please try again later." } )
return
2020-05-23 21:16:41 +00:00
}
2021-05-05 01:48:16 +00:00
2021-12-16 14:53:58 +00:00
if err := storage . MainStore . UpdateAuthUser ( user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to UpdateUser in specialUserOperations: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
}
log . Printf ( "%s: Sent recovery link to: %s" , c . ClientIP ( ) , user . Email )
2020-05-23 21:16:41 +00:00
}
} else if uu . Kind == "validation" {
2021-05-05 01:48:16 +00:00
// Email have already been validated, do nothing
2021-12-16 14:53:58 +00:00
if user . EmailVerification != nil {
2021-05-05 01:48:16 +00:00
c . JSON ( http . StatusOK , res )
return
2020-05-23 21:16:41 +00:00
}
2021-05-05 01:48:16 +00:00
if err = actions . SendValidationLink ( opts , user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to SendValidationLink 2 in specialUserOperations: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to sent email validation link. Please try again later." } )
return
}
log . Printf ( "%s: Sent validation link to: %s" , c . ClientIP ( ) , user . Email )
2020-05-23 16:47:09 +00:00
}
}
2020-05-23 21:16:41 +00:00
2021-05-05 01:48:16 +00:00
c . JSON ( http . StatusOK , res )
2020-05-23 16:47:09 +00:00
}
2021-05-05 01:48:16 +00:00
func SameUserHandler ( c * gin . Context ) {
myuser := c . MustGet ( "LoggedUser" ) . ( * happydns . User )
user := c . MustGet ( "user" ) . ( * happydns . User )
2021-12-16 14:53:58 +00:00
if ! bytes . Equal ( user . Id , myuser . Id ) {
2021-05-05 01:48:16 +00:00
log . Printf ( "%s: tries to do action as %s (logged %s)" , c . ClientIP ( ) , myuser , user )
c . AbortWithStatusJSON ( http . StatusForbidden , gin . H { "errmsg" : "Not authorized" } )
return
2020-05-23 16:47:09 +00:00
}
2021-05-05 01:48:16 +00:00
c . Next ( )
2020-05-23 16:47:09 +00:00
}
2021-05-05 01:48:16 +00:00
func getUser ( c * gin . Context ) {
user := c . MustGet ( "user" ) . ( * happydns . User )
c . JSON ( http . StatusOK , user )
2020-05-23 16:47:09 +00:00
}
2021-05-05 01:48:16 +00:00
func getUserSettings ( c * gin . Context ) {
user := c . MustGet ( "user" ) . ( * happydns . User )
c . JSON ( http . StatusOK , user . Settings )
2020-11-30 07:52:58 +00:00
}
2021-05-05 01:48:16 +00:00
func changeUserSettings ( c * gin . Context ) {
user := c . MustGet ( "user" ) . ( * happydns . User )
2020-11-30 07:52:58 +00:00
var us happydns . UserSettings
2021-05-05 01:48:16 +00:00
if err := c . ShouldBindJSON ( & us ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s sends invalid UserSettings JSON: %s" , c . ClientIP ( ) , err . Error ( ) )
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : fmt . Sprintf ( "Something is wrong in received data: %s" , err . Error ( ) ) } )
2021-05-05 01:48:16 +00:00
return
2020-11-30 07:52:58 +00:00
}
2021-05-05 01:48:16 +00:00
user . Settings = us
2020-11-30 07:52:58 +00:00
2021-05-05 01:48:16 +00:00
if err := storage . MainStore . UpdateUser ( user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to UpdateUser in changeUserSettings: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
2020-11-30 07:52:58 +00:00
}
2021-05-05 01:48:16 +00:00
c . JSON ( http . StatusOK , user . Settings )
2020-11-30 07:52:58 +00:00
}
2020-07-21 02:02:18 +00:00
type passwordForm struct {
Current string
Password string
PasswordConfirm string
}
2021-05-05 01:48:16 +00:00
func changePassword ( opts * config . Options , c * gin . Context ) {
2021-12-16 14:53:58 +00:00
user := c . MustGet ( "authuser" ) . ( * happydns . UserAuth )
2021-05-05 01:48:16 +00:00
2020-07-21 02:02:18 +00:00
var lf passwordForm
2021-05-05 01:48:16 +00:00
if err := c . ShouldBindJSON ( & lf ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s sends invalid passwordForm JSON: %s" , c . ClientIP ( ) , err . Error ( ) )
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : fmt . Sprintf ( "Something is wrong in received data: %s" , err . Error ( ) ) } )
2021-05-05 01:48:16 +00:00
return
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
if ! user . CheckAuth ( lf . Current ) {
c . AbortWithStatusJSON ( http . StatusForbidden , gin . H { "errmsg" : "The given current password is invalid." } )
return
2020-07-21 02:02:18 +00:00
}
if lf . Password != lf . PasswordConfirm {
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : "The new password and its confirmation are different." } )
return
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
if err := user . DefinePassword ( lf . Password ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to DefinePassword in changePassword: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
// Retrieve all user's sessions to disconnect them
2021-12-16 14:53:58 +00:00
sessions , err := storage . MainStore . GetAuthUserSessions ( user )
2021-05-05 01:48:16 +00:00
if err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to GetUserSessions in changePassword: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
2020-12-10 15:43:37 +00:00
}
2021-12-16 14:53:58 +00:00
if err = storage . MainStore . UpdateAuthUser ( user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to DefinePassword in changePassword: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
log . Printf ( "%s changes password for user %s" , c . ClientIP ( ) , user . Email )
2020-12-10 15:43:37 +00:00
for _ , session := range sessions {
2021-05-05 01:48:16 +00:00
err = storage . MainStore . DeleteSession ( session )
if err != nil {
2021-07-30 09:49:11 +00:00
log . Println ( "%s: unable to delete session (password changed): %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
}
2020-12-10 15:43:37 +00:00
}
2021-05-05 01:48:16 +00:00
logout ( opts , c )
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
func deleteUser ( opts * config . Options , c * gin . Context ) {
2021-12-16 14:53:58 +00:00
user := c . MustGet ( "authuser" ) . ( * happydns . UserAuth )
2021-05-05 01:48:16 +00:00
2020-07-21 02:02:18 +00:00
var lf passwordForm
2021-05-05 01:48:16 +00:00
if err := c . ShouldBindJSON ( & lf ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s sends invalid passwordForm JSON: %s" , c . ClientIP ( ) , err . Error ( ) )
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : fmt . Sprintf ( "Something is wrong in received data: %s" , err . Error ( ) ) } )
2021-05-05 01:48:16 +00:00
return
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
if ! user . CheckAuth ( lf . Current ) {
c . AbortWithStatusJSON ( http . StatusForbidden , gin . H { "errmsg" : "The given current password is invalid." } )
return
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
// Retrieve all user's sessions to disconnect them
2021-12-16 14:53:58 +00:00
sessions , err := storage . MainStore . GetAuthUserSessions ( user )
2021-05-05 01:48:16 +00:00
if err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to GetUserSessions in deleteUser: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
2020-12-10 15:43:37 +00:00
}
2021-12-16 14:53:58 +00:00
if err = storage . MainStore . DeleteAuthUser ( user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to DefinePassword in deleteuser: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
log . Printf ( "%s: deletes user: %s" , c . ClientIP ( ) , user . Email )
2020-12-10 15:43:37 +00:00
for _ , session := range sessions {
2021-05-05 01:48:16 +00:00
err = storage . MainStore . DeleteSession ( session )
if err != nil {
2021-07-30 09:49:11 +00:00
log . Println ( "%s: unable to delete session (drop account): %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
}
2020-12-10 15:43:37 +00:00
}
2021-05-05 01:48:16 +00:00
logout ( opts , c )
2020-07-21 02:02:18 +00:00
}
2021-05-05 01:48:16 +00:00
func UserHandlerBase ( c * gin . Context ) ( * happydns . User , error ) {
2022-10-25 16:16:34 +00:00
uid , err := base64 . RawURLEncoding . DecodeString ( c . Param ( "uid" ) )
2021-05-05 01:48:16 +00:00
if err != nil {
return nil , fmt . Errorf ( "Invalid user identifier given: %w" , err )
2020-05-23 16:47:09 +00:00
}
2021-05-05 01:48:16 +00:00
user , err := storage . MainStore . GetUser ( uid )
if err != nil {
return nil , fmt . Errorf ( "User not found" )
}
return user , nil
}
func userHandler ( c * gin . Context ) {
user , err := UserHandlerBase ( c )
if err != nil {
c . AbortWithStatusJSON ( http . StatusNotFound , gin . H { "errmsg" : err . Error ( ) } )
return
}
c . Set ( "user" , user )
c . Next ( )
2020-05-23 16:47:09 +00:00
}
2021-12-16 14:53:58 +00:00
func UserAuthHandlerBase ( c * gin . Context ) ( * happydns . UserAuth , error ) {
2022-10-25 16:16:34 +00:00
uid , err := base64 . RawURLEncoding . DecodeString ( c . Param ( "uid" ) )
2021-12-16 14:53:58 +00:00
if err != nil {
return nil , fmt . Errorf ( "Invalid user identifier given: %w" , err )
}
user , err := storage . MainStore . GetAuthUser ( uid )
if err != nil {
return nil , fmt . Errorf ( "User not found" )
}
return user , nil
}
func userAuthHandler ( c * gin . Context ) {
user , err := UserAuthHandlerBase ( c )
if err != nil {
c . AbortWithStatusJSON ( http . StatusNotFound , gin . H { "errmsg" : err . Error ( ) } )
return
}
c . Set ( "authuser" , user )
c . Next ( )
}
2020-05-23 16:47:09 +00:00
type UploadedAddressValidation struct {
Key string
}
2021-05-05 01:48:16 +00:00
func validateUserAddress ( c * gin . Context ) {
2021-12-16 14:53:58 +00:00
user := c . MustGet ( "authuser" ) . ( * happydns . UserAuth )
2021-05-05 01:48:16 +00:00
2020-05-23 16:47:09 +00:00
var uav UploadedAddressValidation
2021-05-05 01:48:16 +00:00
err := c . ShouldBindJSON ( & uav )
2020-05-23 16:47:09 +00:00
if err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s sends invalid AddressValidation JSON: %s" , c . ClientIP ( ) , err . Error ( ) )
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : fmt . Sprintf ( "Something is wrong in received data: %s" , err . Error ( ) ) } )
2021-05-05 01:48:16 +00:00
return
2020-05-23 16:47:09 +00:00
}
if err := user . ValidateEmail ( uav . Key ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s bad email validation key: %s" , c . ClientIP ( ) , err . Error ( ) )
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : fmt . Sprintf ( "Bad validation key: %s" , err . Error ( ) ) } )
2021-05-05 01:48:16 +00:00
return
2020-05-23 16:47:09 +00:00
}
2021-05-05 01:48:16 +00:00
2021-12-16 14:53:58 +00:00
if err := storage . MainStore . UpdateAuthUser ( user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to UpdateUser in ValidateUserAddress: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
}
c . JSON ( http . StatusOK , true )
2020-05-23 16:47:09 +00:00
}
2020-05-23 21:16:41 +00:00
type UploadedAccountRecovery struct {
Key string
Password string
}
2021-05-05 01:48:16 +00:00
func recoverUserAccount ( c * gin . Context ) {
2021-12-16 14:53:58 +00:00
user := c . MustGet ( "authuser" ) . ( * happydns . UserAuth )
2021-05-05 01:48:16 +00:00
2020-05-23 21:16:41 +00:00
var uar UploadedAccountRecovery
2021-05-05 01:48:16 +00:00
err := c . ShouldBindJSON ( & uar )
2020-05-23 21:16:41 +00:00
if err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s sends invalid AccountRecovey JSON: %s" , c . ClientIP ( ) , err . Error ( ) )
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : fmt . Sprintf ( "Something is wrong in received data: %s" , err . Error ( ) ) } )
2021-05-05 01:48:16 +00:00
return
2020-05-23 21:16:41 +00:00
}
if err := user . CanRecoverAccount ( uar . Key ) ; err != nil {
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusForbidden , gin . H { "errmsg" : err . Error ( ) } )
return
2020-05-23 21:16:41 +00:00
}
2020-07-17 22:23:58 +00:00
2021-05-05 01:48:16 +00:00
if len ( uar . Password ) == 0 {
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : "Password can't be empty!" } )
return
2020-07-17 22:23:58 +00:00
}
2021-05-05 01:48:16 +00:00
if err := user . DefinePassword ( uar . Password ) ; err != nil {
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : err . Error ( ) } )
return
2020-07-17 22:23:58 +00:00
}
2021-05-05 01:48:16 +00:00
2021-12-16 14:53:58 +00:00
if err := storage . MainStore . UpdateAuthUser ( user ) ; err != nil {
2021-07-30 09:49:11 +00:00
log . Printf ( "%s: unable to UpdateUser in recoverUserAccount: %s" , c . ClientIP ( ) , err . Error ( ) )
2021-05-05 01:48:16 +00:00
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Sorry, we are currently unable to update your profile. Please try again later." } )
return
}
log . Printf ( "%s: User recovered: %s" , c . ClientIP ( ) , user . Email )
c . JSON ( http . StatusOK , true )
}
func getSession ( c * gin . Context ) {
session := c . MustGet ( "MySession" ) . ( * happydns . Session )
c . JSON ( http . StatusOK , session )
}
func clearSession ( c * gin . Context ) {
session := c . MustGet ( "MySession" ) . ( * happydns . Session )
session . ClearSession ( )
c . JSON ( http . StatusOK , true )
2020-07-17 22:23:58 +00:00
}