diff --git a/api/BaseResponse.go b/api/BaseResponse.go new file mode 100644 index 0000000..516ada9 --- /dev/null +++ b/api/BaseResponse.go @@ -0,0 +1,17 @@ +package api + +import "github.com/gin-gonic/gin" + +func errorResponse(err error, msg string) gin.H { + return gin.H{ + "error": err.Error(), + "message": msg, + } +} + +func validResponse(data interface{}, msg string) gin.H { + return gin.H{ + "message": msg, + "data": data, + } +} diff --git a/api/server.go b/api/server.go new file mode 100644 index 0000000..bea424e --- /dev/null +++ b/api/server.go @@ -0,0 +1,45 @@ +package api + +import ( + "fmt" + + db "git.nochill.in/nochill/hiling_go/db/sqlc" + "git.nochill.in/nochill/hiling_go/util" + "git.nochill.in/nochill/hiling_go/util/token" + "github.com/gin-gonic/gin" +) + +type Server struct { + config util.Config + store db.Store + tokenMaker token.Maker + router *gin.Engine +} + +func NewServer(config util.Config, store db.Store) (*Server, error) { + tokenMaker, err := token.NewPasetoMaker(config.TokenSymmetricKey) + if err != nil { + return nil, fmt.Errorf("cannot create token maker: %w", err) + } + + server := &Server{ + config: config, + store: store, + tokenMaker: tokenMaker, + } + + server.getRoutes() + return server, nil +} + +func (server *Server) getRoutes() { + router := gin.Default() + + router.POST("/user/create", server.createUser) + + server.router = router +} + +func (server *Server) Start(address string) error { + return server.router.Run(address) +} diff --git a/api/token.go b/api/token.go new file mode 100644 index 0000000..a0a95d5 --- /dev/null +++ b/api/token.go @@ -0,0 +1,96 @@ +package api + +import ( + "time" +) + +type renewAccessRequest struct { + RefreshToken string `json:"refresh_token" binding:"required"` +} + +type renewAccessResponse struct { + AccesToken string `json:"access_token"` + AccessTokenExpiresAt time.Time `json:"access_token_expires_at"` +} + +// func (server *Server) renewAccessToken(ctx *gin.Context) { +// var req renewAccessRequest +// if err := ctx.ShouldBindJSON(&req); err != nil { +// ctx.JSON(http.StatusBadRequest, errorResponse(err, "")) +// return +// } + +// refreshPayload, err := server.tokenMaker.VerifyToken(req.RefreshToken) +// if err != nil { +// ctx.JSON(http.StatusUnauthorized, errorResponse(err, "")) +// return +// } + +// session, err := server.store.GetSession(ctx, refreshPayload.ID) +// if err != nil { +// if err == sql.ErrNoRows { +// ctx.JSON(http.StatusNotFound, errorResponse(err, "")) +// return +// } +// ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) +// return +// } + +// if session.IsBlocked { +// err := fmt.Errorf("blocked session") +// ctx.JSON(http.StatusUnauthorized, errorResponse(err, "")) +// return +// } + +// if session.Email != refreshPayload.Email { +// err := fmt.Errorf("incorrect session user") +// ctx.JSON(http.StatusUnauthorized, errorResponse(err, "")) +// return +// } + +// if session.RefreshToken != req.RefreshToken { +// err := fmt.Errorf("mismatched session token") +// ctx.JSON(http.StatusUnauthorized, errorResponse(err, "")) +// return +// } + +// if time.Now().After(refreshPayload.ExpiredAt) { +// err := fmt.Errorf("Expired session") +// ctx.JSON(http.StatusUnauthorized, errorResponse(err, "")) +// return +// } + +// user, err := server.store.GetUserByEmail(ctx, refreshPayload.Email) +// if err != nil { +// if err == sql.ErrNoRows { +// ctx.JSON(http.StatusNotFound, errorResponse(err, "")) +// return +// } +// ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) +// return +// } + +// merchant, err := server.store.GetMerchantByUserId(ctx, user.ID) +// if err != nil { +// ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) +// return +// } + +// accessToken, accessPayload, err := server.tokenMaker.CreateToken( +// refreshPayload.Email, +// merchant.ID.String(), +// server.config.TokenDuration, +// ) + +// if err != nil { +// ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) +// return +// } + +// res := renewAccessResponse{ +// AccesToken: accessToken, +// AccessTokenExpiresAt: accessPayload.ExpiredAt, +// } + +// ctx.JSON(http.StatusOK, res) +// } diff --git a/api/user.go b/api/user.go new file mode 100644 index 0000000..1e3e6f8 --- /dev/null +++ b/api/user.go @@ -0,0 +1,27 @@ +package api + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +type CreateUserRequest struct { + ClientIpV4 string `json:"client_ip" binding:"required"` +} + +func (server *Server) createUser(ctx *gin.Context) { + var req CreateUserRequest + if err := ctx.ShouldBindJSON(&req); err != nil { + ctx.JSON(http.StatusBadRequest, errorResponse(err, "")) + return + } + + err := server.store.CreateUser(ctx, req.ClientIpV4) + if err != nil { + ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) + return + } + + ctx.Writer.WriteHeader(http.StatusOK) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..68c0774 --- /dev/null +++ b/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "database/sql" + "log" + + "git.nochill.in/nochill/hiling_go/api" + db "git.nochill.in/nochill/hiling_go/db/sqlc" + "git.nochill.in/nochill/hiling_go/util" + _ "github.com/lib/pq" +) + +// "database/sql"? + +// "git.nochill.in/nochill/naice_pos/util" + +func main() { + config, err := util.LoadConfig(".") + if err != nil { + log.Fatal("cannot load config: ", err) + } + dbConn, err := sql.Open(config.DBDriver, config.DBSource) + if err != nil { + log.Fatal("cannot connect to db: ", err) + } + + store := db.NewStore(dbConn) + server, err := api.NewServer(config, store) + if err != nil { + log.Fatal("cannot make server: ", err) + } + + err = server.Start(config.ServerAddress) + if err != nil { + log.Fatal("cannot start server: ", err) + } + +}