Skip to content

Commit

Permalink
Merge pull request #11 from shallwet/login
Browse files Browse the repository at this point in the history
feat(api): login
test(api): add pytest
  • Loading branch information
codycjy authored Feb 5, 2024
2 parents 0a2a753 + 5a3d020 commit 52a6146
Show file tree
Hide file tree
Showing 20 changed files with 538 additions and 21 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/pytest-api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Pythontest Check

on: [pull_request]

env:
TOKEN_EXPIRE_TIME: 15s
RABBITMQ_STR: amqp://guest:guest@localhost:5672//

jobs:
pytest:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Start Redis Docker container
run: |
docker run -d --name my-redis -p 6379:6379 redis
- name: Start RabbitMQ Docker container
run: |
docker run -d --name my-rabbitmq -p 5672:5672 -p :15672:15672 rabbitmq:management
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '^1.21'
cache-dependency-path: "**/*.sum"

- name: Run main.go in test
run: |
cd master
export ENV=test
env env=test go run main.go > output.log 2>&1 &
sleep 60
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.8'

- name: Install dependencies
run: |
cd master/test
pip install -r requirements.txt
- name: Run pytest in test folder
run: |
cd master/test
pytest
72 changes: 72 additions & 0 deletions master/api/auth/login.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package auth

import (
"GalaxyEmpireWeb/api"
"GalaxyEmpireWeb/models"
"GalaxyEmpireWeb/services/jwtservice"
"GalaxyEmpireWeb/services/userservice"
"GalaxyEmpireWeb/utils"
"net/http"

"github.com/gin-gonic/gin"
)

type authResponse struct {
Token string `json:"token"`
}

// @Summary User Login
// @Description Authenticate user and generate JWT token
// @Tags auth
// @Accept json
// @Produce json
// @Param user body models.User required "UserID and Password"
// @Success 200 {object} authResponse "Successful response with JWT token"
// @Failure 400 {object} api.ErrorResponse "Bad request with error message"
// @Failure 500 {object} api.ErrorResponse "Internal server error with error message"
// @Router /login [post]
func LoginHandler(c *gin.Context) {
traceID := utils.TraceIDFromContext(c)
userService, err := userservice.GetService(c)
if err != nil {
c.JSON(http.StatusInternalServerError, api.ErrorResponse{
Succeed: false,
Error: err.Error(),
Message: "Failed to get user service",
TraceID: traceID,
})
}
user := &models.User{}
if err := c.ShouldBindJSON(user); err != nil {
c.JSON(http.StatusBadRequest, api.ErrorResponse{
Succeed: false,
Error: err.Error(),
Message: "Failed to bind json",
TraceID: traceID,
})
return
}
err2 := userService.LoginUser(c, user)
if err2 != nil {
c.JSON(http.StatusUnauthorized, api.ErrorResponse{
Succeed: false,
Error: err2.Error(),
Message: "Wrong Username or Password",
TraceID: traceID,
})
return
}
token, err3 := jwtservice.GenerateToken(user.ID)
if err3 != nil {
c.JSON(http.StatusInternalServerError, api.ErrorResponse{
Succeed: false,
Error: err3.Error(),
Message: "Failed to generate token",
TraceID: traceID,
})
return
}
c.JSON(http.StatusOK, authResponse{
Token: token,
})
}
4 changes: 2 additions & 2 deletions master/api/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func GetUsers(c *gin.Context) {
}

