/*
* Copyright 2014 OpenMarket Ltd
* Copyright 2017 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.matrix.androidsdk.rest.client;
import android.os.Build;
import android.text.TextUtils;
import com.google.gson.JsonObject;
import org.matrix.androidsdk.HomeserverConnectionConfig;
import org.matrix.androidsdk.RestClient;
import org.matrix.androidsdk.rest.api.LoginApi;
import org.matrix.androidsdk.rest.callback.ApiCallback;
import org.matrix.androidsdk.rest.callback.RestAdapterCallback;
import org.matrix.androidsdk.rest.model.login.Credentials;
import org.matrix.androidsdk.rest.model.login.LoginFlow;
import org.matrix.androidsdk.rest.model.login.LoginFlowResponse;
import org.matrix.androidsdk.rest.model.login.PasswordLoginParams;
import org.matrix.androidsdk.rest.model.login.RegistrationParams;
import org.matrix.androidsdk.rest.model.login.TokenLoginParams;
import java.util.List;
import java.util.UUID;
import retrofit.client.Response;
/**
* Class used to make requests to the login API.
*/
public class LoginRestClient extends RestClient<LoginApi> {
public static final String LOGIN_FLOW_TYPE_PASSWORD = "m.login.password";
public static final String LOGIN_FLOW_TYPE_OAUTH2 = "m.login.oauth2";
public static final String LOGIN_FLOW_TYPE_EMAIL_CODE = "m.login.email.code";
public static final String LOGIN_FLOW_TYPE_EMAIL_URL = "m.login.email.url";
public static final String LOGIN_FLOW_TYPE_EMAIL_IDENTITY = "m.login.email.identity";
public static final String LOGIN_FLOW_TYPE_MSISDN = "m.login.msisdn";
public static final String LOGIN_FLOW_TYPE_RECAPTCHA = "m.login.recaptcha";
public static final String LOGIN_FLOW_TYPE_DUMMY = "m.login.dummy";
/**
* Public constructor.
* @param hsConfig the home server connection config
*/
public LoginRestClient(HomeserverConnectionConfig hsConfig) {
super(hsConfig, LoginApi.class, RestClient.URI_API_PREFIX_PATH_R0, false);
}
/**
* Retrieve the login supported flows.
* It should be done to check before displaying a default login form.
* @param callback the callback success and failure callback
*/
public void getSupportedLoginFlows(final ApiCallback<List<LoginFlow>> callback) {
final String description = "geLoginSupportedFlows";
mApi.login(new RestAdapterCallback<LoginFlowResponse>(description, mUnsentEventsManager, callback,
new RestAdapterCallback.RequestRetryCallBack() {
@Override
public void onRetry() {
getSupportedLoginFlows(callback);
}
}
) {
@Override
public void success(LoginFlowResponse loginFlowResponse, Response response) {
onEventSent();
callback.onSuccess(loginFlowResponse.flows);
}
});
}
/**
* Request an account creation
* @param params the registration parameters
* @param callback the callbacks
*/
public void register(final RegistrationParams params, final ApiCallback<Credentials> callback) {
final String description = "register";
// define a default device name only there is a password
if (!TextUtils.isEmpty(params.password) && TextUtils.isEmpty(params.initial_device_display_name)) {
params.initial_device_display_name = Build.MODEL.trim();
}
// Temporary flag to notify the server that we support msisdn flow. Used to prevent old app
// versions to end up in fallback because the HS returns the msisdn flow which they don't support
params.x_show_msisdn = true;
mApi.register(params, new RestAdapterCallback<JsonObject>(description, mUnsentEventsManager, callback,
new RestAdapterCallback.RequestRetryCallBack() {
@Override
public void onRetry() {
register(params, callback);
}
}
) {
@Override
public void success(JsonObject jsonObject, Response response) {
onEventSent();
mCredentials = gson.fromJson(jsonObject, Credentials.class);
callback.onSuccess(mCredentials);
}
});
}
/**
* Attempt to login with username/password
*
* @param user the username
* @param password the password
* @param callback the callback success and failure callback
*/
public void loginWithUser(final String user, final String password, final ApiCallback<Credentials> callback) {
final String description = "loginWithUser : " + user;
PasswordLoginParams params = new PasswordLoginParams();
params.setUserIdentifier(user, password);
login(params, callback, description);
}
/**
* Attempt to login with 3pid/password
*
* @param medium the medium of the 3pid
* @param address the address of the 3pid
* @param password the password
* @param callback the callback success and failure callback
*/
public void loginWith3Pid(final String medium, final String address, final String password, final ApiCallback<Credentials> callback) {
final String description = "loginWith3pid : " + address;
PasswordLoginParams params = new PasswordLoginParams();
params.setThirdPartyIdentifier(medium, address, password);
login(params, callback, description);
}
/**
* Attempt to login with phone number/password
*
* @param phoneNumber the phone number
* @param countryCode the ISO country code
* @param password the password
* @param callback the callback success and failure callback
*/
public void loginWithPhoneNumber(final String phoneNumber, final String countryCode, final String password, final ApiCallback<Credentials> callback) {
final String description = "loginWithPhoneNumber : " + phoneNumber;
PasswordLoginParams params = new PasswordLoginParams();
params.setPhoneIdentifier(phoneNumber, countryCode, password);
login(params, callback, description);
}
/**
* Make login request
*
* @param params login params
* @param callback
* @param description
*/
private void login(final PasswordLoginParams params, final ApiCallback<Credentials> callback, final String description) {
mApi.login(params, new RestAdapterCallback<JsonObject>(description, mUnsentEventsManager, callback,
new RestAdapterCallback.RequestRetryCallBack() {
@Override
public void onRetry() {
login(params, callback, description);
}
}
) {
@Override
public void success(JsonObject jsonObject, Response response) {
onEventSent();
mCredentials = gson.fromJson(jsonObject, Credentials.class);
callback.onSuccess(mCredentials);
}
});
}
/**
* Attempt a user/token log in.
* @param user the user name
* @param token the token
* @param callback the callback success and failure callback
*/
public void loginWithToken(final String user, final String token, final ApiCallback<Credentials> callback) {
loginWithToken(user, token, UUID.randomUUID().toString(), callback);
}
/**
* Attempt a user/token log in.
* @param user the user name
* @param token the token
* @param txn_id the client transactio id to include in the request
* @param callback the callback success and failure callback
*/
public void loginWithToken(final String user, final String token, final String txn_id, final ApiCallback<Credentials> callback) {
// privacy
//final String description = "loginWithPassword user : " + user;
final String description = "loginWithPassword user";
TokenLoginParams params = new TokenLoginParams();
params.user = user;
params.token = token;
params.txn_id = txn_id;
params.initial_device_display_name = Build.MODEL.trim();
mApi.login(params, new RestAdapterCallback<JsonObject>(description, mUnsentEventsManager, callback,
new RestAdapterCallback.RequestRetryCallBack() {
@Override
public void onRetry() {
loginWithToken(user, token, txn_id, callback);
}
}
) {
@Override
public void success(JsonObject jsonObject, Response response) {
onEventSent();
mCredentials = gson.fromJson(jsonObject, Credentials.class);
callback.onSuccess(mCredentials);
}
});
}
/**
* Invalidate the access token, so that it can no longer be used for authorization.
* @param callback the callback success and failure callback
*/
public void logout(final ApiCallback<JsonObject> callback) {
// privacy
final String description = "logout user";
mApi.logout(new RestAdapterCallback<JsonObject>(description, mUnsentEventsManager, callback,
new RestAdapterCallback.RequestRetryCallBack() {
@Override
public void onRetry() {
logout(callback);
}
}
));
}
}