Skip to content

Commit 0d25ae4

Browse files
committed
feat: add multi-instance API
1 parent 569f6ac commit 0d25ae4

7 files changed

Lines changed: 452 additions & 23 deletions

File tree

miracl-sdk/api/miracl-sdk.api

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public final class com/miracl/trust/MIRACLSuccess : com/miracl/trust/MIRACLResul
2525

2626
public final class com/miracl/trust/MIRACLTrust {
2727
public static final field Companion Lcom/miracl/trust/MIRACLTrust$Companion;
28-
public synthetic fun <init> (Landroid/content/Context;Lcom/miracl/trust/configuration/Configuration;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
28+
public synthetic fun <init> (Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Lcom/miracl/trust/configuration/Configuration;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
2929
public final fun abortAuthenticationSession (Lcom/miracl/trust/session/AuthenticationSessionDetails;Lcom/miracl/trust/delegate/ResultHandler;)V
3030
public final fun abortCrossDeviceSession (Lcom/miracl/trust/session/CrossDeviceSession;Lcom/miracl/trust/delegate/ResultHandler;)V
3131
public final synthetic fun abortCrossDeviceSession (Lcom/miracl/trust/session/CrossDeviceSession;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@@ -83,7 +83,13 @@ public final class com/miracl/trust/MIRACLTrust {
8383

8484
public final class com/miracl/trust/MIRACLTrust$Companion {
8585
public final fun configure (Landroid/content/Context;Lcom/miracl/trust/configuration/Configuration;)V
86+
public final fun createInstance (Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Lcom/miracl/trust/MIRACLTrust;
8687
public final fun getInstance ()Lcom/miracl/trust/MIRACLTrust;
88+
public final fun getUsers (Landroid/content/Context;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
89+
public final fun setDefaultConfiguration (Lcom/miracl/trust/configuration/Configuration;)V
90+
}
91+
92+
public abstract interface annotation class com/miracl/trust/MIRACLTrustAuthenticatorApi : java/lang/annotation/Annotation {
8793
}
8894

8995
public abstract class com/miracl/trust/authentication/AuthenticationException : java/lang/Exception {
@@ -145,6 +151,7 @@ public final class com/miracl/trust/configuration/Configuration {
145151
}
146152

147153
public final class com/miracl/trust/configuration/Configuration$Builder {
154+
public fun <init> ()V
148155
public fun <init> (Ljava/lang/String;)V
149156
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
150157
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V

miracl-sdk/src/main/java/com/miracl/trust/MIRACLTrust.kt

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import androidx.annotation.VisibleForTesting
66
import com.miracl.trust.authentication.*
77
import com.miracl.trust.authentication.AuthenticatorScopes
88
import com.miracl.trust.configuration.*
9+
import com.miracl.trust.configuration.factory.ConfigurationFactory
10+
import com.miracl.trust.configuration.factory.DefaultConfigurationFactory
911
import com.miracl.trust.delegate.PinProvider
1012
import com.miracl.trust.delegate.ResultHandler
1113
import com.miracl.trust.factory.ComponentFactory
@@ -20,6 +22,7 @@ import com.miracl.trust.session.SessionManagerContract
2022
import com.miracl.trust.signing.*
2123
import com.miracl.trust.storage.UserStorageException
2224
import com.miracl.trust.storage.UserStorage
25+
import com.miracl.trust.storage.room.RoomDatabaseModule
2326
import com.miracl.trust.util.UrlValidator
2427
import com.miracl.trust.util.json.KotlinxSerializationJsonUtil
2528
import com.miracl.trust.util.log.Logger
@@ -39,11 +42,24 @@ import kotlin.jvm.Throws
3942
*/
4043
public class MIRACLTrust private constructor(
4144
context: Context,
45+
projectId: String,
46+
projectUrl: String,
4247
configuration: Configuration
4348
) {
4449
public companion object {
4550
private const val NOT_INITIALIZED_EXCEPTION = "MIRACLTrust SDK not initialized!"
4651

52+
@VisibleForTesting
53+
internal var configurationFactory: ConfigurationFactory = DefaultConfigurationFactory()
54+
55+
@Volatile
56+
@VisibleForTesting
57+
internal var defaultUserStorage: UserStorage? = null
58+
59+
@Volatile
60+
@VisibleForTesting
61+
internal var defaultConfiguration: Configuration? = null
62+
4763
private lateinit var instance: MIRACLTrust
4864

4965
@JvmStatic
@@ -64,8 +80,77 @@ public class MIRACLTrust private constructor(
6480
*/
6581
@JvmStatic
6682
public fun configure(context: Context, configuration: Configuration) {
67-
instance = MIRACLTrust(context, configuration)
83+
val projectId = requireNotNull(configuration.projectId) {
84+
"MIRACLTrust SDK: Project ID is missing. Pass a valid Project ID to Configuration.Builder."
85+
}
86+
87+
configuration.userStorage?.loadStorage()
88+
instance = MIRACLTrust(
89+
projectId = projectId,
90+
projectUrl = configuration.projectUrl,
91+
context = context,
92+
configuration = configuration
93+
)
94+
}
95+
96+
//region Authenticator API
97+
/**
98+
* This is an experimental API.
99+
* @suppress
100+
*/
101+
@MIRACLTrustAuthenticatorApi
102+
public fun setDefaultConfiguration(configuration: Configuration) {
103+
configuration.userStorage?.loadStorage()
104+
this.defaultConfiguration = configuration
68105
}
106+
107+
/**
108+
* This is an experimental API.
109+
* @suppress
110+
*/
111+
@MIRACLTrustAuthenticatorApi
112+
public fun createInstance(
113+
context: Context,
114+
projectId: String,
115+
projectUrl: String
116+
): MIRACLTrust {
117+
require(projectId.isNotEmpty()) {
118+
"MIRACLTrust SDK: Project ID cannot be empty. Pass a valid Project ID when calling createInstance()."
119+
}
120+
require(UrlValidator.isValid(projectUrl)) {
121+
"MIRACLTrust SDK: Project URL is invalid. Pass a valid URL when calling createInstance()."
122+
}
123+
124+
val configuration = defaultConfiguration ?: configurationFactory.create()
125+
126+
return MIRACLTrust(context, projectId, projectUrl, configuration)
127+
}
128+
129+
/**
130+
* This is an experimental API.
131+
* @suppress
132+
*/
133+
@MIRACLTrustAuthenticatorApi
134+
public suspend fun getUsers(context: Context): List<User> {
135+
val userStorage =
136+
defaultConfiguration?.userStorage ?: defaultUserStorage ?: synchronized(this) {
137+
val userStorage = defaultConfiguration?.userStorage ?: defaultUserStorage
138+
139+
userStorage ?: RoomDatabaseModule(context, "").userStorage().also {
140+
it.loadStorage()
141+
defaultUserStorage = it
142+
}
143+
}
144+
145+
return withContext(Dispatchers.IO) {
146+
try {
147+
userStorage.all().map { it.toUser() }
148+
} catch (ex: Exception) {
149+
throw UserStorageException(ex)
150+
}
151+
}
152+
}
153+
//endregion
69154
}
70155

71156
//region Properties
@@ -85,10 +170,11 @@ public class MIRACLTrust private constructor(
85170
@VisibleForTesting
86171
internal var resultHandlerDispatcher: CoroutineDispatcher = Dispatchers.Main
87172

88-
private val deviceName: String = configuration.deviceName
173+
@VisibleForTesting
174+
internal val deviceName: String = configuration.deviceName
89175

90176
/** Project ID setting for the application in MIRACL Trust platform. */
91-
public var projectId: String = configuration.projectId
177+
public var projectId: String = projectId
92178
private set
93179

94180
//endregion
@@ -102,14 +188,17 @@ public class MIRACLTrust private constructor(
102188
)
103189

104190
val componentFactory = configuration.componentFactory ?: ComponentFactory(context, logger)
105-
apiSettings = ApiSettings(configuration.projectUrl)
191+
apiSettings = ApiSettings(projectUrl)
106192

107193
miraclTrustCoroutineContext = configuration.miraclCoroutineContext
108194
miraclTrustScope = CoroutineScope(SupervisorJob() + configuration.miraclCoroutineContext)
109195

110-
userStorage = configuration.userStorage
111-
?: componentFactory.defaultUserStorage(configuration.projectId)
112-
userStorage.loadStorage()
196+
userStorage = configuration.userStorage ?: defaultUserStorage ?: synchronized(this) {
197+
defaultUserStorage ?: componentFactory.defaultUserStorage(projectId).also {
198+
it.loadStorage()
199+
defaultUserStorage = it
200+
}
201+
}
113202

114203
val registrationApi = RegistrationApiManager(
115204
apiRequestExecutor = apiRequestExecutor,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.miracl.trust
2+
3+
/**
4+
* This is an experimental API.
5+
* @suppress
6+
*/
7+
@RequiresOptIn
8+
@Retention(AnnotationRetention.BINARY)
9+
public annotation class MIRACLTrustAuthenticatorApi

miracl-sdk/src/main/java/com/miracl/trust/configuration/Configuration.kt

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.miracl.trust.configuration
22

33
import android.os.Build
4+
import com.miracl.trust.MIRACLTrustAuthenticatorApi
45
import com.miracl.trust.factory.ComponentFactory
56
import com.miracl.trust.network.HttpRequestExecutor
67
import com.miracl.trust.network.HttpsURLConnectionRequestExecutor
@@ -19,7 +20,7 @@ import kotlin.jvm.Throws
1920
* Instance is created though its [Builder]
2021
*/
2122
public class Configuration private constructor(
22-
internal val projectId: String,
23+
internal val projectId: String?,
2324
internal val projectUrl: String,
2425
internal val deviceName: String,
2526
internal val applicationInfo: String? = null,
@@ -69,16 +70,12 @@ public class Configuration private constructor(
6970
")"
7071
}
7172

72-
/**
73-
* Builds a [Configuration] object.
74-
*
75-
* @param projectId The unique identifier for your MIRACL Trust project.
76-
* @param projectUrl MIRACL Trust Project URL that is used for communication with the MIRACL Trust API.
77-
*/
78-
public class Builder @JvmOverloads constructor(
79-
internal val projectId: String,
80-
internal val projectUrl: String = DEFAULT_PLATFORM_URL
81-
) {
73+
/** Builds a [Configuration] object. */
74+
public class Builder @MIRACLTrustAuthenticatorApi public constructor() {
75+
internal var projectId: String? = null
76+
private set
77+
internal var projectUrl: String = DEFAULT_PLATFORM_URL
78+
private set
8279
internal lateinit var deviceNameValue: String
8380
private set
8481
internal var applicationInfo: String? = null
@@ -100,6 +97,19 @@ public class Configuration private constructor(
10097
internal var readTimeout: Int = DEFAULT_READ_TIMEOUT_SECONDS
10198
private set
10299

100+
/**
101+
* Creates a [Builder] object.
102+
*
103+
* @param projectId The unique identifier for your MIRACL Trust project.
104+
* @param projectUrl MIRACL Trust Project URL that is used for communication with the MIRACL Trust API.
105+
*/
106+
@OptIn(MIRACLTrustAuthenticatorApi::class)
107+
@JvmOverloads
108+
public constructor(projectId: String, projectUrl: String = DEFAULT_PLATFORM_URL) : this() {
109+
this.projectId = projectId
110+
this.projectUrl = projectUrl
111+
}
112+
103113
internal fun componentFactory(componentFactory: ComponentFactory) =
104114
apply { this.componentFactory = componentFactory }
105115

@@ -172,7 +182,7 @@ public class Configuration private constructor(
172182
/** Returns a [com.miracl.trust.configuration.Configuration] object. */
173183
@Throws(ConfigurationException::class)
174184
public fun build(): Configuration {
175-
if (projectId.isBlank()) {
185+
if (projectId?.isBlank() == true) {
176186
throw ConfigurationException.EmptyProjectId
177187
}
178188

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.miracl.trust.configuration.factory
2+
3+
import com.miracl.trust.configuration.Configuration
4+
5+
internal interface ConfigurationFactory {
6+
fun create(): Configuration
7+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.miracl.trust.configuration.factory
2+
3+
import com.miracl.trust.MIRACLTrustAuthenticatorApi
4+
import com.miracl.trust.configuration.Configuration
5+
6+
internal class DefaultConfigurationFactory : ConfigurationFactory {
7+
@OptIn(MIRACLTrustAuthenticatorApi::class)
8+
override fun create(): Configuration {
9+
return Configuration.Builder().build()
10+
}
11+
}

0 commit comments

Comments
 (0)