Skip to content

Commit

Permalink
Add login flash message on throttling (#8)
Browse files Browse the repository at this point in the history
Closes #7
  • Loading branch information
Sheikah45 authored Jul 20, 2021
1 parent ba33e60 commit 8775b72
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ class OAuthController(
model: Model,
): Mono<Rendering> {
val loginFailed = request.queryParams.containsKey("login_failed")
val loginThrottled = request.queryParams.containsKey("login_throttled")
model.addAttribute("loginFailed", loginFailed)
model.addAttribute("loginThrottled", loginThrottled)
model.addAttribute("challenge", challenge)
model.addAttribute("passwordResetUrl", fafProperties.passwordResetUrl)
model.addAttribute("registerAccountUrl", fafProperties.registerAccountUrl)
Expand Down Expand Up @@ -64,7 +66,14 @@ class OAuthController(
when (it) {
is SuccessfulLogin -> redirect(response, it.redirectTo)
is UserBanned -> redirect(response, it.redirectTo)
is LoginThrottlingActive -> redirect(response, it.redirectTo)
is LoginThrottlingActive -> redirect(
response,
UriComponentsBuilder.fromUri(request.uri)
.queryParam("login_challenge", challenge)
.queryParam("login_throttled")
.build()
.toUriString()
)
is UserOrCredentialsMismatch -> redirect(
response,
UriComponentsBuilder.fromUri(request.uri)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ data class SecurityProperties(
)

sealed class LoginResult {
data class LoginThrottlingActive(val redirectTo: String) : LoginResult()
object LoginThrottlingActive : LoginResult()
object UserOrCredentialsMismatch : LoginResult()
data class SuccessfulLogin(val redirectTo: String) : LoginResult()
data class UserBanned(val redirectTo: String, val ban: Ban) : LoginResult()
Expand Down Expand Up @@ -90,8 +90,7 @@ class UserService(
): Mono<LoginResult> = checkLoginThrottlingRequired(ip)
.flatMap { throttlingRequired ->
if (throttlingRequired) {
hydraService.rejectLoginRequest(challenge, GenericError(HYDRA_ERROR_LOGIN_THROTTLED))
.map { LoginResult.LoginThrottlingActive(it.redirectTo) }
Mono.just(LoginResult.LoginThrottlingActive)
} else {
hydraService.getLoginRequest(challenge)
.flatMap { loginRequest ->
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ header.loggedInAs=You are logged in as: {0}
login.title=FAForever Login
login.welcomeBack=Welcome back, Commander!
login.badCredentials=Username or password was wrong
login.throttled=Too many of your login attempts have failed. Please wait some time before trying to login again.
login.usernameOrEmail=Username or email
login.password=Password
login.loginAction=Log in
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/i18n/messages_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ header.loggedInAs=Du bist eingeloggt als: {0}
login.title=FAForever Login
login.welcomeBack=Willkommen zurück, Commander!
login.badCredentials=Benutzername oder Passwort falsch
login.throttled=Zu viele deiner Login-Versuche sind fehlgeschlagen. Bitte warte einige Zeit bevor du es erneut versuchst.
login.usernameOrEmail=Benutzername oder Email
login.password=Passwort
login.loginAction=Einloggen
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ <h2 id="form-header-right" th:text="#{login.welcomeBack}">Welcome back, commande

<div class="error" th:if="${loginFailed}">
<i class="fas fa-exclamation-triangle"></i>
<span th:text="#{login.badCredentials}">Username or password was wrong.</span>
<span th:text="#{login.badCredentials}">Username or password was wrong</span>
</div>

<div class="error" th:if="${loginThrottled}">
<i class="fas fa-exclamation-triangle"></i>
<span th:text="#{login.throttled}">Too many of your login attempts have failed. Please wait some time before trying to login again.</span>
</div>

<input type="hidden" name="login_challenge" th:value="${challenge}" th:if="${challenge != null }"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class UserServiceApplicationTests {
.exchange()
.expectStatus().is3xxRedirection()
.expectHeader()
.location(hydraRedirectUrl)
.location("/login?login_challenge=someChallenge&login_challenge=someChallenge&login_throttled")
.expectBody(String::class.java)

verify(loginLogRepository).findFailedAttemptsByIp(anyString())
Expand Down

0 comments on commit 8775b72

Please sign in to comment.