дописала security
This commit is contained in:
+2
-2
@@ -49,8 +49,8 @@ dependencies {
|
||||
|
||||
implementation(libs.spring.grpc.starter)
|
||||
implementation(libs.grpc.services)
|
||||
// Temporarily disabled due to OAuth2 configuration issues
|
||||
// implementation(libs.spring.boot.starter.oauth2.client)
|
||||
|
||||
implementation(libs.spring.boot.starter.oauth2.client)
|
||||
|
||||
runtimeOnly(libs.micrometer.registry.prometheus)
|
||||
runtimeOnly(libs.h2)
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAu
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
|
||||
import org.springframework.boot.runApplication
|
||||
|
||||
@SpringBootApplication(exclude = [OAuth2ClientAutoConfiguration::class])
|
||||
@SpringBootApplication
|
||||
@ConfigurationPropertiesScan("com.project.movienight.config")
|
||||
class MovieNightApplication
|
||||
|
||||
|
||||
+25
-13
@@ -9,6 +9,7 @@ import com.project.movienight.domain.model.User
|
||||
import org.springframework.jdbc.core.JdbcTemplate
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.sql.ResultSet
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
|
||||
@Repository
|
||||
@@ -27,18 +28,32 @@ class UserRepository(
|
||||
}
|
||||
|
||||
override fun save(user: User): User {
|
||||
val entity = user.toEntity()
|
||||
val updatedRows =
|
||||
jdbc.update(
|
||||
val existingUser = findById(user.id)
|
||||
|
||||
val entity = if (existingUser != null) {
|
||||
val existingEntity = existingUser.toEntity()
|
||||
user.toEntity(
|
||||
provider = existingEntity.provider?.let { AuthProvider.valueOf(it) },
|
||||
providerId = existingEntity.providerId,
|
||||
createdAt = existingEntity.createdAt
|
||||
)
|
||||
} else {
|
||||
user.toEntity()
|
||||
}
|
||||
|
||||
val updatedRows = jdbc.update(
|
||||
"""
|
||||
UPDATE users
|
||||
SET name = ?, email = ?
|
||||
SET name = ?, email = ?, provider = ?, provider_id = ?
|
||||
WHERE id = ?
|
||||
""".trimIndent(),
|
||||
entity.name,
|
||||
entity.email,
|
||||
entity.provider,
|
||||
entity.providerId,
|
||||
entity.id,
|
||||
)
|
||||
|
||||
if (updatedRows == 0) {
|
||||
jdbc.update(
|
||||
"""
|
||||
@@ -57,8 +72,7 @@ class UserRepository(
|
||||
}
|
||||
|
||||
override fun findById(id: UUID): User? {
|
||||
val entities =
|
||||
jdbc.query(
|
||||
val entities = jdbc.query(
|
||||
"SELECT id, name, email, provider, provider_id, created_at FROM users WHERE id = ?",
|
||||
userEntityRowMapper,
|
||||
id,
|
||||
@@ -67,8 +81,7 @@ class UserRepository(
|
||||
}
|
||||
|
||||
override fun findByEmail(email: String): User? {
|
||||
val entities =
|
||||
jdbc.query(
|
||||
val entities = jdbc.query(
|
||||
"SELECT id, name, email, provider, provider_id, created_at FROM users WHERE email = ?",
|
||||
userEntityRowMapper,
|
||||
email,
|
||||
@@ -77,8 +90,7 @@ class UserRepository(
|
||||
}
|
||||
|
||||
override fun findAll(): List<User> =
|
||||
jdbc
|
||||
.query(
|
||||
jdbc.query(
|
||||
"SELECT id, name, email, provider, provider_id, created_at FROM users",
|
||||
userEntityRowMapper,
|
||||
).map { it.toDomain() }
|
||||
@@ -91,10 +103,10 @@ class UserRepository(
|
||||
provider: AuthProvider,
|
||||
providerId: String,
|
||||
): User? {
|
||||
val entities =
|
||||
jdbc.query(
|
||||
val entities = jdbc.query(
|
||||
"""
|
||||
SELECT id, name, email, provider, provider_id, created_at FROM users
|
||||
SELECT id, name, email, provider, provider_id, created_at
|
||||
FROM users
|
||||
WHERE provider = ? AND provider_id = ?
|
||||
""".trimIndent(),
|
||||
userEntityRowMapper,
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.project.movienight.adapters.security
|
||||
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||
import org.springframework.security.web.SecurityFilterChain
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
class SecurityConfiguration(
|
||||
private val customOAuth2UserService: CustomOAuth2UserService,
|
||||
) {
|
||||
@Bean
|
||||
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||
http
|
||||
.oauth2Login { oauth2 ->
|
||||
oauth2
|
||||
.userInfoEndpoint { userInfo ->
|
||||
userInfo.userService(customOAuth2UserService)
|
||||
}
|
||||
.defaultSuccessUrl("/api/users/me", true)
|
||||
}
|
||||
.authorizeHttpRequests { auth ->
|
||||
auth
|
||||
.requestMatchers("/", "/login/**", "/oauth2/**", "/h2-console/**", "/actuator/health").permitAll()
|
||||
.requestMatchers("/api/users/me").authenticated()
|
||||
.requestMatchers("/api/**").authenticated()
|
||||
.anyRequest().authenticated()
|
||||
}
|
||||
.headers { headers ->
|
||||
headers.frameOptions { frameOptions ->
|
||||
frameOptions.sameOrigin()
|
||||
}
|
||||
}
|
||||
.csrf { csrf ->
|
||||
csrf.disable()
|
||||
}
|
||||
|
||||
return http.build()
|
||||
}
|
||||
}
|
||||
@@ -10,15 +10,16 @@ import java.util.UUID
|
||||
class UserPrincipal(
|
||||
private val user: User,
|
||||
private val attributes: Map<String, Any>? = null,
|
||||
) : OAuth2User,
|
||||
UserDetails {
|
||||
) : OAuth2User, UserDetails {
|
||||
|
||||
fun getId(): UUID = user.id
|
||||
|
||||
override fun getName(): String = user.name
|
||||
|
||||
override fun getAttributes(): Map<String, Any> = attributes ?: emptyMap()
|
||||
|
||||
override fun getAuthorities(): Collection<GrantedAuthority> = listOf(SimpleGrantedAuthority("ROLE_USER"))
|
||||
override fun getAuthorities(): Collection<GrantedAuthority> =
|
||||
listOf(SimpleGrantedAuthority("ROLE_USER"))
|
||||
|
||||
override fun getPassword(): String = ""
|
||||
|
||||
@@ -33,9 +34,7 @@ class UserPrincipal(
|
||||
override fun isEnabled(): Boolean = true
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
user: User,
|
||||
attributes: Map<String, Any>? = null,
|
||||
): UserPrincipal = UserPrincipal(user, attributes)
|
||||
fun create(user: User, attributes: Map<String, Any>? = null): UserPrincipal =
|
||||
UserPrincipal(user, attributes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.ResponseStatus
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
//import com.project.movienight.adapters.security.UserPrincipal
|
||||
import java.util.UUID
|
||||
|
||||
@RestController
|
||||
@@ -73,4 +74,12 @@ class UserController(
|
||||
fun delete(
|
||||
@PathVariable id: UUID,
|
||||
) = deleteUserUseCase.delete(id)
|
||||
|
||||
/*
|
||||
@GetMapping("/me")
|
||||
fun getCurrentUser(principal: UserPrincipal): UserResponse =
|
||||
UserResponse.fromDomain(
|
||||
getUserByIdUseCase.getById(principal.getId())
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -25,6 +25,38 @@ spring:
|
||||
console:
|
||||
enabled: ${SPRING_H2_CONSOLE_ENABLED:true}
|
||||
path: /h2-console
|
||||
security:
|
||||
oauth2:
|
||||
client:
|
||||
registration:
|
||||
google:
|
||||
client-id: ${OAUTH2_GOOGLE_CLIENT_ID:test-client-id}
|
||||
client-secret: ${OAUTH2_GOOGLE_CLIENT_SECRET:test-secret}
|
||||
scope: email,profile
|
||||
yandex:
|
||||
client-id: ${OAUTH2_YANDEX_CLIENT_ID:test-client-id}
|
||||
client-secret: ${OAUTH2_YANDEX_CLIENT_SECRET:test-secret}
|
||||
authorization-grant-type: authorization_code
|
||||
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
|
||||
scope: login:email,login:avatar
|
||||
vk:
|
||||
client-id: ${OAUTH2_VK_CLIENT_ID:test-client-id}
|
||||
client-secret: ${OAUTH2_VK_CLIENT_SECRET:test-secret}
|
||||
authorization-grant-type: authorization_code
|
||||
client-authentication-method: client_secret_post
|
||||
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
|
||||
scope: email
|
||||
provider:
|
||||
yandex:
|
||||
authorization-uri: https://oauth.yandex.ru/authorize
|
||||
token-uri: https://oauth.yandex.ru/token
|
||||
user-info-uri: https://login.yandex.ru/info
|
||||
user-name-attribute: id
|
||||
vk:
|
||||
authorization-uri: https://oauth.vk.com/authorize
|
||||
token-uri: https://oauth.vk.com/access_token
|
||||
user-info-uri: https://api.vk.com/method/users.get?v=5.131&fields=photo_200
|
||||
user-name-attribute: response
|
||||
|
||||
server:
|
||||
shutdown: graceful
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_provider_provider_id
|
||||
ON users(provider, provider_id)
|
||||
WHERE provider IS NOT NULL AND provider_id IS NOT NULL;
|
||||
Reference in New Issue
Block a user