001package com.gigya.android.sdk.persistence;
002
003import android.content.Context;
004import android.content.SharedPreferences;
005import android.support.annotation.Nullable;
006
007import com.gigya.android.sdk.GigyaDefinitions;
008
009import java.util.HashSet;
010import java.util.Set;
011
012public class PersistenceService implements IPersistenceService {
013
014    private SharedPreferences _prefs;
015
016    final private Context _context;
017
018    public PersistenceService(Context context) {
019        _context = context;
020    }
021
022    protected SharedPreferences getPrefs() {
023        if (_prefs == null) {
024            _prefs = _context.getSharedPreferences(PREFS_FILE_KEY, Context.MODE_PRIVATE);
025        }
026        return _prefs;
027    }
028
029    //region HELPERS
030
031    /**
032     * Check if session persistence is available.
033     */
034    @Override
035    public boolean isSessionAvailable() {
036        return contains(PREFS_KEY_SESSION);
037    }
038
039    /**
040     * Persist a new encrypted session.
041     *
042     * @param encryptedSession Encrypted session String.
043     */
044    @Override
045    public void setSession(String encryptedSession) {
046        add(PREFS_KEY_SESSION, encryptedSession);
047    }
048
049    /**
050     * Get persistent session.
051     *
052     * @return Encrypted session String or null if session persistence exists.
053     */
054    @Override
055    public String getSession() {
056        return getString(PREFS_KEY_SESSION, null);
057    }
058
059    /**
060     * Set session expiration timestamp.
061     *
062     * @param expiration Expiration timestamp (Long).
063     */
064    @Override
065    public void setSessionExpiration(long expiration) {
066        add(PREFS_KEY_SESSION_EXPIRE_TIMESTAMP, expiration);
067    }
068
069    /**
070     * Get session expiration timestamp.
071     *
072     * @return Persistent session expiration or 0 if timestamp does not exist.
073     */
074    @Override
075    public long getSessionExpiration() {
076        return getLong(PREFS_KEY_SESSION_EXPIRE_TIMESTAMP, 0L);
077    }
078
079    /**
080     * Remove session from persistence store.
081     */
082    @Override
083    public void removeSession() {
084        remove(PREFS_KEY_SESSION);
085    }
086
087    /**
088     * Remove legacy session data if from persistence store.
089     */
090    @Override
091    public void removeLegacySession() {
092        remove("ucid", "gmid", "lastLoginProvider", "session.Token",
093                "session.Secret", "tsOffset", "session.ExpirationTime");
094    }
095
096    /**
097     * Update session encryption type.
098     *
099     * @param encryptionType Encryption type String identifier.
100     */
101    @Override
102    public void setSessionEncryptionType(String encryptionType) {
103        add(PREFS_KEY_SESSION_ENCRYPTION_TYPE, encryptionType);
104    }
105
106    /**
107     * Get session encryption type.
108     *
109     * @return Encryption type String identifier or "DEFAULT" if does not exist.
110     */
111    @Override
112    public String getSessionEncryptionType() {
113        return getString(PREFS_KEY_SESSION_ENCRYPTION_TYPE, GigyaDefinitions.SessionEncryption.DEFAULT);
114    }
115
116    /**
117     * Get social providers identifiers what were used.
118     *
119     * @return Set of provider identifiers or null if none exist.
120     */
121    @Override
122    public Set<String> getSocialProviders() {
123        return getPrefs().getStringSet(PREFS_KEY_PROVIDER_SET, new HashSet<String>());
124    }
125
126    /**
127     * Add a used social provider identifier.
128     *
129     * @param provider Provider identifier name {@link com.gigya.android.sdk.GigyaDefinitions.Providers}
130     */
131    @Override
132    public void addSocialProvider(String provider) {
133        Set<String> providerSet = getSocialProviders();
134        if (providerSet == null) {
135            providerSet = new HashSet<>();
136        }
137        providerSet.add(provider);
138        getPrefs().edit().putStringSet(PREFS_KEY_PROVIDER_SET, providerSet).apply();
139    }
140
141    /**
142     * Remove all saved social provider identifiers.
143     * Will be called after logout.
144     */
145    @Override
146    public void removeSocialProviders() {
147        remove(PREFS_KEY_PROVIDER_SET);
148    }
149
150    //endregion
151
152    //region PRIVATE HELPERS
153
154    private boolean contains(String key) {
155        return _prefs.contains(key);
156    }
157
158    @Override
159    public String getString(String key, String defValue) {
160        return getPrefs().getString(key, defValue);
161    }
162
163    @Override
164    public Long getLong(String key, Long defValue) {
165        return getPrefs().getLong(key, defValue);
166    }
167
168    @Override
169    public void add(String key, Object element) {
170        final SharedPreferences.Editor editor = getPrefs().edit();
171        if (element instanceof String) {
172            editor.putString(key, (String) element);
173        } else if (element instanceof Long) {
174            editor.putLong(key, (Long) element);
175        }
176        editor.apply();
177    }
178
179    private void remove(String... keys) {
180        final SharedPreferences.Editor editor = getPrefs().edit();
181        for (String key : keys) {
182            editor.remove(key);
183        }
184        editor.apply();
185    }
186
187    private Set<String> getSet(String key, Set<String> defValue) {
188        return getPrefs().getStringSet(key, defValue);
189    }
190
191    @Override
192    public void setPushToken(String pushToken) {
193        getPrefs().edit().putString(PREFS_PUSH_TOKEN, pushToken).apply();
194    }
195
196    @Nullable
197    @Override
198    public String getPushToken() {
199        return getPrefs().getString(PREFS_PUSH_TOKEN, null);
200    }
201
202    //endregion
203
204    //region KEYS
205
206    /*
207     * File key for SDK preferences persistence.
208     */
209    public static final String PREFS_FILE_KEY = "GSLIB";
210
211    /*
212     * Value key for Session persistence.
213     */
214    public static final String PREFS_KEY_SESSION = "GS_PREFS";
215
216    /*
217     * Value key for last used social providers.
218     */
219    public static final String PREFS_KEY_PROVIDER_SET = "GS_PROVIDER_SET";
220
221    /*
222     * Value key for session expiration timestamp.
223     */
224    public static final String PREFS_KEY_SESSION_EXPIRE_TIMESTAMP = "GS_SESSION_EXPIRE_TIMESTAMP";
225
226    /*
227   Value key for session encryption type. Value is taken from legacy version 3 to allow upgrading from older SDK versions.
228    */
229    public static final String PREFS_KEY_SESSION_ENCRYPTION_TYPE = "sessionProtectionType";
230
231    /*
232     * Value key for biometric cipher iv spec.
233     */
234    public static final String PREFS_KEY_IV_SPEC = "IV_fingerprint";
235
236    /*
237     * Push token key.
238     */
239    private static final String PREFS_PUSH_TOKEN = "GS_PUSH_TOKEN";
240
241    //endregion
242}