Skip to content

Commit

Permalink
Allow copying the OAuth2 access token from user menu
Browse files Browse the repository at this point in the history
  • Loading branch information
Brutus5000 committed Nov 25, 2024
1 parent df91054 commit ee87c79
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/main/java/com/faforever/client/api/TokenRetriever.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ public class TokenRetriever implements InitializingBean {

private final Mono<String> refreshedTokenMono = Mono.defer(this::refreshAccess)
.cacheInvalidateWhen(this::getExpirationMono)

.map(OAuth2AccessToken::getTokenValue);
.map(OAuth2AccessToken::getTokenValue);

@Override
public void afterPropertiesSet() throws Exception {
Expand Down Expand Up @@ -130,4 +129,8 @@ public void invalidateToken() {
public Flux<Long> invalidationFlux() {
return invalidateFlux;
}

public Mono<String> getAccessToken() {
return refreshedTokenMono;
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
package com.faforever.client.headerbar;

import com.faforever.client.api.TokenRetriever;
import com.faforever.client.domain.server.PlayerInfo;
import com.faforever.client.fx.FxApplicationThreadExecutor;
import com.faforever.client.fx.NodeController;
import com.faforever.client.player.PlayerInfoWindowController;
import com.faforever.client.player.PlayerService;
import com.faforever.client.reporting.ReportDialogController;
import com.faforever.client.theme.UiService;
import com.faforever.client.user.LoginService;
import com.faforever.client.util.ClipboardUtil;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.MenuButton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Slf4j
@RequiredArgsConstructor
public class UserButtonController extends NodeController<Node> {

private final FxApplicationThreadExecutor fxApplicationThreadExecutor;
private final PlayerService playerService;
private final UiService uiService;
private final LoginService loginService;
private final TokenRetriever tokenRetriever;

public MenuButton userMenuButtonRoot;

Expand Down Expand Up @@ -57,6 +64,13 @@ public void onReport() {
reportDialogController.show();
}

public void onCopyAccessToken() {
tokenRetriever.getAccessToken().subscribe(accessToken -> {
log.info("Copied access token to clipboard");
fxApplicationThreadExecutor.execute(() -> ClipboardUtil.copyToClipboard(accessToken));
});
}

public void onLogOut() {
loginService.logOut();
}
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 @@ -21,6 +21,7 @@ view.tiles = Tiles
view.table = Table
userMenu.logOut = Log out
userMenu.showProfile = Show profile
userMenu.copyAccessToken=Copy access token
menu.feedback = Feedback
menu.exit = Exit
menu.settings = Settings
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/theme/headerbar/user_button.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<items>
<MenuItem mnemonicParsing="false" onAction="#onShowProfile" text="%userMenu.showProfile"/>
<MenuItem mnemonicParsing="false" onAction="#onReport" text="%userMenu.moderationReport"/>
<MenuItem mnemonicParsing="false" onAction="#onCopyAccessToken" text="%userMenu.copyAccessToken"/>
<MenuItem mnemonicParsing="false" onAction="#onLogOut" text="%userMenu.logOut"/>
</items>
</MenuButton>
12 changes: 12 additions & 0 deletions src/test/java/com/faforever/client/api/TokenRetrieverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,16 @@ public void testGetRefreshToken() throws Exception {

assertEquals(tokenProperties.get(REFRESH_TOKEN), loginPrefs.getRefreshToken());
}

@Test
public void testGetAccessToken() throws Exception {
loginPrefs.setRememberMe(true);
Map<String, String> tokenProperties = Map.of(EXPIRES_IN, "3600", REFRESH_TOKEN, "refresh", ACCESS_TOKEN, "test",
TOKEN_TYPE, "bearer");
prepareTokenResponse(tokenProperties);

StepVerifier.create(instance.getAccessToken())
.assertNext(accessToken -> assertEquals(accessToken, "test"))
.verifyComplete();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.faforever.client.headerbar;

import com.faforever.client.api.TokenRetriever;
import com.faforever.client.builders.PlayerInfoBuilder;
import com.faforever.client.domain.server.PlayerInfo;
import com.faforever.client.player.PlayerInfoWindowController;
Expand All @@ -13,9 +14,11 @@
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import reactor.core.publisher.Mono;

import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class UserButtonControllerTest extends PlatformTest {
private static final String TEST_USER_NAME = "junit";
Expand All @@ -30,6 +33,8 @@ public class UserButtonControllerTest extends PlatformTest {
private ReportDialogController reportDialogController;
@Mock
private PlayerInfoWindowController playerInfoWindowController;
@Mock
private TokenRetriever tokenRetriever;


@InjectMocks
Expand Down Expand Up @@ -64,6 +69,15 @@ public void testReport() {
verify(reportDialogController).show();
}

@Test
public void testCopyAccessToken() {
when(tokenRetriever.getAccessToken()).thenReturn(Mono.just("someToken"));

instance.onCopyAccessToken();

verify(tokenRetriever).getAccessToken();
}

@Test
public void testLogOut() {
instance.onLogOut();
Expand Down

0 comments on commit ee87c79

Please sign in to comment.