diff --git a/pom.xml b/pom.xml
index 9e8f609..2405f8c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
xyz.aimcup
security-config
- 0.0.7-TEST
+ 0.1.0
17
17
@@ -16,6 +16,16 @@
spring-boot-starter-web
3.1.1
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+ 3.1.1
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ 3.1.1
+
org.springframework.boot
spring-boot-starter-security
@@ -63,6 +73,31 @@
+
+ maven-resources-plugin
+ 3.1.0
+
+
+ copy-resources
+ process-classes
+
+ copy-resources
+
+
+ ${project.basedir}/target/classes/static/
+
+
+ ${project.basedir}/src/main/resources/shared
+
+ **/*.*
+
+
+
+
+
+
+
+
org.springframework.boot
spring-boot-maven-plugin
@@ -87,35 +122,35 @@
-
- org.openapitools
- openapi-generator-maven-plugin
- 6.6.0
-
-
-
- generate
-
-
-
- ${project.basedir}/src/main/resources/shared/openapi/schema.yaml
-
- spring
- xyz.aimcup.generated
- xyz.aimcup.generated.model
- false
-
- true
- true
- true
- false
- true
- false
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/xyz/aimcup/security/configuration/LocalSecurityConfiguration.java b/src/main/java/xyz/aimcup/security/configuration/LocalSecurityConfiguration.java
new file mode 100644
index 0000000..e99ba98
--- /dev/null
+++ b/src/main/java/xyz/aimcup/security/configuration/LocalSecurityConfiguration.java
@@ -0,0 +1,48 @@
+package xyz.aimcup.security.configuration;
+
+import jakarta.annotation.PostConstruct;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+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.UsernamePasswordAuthenticationFilter;
+import xyz.aimcup.security.filter.LocalTokenAuthenticationFilter;
+
+@Configuration
+@EnableWebSecurity
+@EnableFeignClients(basePackages = "xyz.aimcup.security.feign")
+@RequiredArgsConstructor
+@ComponentScan(basePackages = "xyz.aimcup.security")
+@EnableMethodSecurity(
+ securedEnabled = true,
+ jsr250Enabled = true
+)
+@Slf4j
+public class LocalSecurityConfiguration {
+ private final LocalTokenAuthenticationFilter tokenAuthenticationFilter;
+
+ @Bean(name = "globalSecurityFilterChain")
+ SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
+ return httpSecurity
+ .cors(AbstractHttpConfigurer::disable)
+ .csrf(AbstractHttpConfigurer::disable)
+ .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
+ .httpBasic(AbstractHttpConfigurer::disable)
+ .formLogin(AbstractHttpConfigurer::disable)
+ .build();
+ }
+
+ @PostConstruct
+ public void postConstruct() {
+ log.info("SecurityConfiguration loaded. Securing with DEVELOPMENT settings.");
+ }
+}
diff --git a/src/main/java/xyz/aimcup/security/configuration/SecurityConfiguration.java b/src/main/java/xyz/aimcup/security/configuration/SecurityConfiguration.java
index ba261b8..47027e7 100644
--- a/src/main/java/xyz/aimcup/security/configuration/SecurityConfiguration.java
+++ b/src/main/java/xyz/aimcup/security/configuration/SecurityConfiguration.java
@@ -1,10 +1,13 @@
package xyz.aimcup.security.configuration;
+import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
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;
@@ -23,6 +26,8 @@
securedEnabled = true,
jsr250Enabled = true
)
+@Profile("!dev")
+@Slf4j
public class SecurityConfiguration {
private final TokenAuthenticationFilter tokenAuthenticationFilter;
@@ -37,4 +42,9 @@ SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Except
.formLogin(AbstractHttpConfigurer::disable)
.build();
}
+
+ @PostConstruct
+ public void postConstruct() {
+ log.info("SecurityConfiguration loaded. Securing with PRODUCTION settings.");
+ }
}
diff --git a/src/main/java/xyz/aimcup/security/domain/Role.java b/src/main/java/xyz/aimcup/security/domain/Role.java
new file mode 100644
index 0000000..a0e461e
--- /dev/null
+++ b/src/main/java/xyz/aimcup/security/domain/Role.java
@@ -0,0 +1,42 @@
+package xyz.aimcup.security.domain;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import java.util.UUID;
+import lombok.Getter;
+import lombok.Setter;
+import org.hibernate.annotations.NaturalId;
+import org.springframework.security.core.GrantedAuthority;
+
+
+@Entity
+@Getter
+@Setter
+public class Role implements GrantedAuthority {
+ @Id
+ @GeneratedValue(strategy = GenerationType.UUID)
+ private UUID id;
+
+ @Enumerated(EnumType.STRING)
+ @NaturalId
+ @Column(length = 60, name = "name")
+ private RoleName name;
+
+ public Role() {
+
+ }
+
+ public Role(RoleName name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getAuthority() {
+ return this.name.toString();
+ }
+}
diff --git a/src/main/java/xyz/aimcup/security/domain/RoleBase.java b/src/main/java/xyz/aimcup/security/domain/RoleBase.java
deleted file mode 100644
index 226adc4..0000000
--- a/src/main/java/xyz/aimcup/security/domain/RoleBase.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package xyz.aimcup.security.domain;
-
-import java.util.UUID;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.security.core.GrantedAuthority;
-
-
-@Getter
-@Setter
-public class RoleBase implements GrantedAuthority {
- private UUID id;
- private RoleName name;
-
- public RoleBase() {
-
- }
-
- public RoleBase(UUID id, RoleName name) {
- this.id = id;
- this.name = name;
- }
-
- @Override
- public String getAuthority() {
- return this.name.toString();
- }
-}
diff --git a/src/main/java/xyz/aimcup/security/domain/User.java b/src/main/java/xyz/aimcup/security/domain/User.java
new file mode 100644
index 0000000..8f8835c
--- /dev/null
+++ b/src/main/java/xyz/aimcup/security/domain/User.java
@@ -0,0 +1,41 @@
+package xyz.aimcup.security.domain;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.JoinTable;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.Table;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Entity
+@Table(name="\"user\"")
+@Getter
+@Setter
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class User {
+ @Id
+ @GeneratedValue(strategy = GenerationType.UUID)
+ private UUID id;
+ private String username;
+ private Long osuId;
+ private Boolean isRestricted;
+
+ @ManyToMany(fetch = FetchType.EAGER)
+ @JoinTable(name = "user_roles",
+ joinColumns = @JoinColumn(name = "user_id"),
+ inverseJoinColumns = @JoinColumn(name = "role_id"))
+ private Set roles = new HashSet<>();
+}
diff --git a/src/main/java/xyz/aimcup/security/domain/UserBase.java b/src/main/java/xyz/aimcup/security/domain/UserBase.java
deleted file mode 100644
index d1d5e72..0000000
--- a/src/main/java/xyz/aimcup/security/domain/UserBase.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package xyz.aimcup.security.domain;
-
-import java.util.UUID;
-import lombok.*;
-
-import java.util.HashSet;
-import java.util.Set;
-
-@Getter
-@Setter
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class UserBase {
- @Setter(AccessLevel.NONE)
- private UUID id;
- private String username;
- private Long osuId;
- private Boolean isRestricted;
- private Set roles = new HashSet<>();
-}
diff --git a/src/main/java/xyz/aimcup/security/dto/RoleResponseDto.java b/src/main/java/xyz/aimcup/security/dto/RoleResponseDto.java
new file mode 100644
index 0000000..f58f73d
--- /dev/null
+++ b/src/main/java/xyz/aimcup/security/dto/RoleResponseDto.java
@@ -0,0 +1,13 @@
+package xyz.aimcup.security.dto;
+
+import lombok.Data;
+
+import java.util.UUID;
+
+@Data
+public class RoleResponseDto {
+ private UUID id;
+
+ private String name;
+
+}
diff --git a/src/main/java/xyz/aimcup/security/dto/UserResponseDto.java b/src/main/java/xyz/aimcup/security/dto/UserResponseDto.java
new file mode 100644
index 0000000..f59c4d5
--- /dev/null
+++ b/src/main/java/xyz/aimcup/security/dto/UserResponseDto.java
@@ -0,0 +1,21 @@
+package xyz.aimcup.security.dto;
+
+import jakarta.validation.Valid;
+import lombok.Data;
+
+import java.util.List;
+import java.util.UUID;
+
+@Data
+public class UserResponseDto {
+ private UUID id;
+
+ private String username;
+
+ private Integer osuId;
+
+ private Boolean isRestricted;
+
+ @Valid
+ private List