Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADST-566 #85

Merged
merged 5 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion auth/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
android {
namespace 'com.alfresco.auth'
defaultConfig {
versionName "0.8.3"
versionName "0.8.4"
}
}

Expand Down
19 changes: 17 additions & 2 deletions auth/src/main/java/com/alfresco/auth/AuthConfig.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.alfresco.auth

import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json

/**
* Data class holding authentication configuration.
*/
@OptIn(InternalSerializationApi::class)
@Serializable
data class AuthConfig(
/**
Expand Down Expand Up @@ -38,7 +40,13 @@ data class AuthConfig(
/**
* Path to content service
*/
var contentServicePath: String
var contentServicePath: String,

var secret: String = "",
var scope: String = "",
var host: String = "",
var authType: AuthTypeProvider = AuthTypeProvider.NONE,
var additionalParams: Map<String, String> = mapOf<String, String>()
) {
/**
* Convenience method for JSON serialization.
Expand All @@ -51,7 +59,8 @@ data class AuthConfig(
/**
* Convenience method for deserializing a JSON string representation.
*/
@JvmStatic fun jsonDeserialize(str: String): AuthConfig? {
@JvmStatic
fun jsonDeserialize(str: String): AuthConfig? {
return try {
Json.decodeFromString(serializer(), str)
} catch (ex: SerializationException) {
Expand All @@ -60,3 +69,9 @@ data class AuthConfig(
}
}
}


enum class AuthTypeProvider {
NEW_IDP,
NONE;
}
3 changes: 2 additions & 1 deletion auth/src/main/java/com/alfresco/auth/AuthInterceptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.alfresco.auth
import android.content.Context
import android.util.Base64
import com.alfresco.auth.pkce.PkceAuthService
import java.lang.ref.WeakReference
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
Expand All @@ -17,6 +16,7 @@ import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import org.json.JSONException
import java.lang.ref.WeakReference

/**
* OkHttp [Interceptor] which deals with managing session information and attaching authentication headers.
Expand Down Expand Up @@ -225,6 +225,7 @@ class AuthInterceptor(
}

private fun Interceptor.Chain.proceed(type: AuthType, token: String?): Response {

val headerValue = when (type) {
AuthType.BASIC -> "Basic $token"
AuthType.PKCE -> "Bearer $token"
Expand Down
48 changes: 41 additions & 7 deletions auth/src/main/java/com/alfresco/auth/DiscoveryService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package com.alfresco.auth

import android.content.Context
import android.net.Uri
import com.alfresco.auth.data.AppConfigDetails
import com.alfresco.auth.data.ContentServerDetails
import com.alfresco.auth.data.ContentServerDetailsData
import com.alfresco.auth.pkce.PkceAuthService
import java.net.URL
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import java.net.URL
import java.util.concurrent.TimeUnit

/**
* Class that facilitates service discovery process.
Expand Down Expand Up @@ -55,13 +56,41 @@ class DiscoveryService(

val body = response.body?.string() ?: ""
val data = ContentServerDetails.jsonDeserialize(body)
data?.isAtLeast(MIN_ACS_VERSION) ?: false
data?.isAtLeast(MIN_ACS_VERSION) == true
} catch (e: Exception) {
false
}
}
}

/**
* Check whether the content service is running on [endpoint].
*/
internal suspend fun getAppConfigOAuthType(endpoint: String): AppConfigDetails? {
val uri = "https://$endpoint/app-config.json"

return withContext(Dispatchers.IO) {
try {
val client = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.build()
val request = Request.Builder()
.url(URL(uri))
.get()
.build()
val response = client.newCall(request).execute()

if (response.code != 200) return@withContext null

val body = response.body?.string() ?: ""
val data = AppConfigDetails.jsonDeserialize(body)
data
} catch (e: Exception) {
null
}
}
}

/**
* returns content server details based on [endpoint].
*/
Expand Down Expand Up @@ -97,21 +126,26 @@ class DiscoveryService(
val result = try {
val authService = PkceAuthService(context, null, authConfig)
authService.fetchDiscoveryFromUrl(uri)
} catch (exception: Exception) { null }
} catch (exception: Exception) {
null
}
return result != null
}

/**
* Return content service url based on [endpoint].
*/
fun contentServiceUrl(endpoint: String): Uri =
fun contentServiceUrl(
endpoint: String,
authType: AuthTypeProvider = AuthTypeProvider.NONE
): Uri =
PkceAuthService.endpointWith(endpoint, authConfig)
.buildUpon()
.appendPath(authConfig.contentServicePath)
.appendPath(if (authType == AuthTypeProvider.NEW_IDP) "alfresco" else authConfig.contentServicePath)
.build()

private fun contentServiceDiscoveryUrl(endpoint: String): Uri =
contentServiceUrl(endpoint)
contentServiceUrl(endpoint, authConfig.authType)
.buildUpon()
.appendEncodedPath(ACS_SERVER_DETAILS)
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.alfresco.auth.data

import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json

@OptIn(InternalSerializationApi::class)
@Serializable
data class OAuth2Data(
val host: String,
Expand All @@ -21,9 +23,11 @@ data class OAuth2Data(
val redirectUriLogout: String,
val audience: String,
val skipIssuerCheck: Boolean,
val strictDiscoveryDocumentValidation: Boolean
val strictDiscoveryDocumentValidation: Boolean,
val authType: String? = ""
)

@OptIn(InternalSerializationApi::class)
@Serializable
internal data class AppConfigDetails(
val oauth2: OAuth2Data
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package com.alfresco.auth.data

import java.lang.NumberFormatException
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.Serializable
import java.lang.NumberFormatException
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json

@OptIn(InternalSerializationApi::class)
@Serializable
data class ContentServerDetailsData(
val edition: String,
val version: String,
val schema: String
)

@OptIn(InternalSerializationApi::class)
@Serializable
internal data class ContentServerDetails(
val data: ContentServerDetailsData
Expand Down
Loading