MCPcopy
hub / github.com/tinyauthapp/tinyauth / totpHandler

Method totpHandler

internal/controller/user_controller.go:186–278  ·  view source on GitHub ↗
(c *gin.Context)

Source from the content-addressed store, hash-verified

184}
185
186func (controller *UserController) totpHandler(c *gin.Context) {
187 var req TotpRequest
188
189 err := c.ShouldBindJSON(&req)
190 if err != nil {
191 tlog.App.Error().Err(err).Msg("Failed to bind JSON")
192 c.JSON(400, gin.H{
193 "status": 400,
194 "message": "Bad Request",
195 })
196 return
197 }
198
199 context, err := utils.GetContext(c)
200
201 if err != nil {
202 tlog.App.Error().Err(err).Msg("Failed to get user context")
203 c.JSON(500, gin.H{
204 "status": 500,
205 "message": "Internal Server Error",
206 })
207 return
208 }
209
210 if !context.TotpPending {
211 tlog.App.Warn().Msg("TOTP attempt without a pending TOTP session")
212 c.JSON(401, gin.H{
213 "status": 401,
214 "message": "Unauthorized",
215 })
216 return
217 }
218
219 tlog.App.Debug().Str("username", context.Username).Msg("TOTP verification attempt")
220
221 isLocked, remaining := controller.auth.IsAccountLocked(context.Username)
222
223 if isLocked {
224 tlog.App.Warn().Str("username", context.Username).Msg("Account is locked due to too many failed TOTP attempts")
225 c.Writer.Header().Add("x-tinyauth-lock-locked", "true")
226 c.Writer.Header().Add("x-tinyauth-lock-reset", time.Now().Add(time.Duration(remaining)*time.Second).Format(time.RFC3339))
227 c.JSON(429, gin.H{
228 "status": 429,
229 "message": fmt.Sprintf("Too many failed TOTP attempts. Try again in %d seconds", remaining),
230 })
231 return
232 }
233
234 user := controller.auth.GetLocalUser(context.Username)
235
236 ok := totp.Validate(req.Code, user.TotpSecret)
237
238 if !ok {
239 tlog.App.Warn().Str("username", context.Username).Msg("Invalid TOTP code")
240 controller.auth.RecordLoginAttempt(context.Username, false)
241 tlog.AuditLoginFailure(c, context.Username, "totp", "invalid totp code")
242 c.JSON(401, gin.H{
243 "status": 401,

Callers

nothing calls this directly

Calls 9

GetContextFunction · 0.92
AuditLoginFailureFunction · 0.92
AuditLoginSuccessFunction · 0.92
CapitalizeFunction · 0.92
CompileUserEmailFunction · 0.92
IsAccountLockedMethod · 0.80
GetLocalUserMethod · 0.80
RecordLoginAttemptMethod · 0.80
CreateSessionCookieMethod · 0.80

Tested by

no test coverage detected