Tags

, , ,

I found myself in a situation where a background task in an MVC app needed to authenticate with Google Api using OAuth 2.0 in order to consume the Youtube Data Api in a scenario with out user interaction and FlowMedata support.  FlowMedata and Url Redirection are use in web scenarios as they often require user interaction; where as in Native apps an IDataStore is used to cache the token provided by Google as part of its response to the authentication request and the refresh token which is also send as part of the response.  The refresh token avoids the need to authenticate over and over using the same credentials.  In Brief, my current scenario demands my Web app to behave a bit similar to Native app and store the tokens inside a folder local to the web app.  An IDataStore implementation could do just that as it is the facade to some store, orchestrating Objects saving and retrieval using a combination of the object(to be saved) type and a string as  identifier.  Pick-bagging off the FileDataStore implementation, I wrote mine to use  folder local to my MVC app.

 public sealed class WebFileDataStore : IDataStore
    {
        private readonly string _folderPath;


        public WebFileDataStore(string folder)
        {
            _folderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", folder);
            if (Directory.Exists(_folderPath))
                return;
            Directory.CreateDirectory(_folderPath);
        }

        public Task StoreAsync<T>(string key, T value)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentException("Key argument required");
            string contents = NewtonsoftJsonSerializer.Instance.Serialize(value);
            File.WriteAllText(Path.Combine(_folderPath, FileDataStore.GenerateStoredKey(key, typeof(T))), contents);
            return TaskEx.Delay(0);
        }

        public Task DeleteAsync<T>(string key)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentException("Key argument required");
            string path = Path.Combine(_folderPath, FileDataStore.GenerateStoredKey(key, typeof(T)));
            if (File.Exists(path))
                File.Delete(path);
            return TaskEx.Delay(0);
        }

        public Task<T> GetAsync<T>(string key)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentException("Key argument required");
            var completionSource = new TaskCompletionSource<T>();
            string path = Path.Combine(_folderPath, FileDataStore.GenerateStoredKey(key, typeof(T)));
            if (File.Exists(path))
            {
                try
                {
                    string input = File.ReadAllText(path);
                    completionSource.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(input));
                }
                catch (Exception ex)
                {
                    completionSource.SetException(ex);
                }
            }
            else
                completionSource.SetResult(default(T));
            return completionSource.Task;
        }

        public Task ClearAsync()
        {
            if (Directory.Exists(_folderPath))
            {
                Directory.Delete(_folderPath, true);
                Directory.CreateDirectory(_folderPath);
            }
            return TaskEx.Delay(0);
        }

        /// <summary>
        /// Gets the full folder path.
        /// </summary>
        public string FolderPath
        {
            get
            {
                return _folderPath;
            }
        }
    }
Advertisements