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

Kotlin version of app demo #656

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
62 changes: 62 additions & 0 deletions appkotlin/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="net.openid.appauthdemokotlin" >

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="false"
android:fullBackupContent="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name_short"
android:theme="@style/AppTheme"
android:supportsRtl="false">

<!-- Main activity -->
<activity
android:name=".LoginActivity"
android:label="@string/app_name_short"
android:theme="@style/AppTheme"
android:windowSoftInputMode="stateHidden" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".TokenActivity"
android:label="@string/app_name_short"
android:theme="@style/AppTheme"
android:windowSoftInputMode="stateHidden" >
</activity>

<!--
This activity declaration is merged with the version from the library manifest.
It demonstrates how an https redirect can be captured, in addition to or instead of
a custom scheme.

Generally, this should be done in conjunction with an app link declaration for Android M
and above, for additional security and an improved user experience. See:

https://developer.android.com/training/app-links/index.html

The declaration from the library can be completely replaced by adding

tools:node="replace"

To the list of attributes on the activity element.
-->
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"
android:host="appauth.demo-app.io"
android:path="/oauth2redirect"/>
</intent-filter>
</activity>
</application>
</manifest>
65 changes: 65 additions & 0 deletions appkotlin/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
apply plugin: 'com.android.application'
apply plugin: 'checkstyle'
apply plugin: 'kotlin-android'
apply from: '../config/android-common.gradle'
apply from: '../config/keystore.gradle'

android {
defaultConfig {
applicationId 'net.openid.appauthdemokotlin'
project.archivesBaseName = 'appauth-demoapp-kotlin'
vectorDrawables.useSupportLibrary = true

// Make sure this is consistent with the redirect URI used in res/raw/auth_config.json,
// or specify additional redirect URIs in AndroidManifest.xml
manifestPlaceholders = [
'appAuthRedirectScheme': 'net.openid.appauthdemo'
]
}

buildFeatures {
viewBinding true
}

signingConfigs {
debugAndRelease {
storeFile file("${rootDir}/appauth.keystore")
storePassword "appauth"
keyAlias "appauth"
keyPassword "appauth"
}
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

buildTypes {
debug {
signingConfig signingConfigs.debugAndRelease
}
release {
signingConfig signingConfigs.debugAndRelease
}
}
}

dependencies {
implementation project(':library')
implementation "androidx.appcompat:appcompat:${project.androidXVersions.appcompat}"
implementation "androidx.annotation:annotation:${project.androidXVersions.annotation}"
implementation "com.google.android.material:material:${project.googleVersions.material}"
implementation "com.github.bumptech.glide:glide:${project.googleVersions.glide}"
implementation "com.squareup.okio:okio:${project.okioVersion}"
implementation "joda-time:joda-time:${project.jodaVersion}"

annotationProcessor "com.github.bumptech.glide:compiler:${project.googleVersions.glide}"
implementation "androidx.core:core-ktx:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

apply from: '../config/style.gradle'
repositories {
mavenCentral()
}
133 changes: 133 additions & 0 deletions appkotlin/java/net/openid/appauthdemokotlin/AuthStateManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Copyright 2016 The AppAuth for Android Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.openid.appauthdemokotlin

import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.annotation.AnyThread
import org.json.JSONException
import net.openid.appauth.*
import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicReference
import java.util.concurrent.locks.ReentrantLock

class AuthStateManager private constructor(context: Context) {
private val preferences: SharedPreferences = context.getSharedPreferences(STORE_NAME, Context.MODE_PRIVATE)
private val preferencesLock: ReentrantLock = ReentrantLock()
private val currentAuthState: AtomicReference<AuthState> = AtomicReference()

@get:AnyThread
val current: AuthState
get() {
if (currentAuthState.get() != null) {
return currentAuthState.get()
}
val state = readState()
return if (currentAuthState.compareAndSet(null, state)) {
state
} else {
currentAuthState.get()
}
}

@AnyThread
fun replace(state: AuthState): AuthState {
writeState(state)
currentAuthState.set(state)
return state
}

@AnyThread
fun updateAfterAuthorization(
response: AuthorizationResponse?,
ex: AuthorizationException?): AuthState {
val current = current
current.update(response, ex)
return replace(current)
}

@AnyThread
fun updateAfterTokenResponse(
response: TokenResponse?,
ex: AuthorizationException?): AuthState {
val current = current
current.update(response, ex)
return replace(current)
}

@AnyThread
fun updateAfterRegistration(
response: RegistrationResponse?,
ex: AuthorizationException?): AuthState {
val current = current
if (ex != null) {
return current
}
current.update(response)
return replace(current)
}

@AnyThread
private fun readState(): AuthState {
preferencesLock.lock()
return try {
val currentState = preferences.getString(KEY_STATE, null)
?: return AuthState()
try {
AuthState.jsonDeserialize(currentState)
} catch (ex: JSONException) {
Log.w(TAG, "Failed to deserialize stored auth state - discarding")
AuthState()
}
} finally {
preferencesLock.unlock()
}
}

@AnyThread
private fun writeState(state: AuthState?) {
preferencesLock.lock()
try {
val editor = preferences.edit()
if (state == null) {
editor.remove(KEY_STATE)
} else {
editor.putString(KEY_STATE, state.jsonSerializeString())
}
check(editor.commit()) { "Failed to write state to shared prefs" }
} finally {
preferencesLock.unlock()
}
}

companion object {
private val INSTANCE_REF = AtomicReference(WeakReference<AuthStateManager?>(null))
private const val TAG = "AuthStateManager"
private const val STORE_NAME = "AuthState"
private const val KEY_STATE = "state"

@AnyThread
fun getInstance(context: Context): AuthStateManager {
var manager = INSTANCE_REF.get().get()
if (manager == null) {
manager = AuthStateManager(context.applicationContext)
INSTANCE_REF.set(WeakReference(manager))
}
return manager
}
}

}
Loading