Skip to content

Commit a646c2e

Browse files
committed
Login complete
Need fix on recycler view
1 parent c9b7f83 commit a646c2e

3 files changed

Lines changed: 190 additions & 153 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222

2323
<category android:name="android.intent.category.LAUNCHER" />
2424
</intent-filter>
25+
</activity>
26+
<activity
27+
android:name=".AnimeDetailsActivity"
28+
android:exported="true">
29+
</activity>
30+
<activity
31+
android:name=".LoginActivity"
32+
android:exported="true">
2533
<intent-filter>
2634
<action android:name="android.intent.action.VIEW" />
2735

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,174 @@
11
package pmm.ignacio.theanimedatabase;
22

3+
import android.content.Intent;
4+
import android.content.SharedPreferences;
5+
import android.net.Uri;
36
import android.os.Bundle;
7+
import android.preference.PreferenceManager;
8+
import android.util.Log;
9+
import android.widget.Button;
410

11+
import androidx.annotation.NonNull;
512
import androidx.appcompat.app.AppCompatActivity;
613

14+
import okhttp3.MultipartBody;
15+
import okhttp3.RequestBody;
16+
import pmm.ignacio.theanimedatabase.Anime.AnimeToken;
17+
import pmm.ignacio.theanimedatabase.Anime.AuthAnimeService;
18+
import retrofit2.Call;
19+
import retrofit2.Callback;
20+
import retrofit2.Response;
21+
import retrofit2.Retrofit;
22+
import retrofit2.converter.gson.GsonConverterFactory;
23+
724
public class LoginActivity extends AppCompatActivity {
825

26+
private String requestToken;
27+
private static final String TAG = LoginActivity.class.getSimpleName();
28+
private String codeVerifier;
29+
private static final String AUTH_URL = "https://myanimelist.net/v1/oauth2/";
30+
private static final String CLIENT_ID = BuildConfig.CLIENT_ID;
31+
private static final String REDIRECT_URL = "theanimedatabase://callback";
32+
public AnimeToken animeToken;
33+
public String authorization;
34+
935
@Override
1036
protected void onCreate(Bundle savedInstanceState) {
1137
super.onCreate(savedInstanceState);
1238
setContentView(R.layout.login_screen);
1339

1440
// Check if user is already logged in
15-
// TODO
41+
SharedPreferences defPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
42+
String accessToken = defPref.getString("accessToken", null);
43+
if (accessToken != null){
44+
// Goto Main activity
45+
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
46+
startActivity(intent);
47+
}
48+
49+
50+
Button loginButton = findViewById(R.id.login_button);
51+
loginButton.setOnClickListener(v -> {
52+
// OAuth
53+
if (requestToken == null) {
54+
Log.i(TAG, "No code found, requesting new one : " + requestToken);
55+
OAuthRequestPhase1();
56+
}
57+
});
1658

1759

60+
}
61+
62+
@Override
63+
protected void onResume() {
64+
super.onResume();
1865

66+
// OAuth: Get code from browser
67+
Uri uri = getIntent().getData();
68+
if (uri != null && uri.toString().startsWith(REDIRECT_URL) && animeToken == null) {
69+
requestToken = uri.getQueryParameter("code");
70+
Log.d(TAG, "[OAUTH] request token: " + requestToken);
71+
OAuthRequestPhase2();
72+
}
1973
}
74+
75+
76+
77+
private void OAuthRequestPhase1() {
78+
// ----- Request code -----
79+
// Gen Code challenge (PKCE protocol)
80+
//codeVerifier = PkceGenerator.generateVerifier(64);
81+
// V Por algun motivo si no lo establezco a mano, no autentifica. ¯\_(ツ)_/¯
82+
codeVerifier = "1234567890123456789012345678901234567890123456789012345678901234";
83+
Log.d(TAG, "[OAUTH] code verifier: " + codeVerifier);
84+
85+
// Prepare request
86+
Uri uri = Uri.parse(AUTH_URL + "authorize")
87+
.buildUpon()
88+
.appendQueryParameter("response_type", "code")
89+
.appendQueryParameter("client_id", CLIENT_ID)
90+
.appendQueryParameter("code_challenge", codeVerifier)
91+
.appendQueryParameter("state", "theanimedatabase")
92+
.appendQueryParameter("redirect_uri", REDIRECT_URL)
93+
.appendQueryParameter("code_challenge_method", "plain")
94+
.build();
95+
96+
// Launch browser
97+
Log.d(TAG, "[OAUTH] launch uri: " + uri.toString());
98+
99+
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
100+
SharedPreferences.Editor editor = pref.edit();
101+
editor.putString("codeVerifier", codeVerifier);
102+
editor.apply();
103+
104+
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
105+
startActivity(intent);
106+
}
107+
108+
private void OAuthRequestPhase2() {
109+
// ----- Request token -----
110+
// Create retrofit service
111+
Retrofit retrofit = new Retrofit.Builder()
112+
.baseUrl(AUTH_URL)
113+
.addConverterFactory(GsonConverterFactory.create())
114+
.build();
115+
AuthAnimeService authService = retrofit.create(AuthAnimeService.class);
116+
117+
SharedPreferences defPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
118+
codeVerifier = defPref.getString("codeVerifier","");
119+
120+
// Prepare request
121+
RequestBody body = new MultipartBody.Builder()
122+
.setType(MultipartBody.FORM)
123+
.addFormDataPart("client_id", CLIENT_ID)
124+
.addFormDataPart("code", requestToken)
125+
.addFormDataPart("code_verifier", codeVerifier)
126+
.addFormDataPart("grant_type", "authorization_code")
127+
.addFormDataPart("redirect_uri", REDIRECT_URL)
128+
.build();
129+
130+
// Send request
131+
Log.d(TAG, "[OAUTH] requesting access token...");
132+
Call<AnimeToken> call = authService.getAnimeToken(body);
133+
call.enqueue(new Callback<AnimeToken>() {
134+
@Override
135+
public void onResponse(@NonNull Call<AnimeToken> call, @NonNull Response<AnimeToken> response) {
136+
// Receive response
137+
if (response.isSuccessful()) {
138+
animeToken = response.body();
139+
assert animeToken != null; // Avoid annoying warning
140+
assert response.body() != null; // x2
141+
authorization = animeToken.tokenType + " " + animeToken.accessToken;
142+
Log.d(TAG, "[OAUTH] --- TOKEN OBTAINED ---");
143+
Log.d(TAG, "[OAUTH] access token: " + animeToken.accessToken);
144+
Log.d(TAG, "[OAUTH] token type: " + animeToken.tokenType);
145+
Log.d(TAG, "[OAUTH] expires in (mls): " + animeToken.expiresIn);
146+
Log.d(TAG, "[OAUTH] refresh token: " + animeToken.refreshToken);
147+
148+
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
149+
SharedPreferences.Editor editor = pref.edit();
150+
editor.putString("accessToken", animeToken.accessToken);
151+
editor.putString("refreshToken", animeToken.refreshToken);
152+
editor.putString("authorization", authorization);
153+
editor.apply();
154+
155+
// Goto Main activity
156+
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
157+
startActivity(intent);
158+
159+
} else {
160+
Log.e(TAG, "[OAUTH] --- TOKEN ERROR ---");
161+
Log.e(TAG, "[OAUTH] error: " + (response.body() != null ? response.body().errorType : null));
162+
Log.e(TAG, "[OAUTH] message: " + response.body().message);
163+
Log.e(TAG, "[OAUTH] hint: " + response.body().hint);
164+
}
165+
}
166+
167+
@Override
168+
public void onFailure(@NonNull Call<AnimeToken> call, @NonNull Throwable t) {
169+
Log.e(TAG, "[OAUTH] Error calling API: " + t.getMessage());
170+
}
171+
});
172+
}
173+
20174
}

0 commit comments

Comments
 (0)