/* * Copyright (c) 2012 Socialize Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.socialize.api.action.user; import android.content.Context; import com.socialize.android.ioc.IBeanFactory; import com.socialize.api.*; import com.socialize.auth.*; import com.socialize.config.SocializeConfig; import com.socialize.entity.User; import com.socialize.error.SocializeException; import com.socialize.listener.SocializeAuthListener; import com.socialize.listener.user.UserListener; import com.socialize.listener.user.UserSaveListener; import com.socialize.log.SocializeLogger; import com.socialize.notifications.NotificationRegistrationSystem; import com.socialize.provider.SocializeProvider; import com.socialize.ui.profile.UserSettings; import com.socialize.util.BitmapUtils; import com.socialize.util.DeviceUtils; import com.socialize.util.StringUtils; /** * @author Jason Polites */ public class SocializeUserSystem extends SocializeApi<User, SocializeProvider<User>> implements UserSystem { private IBeanFactory<AuthProviderData> authProviderDataFactory; private SocializeSessionPersister sessionPersister; private DeviceUtils deviceUtils; private SocializeLogger logger; private AuthProviderInfoBuilder authProviderInfoBuilder; private SocializeAuthProviderInfoFactory socializeAuthProviderInfoFactory; private NotificationRegistrationSystem notificationRegistrationSystem; private BitmapUtils bitmapUtils; public SocializeUserSystem(SocializeProvider<User> provider) { super(provider); } @Override public void authenticate(Context context, SocializeAuthListener listener, SocializeSessionConsumer sessionConsumer) { String consumerKey = config.getProperty(SocializeConfig.SOCIALIZE_CONSUMER_KEY); String consumerSecret = config.getProperty(SocializeConfig.SOCIALIZE_CONSUMER_SECRET); authenticate(context, consumerKey, consumerSecret, listener, sessionConsumer); } @Override public void authenticate(Context context, String consumerKey, String consumerSecret, AuthProviderInfo authProviderInfo, SocializeAuthListener listener, SocializeSessionConsumer sessionConsumer) { AuthProviderData data = this.authProviderDataFactory.getBean(); data.setAuthProviderInfo(authProviderInfo); authenticate(context, consumerKey, consumerSecret, data, listener, sessionConsumer, true); } @Override public void authenticateKnownUser(Context context, UserProviderCredentials userProviderCredentials, SocializeAuthListener listener, SocializeSessionConsumer sessionConsumer) { String consumerKey = config.getProperty(SocializeConfig.SOCIALIZE_CONSUMER_KEY); String consumerSecret = config.getProperty(SocializeConfig.SOCIALIZE_CONSUMER_SECRET); AuthProviderData authProviderData = this.authProviderDataFactory.getBean(); authProviderData.setAuthProviderInfo(userProviderCredentials.getAuthProviderInfo()); authProviderData.setToken3rdParty(userProviderCredentials.getAccessToken()); authProviderData.setSecret3rdParty(userProviderCredentials.getTokenSecret()); authProviderData.setUserId3rdParty(userProviderCredentials.getUserId()); authenticate(context, consumerKey, consumerSecret, authProviderData, listener, sessionConsumer, false); } @Override public void authenticate(Context context, String consumerKey, String consumerSecret, SocializeAuthListener listener, SocializeSessionConsumer sessionConsumer) { AuthProviderData authProviderData = authProviderDataFactory.getBean(); authProviderData.setAuthProviderInfo(socializeAuthProviderInfoFactory.getInstanceForRead()); authenticate(context, consumerKey, consumerSecret, authProviderData, listener, sessionConsumer, false); } @Override public void authenticate(Context context, AuthProviderType authProviderType, SocializeAuthListener listener, SocializeSessionConsumer sessionConsumer) { String consumerKey = config.getProperty(SocializeConfig.SOCIALIZE_CONSUMER_KEY); String consumerSecret = config.getProperty(SocializeConfig.SOCIALIZE_CONSUMER_SECRET); AuthProviderInfo authProviderInfo = authProviderInfoBuilder.getFactory(authProviderType).getInstanceForRead(); authenticate(context, consumerKey, consumerSecret, authProviderInfo, listener, sessionConsumer); } @Override public void authenticate(Context ctx, String consumerKey, String consumerSecret, AuthProviderData authProviderData, SocializeAuthListener listener, SocializeSessionConsumer sessionConsumer, boolean do3rdPartyAuth) { if(checkKeys(consumerKey, consumerSecret, listener)) { String udid = deviceUtils.getUDID(ctx); String advertiserId = deviceUtils.getAndroidID(ctx); if(StringUtils.isEmpty(udid)) { if(listener != null) { listener.onError(new SocializeException("No UDID provided")); } } else { // All Api instances have authenticate, so we can just use any old one authenticateAsync(ctx, consumerKey, consumerSecret, udid, advertiserId, authProviderData, listener, sessionConsumer, do3rdPartyAuth); } } } @Override public SocializeSession authenticateSynchronous(Context context) { String consumerKey = config.getProperty(SocializeConfig.SOCIALIZE_CONSUMER_KEY); String consumerSecret = config.getProperty(SocializeConfig.SOCIALIZE_CONSUMER_SECRET); try { if(checkKeys(consumerKey, consumerSecret)) { return authenticateSynchronous(context, consumerKey, consumerSecret); } else { throw new SocializeException("Consumer key and/or secret not provided"); } } catch (Exception e) { logError("Error during synchronous authentication", e); return null; } } @Override public SocializeSession authenticateSynchronous(Context ctx, String consumerKey, String consumerSecret) throws SocializeException { String udid = deviceUtils.getUDID(ctx); String advertiserId = deviceUtils.getAndroidID(ctx); SocializeSession session = authenticate(ctx, "/authenticate/",consumerKey, consumerSecret, udid, advertiserId); return session; } @Override public void saveSession(Context context, SocializeSession session) { if(sessionPersister != null) { sessionPersister.save(context, session); } } // For mocking protected SocializeAuthProviderInfo newSocializeAuthProviderInfo() { return new SocializeAuthProviderInfo(); } /* (non-Javadoc) * @see com.socialize.api.action.UserSystem#getUser(com.socialize.api.SocializeSession, long, com.socialize.listener.user.UserListener) */ @Override public void getUser(SocializeSession session, long id, UserListener listener) { getAsync(session, ENDPOINT, String.valueOf(id), listener); } /* (non-Javadoc) * @see com.socialize.api.action.UserSystem#saveUserProfile(android.content.Context, com.socialize.api.SocializeSession, com.socialize.ui.profile.UserProfile, com.socialize.listener.user.UserListener) */ @Override public void saveUserSettings(final Context context, final SocializeSession session, final UserSettings settingsToBeSaved, final UserListener listener) { User sessionUser = session.getUser(); UserSettings sessionSettings = session.getUserSettings(); boolean wasNotificationsEnabled = sessionSettings.isNotificationsEnabled(); // Update the settings and the user in the session so they are saved sessionUser.setFirstName(settingsToBeSaved.getFirstName()); sessionUser.setLastName(settingsToBeSaved.getLastName()); sessionSettings.update(settingsToBeSaved); boolean isNotificationsEnabled = sessionSettings.isNotificationsEnabled(); if(settingsToBeSaved.getImage() != null) { sessionUser.setProfilePicData(bitmapUtils.encode(settingsToBeSaved.getImage())); } // If notifications was not previously enabled, we may need to register. if(isNotificationsEnabled && !wasNotificationsEnabled && notificationRegistrationSystem != null) { notificationRegistrationSystem.registerC2DMAsync(context); } saveUserAsync(context, session, sessionUser, listener); } @Override public void saveUserAsync(final Context context, final SocializeSession session, final User userToBeSaved, final UserListener listener) { final UserSettings settings = session.getUserSettings(); settings.update(userToBeSaved); String endpoint = ENDPOINT + userToBeSaved.getId() + "/"; putAsPostAsync(session, endpoint, userToBeSaved, new UserSaveListener() { @Override public void onError(SocializeException error) { listener.onError(error); } @Override public void onUpdate(User savedUser) { handleUserUpdate(context, session, savedUser, settings, listener); } }); } protected void handleUserUpdate(final Context context, final SocializeSession session, User savedUser, UserSettings userSettings, final UserListener listener) { try { SessionLock.lock(); // Update local in-memory user User sessionUser = session.getUser(); sessionUser.update(savedUser); // Save this user to the local session for next load if(sessionPersister != null) { sessionPersister.saveUser(context, sessionUser, userSettings); } if(listener != null) { listener.onUpdate(sessionUser); } } finally { SessionLock.unlock(); } } protected boolean checkKeys(String consumerKey, String consumerSecret) { return checkKeys(consumerKey, consumerSecret, null); } protected boolean checkKeys(String consumerKey, String consumerSecret, SocializeAuthListener authListener) { return checkKey("consumer key", consumerKey, authListener) && checkKey("consumer secret", consumerSecret, authListener); } protected boolean checkKey(String name, String key, SocializeAuthListener authListener) { if(StringUtils.isEmpty(key)) { String msg = "No key specified in authenticate"; if(authListener != null) { authListener.onError(new SocializeException(msg)); } logErrorMessage(msg); return false; } else { return true; } } protected void logError(String message, Throwable error) { if(logger != null) { logger.error(message, error); } else { SocializeLogger.e(error.getMessage(), error); } } protected void logErrorMessage(String message) { if(logger != null) { logger.error(message); } else { System.err.println(message); } } public void setSessionPersister(SocializeSessionPersister sessionPersister) { this.sessionPersister = sessionPersister; } public void setAuthProviderDataFactory(IBeanFactory<AuthProviderData> authProviderDataFactory) { this.authProviderDataFactory = authProviderDataFactory; } public void setDeviceUtils(DeviceUtils deviceUtils) { this.deviceUtils = deviceUtils; } public void setConfig(SocializeConfig config) { this.config = config; } public void setLogger(SocializeLogger logger) { this.logger = logger; } public void setAuthProviderInfoBuilder(AuthProviderInfoBuilder authProviderInfoBuilder) { this.authProviderInfoBuilder = authProviderInfoBuilder; } public void setSocializeAuthProviderInfoFactory(SocializeAuthProviderInfoFactory socializeAuthProviderInfoFactory) { this.socializeAuthProviderInfoFactory = socializeAuthProviderInfoFactory; } public void setNotificationRegistrationSystem(NotificationRegistrationSystem notificationRegistrationSystem) { this.notificationRegistrationSystem = notificationRegistrationSystem; } public void setBitmapUtils(BitmapUtils bitmapUtils) { this.bitmapUtils = bitmapUtils; } }