mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	API OTP Context (#6674)
* API OTP Context * Update api.go * token * token * fix per discord * copyright header * remove check for token in OTP * Update auth.go * simplify * Update api.go
This commit is contained in:
		
				
					committed by
					
						 Lauris BH
						Lauris BH
					
				
			
			
				
	
			
			
			
						parent
						
							dae94e33be
						
					
				
				
					commit
					19ec2606e9
				
			| @@ -214,9 +214,10 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool) | |||||||
| 					} | 					} | ||||||
| 					return nil, false | 					return nil, false | ||||||
| 				} | 				} | ||||||
|  | 			} else { | ||||||
|  | 				ctx.Data["IsApiToken"] = true | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			ctx.Data["IsApiToken"] = true |  | ||||||
| 			return u, true | 			return u, true | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -114,6 +114,28 @@ func (ctx *APIContext) RequireCSRF() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // CheckForOTP validateds OTP | ||||||
|  | func (ctx *APIContext) CheckForOTP() { | ||||||
|  | 	otpHeader := ctx.Req.Header.Get("X-Gitea-OTP") | ||||||
|  | 	twofa, err := models.GetTwoFactorByUID(ctx.Context.User.ID) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if models.IsErrTwoFactorNotEnrolled(err) { | ||||||
|  | 			return // No 2FA enrollment for this user | ||||||
|  | 		} | ||||||
|  | 		ctx.Context.Error(500) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	ok, err := twofa.ValidateTOTP(otpHeader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Context.Error(500) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	if !ok { | ||||||
|  | 		ctx.Context.Error(401) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| // APIContexter returns apicontext as macaron middleware | // APIContexter returns apicontext as macaron middleware | ||||||
| func APIContexter() macaron.Handler { | func APIContexter() macaron.Handler { | ||||||
| 	return func(c *Context) { | 	return func(c *Context) { | ||||||
|   | |||||||
| @@ -1,10 +1,12 @@ | |||||||
| // Copyright 2014 The Gogs Authors. All rights reserved. | // Copyright 2014 The Gogs Authors. All rights reserved. | ||||||
|  | // Copyright 2019 The Gitea Authors. All rights reserved. | ||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package context | package context | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/auth" | 	"code.gitea.io/gitea/modules/auth" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| @@ -88,6 +90,28 @@ func Toggle(options *ToggleOptions) macaron.Handler { | |||||||
| 				ctx.HTML(200, "user/auth/activate") | 				ctx.HTML(200, "user/auth/activate") | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
|  | 			if ctx.IsSigned && auth.IsAPIPath(ctx.Req.URL.Path) && ctx.IsBasicAuth { | ||||||
|  | 				twofa, err := models.GetTwoFactorByUID(ctx.User.ID) | ||||||
|  | 				if err != nil { | ||||||
|  | 					if models.IsErrTwoFactorNotEnrolled(err) { | ||||||
|  | 						return // No 2FA enrollment for this user | ||||||
|  | 					} | ||||||
|  | 					ctx.Error(500) | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 				otpHeader := ctx.Req.Header.Get("X-Gitea-OTP") | ||||||
|  | 				ok, err := twofa.ValidateTOTP(otpHeader) | ||||||
|  | 				if err != nil { | ||||||
|  | 					ctx.Error(500) | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 				if !ok { | ||||||
|  | 					ctx.JSON(403, map[string]string{ | ||||||
|  | 						"message": "Only signed in user is allowed to call APIs.", | ||||||
|  | 					}) | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Redirect to log in page if auto-signin info is provided and has not signed in. | 		// Redirect to log in page if auto-signin info is provided and has not signed in. | ||||||
|   | |||||||
| @@ -172,6 +172,10 @@ func reqToken() macaron.Handler { | |||||||
| 		if true == ctx.Data["IsApiToken"] { | 		if true == ctx.Data["IsApiToken"] { | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  | 		if ctx.Context.IsBasicAuth { | ||||||
|  | 			ctx.CheckForOTP() | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 		if ctx.IsSigned { | 		if ctx.IsSigned { | ||||||
| 			ctx.RequireCSRF() | 			ctx.RequireCSRF() | ||||||
| 			return | 			return | ||||||
| @@ -181,11 +185,12 @@ func reqToken() macaron.Handler { | |||||||
| } | } | ||||||
|  |  | ||||||
| func reqBasicAuth() macaron.Handler { | func reqBasicAuth() macaron.Handler { | ||||||
| 	return func(ctx *context.Context) { | 	return func(ctx *context.APIContext) { | ||||||
| 		if !ctx.IsBasicAuth { | 		if !ctx.Context.IsBasicAuth { | ||||||
| 			ctx.Error(401) | 			ctx.Context.Error(401) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  | 		ctx.CheckForOTP() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user