add user service
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
.idea
|
.idea
|
||||||
build
|
build
|
||||||
|
.env
|
||||||
41
config/config.go
Normal file
41
config/config.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MSHostsConfig struct {
|
||||||
|
UsersHost string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServerConfig struct {
|
||||||
|
Port string
|
||||||
|
JWTSecret string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
MSHosts MSHostsConfig
|
||||||
|
Server ServerConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *Config {
|
||||||
|
return &Config{
|
||||||
|
MSHosts: MSHostsConfig{
|
||||||
|
UsersHost: getEnv("USERS_HOST", ""),
|
||||||
|
},
|
||||||
|
Server: ServerConfig{
|
||||||
|
Port: getEnv("PORT", ""),
|
||||||
|
JWTSecret: getEnv("JWT_SECRET", "secret"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEnv(key string, defaultVal string) string {
|
||||||
|
if value, exists := os.LookupEnv(key); exists {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
var Env = New()
|
||||||
1
go.mod
1
go.mod
@@ -7,6 +7,7 @@ require (
|
|||||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
github.com/labstack/echo-jwt/v4 v4.2.0 // indirect
|
github.com/labstack/echo-jwt/v4 v4.2.0 // indirect
|
||||||
github.com/labstack/echo/v4 v4.10.2 // indirect
|
github.com/labstack/echo/v4 v4.10.2 // indirect
|
||||||
github.com/labstack/gommon v0.4.0 // indirect
|
github.com/labstack/gommon v0.4.0 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -8,6 +8,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
|
|||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/labstack/echo-jwt/v4 v4.2.0 h1:odSISV9JgcSCuhgQSV/6Io3i7nUmfM/QkBeR5GVJj5c=
|
github.com/labstack/echo-jwt/v4 v4.2.0 h1:odSISV9JgcSCuhgQSV/6Io3i7nUmfM/QkBeR5GVJj5c=
|
||||||
github.com/labstack/echo-jwt/v4 v4.2.0/go.mod h1:MA2RqdXdEn4/uEglx0HcUOgQSyBaTh5JcaHIan3biwU=
|
github.com/labstack/echo-jwt/v4 v4.2.0/go.mod h1:MA2RqdXdEn4/uEglx0HcUOgQSyBaTh5JcaHIan3biwU=
|
||||||
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
|
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import "gorm.io/gorm"
|
|
||||||
|
|
||||||
type Handler struct {
|
|
||||||
DB *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
Key = "secret"
|
|
||||||
)
|
|
||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handler) Health(c echo.Context) error {
|
func Health(c echo.Context) error {
|
||||||
type Resp struct {
|
type Resp struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|||||||
29
main.go
29
main.go
@@ -1,38 +1,37 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"astra-api-gateway/config"
|
||||||
"astra-api-gateway/handler"
|
"astra-api-gateway/handler"
|
||||||
"astra-api-gateway/model"
|
|
||||||
"astra-api-gateway/mw"
|
"astra-api-gateway/mw"
|
||||||
|
"astra-api-gateway/services/users"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
"gorm.io/driver/sqlite"
|
"log"
|
||||||
"gorm.io/gorm"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func init() {
|
||||||
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
if err := godotenv.Load(); err != nil {
|
||||||
if err != nil {
|
log.Print("No .env file found")
|
||||||
panic("failed to connect database")
|
|
||||||
}
|
}
|
||||||
e := echo.New()
|
}
|
||||||
|
|
||||||
db.AutoMigrate(&model.User{})
|
func main() {
|
||||||
|
e := echo.New()
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
e.Use(middleware.Logger())
|
e.Use(middleware.Logger())
|
||||||
e.Use(mw.TokenFromCookies)
|
e.Use(mw.TokenFromCookies)
|
||||||
e.Use(mw.JWTMW)
|
e.Use(mw.JWT_MW)
|
||||||
|
|
||||||
var h = &handler.Handler{DB: db}
|
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
e.GET("/*", checkAuth)
|
e.GET("/*", checkAuth)
|
||||||
e.GET("/auth/login", h.Login)
|
e.POST("/auth/login", users.Login)
|
||||||
e.GET("/health", h.Health)
|
e.GET("/health", handler.Health)
|
||||||
|
|
||||||
e.Logger.Fatal(e.Start(":8080"))
|
e.Logger.Fatal(e.Start(":" + config.Env.Server.Port))
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkAuth(c echo.Context) error {
|
func checkAuth(c echo.Context) error {
|
||||||
|
|||||||
@@ -7,5 +7,7 @@ type (
|
|||||||
gorm.Model
|
gorm.Model
|
||||||
UserName string `json:"userName" gorm:"unique"`
|
UserName string `json:"userName" gorm:"unique"`
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
|
FirstName string `json:"firstName"`
|
||||||
|
LastName string `json:"lastName"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
package mw
|
package mw
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"astra-api-gateway/handler"
|
"astra-api-gateway/config"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"github.com/labstack/echo-jwt/v4"
|
"github.com/labstack/echo-jwt/v4"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var JWTMW = echojwt.WithConfig(echojwt.Config{
|
var JWT_MW = echojwt.WithConfig(echojwt.Config{
|
||||||
SigningKey: []byte(handler.Key),
|
SigningKey: []byte(config.Env.Server.JWTSecret),
|
||||||
Skipper: func(c echo.Context) bool {
|
Skipper: func(c echo.Context) bool {
|
||||||
// Skip authentication for signup and login requests
|
// Skip authentication for signup and login requests
|
||||||
if strings.Contains(c.Path(), "auth") || c.Path() == "/health" {
|
if strings.Contains(c.Path(), "auth") || c.Path() == "/health" {
|
||||||
|
|||||||
31
pkg/api/apiCall.go
Normal file
31
pkg/api/apiCall.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PostRequest(url string, model any) ([]byte, error) {
|
||||||
|
uJson, err := json.Marshal(model)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Post(url,
|
||||||
|
"application/json", bytes.NewReader(uJson))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package handler
|
package users
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"astra-api-gateway/config"
|
||||||
"astra-api-gateway/model"
|
"astra-api-gateway/model"
|
||||||
"crypto/sha256"
|
"astra-api-gateway/pkg/api"
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -11,18 +12,24 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handler) Login(c echo.Context) (err error) {
|
func Login(c echo.Context) (err error) {
|
||||||
// Bind
|
// Bind
|
||||||
u := new(model.User)
|
u := new(model.User)
|
||||||
if err = c.Bind(u); err != nil {
|
if err = c.Bind(u); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
u.Password = fmt.Sprintf("%x", sha256.Sum256([]byte(u.Password)))
|
data, err := api.PostRequest(config.Env.MSHosts.UsersHost+"/login", u)
|
||||||
|
|
||||||
var t = h.DB.Where("user_name = ? AND password = ?", u.UserName, u.Password).First(&u)
|
u.Password = ""
|
||||||
|
|
||||||
if t.RowsAffected == 0 {
|
if err != nil {
|
||||||
|
return c.NoContent(http.StatusBadGateway)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, &u)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
return c.NoContent(http.StatusUnauthorized)
|
return c.NoContent(http.StatusUnauthorized)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +39,7 @@ func (h *Handler) Login(c echo.Context) (err error) {
|
|||||||
claims["id"] = strconv.Itoa(int(u.ID))
|
claims["id"] = strconv.Itoa(int(u.ID))
|
||||||
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
|
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
|
||||||
|
|
||||||
var _token, _ = token.SignedString([]byte(Key))
|
var _token, _ = token.SignedString([]byte(config.Env.Server.JWTSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user