Added User/Address Domain module.

This commit is contained in:
Neil Marietta
2020-12-31 13:12:28 +01:00
parent 147d75dfd5
commit d58e0a751e
21 changed files with 915 additions and 1 deletions
+6
View File
@@ -80,6 +80,12 @@ object Module {
const val keyDomain = "$key:key-domain"
const val keyData = "$key:key-data"
// User
const val user = ":user"
const val userDomain = "$user:user-domain"
const val userPresentation = "$user:user-presentation"
const val userData = "$user:user-data"
// Contacts
const val contacts = ":contacts"
const val contactsDomain = "$contacts:contacts-domain"
@@ -36,6 +36,18 @@ import me.proton.core.key.domain.entity.keyholder.KeyHolderContext
* Executes the given [block] function for a [KeyHolder] on a [KeyHolderContext] and then close any associated
* key resources whether an exception is thrown or not.
*
* Example:
* ```
* keyholder.useKeys(context) {
* val text = "text"
*
* val encryptedText = encryptText(text)
* val signedText = signText(text)
*
* val decryptedText = decryptText(encryptedText)
* val isVerified = verifyText(decryptedText, signedText)
* }
* ```
* @param context [CryptoContext] providing any needed dependencies for Crypto functions.
* @param block a function allowing usage of [KeyHolderContext] extension functions.
* @return the result of [block] function invoked on this [KeyHolder].
@@ -25,4 +25,11 @@ data class PrivateKey(
val key: Armored,
val isPrimary: Boolean,
internal val passphrase: EncryptedByteArray?
)
) {
/**
* True if no passphrase is associated, thereby only public crypto functions are available.
*
* False if a passphrase is associated, thereby public and private crypto functions are available.
*/
val isLocked = passphrase == null
}
@@ -21,3 +21,10 @@ package me.proton.core.key.domain.extension
import me.proton.core.key.domain.entity.keyholder.KeyHolderPrivateKey
fun List<KeyHolderPrivateKey>.primary(): KeyHolderPrivateKey? = firstOrNull { it.privateKey.isPrimary }
/**
* True if no passphrase is associated with any keys, thereby only public crypto functions are available.
*
* False if at least one passphrase is associated, thereby public and private crypto functions are available.
*/
fun List<KeyHolderPrivateKey>.areAllLocked(): Boolean = all { it.privateKey.isLocked }
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
import studio.forface.easygradle.dsl.*
plugins {
id("com.android.library")
kotlin("android")
}
//libVersion = Version(0, 1, 0)
android()
dependencies {
api(
//project(Module.userPresentation),
project(Module.userDomain)
//project(Module.userData)
)
}
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
import studio.forface.easygradle.dsl.*
plugins {
`java-library`
kotlin("jvm")
}
//libVersion = Version(0, 1, 0)
dependencies {
implementation(
project(Module.kotlinUtil),
project(Module.cryptoCommon),
project(Module.domain),
// Feature
project(Module.keyDomain),
// Kotlin
`kotlin-jdk8`,
`coroutines-core`
)
testImplementation(project(Module.kotlinTest))
}
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain
sealed class UnlockResult {
object Success : UnlockResult()
sealed class Error : UnlockResult() {
object NoPrimaryKey : Error()
object NoKeySaltsForPrimaryKey : Error()
object PrimaryKeyInvalidPassphrase : Error()
}
}
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain
import kotlinx.coroutines.flow.Flow
import me.proton.core.crypto.common.simple.EncryptedByteArray
import me.proton.core.crypto.common.simple.PlainByteArray
import me.proton.core.domain.arch.DataResult
import me.proton.core.domain.entity.SessionUserId
import me.proton.core.domain.entity.UserId
import me.proton.core.key.domain.extension.areAllLocked
import me.proton.core.user.domain.entity.User
import me.proton.core.user.domain.entity.UserAddress
interface UserManager {
/**
* Get [User], using [sessionUserId].
*
* @return value emitted from cache/disk, then from fetcher if [refresh] is true.
*/
fun getUser(
sessionUserId: SessionUserId,
refresh: Boolean = false
): Flow<DataResult<User?>>
/**
* Get all [UserAddress], using [sessionUserId].
*
* @return value emitted from cache/disk, then from fetcher if [refresh] is true.
*/
fun getAddresses(
sessionUserId: SessionUserId,
refresh: Boolean = false
): Flow<DataResult<List<UserAddress>>>
/**
* Try to unlock the user with the given [password].
*
* On [UnlockResult.Success], the passphrase, derived from password, is stored and the [User] keys ready to be used.
*
* @param userId [UserId] to unlock.
* @param password [PlainByteArray] to use to unlock.
* @param refresh if false, use data from cache/disk, otherwise data are refreshed before proceeding.
*
* @see [User.keys]
* @see [areAllLocked]
*/
suspend fun unlockWithPassword(
userId: UserId,
password: PlainByteArray,
refresh: Boolean = false
): UnlockResult
/**
* Try to unlock the user with the given [passphrase].
*
* On [UnlockResult.Success], the passphrase is stored and the [User] keys ready to be used.
*
* @param userId [UserId] to unlock.
* @param passphrase [EncryptedByteArray] to use to unlock.
* @param refresh if false, use data from cache/disk, otherwise data is refreshed before proceeding.
*
* @see [User.keys]
* @see [areAllLocked]
*/
suspend fun unlockWithPassphrase(
userId: UserId,
passphrase: EncryptedByteArray,
refresh: Boolean = false
): UnlockResult
/**
* Lock the User Keys.
*
* The passphrase is cleared, and the User Keys not anymore ready to be used.
*/
suspend fun lock(userId: UserId)
/**
* Change password for a [userId].
*
* Note: This function takes care to adapt any needed passphrase or key.
*/
suspend fun changePassword(
userId: UserId,
oldPassword: String,
newPassword: String
)
}
@@ -0,0 +1,118 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.entity
import me.proton.core.domain.entity.UserId
import me.proton.core.key.domain.entity.keyholder.KeyHolder
import me.proton.core.key.domain.extension.areAllLocked
import me.proton.core.key.domain.useKeys
import me.proton.core.user.domain.UserManager
import me.proton.core.user.domain.extension.hasServiceForMail
import me.proton.core.user.domain.extension.hasServiceForVpn
import me.proton.core.user.domain.extension.hasSubscriptionForMail
import me.proton.core.user.domain.extension.hasSubscriptionForVpn
/**
* Represent an authenticated User.
*
* [User] without valid Session is removed from local persistence.
*/
data class User(
val userId: UserId,
/** Optional email address. */
val email: String?,
/** Optional name. */
val name: String?,
/** Optional display name. */
val displayName: String?,
/** Currency expressed in ISO 4217 (3 letters). */
val currency: String,
/** Monetary credits. This value is affected by [currency]. */
val credit: Int,
/** Used space size in Bytes. */
val usedSpace: Long,
/** Max space size in Bytes. */
val maxSpace: Long,
/** Max upload size in Bytes. */
val maxUpload: Long,
/** Organization member role, if any. */
val role: Role?,
/** Whether the user controls their own keys or not. All free users are private. */
val private: Boolean,
/**
* Services flags.
*
* @see [hasServiceForMail]
* @see [hasServiceForVpn]
*/
val services: Int,
/**
* Subscription flags.
*
* @see [hasSubscriptionForMail]
* @see [hasSubscriptionForVpn]
*/
val subscribed: Int,
/** Invoice delinquent. */
val delinquent: Delinquent?,
/**
* User Private Keys used by crypto functions (e.g. encrypt, decrypt, sign, verify).
*
* Example:
* ```
* user.useKeys(context) {
* val text = "text"
*
* val encryptedText = encryptText(text)
* val signedText = signText(text)
*
* val decryptedText = decryptText(encryptedText)
* val isVerified = verifyText(decryptedText, signedText)
* }
* ```
* @see [useKeys]
* @see [areAllLocked]
* @see [UserManager.unlockWithPassword]
* @see [UserManager.unlockWithPassphrase]
* @see [UserManager.lock]
* */
override val keys: List<UserKey>
) : KeyHolder
enum class Delinquent(val value: Int) {
None(0),
InvoiceAvailable(1),
InvoiceOverdue(2),
InvoiceDelinquent(3),
InvoiceMailDisabled(4);
companion object {
val map = values().associateBy { it.value }
}
}
enum class Role(val value: Int) {
NoOrganization(0),
OrganizationMember(1),
OrganizationAdmin(2);
companion object {
val map = values().associateBy { it.value }
}
}
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.entity
import me.proton.core.domain.entity.UserId
import me.proton.core.key.domain.entity.keyholder.KeyHolder
import me.proton.core.key.domain.extension.areAllLocked
import me.proton.core.key.domain.useKeys
import me.proton.core.user.domain.UserManager
data class AddressId(val id: String)
data class UserAddress(
val userId: UserId,
val addressId: AddressId,
val email: String,
val displayName: String? = null,
val domainId: String? = null,
val canSend: Boolean,
val canReceive: Boolean,
val enabled: Boolean,
val type: AddressType? = null,
val order: Int,
/**
* Address Private Keys used by crypto functions (e.g. encrypt, decrypt, sign, verify).
*
* Example:
* ```
* userAddress.useKeys(context) {
* val text = "text"
*
* val encryptedText = encryptText(text)
* val signedText = signText(text)
*
* val decryptedText = decryptText(encryptedText)
* val isVerified = verifyText(decryptedText, signedText)
* }
* ```
* @see [useKeys]
* @see [areAllLocked]
* @see [UserManager.unlockWithPassword]
* @see [UserManager.unlockWithPassphrase]
* @see [UserManager.lock]
* */
override val keys: List<UserAddressKey>
) : KeyHolder
enum class AddressType(val value: Int) {
/** First address the user created using a ProtonMail domain. */
Original(1),
/** Subsequent addresses created using a ProtonMail domain. */
Alias(2),
/** Custom domain address. */
Custom(3),
/** Premium "pm.me" domain. */
Premium(4),
/** External address. */
External(5);
companion object {
val map = values().associateBy { it.value }
}
}
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.entity
import me.proton.core.crypto.common.pgp.Armored
import me.proton.core.key.domain.entity.key.KeyId
import me.proton.core.key.domain.entity.key.PrivateKey
import me.proton.core.key.domain.entity.keyholder.KeyHolderPrivateKey
data class UserAddressKey(
val addressId: AddressId,
val version: Int,
val flags: Int,
val token: Armored? = null,
val signature: Armored? = null,
val activation: Armored? = null,
val active: Boolean,
override val keyId: KeyId,
override val privateKey: PrivateKey
) : KeyHolderPrivateKey
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.entity
import me.proton.core.crypto.common.pgp.Armored
import me.proton.core.domain.entity.UserId
import me.proton.core.key.domain.entity.key.KeyId
import me.proton.core.key.domain.entity.key.PrivateKey
import me.proton.core.key.domain.entity.keyholder.KeyHolderPrivateKey
data class UserKey(
val userId: UserId,
val version: Int,
val activation: Armored? = null,
override val keyId: KeyId,
override val privateKey: PrivateKey,
) : KeyHolderPrivateKey
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.entity
enum class UserType {
/**
* User with no email addresses associated with it.
*/
Username,
/**
* User with at least one internal email address associated with it.
*/
Internal,
/**
* User with at least one external email address associated with it.
*/
External
}
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.extension
import me.proton.core.user.domain.entity.UserAddressKey
private const val MASK_CAN_VERIFY_SIGNATURE = 1 // 01
private const val MASK_CAN_ENCRYPT_VALUE = 2 // 10
fun UserAddressKey.canEncrypt(): Boolean = flags.and(MASK_CAN_ENCRYPT_VALUE) == MASK_CAN_ENCRYPT_VALUE
fun UserAddressKey.canVerifySignature(): Boolean = flags.and(MASK_CAN_VERIFY_SIGNATURE) == MASK_CAN_VERIFY_SIGNATURE
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.extension
import me.proton.core.user.domain.entity.UserType
import me.proton.core.user.domain.entity.AddressType
import me.proton.core.user.domain.entity.UserAddress
/**
* @return primary [UserAddress] (with lower [UserAddress.order]).
*/
fun List<UserAddress>.primary() = minByOrNull { it.order }
/**
* @return [List] of [UserAddress] sorted by [UserAddress.order].
*/
fun List<UserAddress>.sorted() = sortedBy { it.order }
/**
* Checks if all addresses are of type [AddressType.External].
*/
fun List<UserAddress>.allExternal() = all { it.type == AddressType.External }
/**
* Returns `true` if the account is of type [UserType.Username].
*/
fun List<UserAddress>.usernameOnly() = isEmpty()
/**
* Client supplies the minimal [userType] it needs to operate. The result is if current account satisfies the
* required account.
*/
fun List<UserAddress>.satisfiesUserType(userType: UserType): Boolean = when (userType) {
// If client needs Username account, then it should be fine with any account type.
UserType.Username -> true
// If client needs External account, we return true only if current account is External or Internal.
UserType.External -> !usernameOnly()
// If client needs Internal only account to operate, we return true if current account is Internal only.
UserType.Internal -> !usernameOnly() && !allExternal()
}
/**
* Determines and returns current [UserType].
*/
fun List<UserAddress>.currentUserType(): UserType = when {
usernameOnly() -> UserType.Username
allExternal() -> UserType.External
else -> UserType.Internal
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.extension
import me.proton.core.user.domain.entity.User
private const val MASK_MAIL = 1 // 0001
private const val MASK_VPN = 4 // 0100
private fun User.hasServiceFor(mask: Int): Boolean = mask.and(services) == mask
private fun User.hasSubscriptionFor(mask: Int): Boolean = mask.and(subscribed) == mask
fun User.hasServiceForMail(): Boolean = hasServiceFor(MASK_MAIL)
fun User.hasServiceForVpn(): Boolean = hasServiceFor(MASK_VPN)
fun User.hasSubscriptionForMail(): Boolean = hasSubscriptionFor(MASK_MAIL)
fun User.hasSubscriptionForVpn(): Boolean = hasSubscriptionFor(MASK_VPN)
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.repository
import me.proton.core.crypto.common.simple.EncryptedByteArray
import me.proton.core.domain.entity.UserId
interface PassphraseRepository {
/**
* Set encrypted [passphrase] for a [userId].
*/
suspend fun setPassphrase(userId: UserId, passphrase: EncryptedByteArray)
/**
* Get encrypted passphrase for a [userId], if exist, or `null` otherwise.
*/
suspend fun getPassphrase(userId: UserId): EncryptedByteArray?
/**
* Clear passphrase for a [userId].
*/
suspend fun clearPassphrase(userId: UserId)
}
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.repository
import kotlinx.coroutines.flow.Flow
import me.proton.core.domain.arch.DataResult
import me.proton.core.domain.entity.SessionUserId
import me.proton.core.user.domain.entity.AddressId
import me.proton.core.user.domain.entity.UserAddress
interface UserAddressRepository {
/**
* Get all [UserAddress], using [sessionUserId].
*
* @return value emitted from cache/disk, then from fetcher if [refresh] is true.
*/
fun getAddresses(sessionUserId: SessionUserId, refresh: Boolean = false): Flow<DataResult<List<UserAddress>>>
/**
* Get all [UserAddress], using [sessionUserId].
*
* @return value from cache/disk if [refresh] is false, otherwise from fetcher if [refresh] is true.
*/
suspend fun getAddressesBlocking(sessionUserId: SessionUserId, refresh: Boolean = false): List<UserAddress>
/**
* Get [UserAddress], by [addressId], using [sessionUserId].
*
* @return value from cache/disk if [refresh] is false, otherwise from fetcher if [refresh] is true.
*/
suspend fun getAddressBlocking(
sessionUserId: SessionUserId,
addressId: AddressId,
refresh: Boolean = false
): UserAddress?
/**
* Setup new non-sub user [UserAddress] with [displayName] and [domain], remotely.
*/
suspend fun setupAddress(sessionUserId: SessionUserId, displayName: String, domain: String): UserAddress
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain.repository
import kotlinx.coroutines.flow.Flow
import me.proton.core.domain.arch.DataResult
import me.proton.core.domain.entity.SessionUserId
import me.proton.core.user.domain.entity.User
interface UserRepository {
/**
* Get [User], using [sessionUserId].
*
* @return value emitted from cache/disk, then from fetcher if [refresh] is true.
*/
fun getUser(sessionUserId: SessionUserId, refresh: Boolean = false): Flow<DataResult<User>>
/**
* Get [User], using [sessionUserId].
*
* @return value from cache/disk if [refresh] is false, otherwise from fetcher if [refresh] is true.
*/
suspend fun getUserBlocking(sessionUserId: SessionUserId, refresh: Boolean = false): User
}
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* This file is part of Proton Technologies AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.user.domain
import me.proton.core.crypto.common.context.CryptoContext
import me.proton.core.key.domain.decryptAndVerifyData
import me.proton.core.key.domain.decryptAndVerifyDataOrNull
import me.proton.core.key.domain.decryptAndVerifyText
import me.proton.core.key.domain.decryptAndVerifyTextOrNull
import me.proton.core.key.domain.decryptText
import me.proton.core.key.domain.decryptTextOrNull
import me.proton.core.key.domain.encryptAndSignData
import me.proton.core.key.domain.encryptAndSignText
import me.proton.core.key.domain.encryptText
import me.proton.core.key.domain.signText
import me.proton.core.key.domain.useKeys
import me.proton.core.key.domain.verifyText
import me.proton.core.user.domain.entity.User
import me.proton.core.user.domain.entity.UserAddress
internal fun userKeysApi(
context: CryptoContext,
user: User,
userAddress: UserAddress,
) {
// User extends KeyHolder.
user.useKeys(context) {
val message = "message"
val data = message.toByteArray()
// Encrypt + Sign Detached.
val encryptedText = encryptText(message)
val signedText = signText(message)
val decryptedText = decryptText(encryptedText)
verifyText(decryptedText, signedText)
// Encrypt + Sign Embedded (more secure).
val encryptedSignedText = encryptAndSignText(message)
decryptAndVerifyText(encryptedSignedText)
val encryptedSignedData = encryptAndSignData(data)
decryptAndVerifyData(encryptedSignedData)
}
// UserAddress extends KeyHolder.
userAddress.useKeys(context) {
val message = "message"
val data = message.toByteArray()
// Encrypt + Sign Detached.
val encryptedText = encryptText(message)
val signedText = signText(message)
decryptTextOrNull(encryptedText)?.let {
verifyText(it, signedText)
}
// Encrypt + Sign Embedded (more secure).
val encryptedSignedText = encryptAndSignText(message)
decryptAndVerifyTextOrNull(encryptedSignedText)
val encryptedSignedData = encryptAndSignData(data)
decryptAndVerifyDataOrNull(encryptedSignedData)
}
}
+19
View File
@@ -0,0 +1,19 @@
<!--
~ Copyright (c) 2020 Proton Technologies AG
~ This file is part of Proton Technologies AG and ProtonCore.
~
~ ProtonCore is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ ProtonCore is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest package="me.proton.core.user" />