all repos

onasty @ 5495cb456caa00f4564d1c1eed06a766811debaf

a one-time notes service

onasty/internal/transport/http/apiv1/auth.go (view raw)

Smirnov Oleksandr Smirnov Oleksandr
ss2316544@gmail.com
feat: add oauth2 login for google and github (#109)..., 1 year ago
1
package apiv1
2
3
import (
4
	"net/http"
5
	"time"
6
7
	"github.com/gin-gonic/gin"
8
	"github.com/olexsmir/onasty/internal/dtos"
9
)
10
11
type signUpRequest struct {
12
	Username string `json:"username"`
13
	Email    string `json:"email"`
14
	Password string `json:"password"`
15
}
16
17
func (a *APIV1) signUpHandler(c *gin.Context) {
18
	var req signUpRequest
19
	if err := c.ShouldBindJSON(&req); err != nil {
20
		newError(c, http.StatusBadRequest, "invalid request")
21
		return
22
	}
23
24
	if _, err := a.usersrv.SignUp(c.Request.Context(), dtos.SignUp{
25
		Username:    req.Username,
26
		Email:       req.Email,
27
		Password:    req.Password,
28
		CreatedAt:   time.Now(),
29
		LastLoginAt: time.Now(),
30
	}); err != nil {
31
		errorResponse(c, err)
32
		return
33
	}
34
35
	c.Status(http.StatusCreated)
36
}
37
38
type signInRequest struct {
39
	Email    string `json:"email"`
40
	Password string `json:"password"`
41
}
42
43
type signInResponse struct {
44
	AccessToken  string `json:"access_token"`
45
	RefreshToken string `json:"refresh_token"`
46
}
47
48
func (a *APIV1) signInHandler(c *gin.Context) {
49
	var req signInRequest
50
	if err := c.ShouldBindJSON(&req); err != nil {
51
		newError(c, http.StatusBadRequest, "invalid request")
52
		return
53
	}
54
55
	toks, err := a.usersrv.SignIn(c.Request.Context(), dtos.SignIn{
56
		Email:    req.Email,
57
		Password: req.Password,
58
	})
59
	if err != nil {
60
		errorResponse(c, err)
61
		return
62
	}
63
64
	c.JSON(http.StatusOK, signInResponse{
65
		AccessToken:  toks.Access,
66
		RefreshToken: toks.Refresh,
67
	})
68
}
69
70
type refreshTokenRequest struct {
71
	RefreshToken string `json:"refresh_token"`
72
}
73
74
func (a *APIV1) refreshTokensHandler(c *gin.Context) {
75
	var req refreshTokenRequest
76
	if err := c.ShouldBindJSON(&req); err != nil {
77
		newError(c, http.StatusBadRequest, "invalid request")
78
		return
79
	}
80
81
	toks, err := a.usersrv.RefreshTokens(c.Request.Context(), req.RefreshToken)
82
	if err != nil {
83
		errorResponse(c, err)
84
		return
85
	}
86
87
	c.JSON(http.StatusOK, signInResponse{
88
		AccessToken:  toks.Access,
89
		RefreshToken: toks.Refresh,
90
	})
91
}
92
93
func (a *APIV1) verifyHandler(c *gin.Context) {
94
	if err := a.usersrv.Verify(c.Request.Context(), c.Param("token")); err != nil {
95
		errorResponse(c, err)
96
		return
97
	}
98
99
	c.String(http.StatusOK, "email verified")
100
}
101
102
func (a *APIV1) resendVerificationEmailHandler(c *gin.Context) {
103
	var req signInRequest
104
	if err := c.ShouldBindJSON(&req); err != nil {
105
		newError(c, http.StatusBadRequest, "invalid request")
106
		return
107
	}
108
109
	if err := a.usersrv.ResendVerificationEmail(
110
		c.Request.Context(),
111
		dtos.SignIn{
112
			Email:    req.Email,
113
			Password: req.Password,
114
		}); err != nil {
115
		errorResponse(c, err)
116
		return
117
	}
118
119
	c.Status(http.StatusOK)
120
}
121
122
func (a *APIV1) logOutHandler(c *gin.Context) {
123
	if err := a.usersrv.Logout(c.Request.Context(), a.getUserID(c)); err != nil {
124
		errorResponse(c, err)
125
		return
126
	}
127
128
	c.Status(http.StatusNoContent)
129
}
130
131
type changePasswordRequest struct {
132
	CurrentPassword string `json:"current_password"`
133
	NewPassword     string `json:"new_password"`
134
}
135
136
func (a *APIV1) changePasswordHandler(c *gin.Context) {
137
	var req changePasswordRequest
138
	if err := c.ShouldBindJSON(&req); err != nil {
139
		newError(c, http.StatusBadRequest, "invalid request")
140
		return
141
	}
142
143
	if err := a.usersrv.ChangePassword(
144
		c.Request.Context(),
145
		a.getUserID(c),
146
		dtos.ChangeUserPassword{
147
			CurrentPassword: req.CurrentPassword,
148
			NewPassword:     req.NewPassword,
149
		}); err != nil {
150
		errorResponse(c, err)
151
		return
152
	}
153
154
	c.Status(http.StatusOK)
155
}
156
157
func (a *APIV1) oauthLoginHandler(c *gin.Context) {
158
	url, err := a.usersrv.GetOAuthURL(c.Param("provider"))
159
	if err != nil {
160
		errorResponse(c, err)
161
		return
162
	}
163
164
	c.Redirect(http.StatusSeeOther, url)
165
}
166
167
func (a *APIV1) oauthCallbackHandler(c *gin.Context) {
168
	tokens, err := a.usersrv.HandleOAuthLogin(
169
		c.Request.Context(),
170
		c.Param("provider"),
171
		c.Query("code"),
172
	)
173
	if err != nil {
174
		errorResponse(c, err)
175
		return
176
	}
177
178
	c.JSON(http.StatusOK, signInResponse{
179
		AccessToken:  tokens.Access,
180
		RefreshToken: tokens.Refresh,
181
	})
182
}