mirror of
https://github.com/k0shk0sh/FastHub.git
synced 2025-12-08 19:05:54 +00:00
this commit fixed #174 and add optional login via browser for those who don’t trust FastHub login.
This commit is contained in:
parent
23c4745183
commit
247a803e68
@ -14,9 +14,11 @@ import lombok.Setter;
|
||||
|
||||
@Getter @Setter @NoArgsConstructor
|
||||
public class AccessTokenModel implements Parcelable {
|
||||
long id;
|
||||
private long id;
|
||||
private String token;
|
||||
private String hashedToken;
|
||||
private String accessToken;
|
||||
private String tokenType;
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@ -24,15 +26,19 @@ public class AccessTokenModel implements Parcelable {
|
||||
dest.writeLong(this.id);
|
||||
dest.writeString(this.token);
|
||||
dest.writeString(this.hashedToken);
|
||||
dest.writeString(this.accessToken);
|
||||
dest.writeString(this.tokenType);
|
||||
}
|
||||
|
||||
protected AccessTokenModel(Parcel in) {
|
||||
this.id = in.readLong();
|
||||
this.token = in.readString();
|
||||
this.hashedToken = in.readString();
|
||||
this.accessToken = in.readString();
|
||||
this.tokenType = in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<AccessTokenModel> CREATOR = new Parcelable.Creator<AccessTokenModel>() {
|
||||
public static final Creator<AccessTokenModel> CREATOR = new Creator<AccessTokenModel>() {
|
||||
@Override public AccessTokenModel createFromParcel(Parcel source) {return new AccessTokenModel(source);}
|
||||
|
||||
@Override public AccessTokenModel[] newArray(int size) {return new AccessTokenModel[size];}
|
||||
|
||||
@ -3,6 +3,7 @@ package com.fastaccess.data.dao;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fastaccess.data.dao.model.Comment;
|
||||
import com.fastaccess.data.dao.model.Issue;
|
||||
import com.fastaccess.data.dao.model.PullRequest;
|
||||
import com.fastaccess.data.dao.model.Repo;
|
||||
@ -26,6 +27,7 @@ public class PayloadModel implements Parcelable {
|
||||
private PullRequest pullRequest;
|
||||
private String ref;
|
||||
private String refType;
|
||||
private Comment comment;
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
|
||||
@ -6,10 +6,21 @@ import com.fastaccess.data.dao.AccessTokenModel;
|
||||
import com.fastaccess.data.dao.AuthModel;
|
||||
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.Field;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.Headers;
|
||||
import retrofit2.http.POST;
|
||||
import rx.Observable;
|
||||
|
||||
public interface LoginRestService {
|
||||
|
||||
@POST("authorizations") Observable<AccessTokenModel> login(@NonNull @Body AuthModel authModel);
|
||||
|
||||
@FormUrlEncoded @POST("access_token")
|
||||
@Headers("Accept: application/json")
|
||||
Observable<AccessTokenModel> getAccessToken(@NonNull @Field("code") String code,
|
||||
@NonNull @Field("client_id") String clientId,
|
||||
@NonNull @Field("client_secret") String clientSecret,
|
||||
@NonNull @Field("state") String state,
|
||||
@NonNull @Field("redirect_uri") String redirectUrl);
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ public class LoginProvider {
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
|
||||
private static OkHttpClient provideOkHttpClient(@NonNull String authToken, @Nullable String otp) {
|
||||
private static OkHttpClient provideOkHttpClient(@Nullable String authToken, @Nullable String otp) {
|
||||
OkHttpClient.Builder client = new OkHttpClient.Builder();
|
||||
if (BuildConfig.DEBUG) {
|
||||
client.addInterceptor(new HttpLoggingInterceptor()
|
||||
@ -41,7 +41,7 @@ public class LoginProvider {
|
||||
return client.build();
|
||||
}
|
||||
|
||||
private static Retrofit provideRetrofit(@NonNull String authToken, @Nullable String otp) {
|
||||
private static Retrofit provideRetrofit(@Nullable String authToken, @Nullable String otp) {
|
||||
return new Retrofit.Builder()
|
||||
.baseUrl(BuildConfig.REST_URL)
|
||||
.client(provideOkHttpClient(authToken, otp))
|
||||
@ -50,6 +50,16 @@ public class LoginProvider {
|
||||
.build();
|
||||
}
|
||||
|
||||
public static LoginRestService getLoginRestService() {
|
||||
return new Retrofit.Builder()
|
||||
.baseUrl("https://github.com/login/oauth/")
|
||||
.client(provideOkHttpClient(null, null))
|
||||
.addConverterFactory(new GithubResponseConverter(gson))
|
||||
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
|
||||
.build()
|
||||
.create(LoginRestService.class);
|
||||
}
|
||||
|
||||
@NonNull public static LoginRestService getLoginRestService(@NonNull String authToken, @Nullable String otp) {
|
||||
return provideRetrofit(authToken, otp).create(LoginRestService.class);
|
||||
}
|
||||
|
||||
@ -17,7 +17,10 @@ public class AuthenticationInterceptor implements Interceptor {
|
||||
|
||||
@Override public Response intercept(Chain chain) throws IOException {
|
||||
Request original = chain.request();
|
||||
Request.Builder builder = original.newBuilder().header("Authorization", authToken);
|
||||
Request.Builder builder = original.newBuilder();
|
||||
if (!InputHelper.isEmpty(authToken)) {
|
||||
builder.header("Authorization", authToken);
|
||||
}
|
||||
if (!InputHelper.isEmpty(otp)) {
|
||||
builder.addHeader("X-GitHub-OTP", otp.trim());
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import android.view.View;
|
||||
import com.annimon.stream.Collectors;
|
||||
import com.annimon.stream.Stream;
|
||||
import com.fastaccess.data.dao.NameParser;
|
||||
import com.fastaccess.data.dao.PayloadModel;
|
||||
import com.fastaccess.data.dao.SimpleUrlsModel;
|
||||
import com.fastaccess.data.dao.model.Event;
|
||||
import com.fastaccess.data.dao.model.Login;
|
||||
@ -105,13 +106,18 @@ class FeedsPresenter extends BasePresenter<FeedsMvp.View> implements FeedsMvp.Pr
|
||||
NameParser parser = new NameParser(item.getPayload().getForkee().getHtmlUrl());
|
||||
RepoPagerView.startRepoPager(v.getContext(), parser);
|
||||
} else {
|
||||
if (item.getPayload() != null && item.getPayload().getIssue() != null) {
|
||||
SchemeParser.launchUri(v.getContext(), Uri.parse(item.getPayload().getIssue().getHtmlUrl()), true);
|
||||
} else if (item.getPayload() != null && item.getPayload().getPullRequest() != null) {
|
||||
SchemeParser.launchUri(v.getContext(), Uri.parse(item.getPayload().getPullRequest().getHtmlUrl()), true);
|
||||
} else {
|
||||
Repo repoModel = item.getRepo();
|
||||
if (item.getRepo() != null) SchemeParser.launchUri(v.getContext(), Uri.parse(repoModel.getName()), true);
|
||||
PayloadModel payloadModel = item.getPayload();
|
||||
if (payloadModel != null) {
|
||||
if (item.getPayload().getIssue() != null) {
|
||||
SchemeParser.launchUri(v.getContext(), Uri.parse(item.getPayload().getIssue().getHtmlUrl()), true);
|
||||
} else if (item.getPayload().getPullRequest() != null) {
|
||||
SchemeParser.launchUri(v.getContext(), Uri.parse(item.getPayload().getPullRequest().getHtmlUrl()), true);
|
||||
} else if (item.getPayload().getComment() != null) {
|
||||
SchemeParser.launchUri(v.getContext(), Uri.parse(item.getPayload().getComment().getHtmlUrl()), true);
|
||||
} else {
|
||||
Repo repoModel = item.getRepo();
|
||||
if (item.getRepo() != null) SchemeParser.launchUri(v.getContext(), Uri.parse(repoModel.getName()), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.fastaccess.ui.modules.login;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
@ -26,6 +28,10 @@ interface LoginMvp {
|
||||
|
||||
interface Presenter extends BaseMvp.FAPresenter {
|
||||
|
||||
@NonNull Uri getAuthorizationUrl();
|
||||
|
||||
void onHandleAuthIntent(@Nullable Intent intent);
|
||||
|
||||
void onTokenResponse(@Nullable AccessTokenModel response);
|
||||
|
||||
void onUserResponse(@Nullable Login response);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.fastaccess.ui.modules.login;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
@ -9,6 +11,7 @@ import com.fastaccess.data.dao.AccessTokenModel;
|
||||
import com.fastaccess.data.dao.AuthModel;
|
||||
import com.fastaccess.data.dao.model.Login;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.helper.Logger;
|
||||
import com.fastaccess.helper.PrefGetter;
|
||||
import com.fastaccess.provider.rest.LoginProvider;
|
||||
import com.fastaccess.provider.rest.RestProvider;
|
||||
@ -44,7 +47,7 @@ class LoginPresenter extends BasePresenter<LoginMvp.View> implements LoginMvp.Pr
|
||||
|
||||
@Override public void onTokenResponse(@Nullable AccessTokenModel modelResponse) {
|
||||
if (modelResponse != null) {
|
||||
String token = modelResponse.getToken();
|
||||
String token = modelResponse.getToken() != null ? modelResponse.getToken() : modelResponse.getAccessToken();
|
||||
if (!InputHelper.isEmpty(token)) {
|
||||
PrefGetter.setToken(token);
|
||||
makeRestCall(RestProvider.getUserService().getUser(), this::onUserResponse);
|
||||
@ -54,6 +57,37 @@ class LoginPresenter extends BasePresenter<LoginMvp.View> implements LoginMvp.Pr
|
||||
sendToView(view -> view.showMessage(R.string.error, R.string.failed_login));
|
||||
}
|
||||
|
||||
@NonNull @Override public Uri getAuthorizationUrl() {
|
||||
return new Uri.Builder()
|
||||
.scheme("https")
|
||||
.authority("github.com")
|
||||
.appendPath("login")
|
||||
.appendPath("oauth")
|
||||
.appendPath("authorize")
|
||||
.appendQueryParameter("client_id", BuildConfig.GITHUB_CLIENT_ID)
|
||||
.appendQueryParameter("redirect_uri", BuildConfig.REDIRECT_URL)
|
||||
.appendQueryParameter("scope", "user,repo,gist,notifications")
|
||||
.appendQueryParameter("state", BuildConfig.APPLICATION_ID)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override public void onHandleAuthIntent(@Nullable Intent intent) {
|
||||
Logger.e(intent);
|
||||
if (intent != null && intent.getData() != null) {
|
||||
Uri uri = intent.getData();
|
||||
Logger.e(uri.toString());
|
||||
if (uri.toString().startsWith(BuildConfig.REDIRECT_URL)) {
|
||||
String tokenCode = uri.getQueryParameter("code");
|
||||
if (!InputHelper.isEmpty(tokenCode)) {
|
||||
makeRestCall(LoginProvider.getLoginRestService().getAccessToken(tokenCode, BuildConfig.GITHUB_CLIENT_ID,
|
||||
BuildConfig.GITHUB_SECRET, BuildConfig.APPLICATION_ID, BuildConfig.REDIRECT_URL), this::onTokenResponse);
|
||||
} else {
|
||||
sendToView(view -> view.showMessage(R.string.error, R.string.error));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onUserResponse(@Nullable Login userModel) {
|
||||
if (userModel != null) {
|
||||
userModel.setToken(PrefGetter.getToken());
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.fastaccess.ui.modules.login;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
@ -11,6 +12,7 @@ import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.helper.ActivityHelper;
|
||||
import com.fastaccess.helper.AnimHelper;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.ui.base.BaseActivity;
|
||||
@ -34,6 +36,11 @@ public class LoginView extends BaseActivity<LoginMvp.View, LoginPresenter> imple
|
||||
@BindView(R.id.login) FloatingActionButton login;
|
||||
@BindView(R.id.progress) ProgressBar progress;
|
||||
|
||||
@OnClick(R.id.browserLogin) void onOpenBrowser() {
|
||||
Uri uri = getPresenter().getAuthorizationUrl();
|
||||
ActivityHelper.forceOpenInBrowser(this, uri);
|
||||
}
|
||||
|
||||
@OnClick(R.id.login) public void onClick() {
|
||||
getPresenter().login(InputHelper.toString(username),
|
||||
InputHelper.toString(password), InputHelper.toString(twoFactor));
|
||||
@ -75,8 +82,10 @@ public class LoginView extends BaseActivity<LoginMvp.View, LoginPresenter> imple
|
||||
|
||||
@Override public void onSuccessfullyLoggedIn() {
|
||||
hideProgress();
|
||||
startActivity(new Intent(this, MainView.class));
|
||||
finish();
|
||||
Intent intent = new Intent(this, MainView.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
finishAffinity();
|
||||
}
|
||||
|
||||
@Override protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -107,4 +116,16 @@ public class LoginView extends BaseActivity<LoginMvp.View, LoginPresenter> imple
|
||||
progress.setVisibility(View.GONE);
|
||||
login.show();
|
||||
}
|
||||
|
||||
@Override protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
getPresenter().onHandleAuthIntent(intent);
|
||||
setIntent(null);
|
||||
}
|
||||
|
||||
@Override protected void onResume() {
|
||||
super.onResume();
|
||||
getPresenter().onHandleAuthIntent(getIntent());
|
||||
setIntent(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import android.view.View;
|
||||
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.FragmentPagerAdapterModel;
|
||||
import com.fastaccess.data.dao.NameParser;
|
||||
import com.fastaccess.data.dao.model.Commit;
|
||||
import com.fastaccess.helper.ActivityHelper;
|
||||
import com.fastaccess.helper.BundleConstant;
|
||||
@ -25,6 +26,7 @@ import com.fastaccess.helper.ViewHelper;
|
||||
import com.fastaccess.provider.scheme.SchemeParser;
|
||||
import com.fastaccess.ui.adapter.FragmentsPagerAdapter;
|
||||
import com.fastaccess.ui.base.BaseActivity;
|
||||
import com.fastaccess.ui.modules.repos.RepoPagerView;
|
||||
import com.fastaccess.ui.modules.repos.code.commit.details.comments.CommitCommentsView;
|
||||
import com.fastaccess.ui.widgets.AvatarLayout;
|
||||
import com.fastaccess.ui.widgets.FontTextView;
|
||||
@ -127,6 +129,13 @@ public class CommitPagerView extends BaseActivity<CommitPagerMvp.View, CommitPag
|
||||
if (item.getItemId() == R.id.share) {
|
||||
if (getPresenter().getCommit() != null) ActivityHelper.shareUrl(this, getPresenter().getCommit().getHtmlUrl());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.toRepo) {
|
||||
NameParser nameParser = new NameParser("");
|
||||
nameParser.setName(getPresenter().getRepoId());
|
||||
nameParser.setUsername(getPresenter().getLogin());
|
||||
RepoPagerView.startRepoPager(this, nameParser);
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@ -74,6 +74,11 @@ class RepoContributorsPresenter extends BasePresenter<RepoContributorsMvp.View>
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onError(@NonNull Throwable throwable) {
|
||||
onWorkOffline();
|
||||
super.onError(throwable);
|
||||
}
|
||||
|
||||
@Override public void onWorkOffline() {
|
||||
if (users.isEmpty()) {
|
||||
manageSubscription(RxHelper.getObserver(User.getUserContributorList(repoId))
|
||||
|
||||
@ -30,7 +30,6 @@ public class RepoClosedIssuesView extends BaseFragment<RepoIssuesMvp.View, RepoI
|
||||
@BindView(R.id.stateLayout) StateLayout stateLayout;
|
||||
private OnLoadMore<IssueState> onLoadMore;
|
||||
private IssuesAdapter adapter;
|
||||
private final IssueState issueState = IssueState.closed;
|
||||
|
||||
public static RepoClosedIssuesView newInstance(@NonNull String repoId, @NonNull String login) {
|
||||
RepoClosedIssuesView view = new RepoClosedIssuesView();
|
||||
@ -64,7 +63,7 @@ public class RepoClosedIssuesView extends BaseFragment<RepoIssuesMvp.View, RepoI
|
||||
recycler.setAdapter(adapter);
|
||||
recycler.addOnScrollListener(getLoadMore());
|
||||
if (savedInstanceState == null) {
|
||||
getPresenter().onFragmentCreated(getArguments(), issueState);
|
||||
getPresenter().onFragmentCreated(getArguments(), IssueState.closed);
|
||||
} else if (getPresenter().getIssues().isEmpty() && !getPresenter().isApiCalled()) {
|
||||
onRefresh();
|
||||
}
|
||||
@ -93,7 +92,7 @@ public class RepoClosedIssuesView extends BaseFragment<RepoIssuesMvp.View, RepoI
|
||||
if (onLoadMore == null) {
|
||||
onLoadMore = new OnLoadMore<>(getPresenter());
|
||||
}
|
||||
onLoadMore.setParameter(issueState);
|
||||
onLoadMore.setParameter(IssueState.closed);
|
||||
return onLoadMore;
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ interface RepoIssuesMvp {
|
||||
BaseViewHolder.OnItemClickListener<Issue>,
|
||||
BaseMvp.PaginationListener<IssueState> {
|
||||
|
||||
void onFragmentCreated(@NonNull Bundle bundle, IssueState issueState);
|
||||
void onFragmentCreated(@NonNull Bundle bundle, @NonNull IssueState issueState);
|
||||
|
||||
void onWorkOffline();
|
||||
|
||||
|
||||
@ -35,7 +35,6 @@ public class RepoOpenedIssuesView extends BaseFragment<RepoIssuesMvp.View, RepoI
|
||||
@BindView(R.id.stateLayout) StateLayout stateLayout;
|
||||
private OnLoadMore<IssueState> onLoadMore;
|
||||
private IssuesAdapter adapter;
|
||||
private final IssueState issueState = IssueState.open;
|
||||
private RepoIssuesPagerMvp.View pagerCallback;
|
||||
|
||||
public static RepoOpenedIssuesView newInstance(@NonNull String repoId, @NonNull String login) {
|
||||
@ -84,7 +83,7 @@ public class RepoOpenedIssuesView extends BaseFragment<RepoIssuesMvp.View, RepoI
|
||||
recycler.setAdapter(adapter);
|
||||
recycler.addOnScrollListener(getLoadMore());
|
||||
if (savedInstanceState == null) {
|
||||
getPresenter().onFragmentCreated(getArguments(), issueState);
|
||||
getPresenter().onFragmentCreated(getArguments(), IssueState.open);
|
||||
} else if (getPresenter().getIssues().isEmpty() && !getPresenter().isApiCalled()) {
|
||||
onRefresh();
|
||||
}
|
||||
@ -122,7 +121,7 @@ public class RepoOpenedIssuesView extends BaseFragment<RepoIssuesMvp.View, RepoI
|
||||
if (onLoadMore == null) {
|
||||
onLoadMore = new OnLoadMore<>(getPresenter());
|
||||
}
|
||||
onLoadMore.setParameter(issueState);
|
||||
onLoadMore.setParameter(IssueState.open);
|
||||
return onLoadMore;
|
||||
}
|
||||
|
||||
|
||||
@ -125,6 +125,31 @@
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:visibility="gone"/>
|
||||
</FrameLayout>
|
||||
|
||||
<com.fastaccess.ui.widgets.FontTextView
|
||||
style="@style/TextAppearance.AppCompat.Small"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="@dimen/spacing_normal"
|
||||
android:background="@drawable/bottom_border"
|
||||
android:gravity="center"
|
||||
android:text="@string/or_character"/>
|
||||
|
||||
<com.fastaccess.ui.widgets.FontTextView
|
||||
style="@style/TextAppearance.AppCompat.Small"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="@dimen/spacing_normal"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/login_using_your_default_browser"/>
|
||||
|
||||
<com.fastaccess.ui.widgets.FontButton
|
||||
android:id="@+id/browserLogin"
|
||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/open_in_browser"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit c1d32068b64305248f05fb67785b013ccd2ef641
|
||||
Subproject commit c3f8d88974b74c91665bbf7efaa0dcadac498d44
|
||||
Loading…
x
Reference in New Issue
Block a user