Skip to content
This repository has been archived by the owner on Aug 4, 2019. It is now read-only.

Feature/codeverification #20

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
28 changes: 27 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,36 @@ private String generateVersionName() {

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//retrofit
implementation "com.squareup.retrofit2:converter-gson:2.5.0"

//koin
implementation 'org.koin:koin-android-viewmodel:2.0.1'
implementation 'org.koin:koin-android:2.0.1'

//rxJava
implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'

implementation 'com.github.EhsanMashhadi:helpdroid:0.9.0'
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'

implementation ('com.alimuzaffar.lib:pinentryedittext:2.0.6') {
exclude group: 'androidx.appcompat', module: 'appcompat'
}
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'

//test
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-inline:3.0.0"
testImplementation 'org.koin:koin-test:2.0.1'
testImplementation "android.arch.core:core-testing:1.1.1"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package de.netalic.peacock

import androidx.test.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4

import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand Down
33 changes: 24 additions & 9 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.netalic.peacock">

<application android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"/>
</manifest>
xmlns:tools="http://schemas.android.com/tools" package="de.netalic.peacock">

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

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:name="de.netalic.MyApp"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity">

<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>

</manifest>
38 changes: 38 additions & 0 deletions app/src/main/java/de/netalic/MyApp.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package de.netalic

import android.app.Application
import de.netalic.peacock.di.apiModule
import de.netalic.peacock.di.repositoryModule
import de.netalic.peacock.di.viewModelModule
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin

class MyApp : Application() {


override fun onCreate() {
super.onCreate()

instance = this

startKoin {

androidLogger()
androidContext(this@MyApp)

modules(
listOf(
repositoryModule,
apiModule,
viewModelModule
)
)
}
}

companion object {

lateinit var instance: Application
}
}
17 changes: 17 additions & 0 deletions app/src/main/java/de/netalic/peacock/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package de.netalic.peacock

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import de.netalic.peacock.ui.registeration.codeverification.CodeVerificationFragment

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

supportFragmentManager.beginTransaction().add(R.id.frameLayout_mainActivity_fragmentContainer,
CodeVerificationFragment()).commit()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package de.netalic.peacock.data.exception

class ActivationCodeIsNotValid :Throwable()
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package de.netalic.peacock.data.exception

class BadRequestException : Throwable()
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package de.netalic.peacock.data.exception

class InvalidDeviceName:Throwable()
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package de.netalic.peacock.data.exception

class InvalidUdidOrPhone :Throwable()
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package de.netalic.peacock.data.exception

class ServerException : Throwable()
30 changes: 30 additions & 0 deletions app/src/main/java/de/netalic/peacock/data/model/MyResponse.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package de.netalic.peacock.data.model

data class MyResponse<T>(
val status: Status,
val data: T? = null,
val throwable: Throwable? = null
) {

companion object {

fun <T> loading(): MyResponse<T> {
return MyResponse(status = Status.LOADING)
}

fun <T> success(data: T): MyResponse<T> {
return MyResponse(status = Status.SUCCESS, data = data)
}

fun <T> failed(throwable: Throwable): MyResponse<T> {
return MyResponse(status = Status.FAILED, throwable = throwable)
}
}
}

enum class Status {

LOADING,
SUCCESS,
FAILED
}
9 changes: 9 additions & 0 deletions app/src/main/java/de/netalic/peacock/data/model/User.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package de.netalic.peacock.data.model

data class User( val phone:String,
val udid :String,
val deviceName:String,
val deviceType:String,
val firebaseRegistrationId:String,
val actionCode:String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package de.netalic.peacock.data.repository

import de.netalic.peacock.data.model.User
import de.netalic.peacock.data.webservice.InterfaceApi
import io.reactivex.Single
import okhttp3.ResponseBody
import retrofit2.Response


class UserRepository(private val usrApi:InterfaceApi){


fun bind(user:User) :Single<Response<ResponseBody>>{

return usrApi.bind(user.phone,user.udid,user.deviceName,user.deviceType,user.firebaseRegistrationId,
user.actionCode)
}

}
87 changes: 87 additions & 0 deletions app/src/main/java/de/netalic/peacock/data/webservice/ApiClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package de.netalic.peacock.data.webservice


import com.franmontiel.persistentcookiejar.PersistentCookieJar
import com.franmontiel.persistentcookiejar.cache.SetCookieCache
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
import de.netalic.MyApp
import nuesoft.helpdroid.network.SharedPreferencesJwtPersistor
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.ResponseBody
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException

class ApiClient {


companion object {
private var sRetrofit: Retrofit? = null
private var sApi: InterfaceApi? = null


private fun getClient(): Retrofit {

if (sRetrofit == null) {

val okHttpClient = OkHttpClient().newBuilder()
val cookieJar = PersistentCookieJar(SetCookieCache(), SharedPrefsCookiePersistor(MyApp.instance))
okHttpClient.cookieJar(cookieJar).addInterceptor(AuthorizationInterceptor())

sRetrofit = Retrofit.Builder().baseUrl("https://nightly-alpha.carrene.com/apiv1/")
.client(okHttpClient.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
return sRetrofit!!
}


fun getService(): InterfaceApi? {

if (sApi == null) {
sApi = getClient().create(InterfaceApi::class.java)
}
return sApi
}
}

private class AuthorizationInterceptor : Interceptor {

internal var sharedPreferencesJwtPersistor = SharedPreferencesJwtPersistor(MyApp.instance)

@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {

val token = sharedPreferencesJwtPersistor.get()
var request = chain.request()

if (token != null) {
request = request.newBuilder().addHeader("Authorization", "Bearer $token").build()
}

var response = chain.proceed(request)

if (response.request().method() == "BIND" && response.code() == 200) {

val responseBodyString = response.body()!!.string()
val contentType = response.body()!!.contentType()
val body = ResponseBody.create(contentType, responseBodyString)
response = response.newBuilder().body(body).build()
}

val newJwtToken = response.header("X-New-JWT-Token")

if (newJwtToken != null) {
sharedPreferencesJwtPersistor.save(newJwtToken)
}

return response
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package de.netalic.peacock.data.webservice

import io.reactivex.Single
import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.HTTP

interface InterfaceApi {

@FormUrlEncoded
@HTTP(method = "BIND",path ="login", hasBody = true)
fun bind(@Field("phone") phone:String , @Field("udid") udid:String ,
@Field("deviceName") deviceName:String,@Field("deviceType") deviceType:String ,
@Field("firebaseRegistrationId") firebaseRegistrationId:String,
@Field("activationCode") activationCode:String):Single<Response<ResponseBody>>
}
32 changes: 32 additions & 0 deletions app/src/main/java/de/netalic/peacock/di/AppModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package de.netalic.peacock.di

import de.netalic.peacock.data.repository.UserRepository
import de.netalic.peacock.data.webservice.ApiClient
import de.netalic.peacock.ui.registeration.codeverification.CodeVerificationViewModel
import org.koin.android.viewmodel.dsl.viewModel
import org.koin.dsl.module

val repositoryModule = module {

single {

UserRepository(get())
}
}
val viewModelModule = module {

viewModel {

CodeVerificationViewModel(get())
}
}

val apiModule= module {

single {

ApiClient.getService()

}
}

19 changes: 19 additions & 0 deletions app/src/main/java/de/netalic/peacock/ui/base/BaseFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package de.netalic.peacock.ui.base

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment

abstract class BaseFragment : Fragment() {

abstract fun initUiListener()
abstract fun initUiComponent()

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

initUiListener()
initUiComponent()
}

}
Loading