This commit is contained in:
Stefan Schueller 2018-12-17 18:11:41 +01:00
parent c86ebdcf2c
commit 67fcb14b0c
15 changed files with 330 additions and 44 deletions

View File

@ -73,3 +73,6 @@ android {
} }
} }
dependencies {
implementation 'com.android.support.constraint:constraint-layout:+'
}

View File

@ -16,18 +16,19 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning"> tools:ignore="GoogleAppIndexingWarning">
<activity
<activity android:name=".activity.VideoListActivity" android:name=".activity.VideoListActivity"
android:launchMode="singleTop"> android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SEARCH" /> <action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.app.searchable" android:name="android.app.searchable"
android:resource="@xml/searchable"> android:resource="@xml/searchable"></meta-data>
</meta-data>
</activity> </activity>
<activity <activity
android:name=".activity.LoginActivity" android:name=".activity.LoginActivity"
@ -50,6 +51,10 @@
android:exported="false" /> android:exported="false" />
<activity android:name=".activity.SelectServerActivity" /> <activity android:name=".activity.SelectServerActivity" />
<service android:name=".service.VideoPlayerService" /> <service android:name=".service.VideoPlayerService" />
<activity android:name=".activity.UserActivity"></activity>
</application> </application>
</manifest> </manifest>

View File

