Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
5f7c911
(feature) Adds new dependency and initial SecurityConfig file
efpcode Apr 9, 2025
9a803fb
removes env + fixes things
efpcode Apr 14, 2025
ea3d752
Adds import env + debug
efpcode Apr 14, 2025
d94aa78
Adds removes env again
efpcode Apr 14, 2025
51b5a84
(feature) Adds dev-properties for google oauth2
efpcode Apr 14, 2025
35ec3ee
(fix) removes formlogin from SecurityConfigFile
efpcode Apr 14, 2025
35c4ca2
(feature) fixes endpoints authfiltering
efpcode Apr 14, 2025
036eb0c
(feature) adds new OidcClass for mapping user-metadata
efpcode Apr 15, 2025
5e12d76
(todo) Adds placeholder code for apikey filtering and validation
efpcode Apr 15, 2025
7f38b60
Merge branch 'main' into 23-create-security-config-file
efpcode Apr 15, 2025
2068722
(fixes) .env imports with optional now
efpcode Apr 15, 2025
f559892
(fixes) faulty endpoint
efpcode Apr 15, 2025
00ad31d
!(fix) test alterations to pass Securityfilteration and other minor f…
efpcode Apr 15, 2025
ac9cd7f
Merge branch 'main' into 23-create-security-config-file
efpcode Apr 16, 2025
c02518e
Merge branch 'main' into 23-create-security-config-file
efpcode Apr 16, 2025
83b6c9c
!(feature) new entites for handling Apikeys
efpcode Apr 17, 2025
73c243d
(fix) adds serializable to new entites
efpcode Apr 17, 2025
22a64cb
!(feature) Adds migration for new db entites
efpcode Apr 17, 2025
fa77ec5
!(fixes) joins between tables and seeder data generation in Configfile
efpcode Apr 17, 2025
05b17b5
!(feature) adds new fields to account entity and fixes logout
efpcode Apr 17, 2025
a6ee85c
Adds first part of user registration
efpcode Apr 17, 2025
7b7bd06
Adds new find method to account + display of current user
efpcode Apr 17, 2025
8fd974a
(fix) Adds proper logout + foundation for apikey generation
efpcode Apr 18, 2025
c54730e
fix foundation for api key and logout
efpcode Apr 18, 2025
b581bc0
Adds static page for apikey generation + static page for revoke
efpcode Apr 20, 2025
71a3d69
Adds revoke buttons adds new column for reference id to apikey table
efpcode Apr 20, 2025
b49385e
Adds apikey validation for rest-api responses
efpcode Apr 21, 2025
ee65d20
refactors a bit in the webcontroller
efpcode Apr 21, 2025
902f001
Added ApiKeyControllerTest class
SeydaKinaci Apr 21, 2025
0a14e62
Revert "Added ApiKeyControllerTest class"
SeydaKinaci Apr 21, 2025
1e5d67b
Revert "Added ApiKeyControllerTest class"
SeydaKinaci Apr 21, 2025
0072996
Revert "Added ApiKeyControllerTest class"
SeydaKinaci Apr 21, 2025
75dde55
Correct signed version of previous commit
SeydaKinaci Apr 21, 2025
4a21fd9
adds premium role
efpcode Apr 21, 2025
2eced2a
Adds translation
efpcode Apr 21, 2025
79f874a
(fix) minor bug wiht profile loading
efpcode Apr 21, 2025
573ca4e
minor fix
efpcode Apr 21, 2025
6ef9dcf
removes spaces
efpcode Apr 21, 2025
b6ffe92
(fix) WebConctrollerTest passisng after Security changes
efpcode Apr 21, 2025
28fc5a9
(fix) after roast from ai
efpcode Apr 22, 2025
21e22b4
fix minor and inconvience
efpcode Apr 22, 2025
0ba8001
(Fixes) all testing working with all html enpoints working
efpcode Apr 22, 2025
20f9454
!(fix) adds essential envs var to application profile
efpcode Apr 23, 2025
3e8b927
(fix) Secret in constructor
efpcode Apr 23, 2025
a2661ba
Adds new dependencies to failing test
efpcode Apr 23, 2025
e081e18
(fix) removes bean ApiKeyAuthenticationFilter from SecurityConfiguration
efpcode Apr 23, 2025
95f5b37
Adds env vars to ci.yaml
efpcode Apr 23, 2025
5c0ff5a
Adds depency to webcontrolltest
efpcode Apr 23, 2025
f39b682
(fix) Circular dependency between account issuedapikey service + all …
efpcode Apr 23, 2025
46f51bb
Adds a bit of safety add all test are passing
efpcode Apr 23, 2025
54368e1
Adds new injection to apikeycontroll test
efpcode Apr 23, 2025
448f45d
Adds version log to ci workflow
efpcode Apr 23, 2025
77d8972
(fix) Adds logs to ci version
efpcode Apr 23, 2025
3f8bd11
Adds set env vars as the first layer
efpcode Apr 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ on:
jobs:
builds:
runs-on: ubuntu-latest
env:
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
SECRET_KEY: ${{ secrets.SECRET_KEY }}
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}

