diff --git a/app/src/main/java/com/cappielloantonio/play/App.java b/app/src/main/java/com/cappielloantonio/play/App.java index 5d42e50a..3d3e7584 100644 --- a/app/src/main/java/com/cappielloantonio/play/App.java +++ b/app/src/main/java/com/cappielloantonio/play/App.java @@ -44,8 +44,10 @@ public class App extends Application { String server = PreferenceUtil.getInstance(context).getServer(); String username = PreferenceUtil.getInstance(context).getUser(); String password = PreferenceUtil.getInstance(context).getPassword(); + String token = PreferenceUtil.getInstance(context).getToken(); + String salt = PreferenceUtil.getInstance(context).getSalt(); - SubsonicPreferences preferences = new SubsonicPreferences(server, username, password); + SubsonicPreferences preferences = new SubsonicPreferences(server, username, password, token, salt); return new Subsonic(preferences); } diff --git a/app/src/main/java/com/cappielloantonio/play/interfaces/SystemCallback.java b/app/src/main/java/com/cappielloantonio/play/interfaces/SystemCallback.java new file mode 100644 index 00000000..5e4bb7b6 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/interfaces/SystemCallback.java @@ -0,0 +1,10 @@ +package com.cappielloantonio.play.interfaces; + +import java.util.List; + +public interface SystemCallback { + + void onError(Exception exception); + + void onSuccess(String token, String salt); +} diff --git a/app/src/main/java/com/cappielloantonio/play/repository/SystemRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/SystemRepository.java new file mode 100644 index 00000000..2c696eaf --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/repository/SystemRepository.java @@ -0,0 +1,46 @@ +package com.cappielloantonio.play.repository; + +import android.app.Application; + +import com.cappielloantonio.play.App; +import com.cappielloantonio.play.interfaces.SystemCallback; +import com.cappielloantonio.play.subsonic.api.system.SystemClient; +import com.cappielloantonio.play.subsonic.models.ResponseStatus; +import com.cappielloantonio.play.subsonic.models.SubsonicResponse; + +import retrofit2.Call; +import retrofit2.Callback; + +public class SystemRepository { + private static final String TAG = "SongRepository"; + + private SystemClient systemClient; + + public SystemRepository(Application application) { + systemClient = App.getSubsonicClientInstance(application, false).getSystemClient(); + } + + public void checkUserCredential(SystemCallback callback) { + systemClient + .ping() + .enqueue(new Callback() { + @Override + public void onResponse(Call call, retrofit2.Response response) { + if (response.body().getStatus().getValue().equals(ResponseStatus.FAILED)) { + callback.onError(new Exception(response.body().getError().getCode().getValue() + " - " + response.body().getError().getMessage())); + } else if (response.body().getStatus().getValue().equals(ResponseStatus.OK)) { + String salt = response.raw().request().url().queryParameter("s"); + String token = response.raw().request().url().queryParameter("t"); + callback.onSuccess(token, salt); + } else { + callback.onError(new Exception("Empty response")); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + callback.onError(new Exception(t.getMessage())); + } + }); + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/subsonic/SubsonicPreferences.java b/app/src/main/java/com/cappielloantonio/play/subsonic/SubsonicPreferences.java index 3ed8ab50..7763a70a 100644 --- a/app/src/main/java/com/cappielloantonio/play/subsonic/SubsonicPreferences.java +++ b/app/src/main/java/com/cappielloantonio/play/subsonic/SubsonicPreferences.java @@ -7,16 +7,16 @@ import java.util.UUID; public class SubsonicPreferences { private String serverUrl; private String username; - private String clientName = "SubsonicJavaClient"; - private int streamBitRate = 320; - private String streamFormat = "mp3"; + private String clientName = "Play for Subsonic"; - private final SubsonicAuthentication authentication; + private SubsonicAuthentication authentication; - public SubsonicPreferences(String serverUrl, String username, String password) { + public SubsonicPreferences(String serverUrl, String username, String password, String token, String salt) { this.serverUrl = serverUrl; this.username = username; - this.authentication = new SubsonicAuthentication(password); + if(password != null) this.authentication = new SubsonicAuthentication(password); + if(token != null) this.authentication.setToken(token); + if(salt != null) this.authentication.setSalt(salt); } public String getServerUrl() { @@ -31,14 +31,6 @@ public class SubsonicPreferences { return clientName; } - public int getStreamBitRate() { - return streamBitRate; - } - - public String getStreamFormat() { - return streamFormat; - } - public SubsonicAuthentication getAuthentication() { return authentication; } @@ -63,6 +55,14 @@ public class SubsonicPreferences { return token; } + public void setSalt(String salt) { + this.salt = salt; + } + + public void setToken(String token) { + this.token = token; + } + void update(String password) { this.salt = UUID.randomUUID().toString(); this.token = StringUtil.tokenize(password + salt); diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java index 19031a18..1b979fe3 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java @@ -14,19 +14,11 @@ import androidx.fragment.app.Fragment; import com.cappielloantonio.play.App; import com.cappielloantonio.play.databinding.FragmentLoginBinding; -import com.cappielloantonio.play.helper.ErrorHelper; -import com.cappielloantonio.play.subsonic.models.Genre; -import com.cappielloantonio.play.subsonic.models.ResponseStatus; -import com.cappielloantonio.play.subsonic.models.SubsonicResponse; +import com.cappielloantonio.play.interfaces.SystemCallback; +import com.cappielloantonio.play.repository.SystemRepository; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.PreferenceUtil; -import java.util.ArrayList; -import java.util.List; - -import retrofit2.Call; -import retrofit2.Callback; - public class LoginFragment extends Fragment { private static final String TAG = "LoginFragment"; @@ -37,6 +29,8 @@ public class LoginFragment extends Fragment { private String password; private String server; + private SystemRepository systemRepository; + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -56,9 +50,11 @@ public class LoginFragment extends Fragment { } private void init() { + systemRepository = new SystemRepository(App.getInstance()); + bind.loginButton.setOnClickListener(v -> { if (validateInput()) { - saveServerPreference(server, username, password); + saveServerPreference(server, username, password, null, null); authenticate(); } }); @@ -82,36 +78,35 @@ public class LoginFragment extends Fragment { return true; } - private void saveServerPreference(String server, String user, String password) { - PreferenceUtil.getInstance(requireContext()).setUser(user); - PreferenceUtil.getInstance(requireContext()).setServer(server); - PreferenceUtil.getInstance(requireContext()).setPassword(password); - } - private void authenticate() { - App.getSubsonicClientInstance(requireContext(), true) - .getSystemClient() - .ping() - .enqueue(new Callback() { - @Override - public void onResponse(Call call, retrofit2.Response response) { - if (response.body().getStatus().getValue().equals(ResponseStatus.FAILED)) { - ErrorHelper.handle(requireContext(), response.body().getError().getCode().getValue(), response.body().getError().getMessage()); - } else if (response.body().getStatus().getValue().equals(ResponseStatus.OK)) { - enter(); - } else { - Toast.makeText(requireContext(), "Empty response", Toast.LENGTH_LONG).show(); - } - } - @Override - public void onFailure(Call call, Throwable t) { - Log.e(TAG, t.getMessage()); - Toast.makeText(requireContext(), t.getMessage(), Toast.LENGTH_LONG).show(); - } - }); + systemRepository.checkUserCredential(new SystemCallback() { + @Override + public void onError(Exception exception) { + Log.e(TAG, exception.getMessage()); + Toast.makeText(requireContext(), exception.getMessage(), Toast.LENGTH_LONG).show(); + } + + @Override + public void onSuccess(String token, String salt) { + saveServerPreference(null, null, null, token, salt); + enter(); + } + }); } private void enter() { activity.goFromLogin(); } + + private void saveServerPreference(String server, String user, String password, String token, String salt) { + if (user != null) PreferenceUtil.getInstance(requireContext()).setUser(user); + if (server != null) PreferenceUtil.getInstance(requireContext()).setServer(server); + if (password != null) PreferenceUtil.getInstance(requireContext()).setPassword(password); + + if (token != null && salt != null) { + PreferenceUtil.getInstance(requireContext()).setPassword(null); + PreferenceUtil.getInstance(requireContext()).setToken(token); + PreferenceUtil.getInstance(requireContext()).setSalt(salt); + } + } } diff --git a/app/src/main/java/com/cappielloantonio/play/util/PreferenceUtil.java b/app/src/main/java/com/cappielloantonio/play/util/PreferenceUtil.java index 3aeb91bc..8eec91c8 100644 --- a/app/src/main/java/com/cappielloantonio/play/util/PreferenceUtil.java +++ b/app/src/main/java/com/cappielloantonio/play/util/PreferenceUtil.java @@ -20,6 +20,7 @@ public class PreferenceUtil { public static final String USER = "user"; public static final String PASSWORD = "password"; public static final String TOKEN = "token"; + public static final String SALT = "salt"; public static final String MUSIC_LIBRARY_ID = "music_library_id"; public static final String POSITION = "position"; public static final String PROGRESS = "progress"; @@ -96,6 +97,16 @@ public class PreferenceUtil { editor.apply(); } + public String getSalt() { + return mPreferences.getString(SALT, null); + } + + public void setSalt(String salt) { + final SharedPreferences.Editor editor = mPreferences.edit(); + editor.putString(SALT, salt); + editor.apply(); + } + public Boolean getSync() { return mPreferences.getBoolean(SYNC, false); }