/** * Odoo, Open Source Management Solution * Copyright (C) 2012-today Odoo SA (<http:www.odoo.com>) * <p> * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version * <p> * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details * <p> * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http:www.gnu.org/licenses/> * <p> * Created on 17/12/14 6:21 PM */ package com.odoo.core.auth; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerFuture; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.content.Context; import android.os.Build; import android.support.annotation.BoolRes; import android.support.design.widget.BottomSheetDialog; import android.util.Log; import com.odoo.App; import com.odoo.core.orm.OModel; import com.odoo.core.orm.OSQLite; import com.odoo.core.support.OUser; import com.odoo.core.utils.OPreferenceManager; import com.odoo.core.utils.sys.OCacheUtils; import java.io.IOException; import java.net.Authenticator; import java.util.ArrayList; import java.util.List; public class OdooAccountManager { public static final String TAG = OdooAccountManager.class.getSimpleName(); public static final String KEY_ACCOUNT_TYPE = "com.odoo.auth"; public static final String KEY_USER_ACCOUNT_VERSION = "key_user_account_version"; /** * Gets all the account related Odoo Auth * * @param context * @return List of OUser instances if any */ public static List<OUser> getAllAccounts(Context context) { List<OUser> users = new ArrayList<>(); AccountManager aManager = AccountManager.get(context); for (Account account : aManager.getAccountsByType(KEY_ACCOUNT_TYPE)) { OUser user = new OUser(); user.fillFromAccount(aManager, account); user.setAccount(account); users.add(user); } return users; } /** * Check for any account availability * * @param context * @return true, if any account found */ public static boolean hasAnyAccount(Context context) { if (getAllAccounts(context).size() > 0) return true; return false; } public static boolean isValidUserObj(Context context, OUser user) { OPreferenceManager pref = new OPreferenceManager(context); int version = pref.getInt(userObjectKEY(user), 0); if (version == 0) { updateUserData(context, user, user); version = OUser.USER_ACCOUNT_VERSION; } return (version == OUser.USER_ACCOUNT_VERSION); } /** * Creates Odoo account for app * * @param context * @param user user instance (OUser) * @return true, if account created successfully */ public static boolean createAccount(Context context, OUser user) { AccountManager accountManager = AccountManager.get(context); Account account = new Account(user.getAndroidName(), KEY_ACCOUNT_TYPE); if (accountManager.addAccountExplicitly(account, String.valueOf(user.getPassword()), user.getAsBundle())) { OPreferenceManager pref = new OPreferenceManager(context); if (pref.getInt(userObjectKEY(user), 0) != OUser.USER_ACCOUNT_VERSION) { pref.putInt(userObjectKEY(user), OUser.USER_ACCOUNT_VERSION); } return true; } return false; } public static String userObjectKEY(OUser user) { return KEY_USER_ACCOUNT_VERSION + "_" + user.getAndroidName(); } /** * Remove account from device * * @param context * @param username * @return true, if account removed successfully */ public static boolean removeAccount(Context context, String username) { OUser user = getDetails(context, username); if (user != null) { AccountManager accountManager = AccountManager.get(context); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { if (accountManager.removeAccountExplicitly(user.getAccount())) { dropDatabase(user); } return true; } else { try { AccountManagerFuture<Boolean> result = accountManager. removeAccount(user.getAccount(), null, null); if (result.getResult()) { dropDatabase(user); } return true; } catch (OperationCanceledException | IOException | AuthenticatorException e) { e.printStackTrace(); } } } return false; } public static void dropDatabase(OUser user) { OSQLite sqLite = App.getSQLite(user.getAndroidName()); if (sqLite != null) { sqLite.dropDatabase(); App.setSQLite(user.getAndroidName(), null); } } public static OUser updateUserData(Context context, OUser user, OUser newData) { if (user != null) { AccountManager accountManager = AccountManager.get(context); for (String key : newData.getAsBundle().keySet()) { accountManager.setUserData(user.getAccount(), key, newData.getAsBundle().get(key) + ""); } OPreferenceManager pref = new OPreferenceManager(context); if (pref.getInt(userObjectKEY(user), 0) != OUser.USER_ACCOUNT_VERSION) { pref.putInt(userObjectKEY(user), OUser.USER_ACCOUNT_VERSION); } } return getDetails(context, newData.getAndroidName()); } /** * Updates user bundle data in accounts * * @param context * @param newData instance of OUser class * @return new user object with updated values */ public static OUser updateUserData(Context context, OUser newData) { OUser user = getDetails(context, newData.getAndroidName()); return updateUserData(context, user, newData); } /** * Finds any active user for application * * @param context * @return true, if there is any active user for app */ public static boolean anyActiveUser(Context context) { for (OUser user : getAllAccounts(context)) { if (user.isActive()) { return true; } } return false; } /** * Gets active user object * * @param context * @return user object (Instance of OUser class) */ public static OUser getActiveUser(Context context) { for (OUser user : getAllAccounts(context)) { if (user.isActive()) { return user; } } return null; } /** * Returns OUser object with username * * @param context * @param username * @return instance for OUser class or null */ public static OUser getDetails(Context context, String username) { for (OUser user : getAllAccounts(context)) if (user.getAndroidName().equals(username)) { return user; } return null; } /** * Login to user account. changes active state for user. * Other users will be automatically logged out * * @param context * @param username * @return new user object */ public static OUser login(Context context, String username) { // Setting odoo instance to null App app = (App) context.getApplicationContext(); app.setOdoo(null, null); OUser activeUser = getActiveUser(context); // Logging out user if any if (activeUser != null) { logout(context, activeUser.getAndroidName()); } OUser newUser = getDetails(context, username); if (newUser != null) { AccountManager accountManager = AccountManager.get(context); accountManager.setUserData(newUser.getAccount(), "isactive", "true"); Log.i(TAG, newUser.getName() + " Logged in successfully"); return newUser; } // Clearing old cache of the system OCacheUtils.clearSystemCache(context); return null; } /** * Logout user * * @param context * @param username * @return true, if successfully logged out */ public static boolean logout(Context context, String username) { OUser user = getDetails(context, username); if (user != null) { if (cancelUserSync(user.getAccount())) { AccountManager accountManager = AccountManager.get(context); accountManager.setUserData(user.getAccount(), "isactive", "false"); Log.i(TAG, user.getName() + " Logged out successfully"); return true; } } return false; } private static boolean cancelUserSync(Account account) { //TODO: Cancel user's sync services. if any. return true; } }