Skip to content

Commit ac485ba

Browse files
authored
Merge pull request #3 from isoppp/feature/refactor-handlers-etc
refactor handlers, context and others
2 parents d02afbd + eed1e1d commit ac485ba

File tree

13 files changed

+187
-174
lines changed

13 files changed

+187
-174
lines changed

internal/config/config.go

+18-16
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ var (
1313
)
1414

1515
type Config struct {
16-
Port string // flag and env
17-
IsDev bool // flag
18-
DBHost string // env
19-
DBPort string // env
20-
DBName string // env
21-
DBUser string // env
22-
DBPassword string // env
23-
SecretKey string // env
16+
Port string // flag and env
17+
IsDev bool // flag
18+
DBHost string // env
19+
DBPort string // env
20+
DBName string // env
21+
DBUser string // env
22+
DBPassword string // env
23+
SecretKey string // env
24+
SessionExpirationDays string // env
2425
}
2526

2627
func (c *Config) GetDataSourceName() string {
@@ -40,14 +41,15 @@ func NewConfig() *Config {
4041
flag.BoolVar(&isDev, "dev", false, "enable development mode")
4142
flag.Parse()
4243
appConfig = &Config{
43-
Port: getEnv("PORT", "8081"),
44-
IsDev: isDev,
45-
DBHost: getEnv("MY_DB_HOST", "localhost"),
46-
DBPort: getEnv("MY_DB_PORT", "5433"),
47-
DBName: getEnv("MY_DB_NAME", "sandbox"),
48-
DBUser: getEnv("MY_DB_USER", "postgres"),
49-
DBPassword: getEnv("MY_DB_PASSWORD", "postgres"),
50-
SecretKey: getEnv("MY_SECRET_KEY", "12345678901234567890123456789012"),
44+
Port: getEnv("PORT", "8081"),
45+
IsDev: isDev,
46+
DBHost: getEnv("MY_DB_HOST", "localhost"),
47+
DBPort: getEnv("MY_DB_PORT", "5433"),
48+
DBName: getEnv("MY_DB_NAME", "sandbox"),
49+
DBUser: getEnv("MY_DB_USER", "postgres"),
50+
DBPassword: getEnv("MY_DB_PASSWORD", "postgres"),
51+
SecretKey: getEnv("MY_SECRET_KEY", "12345678901234567890123456789012"),
52+
SessionExpirationDays: getEnv("MY_SESSION_EXPIRATION_DAYS", "90"),
5153
}
5254

5355
if isDev {

internal/cookie/keys.go

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package cookie
2+
3+
const SessionCookieKeyName = "session"
4+
const SecureCookieSessionKeyName = "session"

internal/scookie/scookie.go renamed to internal/cookie/securecookie.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package scookie
1+
package cookie
22

33
import (
44
"sandbox-go-api-sqlboiler-rest-auth/internal/config"

internal/handlers/_template.go

-33
This file was deleted.

internal/handlers/handlers.go

-26
This file was deleted.

internal/handlers/session.go

+26-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package handlers
22

33
import (
4-
"context"
54
"net/http"
5+
"sandbox-go-api-sqlboiler-rest-auth/internal/cookie"
6+
"sandbox-go-api-sqlboiler-rest-auth/internal/middleware"
67
"sandbox-go-api-sqlboiler-rest-auth/models"
8+
"strconv"
79
"time"
810

911
"github.com/google/uuid"
@@ -19,53 +21,62 @@ type CreateSessionRequest struct {
1921
Password string `json:"password"`
2022
}
2123

22-
func (h *Handlers) CreateSession(c echo.Context) error {
23-
ctx := context.Background()
24+
func CreateSession(c echo.Context) error {
25+
cc := c.(*middleware.CustomContext)
26+
ctx := cc.Request().Context()
2427
req := new(CreateUserRequest)
2528
if err := c.Bind(req); err != nil {
2629
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
2730
}
2831

29-
ok, _ := models.Users(qm.Where("email = ?", req.Email)).Exists(ctx, h.db)
32+
ok, _ := models.Users(qm.Where("email = ?", req.Email)).Exists(ctx, cc.DB)
3033
if !ok {
3134
return echo.NewHTTPError(http.StatusNotFound, http.StatusText(http.StatusNotFound))
3235
}
33-
u, err := models.Users(qm.Where("email = ?", req.Email)).One(ctx, h.db)
36+
u, err := models.Users(qm.Where("email = ?", req.Email)).One(ctx, cc.DB)
3437
if err != nil {
3538
return echo.NewHTTPError(http.StatusInternalServerError)
3639
}
37-
h.logger.Info(u)
40+
cc.ZapLogger.Info(u)
3841
if u.HashedPassword != req.Password {
3942
return echo.NewHTTPError(http.StatusBadRequest)
4043
}
4144

45+
expirationDays, err := strconv.Atoi(cc.Config.SessionExpirationDays)
46+
if err != nil {
47+
return echo.NewHTTPError(http.StatusInternalServerError)
48+
}
49+
4250
var s models.Session
4351
var uid, _ = uuid.NewUUID()
4452
s.ID = uid.String()
4553
s.UserID = u.ID
46-
s.ExpiresAt = time.Now().Add(time.Hour * 24 * 30)
47-
err = s.Insert(ctx, h.db, boil.Infer())
54+
s.ExpiresAt = time.Now().Add(time.Hour * 24 * time.Duration(expirationDays))
55+
err = s.Insert(ctx, cc.DB, boil.Infer())
4856
if err != nil {
4957
return echo.NewHTTPError(http.StatusInternalServerError)
5058
}
5159

52-
encoded, err := h.secureCookie.Encode("session", s.ID)
60+
encoded, err := cc.SecureCookie.Encode(cookie.SecureCookieSessionKeyName, s.ID)
5361
if err != nil {
5462
return echo.NewHTTPError(http.StatusInternalServerError)
5563
}
56-
cookie := &http.Cookie{
57-
Name: "session",
64+
65+
ck := &http.Cookie{
66+
Name: cookie.SessionCookieKeyName,
5867
Value: encoded,
5968
Path: "/",
60-
Expires: time.Now().Add(time.Hour * 24 * 30),
61-
Secure: !h.cfg.IsDev,
69+
Expires: time.Now().Add(time.Hour * 24 * time.Duration(expirationDays)),
70+
Secure: !cc.Config.IsDev,
6271
HttpOnly: true,
6372
SameSite: 2,
6473
}
65-
c.SetCookie(cookie)
74+
c.SetCookie(ck)
6675
return c.NoContent(http.StatusNoContent)
6776
}
6877

69-
func (h *Handlers) DeleteSession(c echo.Context) error {
78+
func DeleteSession(c echo.Context) error {
79+
//cc := c.(*customcontext.CustomContext)
80+
//ctx := cc.Request().Context()
7081
return c.NoContent(http.StatusNoContent)
7182
}

internal/handlers/status.go

+7-12
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,19 @@ package handlers
22

33
import (
44
"net/http"
5-
"sandbox-go-api-sqlboiler-rest-auth/models"
5+
"sandbox-go-api-sqlboiler-rest-auth/internal/middleware"
66

77
"github.com/labstack/echo/v4"
88
)
99

10-
type CookieValue struct {
11-
UserID int
12-
Name string
13-
}
10+
func GetStatus(c echo.Context) error {
11+
cc := c.(*middleware.CustomContext)
1412

15-
func (h *Handlers) GetStatus(c echo.Context) error {
16-
var u *models.User
17-
uv := c.Get("user")
18-
if uv != nil {
19-
u = uv.(*models.User)
20-
h.logger.Debug("user data?", u)
13+
u := cc.CurrentUser
14+
if u != nil {
15+
cc.ZapLogger.Debug("user data?", u)
2116
} else {
22-
h.logger.Debug("not set user session")
17+
cc.ZapLogger.Debug("not set user session")
2318
}
2419
return c.String(http.StatusOK, "server is running")
2520
}

internal/handlers/user.go

+21-17
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package handlers
22

33
import (
4-
"context"
54
"errors"
65
"net/http"
6+
"sandbox-go-api-sqlboiler-rest-auth/internal/middleware"
77
"sandbox-go-api-sqlboiler-rest-auth/models"
88
"time"
99

@@ -25,13 +25,14 @@ type UsersData struct {
2525
Users *[]PublicUser `json:"users"`
2626
}
2727

28-
func (h *Handlers) GetUsers(c echo.Context) error {
29-
ctx := context.Background()
28+
func GetUsers(c echo.Context) error {
29+
cc := c.(*middleware.CustomContext)
30+
ctx := cc.Request().Context()
3031
var users []PublicUser
3132
res := SuccessResponse{
3233
Data: UsersData{Users: &users},
3334
}
34-
err := models.Users().Bind(ctx, h.db, &users)
35+
err := models.Users().Bind(ctx, cc.DB, &users)
3536
if err != nil {
3637
c.Error(err)
3738
return err
@@ -43,8 +44,9 @@ type UserData struct {
4344
User *PublicUser `json:"user"`
4445
}
4546

46-
func (h *Handlers) GetUser(c echo.Context) error {
47-
ctx := context.Background()
47+
func GetUser(c echo.Context) error {
48+
cc := c.(*middleware.CustomContext)
49+
ctx := cc.Request().Context()
4850
res := SuccessResponse{
4951
Data: UserData{},
5052
}
@@ -56,7 +58,7 @@ func (h *Handlers) GetUser(c echo.Context) error {
5658
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
5759
}
5860

59-
exists, err := models.UserExists(ctx, h.db, id)
61+
exists, err := models.UserExists(ctx, cc.DB, id)
6062
if !exists {
6163
return echo.NewHTTPError(http.StatusNotFound, http.StatusText(http.StatusNotFound))
6264
}
@@ -65,7 +67,7 @@ func (h *Handlers) GetUser(c echo.Context) error {
6567
}
6668

6769
var users []*PublicUser
68-
err = models.Users(qm.Where("id = ?", id)).Bind(ctx, h.db, &users)
70+
err = models.Users(qm.Where("id = ?", id)).Bind(ctx, cc.DB, &users)
6971
if err != nil {
7072
c.Error(err)
7173
return err
@@ -80,8 +82,9 @@ type CreateUserRequest struct {
8082
Password string `json:"password"`
8183
}
8284

83-
func (h *Handlers) CreateUser(c echo.Context) error {
84-
ctx := context.Background()
85+
func CreateUser(c echo.Context) error {
86+
cc := c.(*middleware.CustomContext)
87+
ctx := cc.Request().Context()
8588
res := SuccessResponse{
8689
Data: UserData{},
8790
}
@@ -93,7 +96,7 @@ func (h *Handlers) CreateUser(c echo.Context) error {
9396
Email: req.Email,
9497
HashedPassword: req.Password,
9598
}
96-
err := u.Insert(ctx, h.db, boil.Infer())
99+
err := u.Insert(ctx, cc.DB, boil.Infer())
97100
if err != nil {
98101
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
99102
}
@@ -110,32 +113,33 @@ func (h *Handlers) CreateUser(c echo.Context) error {
110113
return c.JSON(http.StatusOK, res)
111114
}
112115

113-
func (h *Handlers) PatchUser(c echo.Context) error {
116+
func PatchUser(c echo.Context) error {
114117
return errors.New("not implemented")
115118
}
116119

117-
func (h *Handlers) DeleteUser(c echo.Context) error {
118-
ctx := context.Background()
120+
func DeleteUser(c echo.Context) error {
121+
cc := c.(*middleware.CustomContext)
122+
ctx := cc.Request().Context()
119123
var id int
120124
err := echo.PathParamsBinder(c).
121125
Int("id", &id).
122126
BindError()
123127
if err != nil {
124128
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
125129
}
126-
exists, err := models.UserExists(ctx, h.db, id)
130+
exists, err := models.UserExists(ctx, cc.DB, id)
127131
if !exists {
128132
return echo.NewHTTPError(http.StatusNotFound, http.StatusText(http.StatusNotFound))
129133
}
130134
if err != nil {
131135
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
132136
}
133-
u, err := models.FindUser(ctx, h.db, id)
137+
u, err := models.FindUser(ctx, cc.DB, id)
134138
if err != nil {
135139
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
136140
}
137141

138-
_, err = u.Delete(ctx, h.db)
142+
_, err = u.Delete(ctx, cc.DB)
139143
if err != nil {
140144
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
141145
}

internal/middleware/context.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package middleware
2+
3+
import (
4+
"database/sql"
5+
"sandbox-go-api-sqlboiler-rest-auth/internal/config"
6+
"sandbox-go-api-sqlboiler-rest-auth/models"
7+
8+
"github.com/gorilla/securecookie"
9+
"github.com/labstack/echo/v4"
10+
"go.uber.org/zap"
11+
)
12+
13+
type CustomContext struct {
14+
echo.Context
15+
Config *config.Config
16+
ZapLogger *zap.SugaredLogger
17+
DB *sql.DB
18+
SecureCookie *securecookie.SecureCookie
19+
CurrentUser *models.User
20+
}
21+
22+
func NewCustomContext(c echo.Context, cfg *config.Config, l *zap.SugaredLogger, db *sql.DB, sc *securecookie.SecureCookie) *CustomContext {
23+
return &CustomContext{
24+
Context: c,
25+
Config: cfg,
26+
ZapLogger: l,
27+
DB: db,
28+
SecureCookie: sc,
29+
CurrentUser: nil,
30+
}
31+
}

0 commit comments

Comments
 (0)