package io.kaif.mobile.view.daemon;
import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Singleton;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import io.kaif.mobile.config.ApiConfiguration;
import io.kaif.mobile.event.EventPublishSubject;
import io.kaif.mobile.event.account.AccountEvent;
import io.kaif.mobile.event.account.SignInSuccessEvent;
import io.kaif.mobile.event.account.SignOutEvent;
import io.kaif.mobile.model.oauth.AccessTokenManager;
import io.kaif.mobile.service.OauthService;
import rx.Observable;
@Singleton
public class AccountDaemon {
private final EventPublishSubject<AccountEvent> subject;
private final OauthService oauthService;
private final AccessTokenManager accessTokenManager;
private final ApiConfiguration apiConfiguration;
private String state;
@Inject
AccountDaemon(OauthService oauthService,
AccessTokenManager accessTokenManager,
ApiConfiguration apiConfiguration) {
this.oauthService = oauthService;
this.accessTokenManager = accessTokenManager;
this.apiConfiguration = apiConfiguration;
this.subject = new EventPublishSubject<>();
}
public Observable<AccountEvent> getSubject(Class<?>... classes) {
return subject.getSubject(classes);
}
public <T extends AccountEvent> Observable<T> getSubject(Class<T> clazz) {
return subject.getSubject(clazz);
}
public Intent createOauthPageIntent() {
state = UUID.randomUUID().toString();
final Uri uri = Uri.parse(apiConfiguration.getEndPoint())
.buildUpon()
.appendPath("oauth")
.appendPath("authorize")
.appendQueryParameter("client_id", apiConfiguration.getClientId())
.appendQueryParameter("response_type", "code")
.appendQueryParameter("scope", "public feed article vote user debate")
.appendQueryParameter("state", state)
.appendQueryParameter("redirect_uri", apiConfiguration.getRedirectUri())
.build();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
return intent;
}
public boolean hasAccount() {
return accessTokenManager.hasAccount();
}
public void signOut() {
accessTokenManager.signOut();
subject.onNext(new SignOutEvent());
}
public Observable<Void> accessToken(String code, String state) {
if (!TextUtils.equals(this.state, state)) {
return Observable.<Void>error(new IllegalStateException("receive a malicious response"));
}
this.state = null;
return oauthService.getAccessToken(apiConfiguration.getClientId(),
apiConfiguration.getClientSecret(),
code,
apiConfiguration.getRedirectUri(),
"authorization_code").<Void>map(accessTokenInfo -> {
accessTokenManager.saveAccount(accessTokenInfo);
subject.onNext(new SignInSuccessEvent());
return null;
});
}
}