Skip to content

Commit cc4867d

Browse files
authored
Added auth interceptor
Fixes #81 : auth interceptor added for intercepting all auth requests
2 parents d1362b0 + 2df3a3d commit cc4867d

File tree

7 files changed

+142
-89
lines changed

7 files changed

+142
-89
lines changed

app/src/main/java/com/github/code/gambit/data/remote/ApiGatewayInterceptor.kt renamed to app/src/main/java/com/github/code/gambit/data/remote/interceptor/ApiGatewayInterceptor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.code.gambit.data.remote
1+
package com.github.code.gambit.data.remote.interceptor
22

33
import com.github.code.gambit.BuildConfig
44
import okhttp3.Interceptor
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.github.code.gambit.data.remote.interceptor
2+
3+
import android.content.Context
4+
import com.amazonaws.services.cognitoidentityprovider.model.NotAuthorizedException
5+
import com.github.code.gambit.R
6+
import com.github.code.gambit.helper.ServiceResult
7+
import com.github.code.gambit.utility.NoInternetException
8+
import kotlinx.coroutines.Dispatchers
9+
import kotlinx.coroutines.withContext
10+
import java.lang.Exception
11+
12+
class AuthInterceptor
13+
constructor(val context: Context) : InternetCheck(context) {
14+
15+
private suspend fun <T> authRequest(call: suspend () -> T): T {
16+
val a = withContext(Dispatchers.IO) { hasActiveInternetConnection() }
17+
if (!a) {
18+
throw NoInternetException("Not connected to internet")
19+
}
20+
return call.invoke()
21+
}
22+
23+
suspend fun <T, B> authRequest(call: suspend () -> T, result: (res: T) -> ServiceResult<B>): ServiceResult<B> {
24+
return try {
25+
val response = authRequest { call.invoke() }
26+
result(response)
27+
} catch (exception: Exception) {
28+
if (exception.cause is NotAuthorizedException) {
29+
ServiceResult.Error(Exception(context.getString(R.string.incorrect_username_or_password)))
30+
} else {
31+
ServiceResult.Error(exception)
32+
}
33+
}
34+
}
35+
}

app/src/main/java/com/github/code/gambit/data/remote/services/NetworkInterceptor.kt renamed to app/src/main/java/com/github/code/gambit/data/remote/interceptor/InternetCheck.kt

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,20 @@
1-
package com.github.code.gambit.data.remote.services
1+
package com.github.code.gambit.data.remote.interceptor
22

33
import android.annotation.SuppressLint
44
import android.content.Context
55
import android.net.ConnectivityManager
6-
import com.github.code.gambit.utility.NoInternetException
76
import dagger.hilt.android.qualifiers.ApplicationContext
8-
import okhttp3.Interceptor
9-
import okhttp3.Response
107
import timber.log.Timber
118
import java.io.IOException
129
import java.net.HttpURLConnection
1310
import java.net.URL
1411

