Skip to content

Commit 7981f90

Browse files
authored
Merge pull request #14 from isoppp/feature/role-handling
role handling and me api
2 parents c8d0220 + 7dde7a7 commit 7981f90

File tree

10 files changed

+85
-82
lines changed

10 files changed

+85
-82
lines changed

db/migrations/000001_init_schema.down.sql

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ DROP TABLE IF EXISTS user_role;
33
DROP TABLE IF EXISTS roles;
44
DROP TABLE IF EXISTS sessions;
55
DROP TABLE IF EXISTS users;
6+
DROP TYPE IF EXISTS user_role_type;

db/migrations/000001_init_schema.up.sql

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ CREATE TABLE "sessions"
1515
"created_at" timestamptz NOT NULL DEFAULT (now())
1616
);
1717

18+
DROP TYPE IF EXISTS user_role_type;
19+
CREATE TYPE user_role_type AS ENUM('Admin', 'User', 'TEST_DUMMY1', 'TEST_DUMMY2');
20+
1821
CREATE TABLE "roles"
1922
(
2023
"id" SERIAL PRIMARY KEY,
21-
"name" varchar UNIQUE NOT NULL,
22-
"created_at" timestamptz NOT NULL DEFAULT (now()),
23-
"updated_at" timestamptz NOT NULL DEFAULT (now())
24+
"name" user_role_type UNIQUE NOT NULL
2425
);
2526

2627
CREATE TABLE "user_role"

db/seed.sql

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
INSERT INTO roles (id, name)
2-
VALUES (1, 'Admin'), (2, 'User')
1+
INSERT INTO roles (name)
2+
VALUES ('Admin'), ('User')
33
ON CONFLICT DO NOTHING;
44

5-
INSERT INTO users (id, email, hashed_password)
6-
VALUES (1, '[email protected]', 'asdf1234'), (2, '[email protected]', 'asdf1234'), (3, '[email protected]', 'asdf1234')
5+
INSERT INTO users (email, hashed_password)
6+
VALUES ('[email protected]', 'asdf1234'), ('[email protected]', 'asdf1234'), ('[email protected]', 'asdf1234')
77
ON CONFLICT DO NOTHING;
88

99
INSERT INTO user_role (user_id, role_id)
1010
VALUES (1, 1), (2, 2), (3, 2)
1111
ON CONFLICT DO NOTHING;
1212

