@@ -5,12 +5,14 @@ import android.content.SharedPreferences
5
5
import android.os.Parcelable
6
6
import android.util.Log
7
7
import android.webkit.CookieManager
8
+ import androidx.core.content.edit
8
9
import com.google.gson.annotations.SerializedName
9
10
import kotlinx.coroutines.Dispatchers
10
11
import kotlinx.coroutines.withContext
11
12
import kotlinx.parcelize.Parcelize
12
13
import okhttp3.Cookie
13
14
import okhttp3.CookieJar
15
+ import okhttp3.Headers
14
16
import okhttp3.HttpUrl
15
17
import okhttp3.HttpUrl.Companion.toHttpUrl
16
18
import okhttp3.MediaType.Companion.toMediaTypeOrNull
@@ -35,8 +37,7 @@ import retrofit2.http.Query
35
37
import java.io.InputStream
36
38
import java.net.URLConnection
37
39
38
- // TODO: Pass preferences instead of context since context is not used
39
- class ServerApi (context : Context , host : String ) {
40
+ class ServerApi (val context : Context , host : String ) {
40
41
val api: ApiService
41
42
val hostname: String = host
42
43
val authToken: String
@@ -87,6 +88,29 @@ class ServerApi(context: Context, host: String) {
87
88
}
88
89
}
89
90
91
+ private suspend fun reAuthenticate (): String? {
92
+ return try {
93
+ val cookies = CookieManager .getInstance().getCookie(hostname)
94
+ Log .d(" reAuthenticate" , " cookies: $cookies " )
95
+ val httpUrl = hostname.toHttpUrl()
96
+ cookieJar.setCookie(httpUrl, cookies)
97
+
98
+ val tokenResponse = api.getToken()
99
+ Log .d(" reAuthenticate" , " tokenResponse: $tokenResponse " )
100
+
101
+ preferences.edit { putString(" auth_token" , tokenResponse.token) }
102
+ Log .d(" reAuthenticate" , " auth_token: ${tokenResponse.token} " )
103
+ val dao: ServerDao = ServerDatabase .getInstance(context).serverDao()
104
+ withContext(Dispatchers .IO ) {
105
+ dao.setToken(hostname, tokenResponse.token)
106
+ }
107
+ tokenResponse.token
108
+ } catch (e: Exception ) {
109
+ Log .e(" reAuthenticate" , " Exception: ${e.message} " )
110
+ null
111
+ }
112
+ }
113
+
90
114
suspend fun methods (): MethodsResponse {
91
115
Log .d(" Api[methods]" , " getMethods" )
92
116
return api.getMethods()
@@ -95,7 +119,17 @@ class ServerApi(context: Context, host: String) {
95
119
suspend fun upload (fileName : String , inputStream : InputStream ): Response <FileResponse > {
96
120
Log .d(" Api[upload]" , " fileName: $fileName " )
97
121
val multiPart: MultipartBody .Part = inputStreamToMultipart(inputStream, fileName)
98
- return api.postUpload(authToken, multiPart)
122
+ var response = api.postUpload(authToken, multiPart)
123
+ // TODO: Determine how to make this block a reusable function...
124
+ Log .d(" Api[upload]" , " response.code: ${response.code()} " )
125
+ if (response.code() == 401 ) {
126
+ val token = reAuthenticate()
127
+ Log .d(" Api[upload]" , " token: $token " )
128
+ if (token != null ) {
129
+ response = api.postUpload(token, multiPart)
130
+ }
131
+ }
132
+ return response
99
133
}
100
134
101
135
suspend fun shorten (url : String , vanity : String? ): Response <ShortResponse > {
@@ -266,9 +300,9 @@ class ServerApi(context: Context, host: String) {
266
300
return cookieStore[url.host] ? : emptyList()
267
301
}
268
302
269
- // fun setCookie(url: HttpUrl, rawCookie: String) {
270
- // val cookies = Cookie.parseAll(url, Headers.headersOf("Set-Cookie", rawCookie))
271
- // cookieStore[url.host] = cookies
272
- // }
303
+ fun setCookie (url : HttpUrl , rawCookie : String ) {
304
+ val cookies = Cookie .parseAll(url, Headers .headersOf(" Set-Cookie" , rawCookie))
305
+ cookieStore[url.host] = cookies
306
+ }
273
307
}
274
- }
308
+ }
0 commit comments