diff --git a/app/src/main/java/com/fastaccess/data/dao/AuthModel.java b/app/src/main/java/com/fastaccess/data/dao/AuthModel.java index f76c0ffc..31eea8b1 100644 --- a/app/src/main/java/com/fastaccess/data/dao/AuthModel.java +++ b/app/src/main/java/com/fastaccess/data/dao/AuthModel.java @@ -24,6 +24,7 @@ public class AuthModel implements Parcelable { private List scopes; private String state; private String note; + private String noteUr; @SerializedName("X-GitHub-OTP") private String otpCode; @Override public int describeContents() { return 0; } @@ -35,6 +36,8 @@ public class AuthModel implements Parcelable { dest.writeStringList(this.scopes); dest.writeString(this.state); dest.writeString(this.note); + dest.writeString(this.noteUr); + dest.writeString(this.otpCode); } protected AuthModel(Parcel in) { @@ -44,6 +47,8 @@ public class AuthModel implements Parcelable { this.scopes = in.createStringArrayList(); this.state = in.readString(); this.note = in.readString(); + this.noteUr = in.readString(); + this.otpCode = in.readString(); } public static final Creator CREATOR = new Creator() { diff --git a/app/src/main/java/com/fastaccess/data/service/LoginRestService.java b/app/src/main/java/com/fastaccess/data/service/LoginRestService.java index 2f31af67..cda6d0b3 100644 --- a/app/src/main/java/com/fastaccess/data/service/LoginRestService.java +++ b/app/src/main/java/com/fastaccess/data/service/LoginRestService.java @@ -5,25 +5,11 @@ import android.support.annotation.NonNull; import com.fastaccess.data.dao.AccessTokenModel; import com.fastaccess.data.dao.AuthModel; -import retrofit2.Response; import retrofit2.http.Body; -import retrofit2.http.DELETE; -import retrofit2.http.Header; -import retrofit2.http.PUT; -import retrofit2.http.Path; +import retrofit2.http.POST; import rx.Observable; public interface LoginRestService { - @PUT("authorizations/clients/{clientId}/{fingerprint}") - Observable login(@NonNull @Path("clientId") String clientId, - @NonNull @Path("clientId") String fingerprint, - @NonNull @Body AuthModel authModel); - @PUT("authorizations/clients/{clientId}/{fingerprint}") - Observable login(@NonNull @Path("clientId") String clientId, - @NonNull @Path("clientId") String fingerprint, - @NonNull @Body AuthModel authModel, - @NonNull @Header("X-GitHub-OTP") String otpCode); - - @DELETE("authorizations/{id}") Observable> deleteToken(@Path("id") long id); + @POST("authorizations") Observable login(@NonNull @Body AuthModel authModel); } diff --git a/app/src/main/java/com/fastaccess/provider/rest/LoginProvider.java b/app/src/main/java/com/fastaccess/provider/rest/LoginProvider.java index 1062cc09..18a5f32b 100644 --- a/app/src/main/java/com/fastaccess/provider/rest/LoginProvider.java +++ b/app/src/main/java/com/fastaccess/provider/rest/LoginProvider.java @@ -1,6 +1,7 @@ package com.fastaccess.provider.rest; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.fastaccess.BuildConfig; import com.fastaccess.data.service.LoginRestService; @@ -30,26 +31,26 @@ public class LoginProvider { .setPrettyPrinting() .create(); - private static OkHttpClient provideOkHttpClient(@NonNull String authToken) { + private static OkHttpClient provideOkHttpClient(@NonNull String authToken, @Nullable String otp) { OkHttpClient.Builder client = new OkHttpClient.Builder(); if (BuildConfig.DEBUG) { client.addInterceptor(new HttpLoggingInterceptor() .setLevel(HttpLoggingInterceptor.Level.BODY)); } - client.addInterceptor(new AuthenticationInterceptor(authToken)); + client.addInterceptor(new AuthenticationInterceptor(authToken, otp)); return client.build(); } - private static Retrofit provideRetrofit(@NonNull String authToken) { + private static Retrofit provideRetrofit(@NonNull String authToken, @Nullable String otp) { return new Retrofit.Builder() .baseUrl(BuildConfig.REST_URL) - .client(provideOkHttpClient(authToken)) + .client(provideOkHttpClient(authToken, otp)) .addConverterFactory(new GithubResponseConverter(gson)) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); } - @NonNull public static LoginRestService getLoginRestService(@NonNull String authToken) { - return provideRetrofit(authToken).create(LoginRestService.class); + @NonNull public static LoginRestService getLoginRestService(@NonNull String authToken, @Nullable String otp) { + return provideRetrofit(authToken, otp).create(LoginRestService.class); } } diff --git a/app/src/main/java/com/fastaccess/provider/rest/interceptors/AuthenticationInterceptor.java b/app/src/main/java/com/fastaccess/provider/rest/interceptors/AuthenticationInterceptor.java index f5951a35..70b20cac 100644 --- a/app/src/main/java/com/fastaccess/provider/rest/interceptors/AuthenticationInterceptor.java +++ b/app/src/main/java/com/fastaccess/provider/rest/interceptors/AuthenticationInterceptor.java @@ -1,5 +1,7 @@ package com.fastaccess.provider.rest.interceptors; +import com.fastaccess.helper.InputHelper; + import java.io.IOException; import lombok.AllArgsConstructor; @@ -11,10 +13,14 @@ import okhttp3.Response; public class AuthenticationInterceptor implements Interceptor { private String authToken; + private String otp; @Override public Response intercept(Chain chain) throws IOException { Request original = chain.request(); Request.Builder builder = original.newBuilder().header("Authorization", authToken); + if (!InputHelper.isEmpty(otp)) { + builder.addHeader("X-GitHub-OTP", otp.trim()); + } Request request = builder.build(); return chain.proceed(request); } diff --git a/app/src/main/java/com/fastaccess/ui/modules/login/LoginPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/login/LoginPresenter.java index 90c728f4..9235bb7a 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/login/LoginPresenter.java +++ b/app/src/main/java/com/fastaccess/ui/modules/login/LoginPresenter.java @@ -1,6 +1,5 @@ package com.fastaccess.ui.modules.login; -import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -16,11 +15,9 @@ import com.fastaccess.provider.rest.RestProvider; import com.fastaccess.ui.base.mvp.presenter.BasePresenter; import java.util.Arrays; -import java.util.UUID; import okhttp3.Credentials; import retrofit2.adapter.rxjava.HttpException; -import rx.Observable; /** * Created by Kosh on 09 Nov 2016, 9:43 PM @@ -28,6 +25,23 @@ import rx.Observable; class LoginPresenter extends BasePresenter implements LoginMvp.Presenter { + @Override public void onError(@NonNull Throwable throwable) { + if (RestProvider.getErrorCode(throwable) == 401 && throwable instanceof HttpException) { + retrofit2.Response response = ((HttpException) throwable).response(); + if (response != null && response.headers() != null) { + String twoFaToken = response.headers().get("X-GitHub-OTP"); + if (twoFaToken != null) { + sendToView(LoginMvp.View::onRequire2Fa); + return; + } else { + sendToView(view -> view.showMessage(R.string.error, R.string.failed_login)); + return; + } + } + } + super.onError(throwable); + } + @Override public void onTokenResponse(@Nullable AccessTokenModel modelResponse) { if (modelResponse != null) { String token = modelResponse.getToken(); @@ -57,46 +71,17 @@ class LoginPresenter extends BasePresenter implements LoginMvp.Pr getView().onEmptyUserName(usernameIsEmpty); getView().onEmptyPassword(passwordIsEmpty); if (!usernameIsEmpty && !passwordIsEmpty) { - UUID uuid = UUID.randomUUID(); String authToken = Credentials.basic(username, password); AuthModel authModel = new AuthModel(); authModel.setScopes(Arrays.asList("user", "repo", "gist", "notifications")); - String uniqueToken = BuildConfig.APPLICATION_ID + "-" + authToken + "-" + Build.MODEL + "-" + uuid; - authModel.setNote(uniqueToken);//make it unique to FastHub. + authModel.setNote(BuildConfig.APPLICATION_ID); authModel.setClientSecret(BuildConfig.GITHUB_SECRET); - Observable loginCall = LoginProvider.getLoginRestService(authToken) - .login(BuildConfig.GITHUB_CLIENT_ID, uniqueToken, authModel); + authModel.setClientId(BuildConfig.GITHUB_CLIENT_ID); + authModel.setNoteUr(BuildConfig.REDIRECT_URL); if (!InputHelper.isEmpty(twoFactorCode)) { - loginCall = LoginProvider.getLoginRestService(authToken) - .login(BuildConfig.GITHUB_CLIENT_ID, uniqueToken, authModel, twoFactorCode); + authModel.setOtpCode(twoFactorCode); } - makeRestCall(loginCall, tokenModel -> { - if (InputHelper.isEmpty(tokenModel.getToken())) { - makeRestCall(LoginProvider.getLoginRestService(authToken).deleteToken(tokenModel.getId()), - response -> login(username, password, null)); - } else { - onTokenResponse(tokenModel); - } - }); + makeRestCall(LoginProvider.getLoginRestService(authToken, twoFactorCode).login(authModel), this::onTokenResponse); } } - - @Override public void onError(@NonNull Throwable throwable) { - if (RestProvider.getErrorCode(throwable) == 401) { - retrofit2.Response response = ((HttpException) throwable).response(); - if (response != null && response.headers() != null) { - String twoFaToken = response.headers().get("X-GitHub-OTP"); - if (twoFaToken != null) { - sendToView(LoginMvp.View::onRequire2Fa); - return; - } else { - sendToView(view -> { - view.showMessage(R.string.error, R.string.failed_login); - }); - return; - } - } - } - super.onError(throwable); - } } diff --git a/app/src/main/res/layouts/other_layouts/layout/message_dialog.xml b/app/src/main/res/layouts/other_layouts/layout/message_dialog.xml index e0171a2b..e71396d6 100644 --- a/app/src/main/res/layouts/other_layouts/layout/message_dialog.xml +++ b/app/src/main/res/layouts/other_layouts/layout/message_dialog.xml @@ -26,6 +26,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:minHeight="150dp" android:paddingEnd="@dimen/spacing_xs_large" android:paddingStart="@dimen/spacing_xs_large">