/*
* Copyright (C) 2014 Divide.io
*
* 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 io.divide.client;
import com.google.inject.Inject;
import io.divide.client.auth.AuthManager;
import io.divide.client.auth.SignInResponse;
import io.divide.client.auth.SignUpResponse;
import io.divide.client.auth.credentials.LocalCredentials;
import io.divide.client.auth.credentials.LoginCredentials;
import io.divide.client.auth.credentials.SignUpCredentials;
import io.divide.client.auth.credentials.ValidCredentials;
import io.divide.shared.logging.Logger;
import io.divide.shared.transitory.Credentials;
import rx.Observable;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
public final class BackendUser extends Credentials {
private static Logger logger = Logger.getLogger(BackendUser.class);
@Inject private static AuthManager authManager;
private static final String ANONYMOUS_KEY = "anonymous_key";
public BackendUser(){ }
public BackendUser(String username, String email, String password){
this();
this.setUsername(username);
this.setEmailAddress(email);
this.setPassword(password);
}
/**
* Convience method to access the authManager
* @return authManager
*/
private static AuthManager getAM(){
if(authManager==null) throw new RuntimeException("Backend not initialized!");
return authManager;
}
/**
* Convience method to initialize BackendUser from ValidCredentials
* @param credentials
* @return
*/
public static BackendUser from(ValidCredentials credentials){
BackendUser beu = new BackendUser();
beu.initFrom(credentials);
return beu;
}
/**
* @return Currently logged in user.
*/
public static BackendUser getUser(){
return getAM().getUser();
}
/**
* @return True if user is logged in, false if not
*/
public static boolean isLoggedIn(){
return getAM().getUser() != null;
}
// public static ServerResponse<BackendUser> getAnonymousUser(){
// String id = UserUtils.getDeviceIdUnique(Backend.get().app);
// ServerResponse<BackendUser> response;
//
// response = signIn(id, id);
// if(!response.getStatus().isSuccess()){
// response = signUp(id, id, id);
// if(response.getStatus().isSuccess()){
// BackendUser user = response.get();
// user.put(ANONYMOUS_KEY,true);
// user.saveASync();
// }
// }
//
// return response;
// }
/**
* Used to access the stored credentials.
* @return Locally stored credentials for the logged in user.
*/
public static LocalCredentials getStoredAccount(){
return authManager.getStoredAccount();
}
// protected final Credentials getLoggedInUser(){
// return getUser();
// }
@Override
protected final boolean isSystemUser(){
return false;
}
private void initFrom(Credentials credentials){
logger.debug("initFrom: " + credentials);
try {
this.meta_data = credentials.getMetaData();
this.user_data = credentials.getUserData();
} catch (Exception e) {
logger.error("Failed to init BackendUser from Credentials",e);
}
}
/**
* Login using an authtoken
* @param token
* @return BackendUser for the sent token.
*/
public static BackendUser fromToken(String token){
return getAM().getUserFromAuthToken(token).toBlockingObservable().first();
}
/**
* Perform syncronously login attempt.
* @param loginCredentials credentials used for login attempt.
* @return login results.
*/
public static SignInResponse signIn(LoginCredentials loginCredentials){
return getAM().login(loginCredentials);
}
/**
* Perform syncronously login attempt.
* @param email user email address
* @param password user password
* @return login results.
*/
public static SignInResponse signIn(String email, String password){
return signIn(new LoginCredentials(email,password));
}
/**
* Perform syncronously sign up attempt.
* @param signUpCredentials credentials used for sign up attempt.
* @return signup results.
*/
public static SignUpResponse signUp(SignUpCredentials signUpCredentials){
return getAM().signUp(signUpCredentials);
}
/**
* Perform syncronously sign up attempt.
* @param username user name user will be identified by.
* @param email user email address
* @param password user password
* @return login results.
*/
public static SignUpResponse signUp(String username, String email, String password){
return signUp(new SignUpCredentials(username,email,password));
}
/**
* Perform asyncronously login attempt.
* @param email user email address
* @param password user password
* @return login results as observable.
*/
public static Observable<BackendUser> signInInBackground(String email, String password){
return getAM().loginASync(new LoginCredentials(email, password));
}
/**
* Perform asyncronously sign up attempt.
* @param username user name user will be identified by.
* @param email user email address
* @param password user password
* @return login results as observable.
*/
public static Observable<BackendUser> signUpInBackground(String username, String email, String password){
return getAM().signUpASync(new SignUpCredentials(username, email, password));
}
public static void logout(){
getAM().logout();
}
public void requestPasswordReset(String email){
throw new NotImplementedException();
}
public Observable<Boolean> requestPasswordResetInBackground(String email){
throw new NotImplementedException();
}
/**
* Synchronously sign up using credentials provided via constructor or setters.
* @return boolean indicating sign up success
*/
public boolean signUp(){
SignUpCredentials creds = new SignUpCredentials(getUsername(),getEmailAddress(),getPassword());
SignUpResponse response = getAM().signUp(creds);
if(response.getStatus().isSuccess()){
this.initFrom(response.get());
return true;
} else return false;
}
private void save(BackendUser user){
getAM().sendUserData(user).subscribe();
}
private Observable<Void> saveASync(BackendUser user){
return getAM().sendUserData(user);
}
/**
* Asynchronously saves this user object. Saving any data added via the put() method.
* put("1");
* put(1);
* etc.
*/
public void save(){
save(this);
}
/**
* Asynchronously saves this user object return an Observable to monitor. Saving any data added via the put() method.
* put("1");
* put(1);
* etc.
* @return Obserable to monitor operation.
*/
public Observable<Void> saveASync(){
return saveASync(this);
}
@Override
public String toString() {
return "BackendUser{" +
"emailAddress='" + getEmailAddress() + '\'' +
", password='" + getPassword() + '\'' +
", userKey='" + getOwnerId() + '\'' +
", authToken='" + getAuthToken() + '\'' +
", createDate=" + getCreateDate() +
// ", authTokenExpireDate=" + getAuthTokenExpireDate() +
", validation='" + getValidation() + '\'' +
'}';
}
}