Skip to content

Commit 708c562

Browse files
fix(tutorial): fetch ringing tutorial credentials from demo token generator (#1889)
The API key hardcoded in the ringing tutorial was revoked, and the bundled user tokens were signed with its secret. Fetch the API key and token from the demo token generator at login instead, so the tutorial no longer hardcodes keys.
1 parent 9364b68 commit 708c562

2 files changed

Lines changed: 44 additions & 13 deletions

File tree

‎tutorials/tutorial-ringing/src/main/kotlin/io/getstream/video/android/tutorial/ringing/MainActivity.kt‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import android.content.Context
2121
import android.content.pm.PackageManager
2222
import android.os.Build
2323
import android.os.Bundle
24+
import android.util.Log
2425
import android.widget.Toast
2526
import androidx.activity.ComponentActivity
2627
import androidx.activity.compose.setContent
@@ -73,6 +74,8 @@ import kotlinx.coroutines.flow.collectLatest
7374
import kotlinx.coroutines.flow.flatMapLatest
7475
import kotlinx.coroutines.flow.flowOf
7576
import kotlinx.coroutines.launch
77+
import org.json.JSONException
78+
import java.io.IOException
7679
import java.util.UUID
7780

7881
/**
@@ -91,11 +94,21 @@ class MainActivity : ComponentActivity() {
9194
var selectedUser by remember { mutableStateOf(RingingApp.currentUser) }
9295
when (selectedUser) {
9396
null -> LoginScreen(onUserSelected = { user ->
94-
RingingApp.login(applicationContext, user)
95-
// For the simplicity of the tutorial, we are requesting the required permissions here.
96-
// In a real app, you should request the permissions when needed.
97-
resultLauncher.requestDefaultPermissions()
98-
selectedUser = user
97+
lifecycleScope.launch {
98+
try {
99+
RingingApp.login(applicationContext, user)
100+
} catch (e: IOException) {
101+
Log.e("MainActivity", "Login failed", e)
102+
return@launch
103+
} catch (e: JSONException) {
104+
Log.e("MainActivity", "Login failed", e)
105+
return@launch
106+
}
107+
// For the simplicity of the tutorial, we are requesting the required permissions here.
108+
// In a real app, you should request the permissions when needed.
109+
resultLauncher.requestDefaultPermissions()
110+
selectedUser = user
111+
}
99112
})
100113

101114
else -> HomeScreen(

‎tutorials/tutorial-ringing/src/main/kotlin/io/getstream/video/android/tutorial/ringing/RingingApp.kt‎

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@ import io.getstream.video.android.core.StreamVideoBuilder
2929
import io.getstream.video.android.core.notifications.NotificationConfig
3030
import io.getstream.video.android.model.Device
3131
import io.getstream.video.android.model.User
32+
import kotlinx.coroutines.Dispatchers
3233
import kotlinx.coroutines.runBlocking
3334
import kotlinx.coroutines.tasks.await
35+
import kotlinx.coroutines.withContext
36+
import org.json.JSONObject
37+
import java.net.HttpURLConnection
38+
import java.net.URL
3439

3540
class RingingApp : Application() {
3641

@@ -43,6 +48,8 @@ class RingingApp : Application() {
4348

4449
companion object {
4550

51+
private const val TOKEN_URL = "https://pronto.getstream.io/api/auth/create-token"
52+
4653
var currentUser: TutorialUser? = null
4754

4855
val caller get() = currentUser ?: error("#caller; user not logged in")
@@ -62,17 +69,17 @@ class RingingApp : Application() {
6269
}
6370
}
6471

65-
fun login(context: Context, user: TutorialUser) {
72+
suspend fun login(context: Context, user: TutorialUser) {
6673
if (!StreamVideo.isInstalled) {
67-
currentUser = user
74+
val (apiKey, token) = fetchCredentials(user.id)
6875
// Initialize StreamVideo. For a production app we recommend adding
6976
// the client to your Application class or di module.
7077
StreamVideoBuilder(
7178
context = context.applicationContext,
72-
apiKey = "mmhfdzb5evj2",
79+
apiKey = apiKey,
7380
geo = GEO.GlobalEdgeNetwork,
7481
user = user.delegate,
75-
token = user.token,
82+
token = token,
7683
notificationConfig = NotificationConfig(
7784
// Make the notification low priority if the app is in foreground, so its not visible as a popup, since we want to handle
7885
// the incoming call in full screen when app is running.
@@ -89,9 +96,24 @@ class RingingApp : Application() {
8996
),
9097
),
9198
).build()
99+
currentUser = user
92100
}
93101
}
94102

103+
// Credentials come from Stream's demo token generator; use your own backend in production.
104+
private suspend fun fetchCredentials(userId: String): Pair<String, String> =
105+
withContext(Dispatchers.IO) {
106+
val url = URL("$TOKEN_URL?environment=demo&user_id=$userId")
107+
val connection = url.openConnection() as HttpURLConnection
108+
try {
109+
val body = connection.inputStream.bufferedReader().use { it.readText() }
110+
val json = JSONObject(body)
111+
json.getString("apiKey") to json.getString("token")
112+
} finally {
113+
connection.disconnect()
114+
}
115+
}
116+
95117
suspend fun logout() {
96118
if (StreamVideo.isInstalled) {
97119
with(StreamVideo.instance()) {
@@ -116,7 +138,6 @@ class RingingApp : Application() {
116138

117139
data class TutorialUser(
118140
val delegate: User,
119-
val token: String,
120141
val checked: Boolean = false,
121142
) {
122143
val id: String get() = delegate.id
@@ -130,21 +151,18 @@ data class TutorialUser(
130151
id = "android-tutorial-1",
131152
name = "User 1",
132153
),
133-
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYW5kcm9pZC10dXRvcmlhbC0xIn0.3qB-FI6OAqf5ZEETtgs0XhaMmiaRF2jDJOqCVRsqqbc",
134154
),
135155
TutorialUser(
136156
User(
137157
id = "android-tutorial-2",
138158
name = "User 2",
139159
),
140-
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYW5kcm9pZC10dXRvcmlhbC0yIn0.ksOq5ahC0745oZdPDKr2hyLp0j9exfwLE-AQITc9ZSc",
141160
),
142161
TutorialUser(
143162
User(
144163
id = "android-tutorial-3",
145164
name = "User 3",
146165
),
147-
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYW5kcm9pZC10dXRvcmlhbC0zIn0.g5h8coX8J1XUNHagPFoGBI0D7bN6P0w2Sd2rui89puE",
148166
),
149167
)
150168
}

0 commit comments

Comments
 (0)