@ -1,49 +1,33 @@
package net.schueller.peertube.activity; package net.schueller.peertube.activity;
import android.os.StrictMode; import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Toast;
import net.schueller.peertube.R; import net.schueller.peertube.R;
import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.model.OauthClient; import net.schueller.peertube.model.OauthClient;
import net.schueller.peertube.model.Token; import net.schueller.peertube.model.Token;
import net.schueller.peertube.model.VideoList;
import net.schueller.peertube.network.AuthenticationService; import net.schueller.peertube.network.AuthenticationService;
import net.schueller.peertube.network.GetVideoDataService;
import net.schueller.peertube.network.RetrofitInstance; import net.schueller.peertube.network.RetrofitInstance;
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response;
public class LoginActivity extends AppCompatActivity { public class LoginActivity extends AppCompatActivity {
OkHttpClient client = new OkHttpClient();
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private String TAG = "LoginActivity"; private String TAG = "LoginActivity";
// UI references. // UI references.
private AutoCompleteTextView mEmailView; private AutoCompleteTextView mEmailView;
private EditText mPasswordView; private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -57,17 +41,12 @@ public class LoginActivity extends AppCompatActivity {
mEmailView = findViewById(R.id.email); mEmailView = findViewById(R.id.email);
mPasswordView = findViewById(R.id.password); mPasswordView = findViewById(R.id.password);
// if (android.os.Build.VERSION.SDK_INT > 9) {
// StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
// StrictMode.setThreadPolicy(policy);
// }
} }
private void attemptLogin() { private void attemptLogin() {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
// Reset errors. // Reset errors.
mEmailView.setError(null); mEmailView.setError(null);
@ -84,15 +63,18 @@ public class LoginActivity extends AppCompatActivity {
AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class); AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class);
Call<OauthClient> call = service.getOauthClientLocal(); Call<OauthClient> call = service.getOauthClientLocal();
call.enqueue(new Callback<OauthClient>() { call.enqueue(new Callback<OauthClient>() {
@Override @Override
public void onResponse(@NonNull Call<OauthClient> call, @NonNull retrofit2.Response<OauthClient> response) { public void onResponse(@NonNull Call<OauthClient> call, @NonNull Response<OauthClient> response) {
if (response.body() != null) { if (response.isSuccessful()) {
OauthClient oauthClient = response.body();
Call<Token> call2 = service.getAuthenticationToken( Call<Token> call2 = service.getAuthenticationToken(
response.body().getClientId(), oauthClient.getClientId(),
response.body().getClientSecret(), oauthClient.getClientSecret(),
"code", "code",
"password", "password",
"upload", "upload",
@ -103,11 +85,20 @@ public class LoginActivity extends AppCompatActivity {
@Override @Override
public void onResponse(@NonNull Call<Token> call2, @NonNull retrofit2.Response<Token> response2) { public void onResponse(@NonNull Call<Token> call2, @NonNull retrofit2.Response<Token> response2) {
if (response2.body() != null) { if (response2.isSuccessful()) {
Log.wtf(TAG, response2.body().getAccessToken());
Log.wtf(TAG, response2.body().getExpiresIn()); Token token = response2.body();
Log.wtf(TAG, response2.body().getRefreshToken());
Log.wtf(TAG, response2.body().getTokenType()); SharedPreferences.Editor editor = sharedPref.edit();
// TODO: calc expiration
//editor.putInt(getString(R.string.pref_token_expiration), token.getRefreshToken());
editor.putString(getString(R.string.pref_token_access), token.getAccessToken());
editor.putString(getString(R.string.pref_token_refresh), token.getExpiresIn());
editor.putString(getString(R.string.pref_token_type), token.getTokenType());
editor.commit();
} else { } else {
Log.wtf(TAG, response2.toString()); Log.wtf(TAG, response2.toString());
} }

View File

@ -0,0 +1,41 @@
package net.schueller.peertube.activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import net.schueller.peertube.R;
public class UserActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user);
init();
}
private void init() {
// try to get user data
if (!getUserData()) {
Intent intent = new Intent(this, LoginActivity.class);
this.startActivity(intent);
}
}
private boolean getUserData() {
// TODO
return false;
}
@Override
protected void onResume() {
super.onResume();
init();
}
}

View File

@ -103,10 +103,10 @@ public class VideoListActivity extends AppCompatActivity {
case R.id.navigation_account: case R.id.navigation_account:
//Log.v(TAG, "navigation_account"); //Log.v(TAG, "navigation_account");
Toast.makeText(VideoListActivity.this, "Account Not Implemented", Toast.LENGTH_SHORT).show(); // Toast.makeText(VideoListActivity.this, "Account Not Implemented", Toast.LENGTH_SHORT).show();
// Intent intent = new Intent(this, LoginActivity.class); Intent intent = new Intent(this, UserActivity.class);
// this.startActivity(intent); this.startActivity(intent);
return false; return false;
} }

View File

@ -0,0 +1,144 @@
package net.schueller.peertube.model;
public class Me {
private Integer id;
private Account account;
private Boolean autoPlayVideo;
private Boolean blocked;
private String blockedReason;
private String createdAt;
private String email;
private String emailVerified;
private String nsfwPolicy;
private Integer role;
private String roleLabel;
private String username;
// private VideoChannels videoChannels;
private Integer videoQuota;
private Integer videoQuotaDaily;
private String webTorrentEnabled;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public Boolean getAutoPlayVideo() {
return autoPlayVideo;
}
public void setAutoPlayVideo(Boolean autoPlayVideo) {
this.autoPlayVideo = autoPlayVideo;
}
public Boolean getBlocked() {
return blocked;
}
public void setBlocked(Boolean blocked) {
this.blocked = blocked;
}
public String getBlockedReason() {
return blockedReason;
}
public void setBlockedReason(String blockedReason) {
this.blockedReason = blockedReason;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmailVerified() {
return emailVerified;
}
public void setEmailVerified(String emailVerified) {
this.emailVerified = emailVerified;
}
public String getNsfwPolicy() {
return nsfwPolicy;
}
public void setNsfwPolicy(String nsfwPolicy) {
this.nsfwPolicy = nsfwPolicy;
}
public Integer getRole() {
return role;
}
public void setRole(Integer role) {
this.role = role;
}
public String getRoleLabel() {
return roleLabel;
}
public void setRoleLabel(String roleLabel) {
this.roleLabel = roleLabel;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getVideoQuota() {
return videoQuota;
}
public void setVideoQuota(Integer videoQuota) {
this.videoQuota = videoQuota;
}
public Integer getVideoQuotaDaily() {
return videoQuotaDaily;
}
public void setVideoQuotaDaily(Integer videoQuotaDaily) {
this.videoQuotaDaily = videoQuotaDaily;
}
public String getWebTorrentEnabled() {
return webTorrentEnabled;
}
public void setWebTorrentEnabled(String webTorrentEnabled) {
this.webTorrentEnabled = webTorrentEnabled;
}
}

View File

@ -1,8 +1,13 @@
package net.schueller.peertube.model; package net.schueller.peertube.model;
import com.google.gson.annotations.SerializedName;
public class OauthClient { public class OauthClient {
@SerializedName("client_id")
private String clientId; private String clientId;
@SerializedName("client_secret")
private String clientSecret; private String clientSecret;
public String getClientId() { public String getClientId() {

View File

@ -1,10 +1,19 @@
package net.schueller.peertube.model; package net.schueller.peertube.model;
import com.google.gson.annotations.SerializedName;
public class Token { public class Token {
@SerializedName("access_token")
private String accessToken; private String accessToken;
@SerializedName("expires_in")
private String expiresIn; private String expiresIn;
@SerializedName("refresh_token")
private String refreshToken; private String refreshToken;
@SerializedName("token_type")
private String tokenType; private String tokenType;
public String getAccessToken() { public String getAccessToken() {

View File

@ -0,0 +1,24 @@
package net.schueller.peertube.network;
import net.schueller.peertube.model.Token;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Response;
public class AuthorizationInterceptor implements Interceptor {
public AuthorizationInterceptor() {
}
@Override
public Response intercept(Chain chain) throws IOException {
Response mainResponse = chain.proceed(chain.request());
if (mainResponse.code() == 401 || mainResponse.code() == 403) {
}
return mainResponse;
}
}

View File

@ -0,0 +1,14 @@
package net.schueller.peertube.network;
import net.schueller.peertube.model.Me;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Query;
public interface GetUserService {
@GET("users/me")
Call<Me> getMe(@Header("Authorization") String authorization);
}

View File

@ -1,5 +1,6 @@
package net.schueller.peertube.network; package net.schueller.peertube.network;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
@ -11,7 +12,14 @@ public class RetrofitInstance {
public static Retrofit getRetrofitInstance(String newBaseUrl) { public static Retrofit getRetrofitInstance(String newBaseUrl) {
if (retrofit == null || !newBaseUrl.equals(baseUrl)) { if (retrofit == null || !newBaseUrl.equals(baseUrl)) {
baseUrl = newBaseUrl; baseUrl = newBaseUrl;
OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder();
okhttpClientBuilder.addInterceptor(new TokenRenewInterceptor());
okhttpClientBuilder.addInterceptor(new AuthorizationInterceptor());
retrofit = new retrofit2.Retrofit.Builder() retrofit = new retrofit2.Retrofit.Builder()
.client(okhttpClientBuilder.build())
.baseUrl(baseUrl) .baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create())
.build(); .build();

View File

@ -0,0 +1,29 @@
package net.schueller.peertube.network;
import net.schueller.peertube.model.Token;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Response;
public class TokenRenewInterceptor implements Interceptor {
public TokenRenewInterceptor() {
}
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// if 'x-auth-token' is available into the response header
// save the new token into session.The header key can be
// different upon implementation of backend.
String newToken = response.header("x-auth-token");
if (newToken != null) {
}
return response;
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.UserActivity">
</android.support.constraint.ConstraintLayout>

View File

@ -8,7 +8,7 @@
<!-- Strings related to login --> <!-- Strings related to login -->
<string name="prompt_server">Serveur</string> <string name="prompt_server">Serveur</string>
<string name="prompt_email">Email</string> <string name="prompt_email">Email</string>
<string name="prompt_password">Mot de passe (optionnel)</string> <string name="prompt_password">Mot de passe</string>
<string name="action_sign_in">Connexion</string> <string name="action_sign_in">Connexion</string>
<string name="action_sign_in_short">Connexion</string> <string name="action_sign_in_short">Connexion</string>
<string name="error_invalid_email">Cette adresse mail n\'est pas valide</string> <string name="error_invalid_email">Cette adresse mail n\'est pas valide</string>

View File

@ -8,7 +8,7 @@
<!-- Strings related to login --> <!-- Strings related to login -->
<string name="prompt_server">Server</string> <string name="prompt_server">Server</string>
<string name="prompt_email">Email</string> <string name="prompt_email">Email</string>
<string name="prompt_password">Password (optional)</string> <string name="prompt_password">Password</string>
<string name="action_sign_in">Sign in</string> <string name="action_sign_in">Sign in</string>
<string name="action_sign_in_short">Sign in</string> <string name="action_sign_in_short">Sign in</string>
<string name="error_invalid_email">This email address is invalid</string> <string name="error_invalid_email">This email address is invalid</string>
@ -59,5 +59,9 @@
<string name="descr_overflow_button">More</string> <string name="descr_overflow_button">More</string>
<string name="menu_share">Share</string> <string name="menu_share">Share</string>
<string name="playback_channel_name">PeerTube</string> <string name="playback_channel_name">PeerTube</string>
<string name="pref_token_access">pref_token_access</string>
<string name="pref_token_refresh">pref_token_refresh</string>
<string name="pref_token_expiration">pref_token_expiration</string>
<string name="pref_token_type">pref_token_type</string>
</resources> </resources>