add golang backend for login an d webserver
This commit is contained in:
202
backend/login/login.go
Normal file
202
backend/login/login.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package login
|
||||
|
||||
import (
|
||||
"backend/dbRequest"
|
||||
"backend/login/models"
|
||||
"backend/utils"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func (lm *LoginManager) AddUser(c *gin.Context) {
|
||||
body, err := io.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
user := models.User{}
|
||||
err = json.Unmarshal(body, &user)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !user.IsValid() {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "user empty",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
db, err := sql.Open(lm.dbType, lm.dbFile)
|
||||
if dbRequest.CheckDBError(c, user.Name, err) {
|
||||
return
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
var exists bool
|
||||
|
||||
if err := db.QueryRow(dbRequest.DBUserLookup, user.Name).Scan(&exists); dbRequest.CheckDBError(c, user.Name, err) {
|
||||
return
|
||||
}
|
||||
|
||||
if exists {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"error": fmt.Sprintf("user '%s' exists already", user.Name),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
hash, err := utils.HashPassword(user.Password)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
if _, err := db.Exec(dbRequest.DBNewUser, user.Name, hash); dbRequest.CheckDBError(c, user.Name, err) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": fmt.Sprintf("user '%s' successfully added", user.Name),
|
||||
})
|
||||
}
|
||||
|
||||
func (lm *LoginManager) RemoveUser(c *gin.Context) {
|
||||
body, err := io.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
user := models.User{}
|
||||
err = json.Unmarshal(body, &user)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !user.IsValid() {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "user empty",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
db, err := sql.Open(lm.dbType, lm.dbFile)
|
||||
if dbRequest.CheckDBError(c, user.Name, err) {
|
||||
return
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
var storedPassword string
|
||||
if err := db.QueryRow(dbRequest.DBQueryPassword, user.Name).Scan(&storedPassword); dbRequest.CheckDBError(c, user.Name, err) {
|
||||
return
|
||||
}
|
||||
|
||||
if !utils.CheckPassword(user.Password, storedPassword) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "wrong password",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := db.Exec(dbRequest.DBRemoveUser, user.Name); dbRequest.CheckDBError(c, user.Name, err) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": fmt.Sprintf("user '%s' successfully removed", user.Name),
|
||||
})
|
||||
}
|
||||
|
||||
func (lm *LoginManager) Login(c *gin.Context) {
|
||||
body, err := io.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
user := models.User{}
|
||||
err = json.Unmarshal(body, &user)
|
||||
if err != nil {
|
||||
fmt.Println(2)
|
||||
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !user.IsValid() {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "user empty",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
db, err := sql.Open(lm.dbType, lm.dbFile)
|
||||
if dbRequest.CheckDBError(c, user.Name, err) {
|
||||
return
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
var storedPassword string
|
||||
if err := db.QueryRow(dbRequest.DBQueryPassword, user.Name).Scan(&storedPassword); dbRequest.CheckDBError(c, user.Name, err) {
|
||||
return
|
||||
}
|
||||
|
||||
if !utils.CheckPassword(user.Password, storedPassword) {
|
||||
fmt.Println(2, user.Password)
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "wrong password",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Create token
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"username": user.Name,
|
||||
"exp": time.Now().Add(time.Hour * 72).Unix(), // expires in 72h
|
||||
})
|
||||
|
||||
secret, err := utils.GenerateJWTSecret(32) // 32 bytes = 256 bits
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "error generate jwt token"})
|
||||
return
|
||||
}
|
||||
|
||||
// Sign and get the complete encoded token as a string
|
||||
tokenString, err := token.SignedString(secret)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Could not generate token"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.User{
|
||||
Name: user.Name,
|
||||
Token: tokenString,
|
||||
})
|
||||
}
|
49
backend/login/manager.go
Normal file
49
backend/login/manager.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package login
|
||||
|
||||
import (
|
||||
"backend/dbRequest"
|
||||
"backend/utils"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type LoginManager struct {
|
||||
dbType string
|
||||
dbFile string
|
||||
}
|
||||
|
||||
func NewLoginManager(dir string) (*LoginManager, error) {
|
||||
if dir == "" {
|
||||
dir = "."
|
||||
}
|
||||
|
||||
var typ string = "sqlite"
|
||||
var file string = fmt.Sprintf("%s/user.db", dir)
|
||||
|
||||
if _, err := os.Stat(file); err != nil {
|
||||
db, err := sql.Open(typ, file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec(dbRequest.DBCreate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hash, err := utils.HashPassword("tecamino@2025")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = db.Exec(dbRequest.DBNewUser, "admin", hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &LoginManager{
|
||||
dbType: typ,
|
||||
dbFile: file,
|
||||
}, nil
|
||||
}
|
11
backend/login/models/user.go
Normal file
11
backend/login/models/user.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package models
|
||||
|
||||
type User struct {
|
||||
Name string `json:"user"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Token string `json:"token,omitempty"`
|
||||
}
|
||||
|
||||
func (u *User) IsValid() bool {
|
||||
return u.Name != ""
|
||||
}
|
Reference in New Issue
Block a user