15-
class NetworkInterceptor
16-
constructor(@ApplicationContext context: Context) : Interceptor {
17-
18-
private val applicationContext = context.applicationContext
19-
20-
override fun intercept(chain: Interceptor.Chain): Response {
21-
if (!hasActiveInternetConnection()) {
22-
throw NoInternetException("Not connected to internet")
23-
}
24-
return chain.proceed(chain.request())
25-
}
26-
12+
open class InternetCheck(@ApplicationContext val applicationContext: Context) {
2713
@SuppressLint("ServiceCast")
2814
private fun isConnected(): Boolean {
2915
val connectivityManager = applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
30-
val network_info = connectivityManager.activeNetwork
31-
return network_info != null
16+
val networkInfo = connectivityManager.activeNetwork
17+
return networkInfo != null
3218
}
3319

3420
fun hasActiveInternetConnection(): Boolean {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.github.code.gambit.data.remote.interceptor
2+
3+
import android.content.Context
4+
import com.github.code.gambit.R
5+
import com.github.code.gambit.utility.NoInternetException
6+
import okhttp3.Interceptor
7+
import okhttp3.Response
8+
9+
open class NetworkInterceptor
10+
constructor(val context: Context) : Interceptor, InternetCheck(context) {
11+
12+
override fun intercept(chain: Interceptor.Chain): Response {
13+
if (!hasActiveInternetConnection()) {
14+
throw NoInternetException(context.getString(R.string.no_internet_message))
15+
}
16+
return chain.proceed(chain.request())
17+
}
18+
}

app/src/main/java/com/github/code/gambit/data/remote/services/auth/AuthServiceImpl.kt

Lines changed: 69 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,148 +4,151 @@ import com.amplifyframework.auth.AuthException
44
import com.amplifyframework.auth.AuthUserAttribute
55
import com.amplifyframework.auth.AuthUserAttributeKey
66
import com.amplifyframework.auth.cognito.AWSCognitoAuthSession
7-
import com.amplifyframework.auth.cognito.AWSCognitoUserPoolTokens
87
import com.amplifyframework.auth.options.AuthSignUpOptions
98
import com.amplifyframework.kotlin.core.Amplify
9+
import com.github.code.gambit.data.remote.interceptor.AuthInterceptor
1010
import com.github.code.gambit.helper.ServiceResult
1111
import com.github.code.gambit.helper.auth.AuthData
1212
import com.github.code.gambit.utility.extention.defaultBuilder
1313

14-
class AuthServiceImpl : AuthService {
14+
class AuthServiceImpl(private val authInterceptor: AuthInterceptor) : AuthService {
1515

1616
override suspend fun login(authData: AuthData): ServiceResult<Unit> {
17-
return try {
18-
val result = Amplify.Auth.signIn(authData.email, authData.password)
17+
return authInterceptor.authRequest({
18+
Amplify.Auth.signIn(
19+
authData.email,
20+
authData.password
21+
)
22+
}) { result ->
1923
if (result.isSignInComplete) {
2024
ServiceResult.Success(Unit)
2125
} else {
2226
ServiceResult.Error(Exception("Login incomplete + ${result.nextStep}"))
2327
}
24-
} catch (e: AuthException) {
25-
ServiceResult.Error(e)
2628
}
2729
}
2830

2931
override suspend fun signUp(authData: AuthData): ServiceResult<Unit> {
30-
val options = AuthSignUpOptions.builder().defaultBuilder(authData)
31-
return try {
32-
val result = Amplify.Auth.signUp(authData.email, authData.password, options)
32+
return authInterceptor.authRequest({
33+
val options = AuthSignUpOptions.builder().defaultBuilder(authData)
34+
Amplify.Auth.signUp(authData.email, authData.password, options)
35+
}) { result ->
3336
if (result.isSignUpComplete) {
3437
ServiceResult.Success(Unit)
3538
} else {
3639
ServiceResult.Error(Exception("SignUp incomplete + ${result.nextStep}"))
3740
}
38-
} catch (e: AuthException) {
39-
ServiceResult.Error(e)
4041
}
4142
}
4243

4344
override suspend fun logOut(): ServiceResult<Unit> {
44-
return try {
45-
Amplify.Auth.signOut()
46-
ServiceResult.Success(Unit)
47-
} catch (e: AuthException) {
48-
ServiceResult.Error(e)
49-
}
45+
return authInterceptor.authRequest({ Amplify.Auth.signOut() }) { ServiceResult.Success(Unit) }
5046
}
5147

52-
override suspend fun resetPassword(oldPassword: String, newPassword: String): ServiceResult<Unit> {
53-
return try {
54-
val result = Amplify.Auth.updatePassword(oldPassword, newPassword)
55-
ServiceResult.Success(result)
56-
} catch (e: java.lang.Exception) {
57-
ServiceResult.Error(e)
48+
override suspend fun resetPassword(
49+
oldPassword: String,
50+
newPassword: String
51+
): ServiceResult<Unit> {
52+
return authInterceptor.authRequest({
53+
Amplify.Auth.updatePassword(
54+
oldPassword,
55+
newPassword
56+
)
57+
}) {
58+
ServiceResult.Success(it)
5859
}
5960
}
6061

6162
override suspend fun forgotPassword(userEmail: String): ServiceResult<Unit> {
62-
return try {
63-
Amplify.Auth.resetPassword(userEmail)
63+
return authInterceptor.authRequest({ Amplify.Auth.resetPassword(userEmail) }) {
6464
ServiceResult.Success(Unit)
65-
} catch (e: java.lang.Exception) {
66-
ServiceResult.Error(e)
6765
}
6866
}
6967

7068
override suspend fun changePassword(
7169
newPassword: String,
7270
confirmationCode: String
7371
): ServiceResult<Unit> {
74-
return try {
75-
Amplify.Auth.confirmResetPassword(newPassword, confirmationCode)
72+
return authInterceptor.authRequest({
73+
Amplify.Auth.confirmResetPassword(
74+
newPassword,
75+
confirmationCode
76+
)
77+
}) {
7678
ServiceResult.Success(Unit)
77-
} catch (e: java.lang.Exception) {
78-
ServiceResult.Error(e)
7979
}
8080
}
8181

8282
override suspend fun updateUserName(fullName: String): ServiceResult<String> {
83-
return try {
83+
return authInterceptor.authRequest({
8484
val attribute = AuthUserAttribute(AuthUserAttributeKey.name(), fullName)
85-
val result = Amplify.Auth.updateUserAttribute(attribute)
85+
Amplify.Auth.updateUserAttribute(attribute)
86+
}) { result ->
8687
if (result.isUpdated) {
8788
ServiceResult.Success(fullName)
8889
} else {
89-
ServiceResult.Error(AuthException("User name update failed", "Switch you internet connection"))
90+
ServiceResult.Error(
91+
AuthException(
92+
"User name update failed",
93+
"Switch your internet connection"
94+
)
95+
)
9096
}
91-
} catch (e: java.lang.Exception) {
92-
ServiceResult.Error(e)
9397
}
9498
}
9599

96100
override suspend fun confirmSignUp(authData: AuthData): ServiceResult<Unit> {
97-
return try {
98-
val result = Amplify.Auth.confirmSignUp(authData.email, authData.confirmationCode!!)
101+
return authInterceptor.authRequest({
102+
Amplify.Auth.confirmSignUp(
103+
authData.email,
104+
authData.confirmationCode!!
105+
)
106+
}) { result ->
99107
if (result.isSignUpComplete) {
100108
ServiceResult.Success(Unit)
101109
} else {
102110
ServiceResult.Error(Exception("Confirmation incomplete + ${result.nextStep}"))
103111
}
104-
} catch (e: AuthException) {
105-
ServiceResult.Error(e)
106112
}
107113
}
108114

109115
override suspend fun fetchSession(): ServiceResult<AWSCognitoAuthSession> {
110-
return try {
111-
val authSession = Amplify.Auth.fetchAuthSession() as AWSCognitoAuthSession
112-
ServiceResult.Success(authSession)
113-
} catch (e: AuthException) {
114-
ServiceResult.Error(e)
116+
return authInterceptor.authRequest({ Amplify.Auth.fetchAuthSession() as AWSCognitoAuthSession }) {
117+
ServiceResult.Success(
118+
it
119+
)
115120
}
116121
}
117122

118123
override suspend fun fetchIdToken(): ServiceResult<String> {
119-
when (val session = fetchSession()) {
120-
is ServiceResult.Error -> {
121-
return ServiceResult.Error(session.exception)
122-
}
123-
is ServiceResult.Success<AWSCognitoAuthSession> -> {
124-
val tokens: AWSCognitoUserPoolTokens = session.data.userPoolTokens.value
125-
?: return ServiceResult.Error(Exception("token not generated, user might be not authentication"))
126-
return ServiceResult.Success(tokens.idToken)
127-
}
128-
else -> {
129-
return ServiceResult.Error(Exception("Illegal state!!"))
124+
return authInterceptor.authRequest({ fetchSession() }) { session ->
125+
when (session) {
126+
is ServiceResult.Error -> {
127+
ServiceResult.Error(session.exception)
128+
}
129+
is ServiceResult.Success<AWSCognitoAuthSession> -> {
130+
session.data.userPoolTokens.value?.let {
131+
ServiceResult.Success(it.idToken)
132+
}
133+
?: ServiceResult.Error(Exception("token not generated, user might be not authentication"))
134+
}
130135
}
131136
}
132137
}
133138

134139
override suspend fun fetchUserAttribute(): ServiceResult<List<AuthUserAttribute>> {
135-
return try {
136-
val attributes = Amplify.Auth.fetchUserAttributes()
137-
ServiceResult.Success(attributes)
138-
} catch (e: AuthException) {
139-
ServiceResult.Error(e)
140+
return authInterceptor.authRequest({ Amplify.Auth.fetchUserAttributes() }) {
141+
ServiceResult.Success(
142+
it
143+
)
140144
}
141145
}
142146

143147
override suspend fun resentConfirmationCode(email: String): ServiceResult<Unit> {
144-
return try {
145-
Amplify.Auth.resendSignUpCode(email)
146-
ServiceResult.Success(Unit)
147-
} catch (e: AuthException) {
148-
ServiceResult.Error(e)
148+
return authInterceptor.authRequest({ Amplify.Auth.resendSignUpCode(email) }) {
149+
ServiceResult.Success(
150+
Unit
151+
)
149152
}
150153
}
151154
}

app/src/main/java/com/github/code/gambit/di/NetworkModule.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import com.chuckerteam.chucker.api.ChuckerInterceptor
55
import com.github.code.gambit.data.mapper.network.FileNetworkMapper
66
import com.github.code.gambit.data.mapper.network.UrlNetworkMapper
77
import com.github.code.gambit.data.mapper.network.UserNetworkMapper
8-
import com.github.code.gambit.data.remote.ApiGatewayInterceptor
98
import com.github.code.gambit.data.remote.NetworkDataSource
109
import com.github.code.gambit.data.remote.NetworkDataSourceImpl
10+
import com.github.code.gambit.data.remote.interceptor.ApiGatewayInterceptor
11+
import com.github.code.gambit.data.remote.interceptor.AuthInterceptor
12+
import com.github.code.gambit.data.remote.interceptor.NetworkInterceptor
1113
import com.github.code.gambit.data.remote.services.ApiService
12-
import com.github.code.gambit.data.remote.services.NetworkInterceptor
1314
import com.github.code.gambit.data.remote.services.auth.AuthService
1415
import com.github.code.gambit.data.remote.services.auth.AuthServiceImpl
1516
import com.github.code.gambit.data.remote.services.file.FileService
@@ -61,6 +62,14 @@ object NetworkModule {
6162
return ChuckerInterceptor(context)
6263
}
6364

65+
@Singleton
66+
@Provides
67+
fun provideAuthInterceptor(
68+
@ApplicationContext context: Context
69+
): AuthInterceptor {
70+
return AuthInterceptor(context)
71+
}
72+
6473
@Singleton
6574
@Provides
6675
fun provideOkHttpClient(
@@ -108,8 +117,8 @@ object NetworkModule {
108117

109118
@Singleton
110119
@Provides
111-
fun provideAuthService(): AuthService {
112-
return AuthServiceImpl()
120+
fun provideAuthService(authInterceptor: AuthInterceptor): AuthService {
121+
return AuthServiceImpl(authInterceptor)
113122
}
114123

115124
@Singleton

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,6 @@
8080
<string name="between">between</string>
8181
<string name="space">&#160;</string>
8282
<string name="resend">Resend</string>
83+
<string name="no_internet_message">Not connected to internet</string>
84+
<string name="incorrect_username_or_password">Incorrect Username or Password</string>
8385
</resources>

0 commit comments

Comments
 (0)