mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 13:51:35 +01:00 
			
		
		
		
	Only allow token authentication with 2FA enabled (#2184)
* Don't allow for plain username/password authentication when 2FA is enabled * Removed debugging statement * Don't assume a token belongs to a given user, handle two-factor errors properly * Simplified user/token matching, refactored error handling for two-factor authentication * Change authentication response to avoid bruteforcing * Add TODO item as a comment for changing the response for security purposes
This commit is contained in:
		
							parent
							
								
									1d032f5220
								
							
						
					
					
						commit
						7e12aac61c
					
				| @ -156,24 +156,50 @@ func HTTP(ctx *context.Context) { | ||||
| 					ctx.Handle(http.StatusInternalServerError, "UserSignIn error: %v", err) | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 				// Assume username now is a token. | ||||
| 				token, err := models.GetAccessTokenBySHA(authUsername) | ||||
| 			if authUser == nil { | ||||
| 				authUser, err = models.GetUserByName(authUsername) | ||||
| 
 | ||||
| 				if err != nil { | ||||
| 					if models.IsErrUserNotExist(err) { | ||||
| 						ctx.HandleText(http.StatusUnauthorized, "invalid credentials") | ||||
| 					} else { | ||||
| 						ctx.Handle(http.StatusInternalServerError, "GetUserByName", err) | ||||
| 					} | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				// Assume password is a token. | ||||
| 				token, err := models.GetAccessTokenBySHA(authPasswd) | ||||
| 				if err != nil { | ||||
| 					if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) { | ||||
| 						ctx.HandleText(http.StatusUnauthorized, "invalid token") | ||||
| 						ctx.HandleText(http.StatusUnauthorized, "invalid credentials") | ||||
| 					} else { | ||||
| 						ctx.Handle(http.StatusInternalServerError, "GetAccessTokenBySha", err) | ||||
| 					} | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				if authUser.ID != token.UID { | ||||
| 					ctx.HandleText(http.StatusUnauthorized, "invalid credentials") | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				token.Updated = time.Now() | ||||
| 				if err = models.UpdateAccessToken(token); err != nil { | ||||
| 					ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err) | ||||
| 				} | ||||
| 				authUser, err = models.GetUserByID(token.UID) | ||||
| 				if err != nil { | ||||
| 					ctx.Handle(http.StatusInternalServerError, "GetUserByID", err) | ||||
| 
 | ||||
| 			} else { | ||||
| 				_, err = models.GetTwoFactorByUID(authUser.ID) | ||||
| 
 | ||||
| 				if err == nil { | ||||
| 					// TODO: This response should be changed to "invalid credentials" for security reasons once the expectation behind it (creating an app token to authenticate) is properly documented | ||||
| 					ctx.HandleText(http.StatusUnauthorized, "Users with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password. Please create and use a personal access token on the user settings page") | ||||
| 					return | ||||
| 				} else if !models.IsErrTwoFactorNotEnrolled(err) { | ||||
| 					ctx.Handle(http.StatusInternalServerError, "IsErrTwoFactorNotEnrolled", err) | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user