Skip to content

Commit

Permalink
Merge pull request #37
Browse files Browse the repository at this point in the history
CA-2108 New user should accept terms of service on first login/register
  • Loading branch information
RatreeOchn authored Mar 24, 2020
2 parents 6f009eb + 81ce3fd commit 6be0475
Show file tree
Hide file tree
Showing 27 changed files with 380 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.rfcx.ranger.data.remote.setusername.SetNameEndpoint
import org.rfcx.ranger.data.remote.shortlink.ShortLinkEndpoint
import org.rfcx.ranger.data.remote.site.SiteEndpoint
import org.rfcx.ranger.data.remote.subscribe.SubscribeEndpoint
import org.rfcx.ranger.data.remote.terms.TermsEndpoint
import org.rfcx.ranger.data.remote.usertouch.UserTouchEndPoint
import org.rfcx.ranger.util.GsonProvider
import org.rfcx.ranger.util.ImprovedDateTypeAdapter
Expand Down Expand Up @@ -101,6 +102,12 @@ object ServiceFactory {
.create(SubscribeEndpoint::class.java)
}

fun makeTermsService(isDebug: Boolean, context: Context): TermsEndpoint {
return createRetrofit(BuildConfig.RANGER_DOMAIN, createAuthTokenOkHttpClient(isDebug, AuthTokenInterceptor(context)),
GsonProvider.getInstance().gson)
.create(TermsEndpoint::class.java)
}

