Skip to content

Commit

Permalink
Implement summarizing /me payload (replaces redirect)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brutus5000 committed Sep 24, 2019
1 parent 0936e7a commit f3684fc
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

@Data
public class ClanResult {
private final int id;
private final Integer id;
private final String tag;
private final String name;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

@Data
public class PlayerResult {
private final int id;
private final Integer id;
private final String login;

public static PlayerResult of(Player newMember) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
@Setter
@EqualsAndHashCode(of = "id")
public abstract class AbstractEntity {
protected int id;
protected Integer id;
protected OffsetDateTime createTime;
protected OffsetDateTime updateTime;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public int getId() {
public Integer getId() {
return id;
}

Expand Down
86 changes: 70 additions & 16 deletions src/main/java/com/faforever/api/user/MeController.java
Original file line number Diff line number Diff line change
@@ -1,37 +1,91 @@
package com.faforever.api.user;

import com.faforever.api.data.domain.Player;
import com.faforever.api.data.domain.UserGroup;
import com.faforever.api.player.PlayerService;
import com.faforever.api.security.FafUserDetails;
import com.faforever.api.web.JsonApiSingleResource;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.Builder;
import lombok.Value;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
* Provides the route {@code /me} which returns the currently logged in user's information.
*/
@RestController
public class MeController {
private final PlayerService playerService;

public MeController(PlayerService playerService) {
this.playerService = playerService;
}

@RequestMapping(method = RequestMethod.GET, value = "/me")
@ApiOperation(value = "Returns the authentication object of the current user")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success with JSON { id: ?, type: 'player'}"),
@ApiResponse(code = 400, message = "Bad Request")})
@Secured({"ROLE_USER"})
public void me(HttpServletRequest request,
HttpServletResponse response,
@AuthenticationPrincipal FafUserDetails authentication) throws IOException {
// TODO: Find a better way to call elide player route

response.sendRedirect(String.format("/data/player/%d?%s", authentication.getId(), Objects.toString(request.getQueryString(), "")));
@ApiOperation("Returns the authentication object of the current user")
@ApiResponse(code = 200, message = "Success with JsonApi compliant MeResult")
@Secured("ROLE_USER")
public JsonApiSingleResource<MeResult> me(@AuthenticationPrincipal FafUserDetails authentication) {

Player player = playerService.getById(authentication.getId());
Set<String> grantedAuthorities = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toSet());

Set<String> groups = player.getUserGroups().stream()
.map(UserGroup::getTechnicalName)
.collect(Collectors.toSet());

return MeResult.builder()
.userId(player.getId())
.userName(player.getLogin())
.email(player.getEmail())
.clan(player.getClan() == null ? null : Clan.builder()
.id(player.getClan().getId())
.tag(player.getClan().getTag())
.name(player.getClan().getName())
.build()
)
.groups(groups)
.permissions(grantedAuthorities)
.build()
.asJsonApi();
}

@Value
@Builder
public static class MeResult {
Integer userId;
String userName;
String email;
Clan clan;
Set<String> groups;
Set<String> permissions;

@SuppressWarnings("unchecked")
JsonApiSingleResource<MeResult> asJsonApi() {
return JsonApiSingleResource.ofProxy(
() -> "me",
() -> "me",
() -> this
);
}
}

@Value
@Builder
public static class Clan {
Integer id;
String tag;
String name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.faforever.api.web;

public interface JsonApiResourceObject {
String getType();

String getId();

Object getAttributes();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.faforever.api.web;

import java.util.function.Supplier;

class JsonApiResourceObjectProxy<T> implements JsonApiResourceObject {
private final Supplier<String> typeExtractor;
private final Supplier<String> idExtractor;
private final Supplier<T> attributesExtractor;

JsonApiResourceObjectProxy(Supplier<String> typeExtractor, Supplier<String> idExtractor, Supplier<T> attributesExtractor) {
this.typeExtractor = typeExtractor;
this.idExtractor = idExtractor;
this.attributesExtractor = attributesExtractor;
}

public String getType() {
return typeExtractor.get();
}

public String getId() {
return idExtractor.get();
}

public T getAttributes() {
return attributesExtractor.get();
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/faforever/api/web/JsonApiSingleResource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.faforever.api.web;

import lombok.Value;

import java.util.function.Supplier;

@Value
public class JsonApiSingleResource<T> {
JsonApiResourceObject data;

public static JsonApiSingleResource of(JsonApiResourceObject singleDataObject) {
return new JsonApiSingleResource(singleDataObject);
}

public static <T> JsonApiSingleResource ofProxy(Supplier<String> typeExtractor, Supplier<String> idExtractor,
Supplier<T> attributesExtractor) {
return new JsonApiSingleResource<T>(new JsonApiResourceObjectProxy<>(typeExtractor, idExtractor, attributesExtractor));
}
}

0 comments on commit f3684fc

Please sign in to comment.