13-
INSERT INTO posts (id, user_id, content)
13+
INSERT INTO posts (user_id, content)
1414
VALUES
15-
(1, 2, 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,'),
16-
(2, 2, 'post 2'),
17-
(3, 2, 'post 3'),
18-
(4, 3, 'post 4'),
19-
(5, 3, 'post 5')
15+
(2, 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,'),
16+
(2, 'post 2'),
17+
(2, 'post 3'),
18+
(3, 'post 4'),
19+
(3, 'post 5')
2020
ON CONFLICT DO NOTHING;
2121

internal/boilmodels/boil_types.go

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/boilmodels/roles.go

+16-54
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/boilmodels/roles_test.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/boilmodels/users.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/handlers/user.go

+38-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"net/http"
66
"sandbox-go-api-sqlboiler-rest-auth/internal/boilmodels"
77
"sandbox-go-api-sqlboiler-rest-auth/internal/middleware"
8-
"time"
98

109
"github.com/volatiletech/sqlboiler/v4/boil"
1110

@@ -15,10 +14,9 @@ import (
1514
)
1615

1716
type PublicUser struct {
18-
ID int `boil:"id" json:"id"`
19-
Email string `boil:"email" json:"email"`
20-
CreatedAt time.Time `boil:"created_at" json:"created_at"`
21-
UpdatedAt time.Time `boil:"updated_at" json:"updated_at"`
17+
ID int `json:"id"`
18+
Email string `json:"email"`
19+
Roles boilmodels.RoleSlice `json:"roles,omitempty"`
2220
}
2321

2422
type UsersData struct {
@@ -34,6 +32,22 @@ type CreateUserRequest struct {
3432
Password string `json:"password"`
3533
}
3634

35+
func Me(c echo.Context) error {
36+
cc := c.(*middleware.CustomContext)
37+
cu := cc.CurrentUser
38+
cc.ZapLogger.Info("cu:", cu)
39+
if cu == nil {
40+
return echo.NewHTTPError(http.StatusForbidden, http.StatusText(http.StatusForbidden))
41+
}
42+
return c.JSON(http.StatusOK, JsonSuccessResponse(UserData{
43+
User: &PublicUser{
44+
ID: cu.ID,
45+
Email: cu.Email,
46+
Roles: cu.R.Roles,
47+
},
48+
}))
49+
}
50+
3751
func GetUsers(c echo.Context) error {
3852
cc := c.(*middleware.CustomContext)
3953
ctx := cc.Request().Context()
@@ -43,6 +57,7 @@ func GetUsers(c echo.Context) error {
4357
c.Error(err)
4458
return err
4559
}
60+
4661
return c.JSON(http.StatusOK, JsonSuccessResponse(UsersData{
4762
Users: &users,
4863
}))
@@ -86,19 +101,32 @@ func CreateUser(c echo.Context) error {
86101
if err := c.Bind(req); err != nil {
87102
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
88103
}
104+
105+
r, err := boilmodels.Roles(qm.Where("name = ?", boilmodels.UserRoleTypeUser)).One(ctx, cc.DB)
106+
if err != nil {
107+
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
108+
}
109+
cc.ZapLogger.Info(r.Name)
110+
89111
u := boilmodels.User{
90112
Email: req.Email,
91113
HashedPassword: req.Password,
92114
}
93-
err := u.Insert(ctx, cc.DB, boil.Infer())
115+
116+
err = u.Insert(ctx, cc.DB, boil.Infer())
94117
if err != nil {
95118
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
96119
}
120+
121+
err = u.SetRoles(ctx, cc.DB, false, r)
122+
if err != nil {
123+
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
124+
}
125+
97126
pu := PublicUser{
98-
ID: u.ID,
99-
Email: u.Email,
100-
CreatedAt: u.CreatedAt,
101-
UpdatedAt: u.UpdatedAt,
127+
ID: u.ID,
128+
Email: u.Email,
129+
Roles: u.R.Roles,
102130
}
103131

104132
return c.JSON(http.StatusOK, JsonSuccessResponse(UserData{

internal/middleware/middleware.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"sandbox-go-api-sqlboiler-rest-auth/internal/cookie"
99
"time"
1010

11+
"github.com/volatiletech/sqlboiler/v4/queries/qm"
12+
1113
"github.com/gorilla/securecookie"
1214

1315
"go.uber.org/zap"
@@ -44,9 +46,9 @@ func SessionRestorer(db *sql.DB, logger *zap.SugaredLogger, sc *securecookie.Sec
4446
sess, err := boilmodels.FindSession(c.Request().Context(), db, dv)
4547
if err != nil {
4648
// maybe wrong cookie id?
47-
return echo.NewHTTPError(500, "cannot get cookie, but got session id", dv, err)
49+
return echo.NewHTTPError(500, "cannot get user by session id in cookie", dv, err)
4850
}
49-
user, err := sess.User().One(c.Request().Context(), db)
51+
user, err := sess.User(qm.Load(boilmodels.UserRels.Roles)).One(c.Request().Context(), db)
5052
if err != nil {
5153
return echo.NewHTTPError(500, "cannod find user from session relation", dv, err)
5254
}

internal/server/routes.go

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func bindRoutes(e *echo.Echo, cfg *config.Config, l *zap.Logger, db *sql.DB, sc
2121
e.DELETE("/api/v1/sessions", handlers.DeleteSession)
2222

2323
// users
24+
e.GET("/api/v1/me", handlers.Me)
2425
e.GET("/api/v1/users", handlers.GetUsers)
2526
e.POST("/api/v1/users", handlers.CreateUser)
2627
e.GET("/api/v1/users/:id", handlers.GetUser)

0 commit comments

Comments
 (0)