add login logic
This commit is contained in:
1 parent
e459e61fba
commit
81f2943967
6 files changed
+148
-5
No files matched your search
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
PORT=8080
|
PORT=8080
|
||||||
mongoURI=mongodb://localhost:27017
|
mongoURI=mongodb://localhost:27017
|
||||||
dbo=school
|
dbo=bugbegone
|
||||||
|
secret=secretkey
|
||||||
@@ -2,21 +2,29 @@ package controllers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/SowinskiBraeden/BugBeGone/database"
|
"github.com/SowinskiBraeden/BugBeGone/database"
|
||||||
"github.com/SowinskiBraeden/BugBeGone/models"
|
"github.com/SowinskiBraeden/BugBeGone/models"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
|
||||||
|
"github.com/dgrijalva/jwt-go"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
)
|
)
|
||||||
|
|
||||||
var userCollection *mongo.Collection = database.OpenCollection(database.Client, "users")
|
var userCollection *mongo.Collection = database.OpenCollection(database.Client, "users")
|
||||||
|
var SecretKey string
|
||||||
|
|
||||||
func toBase64(b []byte) string {
|
func Init() {
|
||||||
return base64.StdEncoding.EncodeToString(b)
|
godotenv.Load(".env")
|
||||||
|
SecretKey = os.Getenv("secret")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Register(c *fiber.Ctx) error {
|
func Register(c *fiber.Ctx) error {
|
||||||
@@ -76,12 +84,15 @@ func Register(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.UID = uuid.New().String()
|
||||||
user.Username = username
|
user.Username = username
|
||||||
user.Firstname = firstname
|
user.Firstname = firstname
|
||||||
user.Lastname = lastname
|
user.Lastname = lastname
|
||||||
user.Email = email
|
user.Email = email
|
||||||
user.Password = user.HashPassword(password)
|
user.Password = user.HashPassword(password)
|
||||||
user.TempPassword = false
|
user.TempPassword = false
|
||||||
|
user.Attempts = 0
|
||||||
|
user.Disabled = false
|
||||||
user.ID = primitive.NewObjectID()
|
user.ID = primitive.NewObjectID()
|
||||||
user.Created_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
|
user.Created_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
|
||||||
user.Updated_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
|
user.Updated_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
|
||||||
@@ -103,5 +114,126 @@ func Register(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Login(c *fiber.Ctx) error {
|
func Login(c *fiber.Ctx) error {
|
||||||
return c.Status(fiber.StatusNotImplemented).JSON(fiber.Map{})
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||||
|
username := c.FormValue("username")
|
||||||
|
password := c.FormValue("password")
|
||||||
|
|
||||||
|
if username == "" && password == "" {
|
||||||
|
cancel()
|
||||||
|
return c.Status(fiber.StatusBadRequest).Render("login", fiber.Map{
|
||||||
|
"msg": "",
|
||||||
|
"errorMsg": "Username and password can't be blank",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if username == "" {
|
||||||
|
cancel()
|
||||||
|
return c.Status(fiber.StatusBadRequest).Render("login", fiber.Map{
|
||||||
|
"msg": "",
|
||||||
|
"errorMsg": "Username can't be blank",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if password == "" {
|
||||||
|
cancel()
|
||||||
|
return c.Status(fiber.StatusBadRequest).Render("login", fiber.Map{
|
||||||
|
"msg": "",
|
||||||
|
"errorMsg": "Password can't be blank",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var user models.User
|
||||||
|
err := userCollection.FindOne(ctx, bson.M{"username": username}).Decode(&user)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
cancel()
|
||||||
|
return c.Status(fiber.StatusInternalServerError).Render("login", fiber.Map{
|
||||||
|
"msg": "",
|
||||||
|
"errorMsg": "user not found",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var localAccountDisabled = false
|
||||||
|
if user.Attempts >= 5 {
|
||||||
|
localAccountDisabled = true // Catches newly disbaled account before student obj is updated
|
||||||
|
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
|
||||||
|
update := bson.M{
|
||||||
|
"$set": bson.M{
|
||||||
|
"disabled": true,
|
||||||
|
"attempts": 0,
|
||||||
|
"updated_at": update_time,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, updateErr := userCollection.UpdateOne(
|
||||||
|
ctx,
|
||||||
|
bson.M{"username": username},
|
||||||
|
update,
|
||||||
|
)
|
||||||
|
if updateErr != nil {
|
||||||
|
cancel()
|
||||||
|
return c.Status(fiber.StatusInternalServerError).Render("login", fiber.Map{
|
||||||
|
"msg": "",
|
||||||
|
"errorMsg": "the user could not be updated",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if localAccountDisabled || user.Disabled {
|
||||||
|
cancel()
|
||||||
|
return c.Status(fiber.StatusForbidden).Render("login", fiber.Map{
|
||||||
|
"msg": "Account is Disabled, contact support",
|
||||||
|
"errorMsg": "Account is Disabled, contact support",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var verified bool = user.ComparePasswords(password)
|
||||||
|
if verified == false {
|
||||||
|
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
|
||||||
|
update := bson.M{
|
||||||
|
"$set": bson.M{
|
||||||
|
"Attempts": user.Attempts + 1,
|
||||||
|
"updated_at": update_time,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, updateErr := userCollection.UpdateOne(
|
||||||
|
ctx,
|
||||||
|
bson.M{"username": username},
|
||||||
|
update,
|
||||||
|
)
|
||||||
|
cancel()
|
||||||
|
if updateErr != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).Render("login", fiber.Map{
|
||||||
|
"msg": "",
|
||||||
|
"errorMsg": "the student could not be updated",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return c.Status(fiber.StatusBadRequest).Render("login", fiber.Map{
|
||||||
|
"msg": "",
|
||||||
|
"errorMsg": "incorrect password",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
claims := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.StandardClaims{
|
||||||
|
Issuer: user.UID,
|
||||||
|
ExpiresAt: time.Now().Add(time.Hour * 24).Unix(), // 1 Day
|
||||||
|
})
|
||||||
|
token, err := claims.SignedString([]byte(SecretKey))
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).Render("login", fiber.Map{
|
||||||
|
"msg": "",
|
||||||
|
"errorMsg": "could not log in",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie := fiber.Cookie{
|
||||||
|
Name: "jwt",
|
||||||
|
Value: token,
|
||||||
|
Expires: time.Now().Add(time.Hour * 24),
|
||||||
|
HTTPOnly: true,
|
||||||
|
}
|
||||||
|
c.Cookie(&cookie)
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusNotImplemented).Render("dasboard", fiber.Map{})
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,10 @@ module github.com/SowinskiBraeden/BugBeGone
|
|||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/gofiber/fiber/v2 v2.31.0
|
github.com/gofiber/fiber/v2 v2.31.0
|
||||||
github.com/gofiber/template v1.6.26
|
github.com/gofiber/template v1.6.26
|
||||||
|
github.com/google/uuid v1.1.2
|
||||||
github.com/joho/godotenv v1.4.0
|
github.com/joho/godotenv v1.4.0
|
||||||
go.mongodb.org/mongo-driver v1.8.4
|
go.mongodb.org/mongo-driver v1.8.4
|
||||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292
|
golang.org/x/crypto v0.0.0-20220214200702-86341886e292
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/SowinskiBraeden/BugBeGone/controllers"
|
||||||
"github.com/SowinskiBraeden/BugBeGone/routes"
|
"github.com/SowinskiBraeden/BugBeGone/routes"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||||
@@ -21,6 +22,8 @@ func main() {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
controllers.Init()
|
||||||
|
|
||||||
app := fiber.New(fiber.Config{
|
app := fiber.New(fiber.Config{
|
||||||
Views: engine,
|
Views: engine,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ var (
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID primitive.ObjectID `bson:"_id"`
|
ID primitive.ObjectID `bson:"_id"`
|
||||||
|
UID string `json:"uid"`
|
||||||
Firstname string `json:"firstname"`
|
Firstname string `json:"firstname"`
|
||||||
Lastname string `json:"lastname"`
|
Lastname string `json:"lastname"`
|
||||||
Username string `json:"username" validate:"required"`
|
Username string `json:"username" validate:"required"`
|
||||||
@@ -26,6 +27,8 @@ type User struct {
|
|||||||
Password string `json:"-" validate:"min=10,max=32"`
|
Password string `json:"-" validate:"min=10,max=32"`
|
||||||
TempPassword bool `json:"temppassword"`
|
TempPassword bool `json:"temppassword"`
|
||||||
Subscription string `json:"subscription"` // standard, professional, business
|
Subscription string `json:"subscription"` // standard, professional, business
|
||||||
|
Attempts int `json:"attempts"`
|
||||||
|
Disabled bool `json:""`
|
||||||
Created_at time.Time `json:"created_at"`
|
Created_at time.Time `json:"created_at"`
|
||||||
Updated_at time.Time `json:"updated_at"`
|
Updated_at time.Time `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user