All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.komune.im.f2.user.lib.UserAggregateService.kt Maven / Gradle / Ivy

The newest version!
package io.komune.im.f2.user.lib

import io.komune.im.commons.auth.AuthenticationProvider
import io.komune.im.commons.model.OrganizationId
import io.komune.im.commons.model.PrivilegeIdentifier
import io.komune.im.commons.utils.EmptyAddress
import io.komune.im.commons.utils.mapAsync
import io.komune.im.commons.utils.toJson
import io.komune.im.core.organization.api.OrganizationCoreFinderService
import io.komune.im.core.privilege.api.PrivilegeCoreFinderService
import io.komune.im.core.privilege.api.model.checkTarget
import io.komune.im.core.privilege.domain.model.RoleTarget
import io.komune.im.core.user.api.UserCoreAggregateService
import io.komune.im.core.user.domain.command.UserCoreDefineCommand
import io.komune.im.core.user.domain.command.UserCoreDisableCommand
import io.komune.im.core.user.domain.command.UserCoreSendEmailCommand
import io.komune.im.f2.user.domain.command.UserCreateCommand
import io.komune.im.f2.user.domain.command.UserCreatedEvent
import io.komune.im.f2.user.domain.command.UserDeleteCommand
import io.komune.im.f2.user.domain.command.UserDeletedEvent
import io.komune.im.f2.user.domain.command.UserDisableCommand
import io.komune.im.f2.user.domain.command.UserDisabledEvent
import io.komune.im.f2.user.domain.command.UserResetPasswordCommand
import io.komune.im.f2.user.domain.command.UserResetPasswordEvent
import io.komune.im.f2.user.domain.command.UserUpdateCommand
import io.komune.im.f2.user.domain.command.UserUpdateEmailCommand
import io.komune.im.f2.user.domain.command.UserUpdatePasswordCommand
import io.komune.im.f2.user.domain.command.UserUpdatedEmailEvent
import io.komune.im.f2.user.domain.command.UserUpdatedEvent
import io.komune.im.f2.user.domain.command.UserUpdatedPasswordEvent
import io.komune.im.f2.user.domain.model.UserDTO
import org.keycloak.events.EventType
import org.springframework.stereotype.Service

@Service
class UserAggregateService(
    private val organizationCoreFinderService: OrganizationCoreFinderService,
    private val privilegeCoreFinderService: PrivilegeCoreFinderService,
    private val userCoreAggregateService: UserCoreAggregateService,
) {
    suspend fun create(command: UserCreateCommand): UserCreatedEvent {
        checkOrganizationExist(command.memberOf)
        checkRoles(command.roles)

        val userId = UserCoreDefineCommand(
            id = null,
            email = command.email,
            givenName = command.givenName,
            familyName = command.familyName,
            roles = command.roles,
            memberOf = command.memberOf,
            password = command.password,
            isPasswordTemporary = command.isPasswordTemporary,
            isEmailVerified = command.isEmailVerified,
            attributes = command.attributes.orEmpty().plus(listOfNotNull(
                command.address?.let { UserDTO::address.name to it.toJson() },
                command.phone?.let { UserDTO::phone.name to it },
            )).toMap(),
        ).let { userCoreAggregateService.define(it).id }

        val actions = listOfNotNull(
            EventType.VERIFY_EMAIL.takeIf { command.sendVerifyEmail },
            EventType.UPDATE_PASSWORD.takeIf { command.sendResetPassword },
        ).map(EventType::name)

        if (actions.isNotEmpty()) {
            UserCoreSendEmailCommand(
                id = userId,
                actions = actions
            ).let { userCoreAggregateService.sendEmail(it) }
        }

        return UserCreatedEvent(userId)
    }

    suspend fun resetPassword(command: UserResetPasswordCommand): UserResetPasswordEvent {
        UserCoreSendEmailCommand(
            id = command.id,
            actions = listOf(EventType.UPDATE_PASSWORD.name)
        ).let { userCoreAggregateService.sendEmail(it) }
        return UserResetPasswordEvent(command.id)
    }

    suspend fun updatePassword(command: UserUpdatePasswordCommand): UserUpdatedPasswordEvent {
        UserCoreDefineCommand(
            id = command.id,
            password = command.password,
            isPasswordTemporary = false
        ).let { userCoreAggregateService.define(it) }
        return UserUpdatedPasswordEvent(command.id)
    }

    suspend fun update(command: UserUpdateCommand): UserUpdatedEvent {
        checkRoles(command.roles)
        val event = UserCoreDefineCommand(
            id = command.id,
            givenName = command.givenName,
            familyName = command.familyName,
            roles = command.roles,
            memberOf = command.memberOf,
            attributes = command.attributes.orEmpty().plus(listOfNotNull(
                command.address?.let { UserDTO::address.name to it.toJson() },
                command.phone?.let { UserDTO::phone.name to it },
            )).toMap(),
        ).let { userCoreAggregateService.define(it) }

        return UserUpdatedEvent(event.id)
    }

    suspend fun updateEmail(command: UserUpdateEmailCommand): UserUpdatedEmailEvent {
        UserCoreDefineCommand(
            id = command.id,
            email = command.email,
            isEmailVerified = false
        ).let { userCoreAggregateService.define(it) }

        if (command.sendVerificationEmail) {
            UserCoreSendEmailCommand(
                id = command.id,
                actions = listOf(EventType.VERIFY_EMAIL.name)
            ).let { userCoreAggregateService.sendEmail(it) }
        }

        return UserUpdatedEmailEvent(command.id)
    }

    suspend fun disable(command: UserDisableCommand): UserDisabledEvent {
        UserCoreDisableCommand(
            id = command.id,
            disabledBy = command.disabledBy ?: AuthenticationProvider.getAuthedUser()?.id ?: ""
        ).let { userCoreAggregateService.disable(it) }

        if (command.anonymize) {
            UserCoreDefineCommand(
                id = command.id,
                email = "${command.id}@anonymous.com",
                givenName = "anonymous",
                familyName = "anonymous",
                attributes = command.attributes.orEmpty().plus(mapOf(
                    UserDTO::address.name to EmptyAddress.toJson(),
                    UserDTO::phone.name to "",
                )),
                isEmailVerified = false
            ).let { userCoreAggregateService.define(it) }
        }

        return UserDisabledEvent(command.id)
    }

    suspend fun delete(command: UserDeleteCommand): UserDeletedEvent {
        return userCoreAggregateService.delete(command)
    }

    private suspend fun checkOrganizationExist(organizationId: OrganizationId?) {
        organizationId?.let { organizationCoreFinderService.get(it) }
    }

    private suspend fun checkRoles(roles: List) {
        roles.mapAsync {
            val privilege = privilegeCoreFinderService.getPrivilege(it)
            privilege.checkTarget(RoleTarget.USER)
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy