Public Access
Added dev impersonation and changed api a little bit
This commit is contained in:
1 parent
697fdcb208
commit
44783ea523
8 files changed
+104
-18
No files matched your search
@@ -0,0 +1,51 @@
|
||||
package core_service.configuration.security;
|
||||
|
||||
import core_service.shared.security.UserPrincipal;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Development-specific authentication filter that bypasses real JWT validation.
|
||||
* It automatically injects a default user principal for every request when the 'dev' profile is active.
|
||||
*/
|
||||
@Component("jwtAuthenticationFilter")
|
||||
@Profile("dev")
|
||||
@Slf4j
|
||||
public class DevJwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(
|
||||
@NonNull HttpServletRequest request,
|
||||
@NonNull HttpServletResponse response,
|
||||
@NonNull FilterChain filterChain
|
||||
) throws ServletException, IOException {
|
||||
|
||||
if (SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
// Default user principal for dev mode: Using the requested Steam ID 76561198005679788
|
||||
UserPrincipal principal = new UserPrincipal("1", "dev@example.com", 76561198005679788L);
|
||||
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
|
||||
principal,
|
||||
null,
|
||||
Collections.emptyList()
|
||||
);
|
||||
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authToken);
|
||||
log.trace("Dev mode: Injected default user principal with SteamID: {}", principal.steamId());
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
@@ -17,7 +18,8 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
@Component
|
||||
@Component("jwtAuthenticationFilter")
|
||||
@Profile("!dev")
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
@@ -4,10 +4,12 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Configuration
|
||||
@Profile("!dev")
|
||||
@ConfigurationProperties(prefix = "security.jwt")
|
||||
public class JwtConfig {
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@ package core_service.configuration.security;
|
||||
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Service
|
||||
@Profile("!dev")
|
||||
public class JwtService {
|
||||
|
||||
private final JwtConfig jwtConfig;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package core_service.configuration.security;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -14,13 +15,13 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@RequiredArgsConstructor
|
||||
public class SecurityConfig {
|
||||
|
||||
private static final String[] WHITE_LIST_URLS = {
|
||||
@@ -31,7 +32,11 @@ public class SecurityConfig {
|
||||
"/api/steam/test/**"
|
||||
};
|
||||
|
||||
private final JwtAuthenticationFilter jwtAuthFilter;
|
||||
private final OncePerRequestFilter jwtAuthFilter;
|
||||
|
||||
public SecurityConfig(@Qualifier("jwtAuthenticationFilter") OncePerRequestFilter jwtAuthFilter) {
|
||||
this.jwtAuthFilter = jwtAuthFilter;
|
||||
}
|
||||
|
||||
@Value("${app.cors.allowed-origins}")
|
||||
private String[] allowedOrigins;
|
||||
|
||||
+10
-4
@@ -1,18 +1,24 @@
|
||||
package core_service.modules.steam_adapter.api.dto.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.List;
|
||||
|
||||
public record SteamOwnedGamesResponse(OwnedGamesResponse response) {
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record SteamOwnedGamesResponse(
|
||||
@JsonProperty("response") OwnedGamesResponse response
|
||||
) {
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record OwnedGamesResponse(
|
||||
@JsonProperty("game_count") Integer gameCount,
|
||||
List<Game> games
|
||||
@JsonProperty("games") List<Game> games
|
||||
) {}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record Game(
|
||||
Integer appid,
|
||||
String name,
|
||||
@JsonProperty("appid") Integer appid,
|
||||
@JsonProperty("name") String name,
|
||||
@JsonProperty("playtime_forever") Integer playtimeForever,
|
||||
@JsonProperty("img_icon_url") String imgIconUrl,
|
||||
@JsonProperty("has_community_visible_stats") Boolean hasCommunityVisibleStats
|
||||
|
||||
@@ -14,9 +14,9 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class SteamApiService {
|
||||
|
||||
private final RestClient steamRestClient;
|
||||
@@ -26,24 +26,42 @@ public class SteamApiService {
|
||||
|
||||
@Cacheable(value = "steamGameCount", key = "#steamId")
|
||||
public int getOwnedGamesCount(String steamId) {
|
||||
if (apiKey == null || apiKey.isEmpty() || apiKey.equals("${STEAM_API_KEY}")) {
|
||||
log.error("Steam API Key is not configured correctly!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
log.info("Fetching owned games count for SteamID: {}", steamId);
|
||||
log.info("Fetching owned games count for SteamID: {} using API Key starting with: {}",
|
||||
steamId, apiKey.substring(0, Math.min(apiKey.length(), 4)));
|
||||
|
||||
SteamOwnedGamesResponse response = steamRestClient.get()
|
||||
.uri(uriBuilder -> uriBuilder
|
||||
.path("/IPlayerService/GetOwnedGames/v0001/")
|
||||
.path("/IPlayerService/GetOwnedGames/v1/")
|
||||
.queryParam("key", apiKey)
|
||||
.queryParam("steamid", steamId)
|
||||
.queryParam("include_appinfo", 0)
|
||||
.queryParam("include_played_free_games", 1)
|
||||
.queryParam("include_appinfo", "true")
|
||||
.queryParam("include_played_free_games", "true")
|
||||
.queryParam("format", "json")
|
||||
.build())
|
||||
.retrieve()
|
||||
.body(SteamOwnedGamesResponse.class);
|
||||
|
||||
log.info("SteamOwnedGamesResponse: {}", response);
|
||||
log.info("Steam API Response object for {}: {}", steamId, response);
|
||||
|
||||
if (response != null && response.response() != null) {
|
||||
return response.response().gameCount() != null ? response.response().gameCount() : 0;
|
||||
Integer count = response.response().gameCount();
|
||||
if (count == null) {
|
||||
if (response.response().games() != null) {
|
||||
int size = response.response().games().size();
|
||||
log.info("game_count was null, but games list has {} entries for SteamID: {}", size, steamId);
|
||||
return size;
|
||||
}
|
||||
log.warn("Steam API returned an empty response object for SteamID: {}. Check if the ID is correct and 'Game details' are Public.", steamId);
|
||||
return 0;
|
||||
}
|
||||
log.info("Successfully fetched {} games for SteamID: {}", count, steamId);
|
||||
return count;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
Reference in new issue
Block a user