private fun createRetrofit(baseUrl: String, okHttpClient: OkHttpClient, gson: Gson): Retrofit {
return Retrofit.Builder().baseUrl(baseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.rfcx.ranger.data.remote.terms

import io.reactivex.Single
import org.rfcx.ranger.entity.terms.TermsRequest
import org.rfcx.ranger.entity.terms.TermsResponse
import retrofit2.http.Body
import retrofit2.http.POST

interface TermsEndpoint {
@POST("v1/users/accept-terms")
fun sendPayload(@Body body: TermsRequest): Single<TermsResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.rfcx.ranger.data.remote.terms

import io.reactivex.Single
import org.rfcx.ranger.entity.terms.TermsRequest
import org.rfcx.ranger.entity.terms.TermsResponse

interface TermsRepository {
fun sendBodyPayload(sendBody: TermsRequest): Single<TermsResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.rfcx.ranger.data.remote.terms

import io.reactivex.Single
import org.rfcx.ranger.entity.terms.TermsRequest
import org.rfcx.ranger.entity.terms.TermsResponse

class TermsRepositoryImp(private val termsEndpoint: TermsEndpoint) : TermsRepository {
override fun sendBodyPayload(sendBody: TermsRequest): Single<TermsResponse> {
return termsEndpoint.sendPayload(sendBody)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.rfcx.ranger.data.remote.terms

import io.reactivex.Single
import org.rfcx.ranger.data.remote.domain.SingleUseCase
import org.rfcx.ranger.data.remote.domain.executor.PostExecutionThread
import org.rfcx.ranger.data.remote.domain.executor.ThreadExecutor
import org.rfcx.ranger.entity.terms.TermsRequest
import org.rfcx.ranger.entity.terms.TermsResponse

class TermsUseCase(private val termsRepository: TermsRepository,
threadExecutor: ThreadExecutor, postExecutionThread: PostExecutionThread
) : SingleUseCase<TermsRequest, TermsResponse>(threadExecutor, postExecutionThread) {
override fun buildUseCaseObservable(params: TermsRequest): Single<TermsResponse> {
return termsRepository.sendBodyPayload(params)
}
}
7 changes: 7 additions & 0 deletions app/src/main/java/org/rfcx/ranger/di/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ import org.rfcx.ranger.data.remote.subscribe.SubscribeUseCase
import org.rfcx.ranger.data.remote.subscribe.unsubscribe.UnsubscribeRepository
import org.rfcx.ranger.data.remote.subscribe.unsubscribe.UnsubscribeRepositoryImp
import org.rfcx.ranger.data.remote.subscribe.unsubscribe.UnsubscribeUseCase
import org.rfcx.ranger.data.remote.terms.TermsRepository
import org.rfcx.ranger.data.remote.terms.TermsRepositoryImp
import org.rfcx.ranger.data.remote.terms.TermsUseCase
import org.rfcx.ranger.data.remote.usertouch.CheckUserTouchUseCase
import org.rfcx.ranger.data.remote.usertouch.UserTouchRepository
import org.rfcx.ranger.data.remote.usertouch.UserTouchRepositoryImp
Expand Down Expand Up @@ -110,6 +113,9 @@ object DataModule {
single { UnsubscribeRepositoryImp(get()) } bind UnsubscribeRepository::class
single { UnsubscribeUseCase(get(), get(), get()) }

single { TermsRepositoryImp(get()) } bind TermsRepository::class
single { TermsUseCase(get(), get(), get()) }

}

val remoteModule = module {
Expand All @@ -125,6 +131,7 @@ object DataModule {
factory { ServiceFactory.makePasswordService(BuildConfig.DEBUG, androidContext()) }
factory { ServiceFactory.makeProfilePhotoService(BuildConfig.DEBUG, androidContext()) }
factory { ServiceFactory.makeSubscribeService(BuildConfig.DEBUG, androidContext()) }
factory { ServiceFactory.makeTermsService(BuildConfig.DEBUG, androidContext()) }
}

val localModule = module {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/org/rfcx/ranger/di/UiModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.rfcx.ranger.view.alerts.guardian.alertType.AlertValueViewModel
import org.rfcx.ranger.view.login.InvitationCodeViewModel
import org.rfcx.ranger.view.login.LoginViewModel
import org.rfcx.ranger.view.login.SetUserNameViewModel
import org.rfcx.ranger.view.login.TermsAndServiceViewModel
import org.rfcx.ranger.view.map.MapDetailViewModel
import org.rfcx.ranger.view.map.MapViewModel
import org.rfcx.ranger.view.map.ReportViewPagerFragmentViewModel
Expand Down Expand Up @@ -67,5 +68,6 @@ object UiModule {
viewModel { LoginViewModel(androidContext(), get()) }
viewModel { InvitationCodeViewModel(androidContext(), get()) }
viewModel { SetUserNameViewModel(androidContext(), get()) }
viewModel { TermsAndServiceViewModel(androidContext(), get()) }
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/org/rfcx/ranger/entity/terms/Terms.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.rfcx.ranger.entity.terms

import com.google.gson.annotations.SerializedName

open class TermsRequest(
val app: String
)

open class TermsResponse(
@SerializedName("success")
val success: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@ import com.google.gson.annotations.SerializedName

data class InvitationCodeRequest(
@SerializedName("code")
val code: String
val code: String,

@SerializedName("accept_terms")
val acceptTerms: String,

@SerializedName("app")
val app: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package org.rfcx.ranger.entity.user

data class UserAuthResponse (val guid: String, val email: String?, val nickname: String?,
val idToken: String, val accessToken: String?, val refreshToken: String?,
val roles: Set<String> = setOf(), val accessibleSites: Set<String> = setOf(), val defaultSite: String? = null, val picture: String?) {
val roles: Set<String> = setOf(), val accessibleSites: Set<String> = setOf(), val defaultSite: String? = null, val picture: String?, val consentGivenRangerApp: String?) {

val isRanger: Boolean get() = roles.contains("rfcxUser") && defaultSite != null

Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/org/rfcx/ranger/util/CredentialKeeper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class CredentialKeeper(val context: Context) {
if (user.picture != null) {
preferences.putString(Preferences.IMAGE_PROFILE, user.picture)
}
if (user.consentGivenRangerApp != null) {
preferences.putBoolean(Preferences.CONSENT_GIVEN, true)
}
preferences.putStringSet(Preferences.ROLES, user.roles)
preferences.putStringSet(Preferences.ACCESSIBLE_SITES, user.accessibleSites)
if (user.defaultSite != null) {
Expand Down
17 changes: 16 additions & 1 deletion app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class CredentialVerifier(val context: Context) {

// Parsing JWT Token
val metaDataKey = getString(R.string.auth0_metadata_key)
val userMetaDataKey = getString(R.string.auth0_user_metadata_key)
val withoutSignature = token.substring(0, token.lastIndexOf('.') + 1)
try {
val untrusted = Jwts.parser().parseClaimsJwt(withoutSignature)
Expand Down Expand Up @@ -64,12 +65,26 @@ class CredentialVerifier(val context: Context) {
}
}

val userUntrusted = Jwts.parser().parseClaimsJwt(withoutSignature)
var consentGivenRangerApp: String? = null

if (userUntrusted.body[userMetaDataKey] == null) {
consentGivenRangerApp = null
}

val userMetadata = userUntrusted.body[userMetaDataKey]
if (userMetadata != null) {
if ((userMetadata is HashMap<*, *>)) {
consentGivenRangerApp = userMetadata["consentGivenRangerApp"] as String?
}
}

when {
guid.isNullOrEmpty() -> {
return Err(getString(R.string.an_error_occurred))
}
else -> {
return Ok(UserAuthResponse(guid, email, nickname, token, credentials.accessToken, credentials.refreshToken, roles, accessibleSites, defaultSite, picture))
return Ok(UserAuthResponse(guid, email, nickname, token, credentials.accessToken, credentials.refreshToken, roles, accessibleSites, defaultSite, picture, consentGivenRangerApp))
}
}
} catch (e: Exception) {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/org/rfcx/ranger/util/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class Preferences(context: Context) {
const val IMAGE_PROFILE = "${PREFIX}IMAGE_PROFILE"
const val EMAIL_SUBSCRIBE = "${PREFIX}EMAIL_SUBSCRIBE"
const val COORDINATES_FORMAT = "${PREFIX}COORDINATES_FORMAT"
const val CONSENT_GIVEN = "${PREFIX}CONSENT_GIVEN"
const val IS_RANGER = "${PREFIX}IS_RANGER"
}

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class InvitationCodeViewModel(private val context: Context, private val sendInvi
override fun onError(e: Throwable) {
callback(false)
}
}, InvitationCodeRequest(code))
}, InvitationCodeRequest(code, USER_ACCEPTED, APP_NAME))
}

private fun refreshToken(callback: (Boolean) -> Unit) {
Expand Down Expand Up @@ -94,6 +94,11 @@ class InvitationCodeViewModel(private val context: Context, private val sendInvi
}
})
}

companion object {
const val USER_ACCEPTED = "true"
const val APP_NAME = "RangerApp"
}
}

enum class SubmitState {
Expand Down
18 changes: 17 additions & 1 deletion app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ class LoginActivityNew : BaseActivity(), LoginListener {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login_new)
val eventGuId = getEventFromIntentIfHave(intent)
if (CredentialKeeper(this).hasValidCredentials() && getSiteName().isNotEmpty() && getUserNickname().substring(0, 1) != "+") {

val preferenceHelper = Preferences.getInstance(this)
val isConsentGiven = preferenceHelper.getBoolean(Preferences.CONSENT_GIVEN,false)

if(CredentialKeeper(this).hasValidCredentials() && !isConsentGiven) {
supportFragmentManager.beginTransaction()
.add(loginContainer.id, TermsAndServiceFragment(),
"TermsAndServiceFragment").commit()
} else if (CredentialKeeper(this).hasValidCredentials() && getSiteName().isNotEmpty() && getUserNickname().substring(0, 1) != "+") {
MainActivityNew.startActivity(this@LoginActivityNew, eventGuId)
finish()
} else {
Expand Down Expand Up @@ -77,6 +85,13 @@ class LoginActivityNew : BaseActivity(), LoginListener {

}

override fun openTermsAndServiceFragment() {
supportFragmentManager.beginTransaction()
.replace(loginContainer.id, TermsAndServiceFragment(),
"TermsAndServiceFragment").commit()

}

private fun getEventFromIntentIfHave(intent: Intent?) :String? {
if (intent?.hasExtra("event_guid") == true) {
return intent.getStringExtra("event_guid")
Expand All @@ -89,4 +104,5 @@ interface LoginListener {
fun openMain()
fun openInvitationCodeFragment()
fun openSetUserNameFragmentFragment()
fun openTermsAndServiceFragment()
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ class LoginFragment : BaseFragment() {
loginViewModel.redirectPage.observe(this, Observer { loginRedirect ->
when (loginRedirect) {
LoginRedirect.MAIN_PAGE -> listener.openMain()
LoginRedirect.INVITE_CODE_PAGE -> listener.openInvitationCodeFragment()
LoginRedirect.SET_USER_NAME -> listener.openSetUserNameFragmentFragment()
LoginRedirect.TERMS_AND_SERVICE -> listener.openTermsAndServiceFragment()
else -> loading(false)
}
})
Expand Down
13 changes: 10 additions & 3 deletions app/src/main/java/org/rfcx/ranger/view/login/LoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -159,18 +159,25 @@ class LoginViewModel(private val context: Context, private val checkUserTouchUse
// }

fun checkUserDetail(userAuthResponse: UserAuthResponse) {
val preferenceHelper = Preferences.getInstance(context)
CredentialKeeper(context).save(userAuthResponse)

checkUserTouchUseCase.execute(object : DisposableSingleObserver<Boolean>() {
override fun onSuccess(t: Boolean) {
val isConsentGiven = preferenceHelper.getBoolean(Preferences.CONSENT_GIVEN)

if (userAuthResponse.isRanger) {
if (context.getUserNickname().substring(0, 1) == "+") {
preferenceHelper.putBoolean(Preferences.IS_RANGER, true)
if (!isConsentGiven) {
_redirectPage.postValue(LoginRedirect.TERMS_AND_SERVICE)
} else if (context.getUserNickname().substring(0, 1) == "+") {
_redirectPage.postValue(LoginRedirect.SET_USER_NAME)
} else {
_redirectPage.postValue(LoginRedirect.MAIN_PAGE)
}
} else {
_redirectPage.postValue(LoginRedirect.INVITE_CODE_PAGE)
preferenceHelper.putBoolean(Preferences.IS_RANGER, false)
_redirectPage.postValue(LoginRedirect.TERMS_AND_SERVICE)
}
}

Expand All @@ -183,5 +190,5 @@ class LoginViewModel(private val context: Context, private val checkUserTouchUse
}

enum class LoginRedirect {
MAIN_PAGE, INVITE_CODE_PAGE, SET_USER_NAME
MAIN_PAGE, SET_USER_NAME, TERMS_AND_SERVICE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.rfcx.ranger.view.login


import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import kotlinx.android.synthetic.main.fragment_terms_and_service.*
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.rfcx.ranger.R
import org.rfcx.ranger.data.remote.success
import org.rfcx.ranger.util.Preferences
import org.rfcx.ranger.view.MainActivityNew
import org.rfcx.ranger.view.base.BaseFragment

class TermsAndServiceFragment : BaseFragment() {
lateinit var listener: LoginListener
private val termsAndServiceViewModel: TermsAndServiceViewModel by viewModel()

override fun onAttach(context: Context) {
super.onAttach(context)
listener = (context as LoginListener)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_terms_and_service, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

termsAndConditionsWebview.loadUrl("https://rfcx.org/terms-of-service-ranger-app-text-only")

checkBox.setOnClickListener {
submitButton.isEnabled = checkBox.isChecked
}

submitButton.setOnClickListener {
val preferenceHelper = context?.let { it1 -> Preferences.getInstance(it1) }
val isRanger = preferenceHelper?.getBoolean(Preferences.IS_RANGER, false)

if (isRanger != null) {
if(isRanger){
termsAndServiceViewModel.acceptTerms()
} else {
listener.openInvitationCodeFragment()
}
}

termsAndServiceViewModel.consentGivenState.observe(this, Observer {
it.success({ state ->
if (state) {
context?.let { it1 -> MainActivityNew.startActivity(it1, null) }
}
}, {
termsProgressBar.visibility = View.GONE
submitButton.visibility = View.VISIBLE

}, {
termsProgressBar.visibility = View.VISIBLE
submitButton.visibility = View.INVISIBLE
})
})
}
}
}
Loading

0 comments on commit 6be0475

Please sign in to comment.