// CreateUser godoc
// @Summary Crea user
// @Summary Create user
// @Description Create User
// @Tags user
// @Accept json
Expand All @@ -132,7 +132,7 @@ func GetUsers(c *gin.Context) {
// @Router /user [post]
func CreateUser(c *gin.Context) {
traceID := c.GetString("traceID")
var user *models.User
user := &models.User{}
err := c.BindJSON(user)
if err != nil {

Expand Down
3 changes: 3 additions & 0 deletions master/config/rabbitmq.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type RabbitMQConfig struct {
// 获取 RabbitMQ 配置的函数
func GetRabbitMQConfig() *RabbitMQConfig {
config := &RabbitMQConfig{}
if os.Getenv("env") == "test" {
return config
}
yamlFile, err := os.ReadFile("config/yamls/rabbitmq.yaml")
if err != nil {
log.Fatalf("yamlFile.Get err #%v ", err)
Expand Down
54 changes: 54 additions & 0 deletions master/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,52 @@ const docTemplate = `{
}
}
},
"/login": {
"post": {
"description": "Authenticate user and generate JWT token",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "User Login",
"parameters": [
{
"description": "UserID and Password",
"name": "user",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.User"
}
}
],
"responses": {
"200": {
"description": "Successful response with JWT token",
"schema": {
"$ref": "#/definitions/auth.succeedResponse"
}
},
"400": {
"description": "Bad request with error message",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"500": {
"description": "Internal server error with error message",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
},
"/ping": {
"get": {
"description": "do ping",
Expand Down Expand Up @@ -628,6 +674,14 @@ const docTemplate = `{
}
}
},
"auth.succeedResponse": {
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
},
"gorm.DeletedAt": {
"type": "object",
"properties": {
Expand Down
54 changes: 54 additions & 0 deletions master/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,52 @@
}
}
},
"/login": {
"post": {
"description": "Authenticate user and generate JWT token",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "User Login",
"parameters": [
{
"description": "UserID and Password",
"name": "user",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.User"
}
}
],
"responses": {
"200": {
"description": "Successful response with JWT token",
"schema": {
"$ref": "#/definitions/auth.succeedResponse"
}
},
"400": {
"description": "Bad request with error message",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"500": {
"description": "Internal server error with error message",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
},
"/ping": {
"get": {
"description": "do ping",
Expand Down Expand Up @@ -617,6 +663,14 @@
}
}
},
"auth.succeedResponse": {
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
},
"gorm.DeletedAt": {
"type": "object",
"properties": {
Expand Down
35 changes: 35 additions & 0 deletions master/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ definitions:
message:
type: string
type: object
auth.succeedResponse:
properties:
token:
type: string
type: object
gorm.DeletedAt:
properties:
time:
Expand Down Expand Up @@ -416,6 +421,36 @@ paths:
summary: Generate captcha picture
tags:
- Captcha
/login:
post:
consumes:
- application/json
description: Authenticate user and generate JWT token
parameters:
- description: UserID and Password
in: body
name: user
required: true
schema:
$ref: '#/definitions/models.User'
produces:
- application/json
responses:
"200":
description: Successful response with JWT token
schema:
$ref: '#/definitions/auth.succeedResponse'
"400":
description: Bad request with error message
schema:
$ref: '#/definitions/api.ErrorResponse'
"500":
description: Internal server error with error message
schema:
$ref: '#/definitions/api.ErrorResponse'
summary: User Login
tags:
- auth
/ping:
get:
consumes:
Expand Down
1 change: 1 addition & 0 deletions master/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ require (
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
Expand Down
2 changes: 2 additions & 0 deletions master/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
Expand Down
32 changes: 32 additions & 0 deletions master/middleware/JWT.go
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
package middleware

import (
"GalaxyEmpireWeb/services/jwtservice"
"GalaxyEmpireWeb/services/userservice"
"net/http"

"github.com/gin-gonic/gin"
)

func JWTAuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Get token from header
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization header is missing"})
return
}
claims, err := jwtservice.ParseToken(authHeader)
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
return
}
userService, err := userservice.GetService(c)
role := userService.GetUserRole(c, claims.UserID)
// 设置上下文
c.Set("claims", claims)
c.Set("role", role)
c.Set("userID", claims.UserID)
c.Next()

}
}
Loading

0 comments on commit 52a6146

Please sign in to comment.