steps:
- name: Checkout
Expand All @@ -21,6 +26,14 @@ jobs:
java-version: 24
cache: 'maven'

- name: Check Maven version
run: mvn --version

- name: Check Java version
run: java -version



- name: Compile with Maven
run: mvn -B --no-transfer-progress compile --file pom.xml

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ build/

### VS Code ###
.vscode/
.env
.env
17 changes: 17 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.ai.mistralai.MistralAiChatModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

Expand All @@ -24,6 +25,7 @@ public MistralAiController(MistralAiChatModel chatModel) {
this.chatModel = chatModel;
}

@PreAuthorize("hasRole('PREMIUM')")
@GetMapping("/ai/generate")
public ResponseEntity<Map<String, String>> generate() {
try {
Expand All @@ -35,4 +37,4 @@ public ResponseEntity<Map<String, String>> generate() {
return ResponseEntity.internalServerError().body(Map.of(genKey, "Sorry, I couldn't generate a response. Please try again later."));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package org.storkforge.barkr.api.controller;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.storkforge.barkr.domain.IssuedApiKeyService;
import org.storkforge.barkr.dto.apiKeyDto.GenerateApiKeyRequest;
import org.storkforge.barkr.dto.apiKeyDto.ResponseApiKeyOnce;
import org.storkforge.barkr.dto.apiKeyDto.UpdateApiKey;
import org.storkforge.barkr.mapper.ApiKeyMapper;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.UUID;


@Controller
@RequestMapping("/apikeys")
public class ApiKeyController {
private final IssuedApiKeyService issuedApiKeyService;

public ApiKeyController(IssuedApiKeyService issuedApiKeyService) {
this.issuedApiKeyService = issuedApiKeyService;
}

@GetMapping("/apikeyform")
@PreAuthorize("hasRole('USER')")
public String showApiKeyForm(Model model) {
String now = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"));
model.addAttribute("now", now);
return "apikeys";
}


@GetMapping("/result")
@PreAuthorize("hasRole('USER')")
public String showGeneratedApiKey(@ModelAttribute("response") ResponseApiKeyOnce response, Model model) {
if (response == null || response.value() == null) {
return "redirect:/apikeys/apikeyform";
}

model.addAttribute("response", response);
return "apikeys/result";
}


@PostMapping("/generate")
@PreAuthorize("hasRole('USER')")
public String generateApiKey(
@RequestParam String apiKeyName,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME
) LocalDateTime expiresAt,
RedirectAttributes redirectAttributes
) throws NoSuchAlgorithmException, InvalidKeyException {
GenerateApiKeyRequest inputRequest = new GenerateApiKeyRequest(apiKeyName, expiresAt);
GenerateApiKeyRequest request = ApiKeyMapper.normalizeExpiresAt(inputRequest);

String apiKey;
String hashedApiKey;

do{
apiKey = issuedApiKeyService.generateRawApiKey();
hashedApiKey = issuedApiKeyService.hashedApiKey(apiKey);
} while (issuedApiKeyService.apiKeyExists(hashedApiKey));
issuedApiKeyService.apiKeyGenerate(request, hashedApiKey);

ResponseApiKeyOnce response = new ResponseApiKeyOnce(
"API-KEY", apiKey, "Please store these credentials safely");

redirectAttributes.addFlashAttribute("response", response);

return "redirect:/apikeys/result";


}

@GetMapping("/mykeys")
public String myKeys(Model model , @AuthenticationPrincipal OidcUser user) {
var currentUser = issuedApiKeyService.findByGoogleOidc2Id(user.getName());
var keys = issuedApiKeyService.allApiKeys(user.getName());
model.addAttribute("account", currentUser.get().getAccount());
model.addAttribute("keys", keys.apiKeys());
Comment on lines +89 to +91

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add null check for user and optional handling

The current implementation doesn't handle the case where the user might not be found. Add proper null checks and Optional handling.

    @GetMapping("/mykeys")
    public String myKeys(Model model , @AuthenticationPrincipal OidcUser user) {
-       var currentUser = issuedApiKeyService.findByGoogleOidc2Id(user.getName());
-       var keys = issuedApiKeyService.allApiKeys(user.getName());
-       model.addAttribute("account", currentUser.get().getAccount());
+       var currentUser = issuedApiKeyService.findByGoogleOidc2Id(user.getName());
+       if (currentUser.isEmpty()) {
+           return "redirect:/error";
+       }
+       var keys = issuedApiKeyService.allApiKeys(user.getName());
+       model.addAttribute("account", currentUser.get().getAccount());
        model.addAttribute("keys", keys.apiKeys());
        return "apikeys/mykeys";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var keys = issuedApiKeyService.allApiKeys(user.getName());
model.addAttribute("account", currentUser.get().getAccount());
model.addAttribute("keys", keys.apiKeys());
@GetMapping("/mykeys")
public String myKeys(Model model, @AuthenticationPrincipal OidcUser user) {
var currentUser = issuedApiKeyService.findByGoogleOidc2Id(user.getName());
if (currentUser.isEmpty()) {
return "redirect:/error";
}
var keys = issuedApiKeyService.allApiKeys(user.getName());
model.addAttribute("account", currentUser.get().getAccount());
model.addAttribute("keys", keys.apiKeys());
return "apikeys/mykeys";
}

return "apikeys/mykeys";

}
Comment on lines +86 to +94

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add @PreAuthorize annotation for consistency

The myKeys method is missing the @PreAuthorize("hasRole('USER')") annotation that's present on other endpoints. Add it for consistency and to ensure proper role-based access control.

    @GetMapping("/mykeys")
+   @PreAuthorize("hasRole('USER')")
    public String myKeys(Model model , @AuthenticationPrincipal OidcUser user) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@GetMapping("/mykeys")
public String myKeys(Model model , @AuthenticationPrincipal OidcUser user) {
var currentUser = issuedApiKeyService.findByGoogleOidc2Id(user.getName());
var keys = issuedApiKeyService.allApiKeys(user.getName());
model.addAttribute("account", currentUser.get().getAccount());
model.addAttribute("keys", keys.apiKeys());
return "apikeys/mykeys";
}
@GetMapping("/mykeys")
@PreAuthorize("hasRole('USER')")
public String myKeys(Model model, @AuthenticationPrincipal OidcUser user) {
var currentUser = issuedApiKeyService.findByGoogleOidc2Id(user.getName());
var keys = issuedApiKeyService.allApiKeys(user.getName());
model.addAttribute("account", currentUser.get().getAccount());
model.addAttribute("keys", keys.apiKeys());
return "apikeys/mykeys";
}


@PostMapping("/mykeys/revoke")
public String revokeKey(@RequestParam String referenceId, @AuthenticationPrincipal OidcUser user) {
if (issuedApiKeyService.isValidUuid(UUID.fromString(referenceId), user.getName())) {
var update = new UpdateApiKey(UUID.fromString(referenceId),null, true, null);
issuedApiKeyService.updateApiKey(update);
}
Comment on lines +98 to +101

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for UUID validation and provide user feedback

The method silently fails if the UUID is invalid. Consider adding proper error handling and redirecting with an error message if validation fails.

    @PostMapping("/mykeys/revoke")
    public String revokeKey(@RequestParam String referenceId, @AuthenticationPrincipal OidcUser user, RedirectAttributes redirectAttributes) {
-       if (issuedApiKeyService.isValidUuid(UUID.fromString(referenceId), user.getName())) {
-       var update = new UpdateApiKey(UUID.fromString(referenceId),null, true, null);
-       issuedApiKeyService.updateApiKey(update);
-       }
+       try {
+           UUID uuid = UUID.fromString(referenceId);
+           if (issuedApiKeyService.isValidUuid(uuid, user.getName())) {
+               var update = new UpdateApiKey(uuid, null, true, null);
+               issuedApiKeyService.updateApiKey(update);
+               redirectAttributes.addFlashAttribute("success", "API key successfully revoked");
+           } else {
+               redirectAttributes.addFlashAttribute("error", "You don't have permission to revoke this API key");
+           }
+       } catch (IllegalArgumentException e) {
+           redirectAttributes.addFlashAttribute("error", "Invalid API key reference");
+       }
        return "redirect:/apikeys/mykeys";
    }

return "redirect:/apikeys/mykeys";
}

@PostMapping("mykeys/nameupdate")
public String nameUpdate(@RequestParam String apiKeyName, @RequestParam String referenceId, @AuthenticationPrincipal OidcUser user) {
if(issuedApiKeyService.isValidUuid(UUID.fromString(referenceId), user.getName())) {
var update = new UpdateApiKey(UUID.fromString(referenceId), apiKeyName, false, null);
issuedApiKeyService.updateApiKey(update);
}
return "redirect:/apikeys/mykeys";
Comment on lines +106 to +111

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for nameUpdate method

Similar to the revokeKey method, this method needs proper error handling for UUID validation and user feedback.

    @PostMapping("mykeys/nameupdate")
-   public String nameUpdate(@RequestParam String apiKeyName, @RequestParam String referenceId, @AuthenticationPrincipal OidcUser user) {
-       if(issuedApiKeyService.isValidUuid(UUID.fromString(referenceId), user.getName())) {
-       var update = new UpdateApiKey(UUID.fromString(referenceId), apiKeyName, false, null);
-       issuedApiKeyService.updateApiKey(update);
-       }
+   public String nameUpdate(@RequestParam String apiKeyName, @RequestParam String referenceId, 
+                            @AuthenticationPrincipal OidcUser user, RedirectAttributes redirectAttributes) {
+       try {
+           UUID uuid = UUID.fromString(referenceId);
+           if (issuedApiKeyService.isValidUuid(uuid, user.getName())) {
+               var update = new UpdateApiKey(uuid, apiKeyName, false, null);
+               issuedApiKeyService.updateApiKey(update);
+               redirectAttributes.addFlashAttribute("success", "API key name updated successfully");
+           } else {
+               redirectAttributes.addFlashAttribute("error", "You don't have permission to update this API key");
+           }
+       } catch (IllegalArgumentException e) {
+           redirectAttributes.addFlashAttribute("error", "Invalid API key reference");
+       }
        return "redirect:/apikeys/mykeys";
    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public String nameUpdate(@RequestParam String apiKeyName, @RequestParam String referenceId, @AuthenticationPrincipal OidcUser user) {
if(issuedApiKeyService.isValidUuid(UUID.fromString(referenceId), user.getName())) {
var update = new UpdateApiKey(UUID.fromString(referenceId), apiKeyName, false, null);
issuedApiKeyService.updateApiKey(update);
}
return "redirect:/apikeys/mykeys";
@PostMapping("mykeys/nameupdate")
public String nameUpdate(@RequestParam String apiKeyName,
@RequestParam String referenceId,
@AuthenticationPrincipal OidcUser user,
RedirectAttributes redirectAttributes) {
try {
UUID uuid = UUID.fromString(referenceId);
if (issuedApiKeyService.isValidUuid(uuid, user.getName())) {
var update = new UpdateApiKey(uuid, apiKeyName, false, null);
issuedApiKeyService.updateApiKey(update);
redirectAttributes.addFlashAttribute("success", "API key name updated successfully");
} else {
redirectAttributes.addFlashAttribute("error", "You don't have permission to update this API key");
}
} catch (IllegalArgumentException e) {
redirectAttributes.addFlashAttribute("error", "Invalid API key reference");
}
return "redirect:/apikeys/mykeys";
}

}

}
23 changes: 23 additions & 0 deletions src/main/java/org/storkforge/barkr/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.EnableCaching;
import org.storkforge.barkr.domain.entity.GoogleAccountApiKeyLink;
import org.storkforge.barkr.domain.entity.Post;
import org.springframework.boot.CommandLineRunner;
import org.storkforge.barkr.domain.entity.Account;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import org.storkforge.barkr.domain.roles.BarkrRole;
import org.storkforge.barkr.infrastructure.persistence.PostRepository;
import org.storkforge.barkr.infrastructure.persistence.AccountRepository;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Configuration
@Profile("!test")
Expand All @@ -31,17 +35,36 @@ CommandLineRunner accountInit(AccountRepository accountRepository, PostRepositor
Account accountOne = new Account();
accountOne.setUsername("Bella Pawkins");
accountOne.setBreed("Golden Retriever");
accountOne.setGoogleOidc2Id("1");
accountOne.setImage(null);
accountOne.setRoles(new HashSet<>(Set.of(BarkrRole.USER)));

Account accountTwo = new Account();
accountTwo.setUsername("Charlie Barkson");
accountTwo.setBreed("Siberian Husky");
accountTwo.setGoogleOidc2Id("2");
accountTwo.setImage(null);
accountTwo.setRoles(new HashSet<>(Set.of(BarkrRole.USER)));

Account accountThree = new Account();
accountThree.setUsername("Max Woofington");
accountThree.setBreed("German Shepherd");
accountThree.setGoogleOidc2Id("3");
accountThree.setImage(null);
accountThree.setRoles(new HashSet<>(Set.of(BarkrRole.USER)));

GoogleAccountApiKeyLink link1 = new GoogleAccountApiKeyLink();
link1.setAccount(accountOne);
accountOne.setGoogleAccountApiKeyLink(link1);

GoogleAccountApiKeyLink link2 = new GoogleAccountApiKeyLink();
link2.setAccount(accountTwo);
accountTwo.setGoogleAccountApiKeyLink(link2);

GoogleAccountApiKeyLink link3 = new GoogleAccountApiKeyLink();
link3.setAccount(accountThree);
accountThree.setGoogleAccountApiKeyLink(link3);


accountRepository.saveAll(List.of(accountOne, accountTwo, accountThree));

Expand Down
94 changes: 94 additions & 0 deletions src/main/java/org/storkforge/barkr/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.storkforge.barkr.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.storkforge.barkr.domain.IssuedApiKeyService;
import org.storkforge.barkr.domain.roles.BarkrRole;
import org.storkforge.barkr.filters.ApiKeyAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

@Bean
@Order(3)
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
http
.oauth2Login(Customizer.withDefaults())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/","/login", "/error", "/css/**", "/js/**", "/images/**").permitAll()
.requestMatchers("/post/load").permitAll()
.requestMatchers( "/account/{id}/image").permitAll()
.requestMatchers("/ai/generate").hasRole(BarkrRole.PREMIUM.name())
.requestMatchers("/post/add").authenticated()
.requestMatchers("/account/{id}/upload").authenticated()
.requestMatchers("/{username}").authenticated()
.requestMatchers("/apikeys/generate").authenticated()
.requestMatchers("/apikeys/apikeyform").authenticated()
.requestMatchers("/apikeys/result").authenticated()
.requestMatchers("/apikeys/mykeys").authenticated()
.requestMatchers("/apikeys/mykeys/revoke").authenticated()
.requestMatchers("/apikeys/mykeys/nameupdate").authenticated()
.requestMatchers("/unlock-easter-egg").authenticated()

.anyRequest().denyAll()

)
.logout(logout -> logout
.logoutUrl("/logout")
.invalidateHttpSession(true)
.clearAuthentication(true)
.deleteCookies("JSESSIONID")
.logoutSuccessUrl("/barkr/logout")
.permitAll()

).csrf(csrf -> csrf
.ignoringRequestMatchers("/logout", "/ai/generate")
);

return http.build();
}


@Bean
@Order(2)
public SecurityFilterChain restAPIAndGraphQLFilterChain(
HttpSecurity http,
IssuedApiKeyService issuedApiKeyService) throws Exception {
http.securityMatcher("/api/**", "/graphql")
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.csrf(AbstractHttpConfigurer::disable)
.addFilterAfter(new ApiKeyAuthenticationFilter(issuedApiKeyService), LogoutFilter.class)
.authorizeHttpRequests(
authorize -> authorize
.requestMatchers("/api/accounts").authenticated()
.requestMatchers("/api/posts").authenticated()
.requestMatchers("/api/accounts/{id}").authenticated()
.requestMatchers("/api/posts/{id}").authenticated()
.requestMatchers("/api/keys").authenticated()
.requestMatchers(HttpMethod.POST, "/graphql").authenticated()
.anyRequest().denyAll()

);
return http.build();

}







}
10 changes: 10 additions & 0 deletions src/main/java/org/storkforge/barkr/domain/AccountService.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public AccountService(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}

public Optional<Account> findByGoogleOidc2Id(String googleOidc2Id) {
return accountRepository.findByGoogleOidc2Id(googleOidc2Id);
}

@Cacheable("allAccounts")
public Page<ResponseAccount> findAll(Pageable pageable) {
log.info("Finding all accounts");
Expand Down Expand Up @@ -85,4 +89,10 @@ public void updateImage(Long id, byte[] image) {

accountRepository.save(account);
}






}
Loading