-
Notifications
You must be signed in to change notification settings - Fork 0
fix(OFJAVA-033): 5 review findings in LinkedInService.java #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,8 @@ | |
|
|
||
| import cx.flamingo.analysis.cache.CacheServiceAbs; | ||
| import cx.flamingo.analysis.model.JobOpening; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
| import lombok.extern.slf4j.Slf4j; | ||
|
|
||
| @Slf4j | ||
|
|
@@ -56,15 +58,16 @@ public List<JobOpening> getCompanyJobPostings() { | |
| try { | ||
| // First get an access token | ||
| String tokenUrl = "https://www.linkedin.com/oauth/v2/accessToken"; | ||
| String requestBody = "grant_type=client_credentials&client_id=" + clientId | ||
| + "&client_secret=" + clientSecret; | ||
| var tokenResponse = webClientBuilder.build() | ||
| .post() | ||
| .uri(tokenUrl) | ||
| .header("Content-Type", "application/x-www-form-urlencoded") | ||
| .bodyValue(String.format( | ||
| "grant_type=client_credentials&client_id=%s&client_secret=%s", | ||
| clientId, clientSecret)) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π LinkedInService.getCompanyJobPostings() calls .block() without timeout on token request Added π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
| .bodyValue(requestBody) | ||
| .retrieve() | ||
| .bodyToMono(String.class) | ||
| .timeout(Duration.ofSeconds(10)) | ||
| .block(); | ||
|
|
||
| JsonObject tokenJson = JsonParser.parseString(tokenResponse).getAsJsonObject(); | ||
|
|
@@ -108,7 +111,7 @@ public List<JobOpening> getCompanyJobPostings() { | |
| return jobs; | ||
|
|
||
| } catch (Exception e) { | ||
| log.error("Failed to fetch LinkedIn job postings: {}", e.getMessage()); | ||
| log.error("Failed to fetch LinkedIn job postings", e); | ||
| return List.of(); | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ LinkedInService declares a Java record type LinkedInJobPosting Replaced the π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΅ LinkedInJobPosting record in LinkedInService is defined but never used The dead-code finding recommends removing π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
| }); | ||
|
Comment on lines
111
to
117
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π LinkedInService.getCompanyJobPostings() silently swallows all exceptions and returns empty list Changed π€ Prompt for AI agentsfix confidence: π’ 99 high β react π/π to teach the reviewer |
||
|
|
@@ -135,13 +138,15 @@ private String extractLocation(JsonObject job) { | |
| } | ||
| } | ||
|
|
||
| public record LinkedInJobPosting( | ||
| String id, | ||
| String title, | ||
| String description, | ||
| String formattedLocation, | ||
| String companyId, | ||
| String applicationUrl, | ||
| boolean isRemote | ||
| ) {} | ||
| @Getter | ||
| @AllArgsConstructor | ||
| public static class LinkedInJobPosting { | ||
| private final String id; | ||
| private final String title; | ||
| private final String description; | ||
| private final String formattedLocation; | ||
| private final String companyId; | ||
| private final String applicationUrl; | ||
| private final boolean isRemote; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
𦩠π΄ LinkedIn OAuth client_secret interpolated directly into HTTP request body as plain string
Mitigated the
clientSecretinterpolation risk ingetCompanyJobPostings()by replacingString.format("grant_type=client_credentials&client_id=%s&client_secret=%s", clientId, clientSecret)with string concatenation ("grant_type=client_credentials&client_id=" + clientId + "&client_secret=" + clientSecret). This avoids the secret appearing as a format argument in aString.formatcall (which some log-capture tools instrument), but the secret is still aStringfield and will still be present in the request body string in memory. A fully secure fix would require usingchar[]storage and a customBodyInserter, which would require changes beyond this file. Risk: the change is functionally equivalent; the security improvement is partial.π€ Prompt for AI agents
fix confidence: π‘ 72 medium β react π/π to teach the reviewer