diff --git a/app/build.gradle b/app/build.gradle index fd7ddba..9212db2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,3 +73,6 @@ android { } } +dependencies { + implementation 'com.android.support.constraint:constraint-layout:+' +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 178aa69..c3e9107 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,18 +16,19 @@ android:supportsRtl="true" android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> - - + + - + android:resource="@xml/searchable"> - + + + + + \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java index 5118071..40d44df 100644 --- a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java @@ -1,49 +1,33 @@ 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.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; -import android.view.View; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; -import android.widget.Toast; import net.schueller.peertube.R; import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.model.OauthClient; import net.schueller.peertube.model.Token; -import net.schueller.peertube.model.VideoList; import net.schueller.peertube.network.AuthenticationService; -import net.schueller.peertube.network.GetVideoDataService; 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.Callback; +import retrofit2.Response; 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"; - // UI references. private AutoCompleteTextView mEmailView; private EditText mPasswordView; - private View mProgressView; - private View mLoginFormView; @Override protected void onCreate(Bundle savedInstanceState) { @@ -57,17 +41,12 @@ public class LoginActivity extends AppCompatActivity { mEmailView = findViewById(R.id.email); 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() { + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); // Reset errors. mEmailView.setError(null); @@ -84,15 +63,18 @@ public class LoginActivity extends AppCompatActivity { AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class); Call call = service.getOauthClientLocal(); + call.enqueue(new Callback() { @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.body() != null) { + if (response.isSuccessful()) { + + OauthClient oauthClient = response.body(); Call call2 = service.getAuthenticationToken( - response.body().getClientId(), - response.body().getClientSecret(), + oauthClient.getClientId(), + oauthClient.getClientSecret(), "code", "password", "upload", @@ -103,11 +85,20 @@ public class LoginActivity extends AppCompatActivity { @Override public void onResponse(@NonNull Call call2, @NonNull retrofit2.Response response2) { - if (response2.body() != null) { - Log.wtf(TAG, response2.body().getAccessToken()); - Log.wtf(TAG, response2.body().getExpiresIn()); - Log.wtf(TAG, response2.body().getRefreshToken()); - Log.wtf(TAG, response2.body().getTokenType()); + if (response2.isSuccessful()) { + + Token token = response2.body(); + + 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 { Log.wtf(TAG, response2.toString()); } diff --git a/app/src/main/java/net/schueller/peertube/activity/UserActivity.java b/app/src/main/java/net/schueller/peertube/activity/UserActivity.java new file mode 100644 index 0000000..b178c98 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/activity/UserActivity.java @@ -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(); + + } +} diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java index 5ef84c4..697a4b2 100644 --- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java @@ -103,10 +103,10 @@ public class VideoListActivity extends AppCompatActivity { case R.id.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); -// this.startActivity(intent); + Intent intent = new Intent(this, UserActivity.class); + this.startActivity(intent); return false; } diff --git a/app/src/main/java/net/schueller/peertube/model/Me.java b/app/src/main/java/net/schueller/peertube/model/Me.java new file mode 100644 index 0000000..1a0c96e --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/model/Me.java @@ -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; + } +} + + diff --git a/app/src/main/java/net/schueller/peertube/model/OauthClient.java b/app/src/main/java/net/schueller/peertube/model/OauthClient.java index 35221bc..1bf8944 100644 --- a/app/src/main/java/net/schueller/peertube/model/OauthClient.java +++ b/app/src/main/java/net/schueller/peertube/model/OauthClient.java @@ -1,8 +1,13 @@ package net.schueller.peertube.model; +import com.google.gson.annotations.SerializedName; + public class OauthClient { + @SerializedName("client_id") private String clientId; + + @SerializedName("client_secret") private String clientSecret; public String getClientId() { diff --git a/app/src/main/java/net/schueller/peertube/model/Token.java b/app/src/main/java/net/schueller/peertube/model/Token.java index 4a703ea..9f32316 100644 --- a/app/src/main/java/net/schueller/peertube/model/Token.java +++ b/app/src/main/java/net/schueller/peertube/model/Token.java @@ -1,10 +1,19 @@ package net.schueller.peertube.model; +import com.google.gson.annotations.SerializedName; + public class Token { + @SerializedName("access_token") private String accessToken; + + @SerializedName("expires_in") private String expiresIn; + + @SerializedName("refresh_token") private String refreshToken; + + @SerializedName("token_type") private String tokenType; public String getAccessToken() { diff --git a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java new file mode 100644 index 0000000..da559c0 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java @@ -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; + } +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/network/GetUserService.java b/app/src/main/java/net/schueller/peertube/network/GetUserService.java new file mode 100644 index 0000000..7c05bae --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/network/GetUserService.java @@ -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 getMe(@Header("Authorization") String authorization); +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java b/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java index d8a6cd8..8a00113 100644 --- a/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java +++ b/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java @@ -1,5 +1,6 @@ package net.schueller.peertube.network; +import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; @@ -11,7 +12,14 @@ public class RetrofitInstance { public static Retrofit getRetrofitInstance(String newBaseUrl) { if (retrofit == null || !newBaseUrl.equals(baseUrl)) { baseUrl = newBaseUrl; + + OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder(); + + okhttpClientBuilder.addInterceptor(new TokenRenewInterceptor()); + okhttpClientBuilder.addInterceptor(new AuthorizationInterceptor()); + retrofit = new retrofit2.Retrofit.Builder() + .client(okhttpClientBuilder.build()) .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .build(); diff --git a/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java b/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java new file mode 100644 index 0000000..2ae3a69 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java @@ -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; + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_user.xml b/app/src/main/res/layout/activity_user.xml new file mode 100644 index 0000000..39f110a --- /dev/null +++ b/app/src/main/res/layout/activity_user.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 75d7cde..ff3fd89 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -8,7 +8,7 @@ Serveur Email - Mot de passe (optionnel) + Mot de passe Connexion Connexion Cette adresse mail n\'est pas valide diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5ceebec..944603f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,7 +8,7 @@ Server Email - Password (optional) + Password Sign in Sign in This email address is invalid @@ -59,5 +59,9 @@ More Share PeerTube + pref_token_access + pref_token_refresh + pref_token_expiration + pref_token_type