user management pt1

This commit is contained in:
Yann Stepienik 2023-02-12 23:21:07 +00:00
parent 34445af9aa
commit 987fd909a9
8 changed files with 254 additions and 30 deletions

View file

@ -2,13 +2,15 @@
"author": "Yann Stepienik",
"cli": {
"aliases": {
"start": "build/bin",
"certificate": "sh generate-certificate.sh"
"certificate": "sh generate-certificate.sh",
"start": "build/bin"
}
},
"dependencies": {
"default": {
"go://github.com/go-playground/validator/v10": "master",
"go://github.com/golang-jwt/jwt": "master",
"go://github.com/golang/crypto/": "master",
"go://github.com/gorilla/mux": "master",
"go://github.com/imdario/mergo": "master",
"go://github.com/joho/godotenv": "master",

64
src/user/create.go Normal file
View file

@ -0,0 +1,64 @@
package user
import (
"net/http"
"log"
// "io"
// "os"
"encoding/json"
"go.mongodb.org/mongo-driver/mongo"
"time"
// "golang.org/x/crypto/bcrypt"
"../utils"
)
func UserCreate(w http.ResponseWriter, req *http.Request) {
utils.SetHeaders(w)
if(req.Method == "POST") {
nickname := req.FormValue("nickname")
c := utils.GetCollection(utils.GetRootAppId(), "users")
user := utils.User{}
err := c.FindOne(nil, map[string]interface{}{
"Nickname": nickname,
}).Decode(&user)
if err != mongo.ErrNoDocuments {
log.Println("UserCreation: User already exists")
http.Error(w, "User Creation Error", http.StatusNotFound)
} else if err != nil {
log.Println("UserCreation: Error while finding user")
http.Error(w, "User Creation Error", http.StatusInternalServerError)
} else {
RegisterKey := utils.GenerateRandomString(24)
RegisterKeyExp := time.Now().Add(time.Hour * 24 * 7)
_, err := c.InsertOne(nil, map[string]interface{}{
"Nickname": nickname,
"Password": "",
"RegisterKey": RegisterKey,
"RegisterKeyExp": RegisterKeyExp,
"Role": utils.USER,
})
if err != nil {
log.Println("UserCreation: Error while creating user")
http.Error(w, "User Creation Error", http.StatusInternalServerError)
}
json.NewEncoder(w).Encode(map[string]interface{}{
"Status": "OK",
"RegisterKey": RegisterKey,
"RegisterKeyExp": RegisterKeyExp,
})
}
} else {
log.Println("UserCreation: Method not allowed" + req.Method)
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}

View file

@ -3,7 +3,12 @@ package user
import (
"net/http"
"log"
"math/rand"
"encoding/json"
"go.mongodb.org/mongo-driver/mongo"
"time"
"golang.org/x/crypto/bcrypt"
"github.com/golang-jwt/jwt"
"../utils"
)
@ -12,11 +17,55 @@ func UserLogin(w http.ResponseWriter, req *http.Request) {
utils.SetHeaders(w)
if(req.Method == "POST") {
time.Sleep(time.Duration(rand.Float64()*2)*time.Second)
nickname := req.FormValue("nickname")
password := req.FormValue("password")
log.Println("UserLogin: nickname: " + nickname)
log.Println("UserLogin: password: " + password) // im just testing ok dont panic
err := bcrypt.CompareHashAndPassword([]byte(utils.GetHash()), []byte(password))
if err != nil {
log.Println("UserLogin: Encryption error")
http.Error(w, "User Logging Error", http.StatusUnauthorized)
}
c := utils.GetCollection(utils.GetRootAppId(), "users")
err = c.FindOne(nil, map[string]interface{}{
"Nickname": nickname,
"Password": password,
}).Decode(&utils.User{})
if err == mongo.ErrNoDocuments {
log.Println("UserLogin: User not found")
http.Error(w, "User Logging Error", http.StatusNotFound)
} else if err != nil {
log.Println("UserLogin: Error while finding user")
http.Error(w, "User Logging Error", http.StatusInternalServerError)
} else {
token := jwt.New(jwt.SigningMethodEdDSA)
claims := token.Claims.(jwt.MapClaims)
claims["exp"] = time.Now().Add(30 * 24 * time.Hour)
claims["authorized"] = true
claims["nickname"] = nickname
tokenString, err := token.SignedString(utils.GetPrivateAuthKey())
if err != nil {
log.Println("UserLogin: Error while signing token")
http.Error(w, "User Logging Error", http.StatusInternalServerError)
}
expiration := time.Now().Add(30 * 24 * time.Hour)
cookie := http.Cookie{
Name: "jwttoken",
Value: tokenString,
Expires: expiration,
}
http.SetCookie(w, &cookie)
}
json.NewEncoder(w).Encode(map[string]interface{}{
"Status": "OK",
@ -25,4 +74,4 @@ func UserLogin(w http.ResponseWriter, req *http.Request) {
log.Println("UserLogin: Method not allowed" + req.Method)
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
}

View file

@ -3,9 +3,11 @@ package user
import (
"net/http"
"log"
// "io"
// "os"
"math/rand"
"encoding/json"
"go.mongodb.org/mongo-driver/mongo"
"time"
"golang.org/x/crypto/bcrypt"
"../utils"
)
@ -13,31 +15,61 @@ import (
func UserRegister(w http.ResponseWriter, req *http.Request) {
utils.SetHeaders(w)
if(req.Method == "GET") {
// sedn form
}
if(req.Method == "POST") {
// check origin
time.Sleep(time.Duration(rand.Float64()*2)*time.Second)
// check password strength
nickname := req.FormValue("nickname")
registerKey := req.FormValue("registerKey")
password := req.FormValue("password")
user := &utils.User{
Nickname: req.FormValue("nickname"),
Password: req.FormValue("password"),
Role: (utils.Role)(req.FormValue("role")),
err := bcrypt.CompareHashAndPassword([]byte(utils.GetHash()), []byte(password))
if err != nil {
log.Println("UserRegister: Encryption error")
http.Error(w, "User Register Error", http.StatusUnauthorized)
}
err := utils.Validate.Struct(user)
c := utils.GetCollection(utils.GetRootAppId(), "users")
if(err != nil) {
log.Fatal(err)
user := utils.User{}
err = c.FindOne(nil, map[string]interface{}{
"Nickname": nickname,
"RegisterKey": registerKey,
"Password": "",
}).Decode(&user)
if err == mongo.ErrNoDocuments {
log.Println("UserRegister: User not found")
http.Error(w, "User Register Error", http.StatusNotFound)
} else if !user.RegisterKeyExp.Before(time.Now()) {
log.Println("UserRegister: Link expired")
http.Error(w, "User Register Error", http.StatusNotFound)
} else if err != nil {
log.Println("UserRegister: Error while finding user")
http.Error(w, "User Register Error", http.StatusInternalServerError)
} else {
_, err := c.UpdateOne(nil, map[string]interface{}{
"Nickname": nickname,
"RegisterKey": registerKey,
"Password": "",
}, map[string]interface{}{
"Password": password,
"RegisterKey": "",
"RegisterKeyExp": time.Time{},
})
if err != nil {
log.Println("UserRegister: Error while updating user")
http.Error(w, "User Register Error", http.StatusInternalServerError)
}
}
req.ParseForm()
json.NewEncoder(w).Encode(map[string]interface{}{
"Status": "OK",
})
} else {
log.Println("UserRegister: Method not allowed" + req.Method)
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
// return json object
json.NewEncoder(w).Encode(map[string]interface{}{
"Status": "OK",
})
}

59
src/user/resend.go Normal file
View file

@ -0,0 +1,59 @@
package user
import (
"net/http"
"log"
"encoding/json"
"go.mongodb.org/mongo-driver/mongo"
"time"
"../utils"
)
func UserResendInviteLink(w http.ResponseWriter, req *http.Request) {
utils.SetHeaders(w)
if(req.Method == "POST") {
id := req.FormValue("id")
c := utils.GetCollection(utils.GetRootAppId(), "users")
user := utils.User{}
err := c.FindOne(nil, map[string]interface{}{
"_id": id,
}).Decode(&user)
if err == mongo.ErrNoDocuments {
log.Println("UserResend: User not found")
http.Error(w, "User Resend Invite Error", http.StatusNotFound)
} else if err != nil {
log.Println("UserResend: Error while finding user")
http.Error(w, "User Resend Invite Error", http.StatusInternalServerError)
} else {
RegisterKeyExp := time.Now().Add(time.Hour * 24 * 7)
_, err := c.UpdateOne(nil, map[string]interface{}{
"_id": id,
}, map[string]interface{}{
"$set": map[string]interface{}{
"RegisterKeyExp": RegisterKeyExp,
},
})
if err != nil {
log.Println("UserResend: Error while updating user")
http.Error(w, "User Resend Invite Error", http.StatusInternalServerError)
}
json.NewEncoder(w).Encode(map[string]interface{}{
"Status": "OK",
"RegisterKey": user.RegisterKey,
"RegisterKeyExp": RegisterKeyExp,
})
}
} else {
log.Println("UserResend: Method not allowed" + req.Method)
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}

View file

@ -21,9 +21,9 @@ var defaultConfig = GucoConfiguration{
}
func GetConfigs() GucoConfiguration {
c := GetCollection("GUCO", "Configurations")
c := GetCollection(GetRootAppId(), "Configurations")
config := GucoConfiguration{}
err := c.FindOne(context.TODO(), bson.M{"_id": "GUCO"}).Decode(&config)
err := c.FindOne(context.TODO(), bson.M{"_id": GetRootAppId()}).Decode(&config)
if err == mongo.ErrNoDocuments {
log.Println("Record does not exist")
} else if err != nil {
@ -40,10 +40,10 @@ func SetConfig(config GucoConfiguration) {
mergo.Merge(&config, currentConfig)
c := GetCollection("GUCO", "Configurations")
c := GetCollection(GetRootAppId(), "Configurations")
opts := options.Update().SetUpsert(true)
filter := bson.D{{"_id", "GUCO"}}
filter := bson.D{{"_id", GetRootAppId()}}
update := bson.D{{"$set", config}}
_, err := c.UpdateOne(context.Background(), filter, update, opts)

View file

@ -25,5 +25,7 @@ type FileStats struct {
type User struct {
Nickname string `validate:"required"`
Password string `validate:"required"`
RegisterKey string
RegisterKeyExp time.Time
Role Role `validate:"required"`
}

View file

@ -35,4 +35,20 @@ func FileExists(path string) bool {
}
log.Println(err)
return false
}
func GetHash() string {
return "hash"
}
func GetRootAppId() string {
return "GUCO"
}
func GetPrivateAuthKey() string {
return "private"
}
func GenerateRandomString(len int) string {
return "random"
}