Skip to content

Commit

Permalink
Move secure-storage modules to live inside of autofill (#3976)
Browse files Browse the repository at this point in the history
<!--
Note: This checklist is a reminder of our shared engineering
expectations.
The items in Bold are required
If your PR involves UI changes:
1. Upload screenshots or screencasts that illustrate the changes before
/ after
2. Add them under the UI changes section (feel free to add more columns
if needed)
If your PR does not involve UI changes, you can remove the **UI
changes** section

At a minimum, make sure your changes are tested in API 23 and one of the
more recent API levels available.
-->

Task/Issue URL:
https://app.asana.com/0/488551667048375/1206104819543265/f

### Description
Moves the `secure-storage` modules inside `autofill`. Most of the
changelog is just updated package names.

### Steps to test this PR

- [x] Install from `develop` first.
- [x] Add some logins
- [x] Install from this branch
- [x] Ensure logins remain and still correct
  • Loading branch information
CDRussell authored Dec 7, 2023
1 parent 44a7249 commit 2a9e0bb
Show file tree
Hide file tree
Showing 48 changed files with 227 additions and 363 deletions.
4 changes: 0 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,6 @@ dependencies {
implementation project(':site-permissions-api')
implementation project(':site-permissions-impl')

implementation project(':secure-storage-api')
implementation project(':secure-storage-impl')
implementation project(':secure-storage-store')

implementation project(':ad-click-api')
implementation project(':ad-click-impl')
implementation project(':ad-click-store')
Expand Down
3 changes: 2 additions & 1 deletion autofill/autofill-impl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ dependencies {
implementation project(path: ':common-utils')
implementation project(path: ':common-ui')
implementation project(path: ':autofill-api')
implementation project(path: ':secure-storage-api')
implementation project(path: ':browser-api')
implementation project(path: ':autofill-store')
implementation project(path: ':statistics')
Expand Down Expand Up @@ -60,6 +59,8 @@ dependencies {
implementation AndroidX.room.ktx
implementation AndroidX.biometric

implementation "net.zetetic:android-database-sqlcipher:_"

implementation "com.jakewharton.threetenabp:threetenabp:_"
testImplementation "org.threeten:threetenbp:_"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ import com.duckduckgo.autofill.api.domain.app.LoginCredentials
import com.duckduckgo.autofill.api.store.AutofillStore
import com.duckduckgo.autofill.api.store.AutofillStore.ContainsCredentialsResult
import com.duckduckgo.autofill.api.store.AutofillStore.ContainsCredentialsResult.NoMatch
import com.duckduckgo.autofill.impl.securestorage.SecureStorage
import com.duckduckgo.autofill.impl.securestorage.WebsiteLoginDetails
import com.duckduckgo.autofill.impl.securestorage.WebsiteLoginDetailsWithCredentials
import com.duckduckgo.autofill.impl.urlmatcher.AutofillUrlMatcher
import com.duckduckgo.autofill.store.AutofillPrefsStore
import com.duckduckgo.autofill.store.LastUpdatedTimeProvider
import com.duckduckgo.autofill.sync.SyncCredentialsListener
import com.duckduckgo.common.utils.DefaultDispatcherProvider
import com.duckduckgo.common.utils.DispatcherProvider
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.securestorage.api.SecureStorage
import com.duckduckgo.securestorage.api.WebsiteLoginDetails
import com.duckduckgo.securestorage.api.WebsiteLoginDetailsWithCredentials
import com.squareup.anvil.annotations.ContributesBinding
import dagger.SingleInstanceIn
import javax.inject.Inject
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl
package com.duckduckgo.autofill.impl.securestorage

import java.security.Key
import javax.crypto.SecretKeyFactory
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,14 +14,13 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl
package com.duckduckgo.autofill.impl.securestorage

import com.duckduckgo.autofill.impl.securestorage.SecureStorageException.InternalSecureStorageException
import com.duckduckgo.autofill.impl.securestorage.encryption.EncryptionHelper
import com.duckduckgo.autofill.impl.securestorage.encryption.EncryptionHelper.EncryptedBytes
import com.duckduckgo.autofill.impl.securestorage.encryption.EncryptionHelper.EncryptedString
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.securestorage.api.SecureStorageException
import com.duckduckgo.securestorage.api.SecureStorageException.InternalSecureStorageException
import com.duckduckgo.securestorage.impl.encryption.EncryptionHelper
import com.duckduckgo.securestorage.impl.encryption.EncryptionHelper.EncryptedBytes
import com.duckduckgo.securestorage.impl.encryption.EncryptionHelper.EncryptedString
import com.squareup.anvil.annotations.ContributesBinding
import dagger.SingleInstanceIn
import javax.inject.Inject
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl
package com.duckduckgo.autofill.impl.securestorage

import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.securestorage.store.RealSecureStorageRepository
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,14 +14,11 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl
package com.duckduckgo.autofill.impl.securestorage

import com.duckduckgo.autofill.impl.securestorage.encryption.EncryptionHelper.EncryptedString
import com.duckduckgo.common.utils.DispatcherProvider
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.securestorage.api.SecureStorage
import com.duckduckgo.securestorage.api.WebsiteLoginDetails
import com.duckduckgo.securestorage.api.WebsiteLoginDetailsWithCredentials
import com.duckduckgo.securestorage.impl.encryption.EncryptionHelper.EncryptedString
import com.duckduckgo.securestorage.store.SecureStorageRepository
import com.duckduckgo.securestorage.store.db.WebsiteLoginCredentialsEntity
import com.squareup.anvil.annotations.ContributesBinding
Expand All @@ -33,6 +30,100 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext

/** Public API for the secure storage feature */
interface SecureStorage {

/**
* This method can be used to check if the secure storage has been instantiated properly.
*
* @return `true` if all dependencies of SecureStorage have been instantiated properly otherwise `false`
*/
fun canAccessSecureStorage(): Boolean

/**
* This method adds a raw plaintext [WebsiteLoginDetailsWithCredentials] into the [SecureStorage]. If [canAccessSecureStorage] is false when
* this is invoked, nothing will be done.
*
* @throws [SecureStorageException] if something went wrong while trying to perform the action. See type to get more info on the cause.
* @return The saved credential if it saved successfully, otherwise null
*/
@Throws(SecureStorageException::class)
suspend fun addWebsiteLoginDetailsWithCredentials(
websiteLoginDetailsWithCredentials: WebsiteLoginDetailsWithCredentials,
): WebsiteLoginDetailsWithCredentials?

/**
* This method returns all [WebsiteLoginDetails] with the [domain] stored in the [SecureStorage].
* Only L1 encrypted data is returned by these function. This is best use when the need is only to access non-sensitive data.
* If [canAccessSecureStorage] is false when this is invoked, an empty flow will be emitted.
*
* @return Flow<List<WebsiteLoginDetails>> a flow emitting a List of plain text WebsiteLoginDetails stored in SecureStorage.
*/
suspend fun websiteLoginDetailsForDomain(domain: String): Flow<List<WebsiteLoginDetails>>

/**
* This method returns all [WebsiteLoginDetails] stored in the [SecureStorage].
* Only L1 encrypted data is returned by these function. This is best use when the need is only to access non-sensitive data.
* If [canAccessSecureStorage] is false when this is invoked, an empty flow will be emitted.
*
* @return Flow<List<WebsiteLoginDetails>> a flow containing a List of plain text WebsiteLoginDetails stored in SecureStorage.
*/
suspend fun websiteLoginDetails(): Flow<List<WebsiteLoginDetails>>

/**
* This method returns the [WebsiteLoginDetailsWithCredentials] with the [id] stored in the [SecureStorage].
* This returns decrypted sensitive data (encrypted in L2). Use this only when sensitive data is needed to be accessed.
* If [canAccessSecureStorage] is false when this is invoked, null will be returned.
*
* @return [WebsiteLoginDetailsWithCredentials] containing the plaintext password
* @throws [SecureStorageException] if something went wrong while trying to perform the action. See type to get more info on the cause.
*/
@Throws(SecureStorageException::class)
suspend fun getWebsiteLoginDetailsWithCredentials(id: Long): WebsiteLoginDetailsWithCredentials?

/**
* This method returns the [WebsiteLoginDetailsWithCredentials] with the [domain] stored in the [SecureStorage].
* This returns decrypted sensitive data (encrypted in L2). Use this only when sensitive data is needed to be accessed.
* If [canAccessSecureStorage] is false when this is invoked, an empty flow will be emitted.
*
* @return Flow<List<WebsiteLoginDetailsWithCredentials>> a flow emitting a List of plain text WebsiteLoginDetailsWithCredentials stored
* in SecureStorage containing the plaintext password
* @throws [SecureStorageException] if something went wrong while trying to perform the action. See type to get more info on the cause.
*/
@Throws(SecureStorageException::class)
suspend fun websiteLoginDetailsWithCredentialsForDomain(domain: String): Flow<List<WebsiteLoginDetailsWithCredentials>>

/**
* This method returns all the [WebsiteLoginDetailsWithCredentials] stored in the [SecureStorage].
* This returns decrypted sensitive data (encrypted in L2). Use this only when sensitive data is needed to be accessed.
* If [canAccessSecureStorage] is false when this is invoked, an empty flow will be emitted.
*
* @return Flow<List<WebsiteLoginDetailsWithCredentials>> a flow emitting a List of plain text WebsiteLoginDetailsWithCredentials stored
* in SecureStorage containing the plaintext password
* @throws [SecureStorageException] if something went wrong while trying to perform the action. See type to get more info on the cause.
*/
@Throws(SecureStorageException::class)
suspend fun websiteLoginDetailsWithCredentials(): Flow<List<WebsiteLoginDetailsWithCredentials>>

/**
* This method updates an existing [WebsiteLoginDetailsWithCredentials] in the [SecureStorage].
* If [canAccessSecureStorage] is false when this is invoked, nothing will be done.
*
* @throws [SecureStorageException] if something went wrong while trying to perform the action. See type to get more info on the cause.
* @return The updated credential if it saved successfully, otherwise null
*/
@Throws(SecureStorageException::class)
suspend fun updateWebsiteLoginDetailsWithCredentials(
websiteLoginDetailsWithCredentials: WebsiteLoginDetailsWithCredentials,
): WebsiteLoginDetailsWithCredentials?

/**
* This method removes an existing [WebsiteLoginDetailsWithCredentials] associated with an [id] from the [SecureStorage].
* If [canAccessSecureStorage] is false when this is invoked, nothing will be done.
*/
suspend fun deleteWebsiteLoginDetailsWithCredentials(id: Long)
}

@ContributesBinding(AppScope::class)
@SingleInstanceIn(AppScope::class)
class RealSecureStorage @Inject constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl
package com.duckduckgo.autofill.impl.securestorage

import android.content.Context
import androidx.room.Room
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.api
package com.duckduckgo.autofill.impl.securestorage

import java.lang.Exception

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl
package com.duckduckgo.autofill.impl.securestorage

import android.os.Build
import android.security.keystore.KeyProperties
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,11 +14,11 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl
package com.duckduckgo.autofill.impl.securestorage

import com.duckduckgo.autofill.impl.securestorage.encryption.EncryptionHelper
import com.duckduckgo.autofill.impl.securestorage.encryption.EncryptionHelper.EncryptedBytes
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.securestorage.impl.encryption.EncryptionHelper
import com.duckduckgo.securestorage.impl.encryption.EncryptionHelper.EncryptedBytes
import com.duckduckgo.securestorage.impl.encryption.RandomBytesGenerator
import com.duckduckgo.securestorage.store.SecureStorageKeyRepository
import com.squareup.anvil.annotations.ContributesBinding
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.api
package com.duckduckgo.autofill.impl.securestorage

/**
* Public data class that wraps all data related to a website login. All succeeding l2 and above attributes should be added here directly.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,13 +14,13 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl.di
package com.duckduckgo.autofill.impl.securestorage.di

import android.content.Context
import com.duckduckgo.autofill.impl.securestorage.DerivedKeySecretFactory
import com.duckduckgo.autofill.impl.securestorage.LegacyDerivedKeySecretFactory
import com.duckduckgo.autofill.impl.securestorage.RealDerivedKeySecretFactory
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.securestorage.impl.DerivedKeySecretFactory
import com.duckduckgo.securestorage.impl.LegacyDerivedKeySecretFactory
import com.duckduckgo.securestorage.impl.RealDerivedKeySecretFactory
import com.duckduckgo.securestorage.store.RealSecureStorageKeyRepository
import com.duckduckgo.securestorage.store.SecureStorageKeyRepository
import com.duckduckgo.securestorage.store.keys.RealSecureStorageKeyStore
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DuckDuckGo
* Copyright (c) 2023 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,13 +14,13 @@
* limitations under the License.
*/

package com.duckduckgo.securestorage.impl.encryption
package com.duckduckgo.autofill.impl.securestorage.encryption

import android.security.keystore.KeyProperties
import com.duckduckgo.autofill.impl.securestorage.SecureStorageException
import com.duckduckgo.autofill.impl.securestorage.SecureStorageException.InternalSecureStorageException
import com.duckduckgo.autofill.impl.securestorage.encryption.EncryptionHelper.EncryptedBytes
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.securestorage.api.SecureStorageException
import com.duckduckgo.securestorage.api.SecureStorageException.InternalSecureStorageException
import com.duckduckgo.securestorage.impl.encryption.EncryptionHelper.EncryptedBytes
import com.squareup.anvil.annotations.ContributesBinding
import java.lang.Exception
import java.security.Key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
package com.duckduckgo.autofill.sync

import com.duckduckgo.autofill.api.domain.app.LoginCredentials
import com.duckduckgo.autofill.impl.securestorage.SecureStorage
import com.duckduckgo.autofill.impl.securestorage.WebsiteLoginDetails
import com.duckduckgo.autofill.impl.securestorage.WebsiteLoginDetailsWithCredentials
import com.duckduckgo.autofill.store.CredentialsSyncMetadataEntity
import com.duckduckgo.autofill.sync.provider.LoginCredentialEntry
import com.duckduckgo.common.utils.formatters.time.DatabaseDateFormatter
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.securestorage.api.SecureStorage
import com.duckduckgo.securestorage.api.WebsiteLoginDetails
import com.duckduckgo.securestorage.api.WebsiteLoginDetailsWithCredentials
import com.duckduckgo.sync.api.SyncCrypto
import dagger.SingleInstanceIn
import javax.inject.*
Expand Down
Loading

0 comments on commit 2a9e0bb

Please sign in to comment.