Исправлена V1 миграция - добавлена запятая после email

Реализован saveWithOAuth2() в UserRepository
Реализован findByProviderAndProviderId() в UserRepository
Обновлен CustomOAuth2UserService для использования OAuth2 методов
Исправил package declaration во всех 7 OAuth2 файлах
This commit is contained in:
skettiks
2026-04-23 18:47:30 +03:00
parent 689ee91d1f
commit d50e2e640c
10 changed files with 84 additions and 24 deletions
@@ -26,22 +26,24 @@ class UserRepository(
jdbc.update( jdbc.update(
""" """
UPDATE users UPDATE users
SET name = ?, email = ? SET name = ?, email = ?, password = ?
WHERE id = ? WHERE id = ?
""".trimIndent(), """.trimIndent(),
user.name, user.name,
user.email, user.email,
user.password,
user.id, user.id,
) )
if (updatedRows == 0) { if (updatedRows == 0) {
jdbc.update( jdbc.update(
""" """
INSERT INTO users (id, name, email) INSERT INTO users (id, name, email, password)
VALUES (?, ?, ?) VALUES (?, ?, ?, ?)
""".trimIndent(), """.trimIndent(),
user.id, user.id,
user.name, user.name,
user.email, user.email,
user.password,
) )
} }
return user return user
@@ -50,7 +52,7 @@ class UserRepository(
override fun findById(id: UUID): User? { override fun findById(id: UUID): User? {
val users = val users =
jdbc.query( jdbc.query(
"SELECT id, name, email FROM users WHERE id = ?", "SELECT id, name, email, password FROM users WHERE id = ?",
userRowMapper, userRowMapper,
id, id,
) )
@@ -68,11 +70,51 @@ class UserRepository(
override fun findAll(): List<User> = override fun findAll(): List<User> =
jdbc.query( jdbc.query(
"SELECT id, name, email FROM users", "SELECT id, name, email, password FROM users",
userRowMapper, userRowMapper,
) )
override fun deleteById(id: UUID) { override fun deleteById(id: UUID) {
jdbc.update("DELETE FROM users WHERE id = ?", id) jdbc.update("DELETE FROM users WHERE id = ?", id)
} }
override fun saveWithOAuth2(user: User, provider: String, providerId: String): User {
val updatedRows = jdbc.update("""
UPDATE users
SET name = ?, email = ?, password = ?, provider = ?, provider_id = ?
WHERE id = ?
""".trimIndent(),
user.name,
user.email,
user.password,
provider,
providerId,
user.id,
)
if (updatedRows == 0) {
jdbc.update(
"""
INSERT INTO users (id, name, email, password, provider, provider_id)
VALUES (?, ?, ?, ?, ?, ?)
""".trimIndent(),
user.id,
user.name,
user.email,
user.password,
provider,
providerId,
)
}
return user
}
override fun findByProviderAndProviderId(provider: String, providerId: String): User? {
val users = jdbc.query(
"SELECT id, name, email, password FROM users WHERE provider = ? AND provider_id = ?",
userRowMapper,
provider,
providerId,
)
return users.firstOrNull()
}
} }
@@ -1,4 +1,4 @@
package com.project.movienight.adapters.security.oauth2 package com.project.movienight.adapters.security
import com.project.movienight.application.ports.output.IdGenerator import com.project.movienight.application.ports.output.IdGenerator
import com.project.movienight.application.ports.output.UserRepositoryPort import com.project.movienight.application.ports.output.UserRepositoryPort
@@ -37,21 +37,34 @@ class CustomOAuth2UserService(
} }
private fun findOrCreateUser(userInfo: OAuth2UserInfo): User { private fun findOrCreateUser(userInfo: OAuth2UserInfo): User {
val existingUser = userRepository.findByEmail(userInfo.getEmail()) // Сначала ищем по provider + provider_id (основной способ для OAuth2)
val existingUser = userRepository.findByProviderAndProviderId(
userInfo.getProvider(),
userInfo.getProviderId()
)
return if (existingUser != null) { return if (existingUser != null) {
log.debug("User found by email: {}", userInfo.getEmail()) log.debug("User found by provider: {}", userInfo.getProvider())
existingUser existingUser
} else { } else {
log.debug("Creating new user for provider: {}", userInfo.getProvider()) // Проверяем нет ли пользователя с таким email (связывание аккаунтов)
val newUser = User( val userByEmail = userRepository.findByEmail(userInfo.getEmail())
id = idGenerator.generateId(),
name = userInfo.getName(), if (userByEmail != null) {
email = userInfo.getEmail(), // Пользователь существует, обновляем его OAuth2 данными
password = "", // OAuth2 пользователи не имеют пароля log.debug("Linking OAuth2 account to existing user: {}", userInfo.getEmail())
library = null, userRepository.saveWithOAuth2(userByEmail, userInfo.getProvider(), userInfo.getProviderId())
) } else {
userRepository.save(newUser) log.debug("Creating new user for provider: {}", userInfo.getProvider())
val newUser = User(
id = idGenerator.generateId(),
name = userInfo.getName(),
email = userInfo.getEmail(),
password = "",
library = null,
)
userRepository.saveWithOAuth2(newUser, userInfo.getProvider(), userInfo.getProviderId())
}
} }
} }
} }
@@ -1,4 +1,4 @@
package com.project.movienight.adapters.security.oauth2 package com.project.movienight.adapters.security
class GoogleOAuth2UserInfo( class GoogleOAuth2UserInfo(
private val attributes: Map<String, Any> private val attributes: Map<String, Any>
@@ -1,4 +1,4 @@
package com.project.movienight.adapters.security.oauth2 package com.project.movienight.adapters.security
interface OAuth2UserInfo { interface OAuth2UserInfo {
fun getProviderId(): String fun getProviderId(): String
@@ -1,4 +1,4 @@
package com.project.movienight.adapters.security.oauth2 package com.project.movienight.adapters.security
import org.springframework.security.oauth2.core.OAuth2AuthenticationException import org.springframework.security.oauth2.core.OAuth2AuthenticationException
import org.springframework.security.oauth2.core.user.OAuth2User import org.springframework.security.oauth2.core.user.OAuth2User
@@ -1,4 +1,4 @@
package com.project.movienight.adapters.security.oauth2 package com.project.movienight.adapters.security
import com.project.movienight.domain.model.User import com.project.movienight.domain.model.User
import org.springframework.security.core.GrantedAuthority import org.springframework.security.core.GrantedAuthority
@@ -1,4 +1,4 @@
package com.project.movienight.adapters.security.oauth2 package com.project.movienight.adapters.security
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
class VkOAuth2UserInfo( class VkOAuth2UserInfo(
@@ -1,4 +1,4 @@
package com.project.movienight.adapters.security.oauth2 package com.project.movienight.adapters.security
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
class YandexOAuth2UserInfo( class YandexOAuth2UserInfo(
@@ -6,6 +6,10 @@ import java.util.UUID
interface UserRepositoryPort { interface UserRepositoryPort {
fun save(user: User): User fun save(user: User): User
fun saveWithOAuth2(user: User, provider: String, providerId: String): User
fun findByProviderAndProviderId(provider: String, providerId: String): User?
fun findById(id: UUID): User? fun findById(id: UUID): User?
fun findByEmail(email: String): User? fun findByEmail(email: String): User?
+2 -1
View File
@@ -1,7 +1,8 @@
CREATE TABLE IF NOT EXISTS public.users ( CREATE TABLE IF NOT EXISTS public.users (
id UUID PRIMARY KEY, id UUID PRIMARY KEY,
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
email VARCHAR(320) NOT NULL UNIQUE email VARCHAR(320) NOT NULL UNIQUE,
password VARCHAR(255)
); );
CREATE TABLE IF NOT EXISTS public.films ( CREATE TABLE IF NOT EXISTS public.films (