mirror of
https://github.com/ProtonMail/protoncore_android.git
synced 2026-05-15 09:50:41 +00:00
Added User/Address Domain module.
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
+7
@@ -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 }
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
@@ -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)
|
||||
+39
@@ -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)
|
||||
}
|
||||
+57
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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" />
|
||||
Reference in New Issue
Block a user