Skip to content

Commit

Permalink
fix: Improve ok() helper function (#1542)
Browse files Browse the repository at this point in the history
I'm hesitant to change this function too much, since we don't know what
kind of odd dependencies on its current behavior might exist. However,
adding exception chaining and surfacing the original error message seems
like a risk worth taking.

- Eliminate duplicated version in AuthSession by delegating to a shared
implementation defined on the SDKResponse companion object.

- For the SDKError case:
  - Set Error.message from SDKError.message
  - Set Error.casue from SDKError.cause

- Also ran `ktlint -F` on the files I changed so that `gradle check`
would pass the linting stage
- Also added kotlin-ci.yml to run `./gradlew jar` on kotlin changes

Fixes #1539 🦕
  • Loading branch information
haywood authored Dec 9, 2024
1 parent d880219 commit 7b15f90
Show file tree
Hide file tree
Showing 3 changed files with 288 additions and 214 deletions.
63 changes: 63 additions & 0 deletions .github/workflows/kotlin-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Kotlin CI

on:
pull_request:
paths:
- kotlin/**
- .github/workflows/gradle.yml

push:
branches: [ "main" ]
paths:
- kotlin/**
- .github/workflows/gradle.yml

# TODO(#1544): Also run tests
jobs:
build:

runs-on: ubuntu-latest
permissions:
contents: read

steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Build with Gradle Wrapper
run: ./gradlew jar
working-directory: kotlin

dependency-submission:

runs-on: ubuntu-latest
permissions:
contents: write

steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- run: cd kotlin

# Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies.
# See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
with:
build-root-directory: kotlin
109 changes: 49 additions & 60 deletions kotlin/src/main/com/looker/rtl/AuthSession.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,19 @@ open class AuthSession(
open val apiSettings: ConfigurationProvider,
open val transport: Transport = Transport(apiSettings),
) {

var authToken: AuthToken = AuthToken()
private var sudoToken: AuthToken = AuthToken()
var sudoId: String = ""

/**
* Abstraction of AuthToken retrieval to support sudo mode
*/
/** Abstraction of AuthToken retrieval to support sudo mode */
fun activeToken(): AuthToken {
if (sudoToken.accessToken.isNotEmpty()) {
return sudoToken
}
return authToken
}

/**
* Is there an active authentication token?
*/
/** Is there an active authentication token? */
open fun isAuthenticated(): Boolean {
val token = activeToken()
if (token.accessToken.isBlank()) return false
Expand All @@ -56,8 +51,8 @@ open class AuthSession(

/**
* Add authentication data to the pending API request
* @param[init] Initialized API request properties
*
* @param[init] Initialized API request properties
* @return The updated request properties
*/
fun authenticate(init: RequestSettings): RequestSettings {
Expand All @@ -69,13 +64,11 @@ open class AuthSession(
return init.copy(headers = headers)
}

fun isSudo(): Boolean {
return sudoId.isNotBlank() && sudoToken.isActive()
}
fun isSudo(): Boolean = sudoId.isNotBlank() && sudoToken.isActive()

/**
* Retrieve the current authentication token. If there is no active token, performs default login to retrieve the
* token.
* Retrieve the current authentication token. If there is no active token, performs default
* login to retrieve the token.
*/
open fun getToken(): AuthToken {
if (!isAuthenticated()) {
Expand All @@ -84,9 +77,7 @@ open class AuthSession(
return activeToken()
}

/**
* Reset the authentication session
*/
/** Reset the authentication session */
fun reset() {
sudoId = ""
authToken.reset()
Expand All @@ -95,13 +86,14 @@ open class AuthSession(

/**
* Activate the authentication token for the API3 or sudo user
*
* @param[sudoId] If provided, impersonates the user specified
*/

fun login(sudoId: String = ""): AuthToken = doLogin(sudoId)

/**
* Logout the active user. If the active user is impersonated , the session reverts to the API3 user.
* Logout the active user. If the active user is impersonated , the session reverts to the API3
* user.
*/
fun logout(): Boolean {
if (isAuthenticated()) {
Expand All @@ -110,14 +102,7 @@ open class AuthSession(
return false
}

fun <T> ok(response: SDKResponse): T {
@Suppress("UNCHECKED_CAST")
when (response) {
is SDKResponse.SDKErrorResponse<*> -> throw Error(response.value.toString())
is SDKResponse.SDKSuccessResponse<*> -> return response.value as T
else -> throw Error("Fail!!")
}
}
fun <T> ok(response: SDKResponse) = SDKResponse.ok<T>(response)

private fun sudoLogout(): Boolean {
var result = false
Expand All @@ -140,57 +125,61 @@ open class AuthSession(
val client_secret = "client_secret"
val config = apiSettings.readConfig()
val clientId =
unQuote(System.getProperty("${apiSettings.environmentPrefix}_CLIENT_ID") ?: config[client_id])
unQuote(
System.getProperty("${apiSettings.environmentPrefix}_CLIENT_ID")
?: config[client_id],
)
val clientSecret =
unQuote(System.getProperty("${apiSettings.environmentPrefix}_CLIENT_SECRET") ?: config[client_secret])
val params = mapOf(
client_id to clientId,
client_secret to clientSecret,
)
unQuote(
System.getProperty("${apiSettings.environmentPrefix}_CLIENT_SECRET")
?: config[client_secret],
)
val params = mapOf(client_id to clientId, client_secret to clientSecret)
val body = UrlEncodedContent(params)
val token = ok<AuthToken>(
transport.request<AuthToken>(
HttpMethod.POST,
"$apiPath/login",
emptyMap(),
body,
),
)
val token =
ok<AuthToken>(
transport.request<AuthToken>(
HttpMethod.POST,
"$apiPath/login",
emptyMap(),
body,
),
)
authToken = token
}

if (sudoId.isNotBlank()) {
val token = activeToken()
val sudoToken = transport.request<AuthToken>(
HttpMethod.POST,
"/login/$newId",
) { requestSettings ->
val headers = requestSettings.headers.toMutableMap()
if (token.accessToken.isNotBlank()) {
headers["Authorization"] = "Bearer ${token.accessToken}"
val sudoToken =
transport.request<AuthToken>(HttpMethod.POST, "/login/$newId") { requestSettings ->
val headers = requestSettings.headers.toMutableMap()
if (token.accessToken.isNotBlank()) {
headers["Authorization"] = "Bearer ${token.accessToken}"
}
requestSettings.copy(headers = headers)
}
requestSettings.copy(headers = headers)
}
this.sudoToken = ok(sudoToken)
}
return activeToken()
}

private fun doLogout(): Boolean {
val token = activeToken()
val resp = transport.request<String>(HttpMethod.DELETE, "/logout") {
val headers = it.headers.toMutableMap()
if (token.accessToken.isNotBlank()) {
headers["Authorization"] = "Bearer ${token.accessToken}"
val resp =
transport.request<String>(HttpMethod.DELETE, "/logout") {
val headers = it.headers.toMutableMap()
if (token.accessToken.isNotBlank()) {
headers["Authorization"] = "Bearer ${token.accessToken}"
}
it.copy(headers = headers)
}
it.copy(headers = headers)
}

val success = when (resp) {
is SDKResponse.SDKSuccessResponse<*> -> true
is SDKResponse.SDKErrorResponse<*> -> false
else -> false
}
val success =
when (resp) {
is SDKResponse.SDKSuccessResponse<*> -> true
is SDKResponse.SDKErrorResponse<*> -> false
else -> false
}
if (sudoId.isNotBlank()) {
sudoId = ""
sudoToken.reset()
Expand Down
Loading

0 comments on commit 7b15f90

Please sign in to comment.