AuthWorker class is responsible for working with OAuth authorization server, retrieving access tokens and refreshing them
        private string ExtractUserName()
        {
            var _s = Request.Headers["Authorization"];
            if (_s != null && _s.StartsWith("OAuth"))
            {
                var _strings = _s.Split(' ');
                var _token = _strings[1];

                var _userName = new AuthWorker(Options.OAuthUrl, Options.OAuthRedirectUrl, Options.OAuthSecret, Options.OAuthAppId).GetUserInfo(_token).username;
                return _userName;
            }
            return null;
        }
        public JsonResult GetForecast(ForecastRetrieveDTO forecastDTO)
        {
            GenericResponse responseObj = null;
            int timeStart = DateTime.Now.TimeOfDay.Seconds;
            try
            {
                string userName = new AuthWorker(Options.OAuthUrl, Options.OAuthRedirectUrl, Options.OAuthSecret,
                        Options.OAuthAppId).GetUserInfo(forecastDTO.authToken).username;
                if(userName == null) throw new Sequencing.WeatherApp.Controllers.DaoLayer.ApplicationException(string.Format("Invalid access token {0}", forecastDTO.authToken));

                AppChainResults acr = new AppChainResults
                {
                    MelanomaAppChainResult = forecastDTO.melanomaRisk,
                    VitDAppChainResult = forecastDTO.vitaminD
                };

                var _s = new PersonalizedRecommendationsWorker().GetRecommendation(forecastDTO.forecastRequest, acr, userName, forecastDTO.appId);

                responseObj = new GenericResponse()
                {
                    Status = 0,
                    ResponseTime = DateTime.Now.TimeOfDay.Seconds - timeStart,
                    Message = "Genetically tailored forecast successfully retrieved",
                    Data = _s,
                };

                return Json(responseObj, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                responseObj = new GenericResponse()
                {
                    Status = 1,
                    ResponseTime = DateTime.Now.TimeOfDay.Milliseconds - timeStart,
                    Message = e.Message,
                    Data = "Personalization is not possible due to insufficient genetic data in the selected file. Choose a different genetic data file.",
                };

                ExternalSettingsController.ResponseLogging(responseObj);
                return Json(responseObj, JsonRequestBehavior.AllowGet);
            }
        }
        public JsonResult SubscribePushNotification(PushSubscribeDTO pushDTO)
        {
            GenericResponse responseObj = null;
            int timeStart = DateTime.Now.TimeOfDay.Seconds;

            try
            {
                if (pushDTO.pushCheck)
                    pushService.Subscribe(pushDTO.deviceToken, pushDTO.deviceType, pushDTO.accessToken, pushDTO.appType);
                else
                {
                    string userName = new AuthWorker(Options.OAuthUrl, Options.OAuthRedirectUrl, Options.OAuthSecret,
                        Options.OAuthAppId).GetUserInfo(pushDTO.accessToken).username;
                    if (userName != null)
                    {
                        var userId = factory.GetDeviceTokenDao().GetUserIdByName(userName);
                        pushService.Unsubscribe(pushDTO.deviceToken, userId);
                    }
                    else
                        throw new Sequencing.WeatherApp.Controllers.DaoLayer.ApplicationException(string.Format("Invalid access token {0}", pushDTO.accessToken));
                }

                responseObj = new GenericResponse()
                {
                    Status = 0,
                    ResponseTime = DateTime.Now.TimeOfDay.Seconds - timeStart,
                    Message = "Push notification successfully " + (pushDTO.pushCheck ? "subscribed" : "unsubscribed"),
                    Data = null,
                };

                return Json(responseObj, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                responseObj = new GenericResponse()
                {
                    Status = 1,
                    ResponseTime = DateTime.Now.TimeOfDay.Seconds - timeStart,
                    Message = e.Message,
                    Data = null,
                };

                ResponseLogging(responseObj);
                return Json(responseObj, JsonRequestBehavior.AllowGet);
            }
        }
 /// <summary>
 /// Runs requests, is executed several times in case of error - request is attempted with refreshed auth data
 /// </summary>
 /// <param name="_restClient"></param>
 /// <param name="_restRequest"></param>
 /// <returns></returns>
 private IRestResponse RunRq(RestClient _restClient, RestRequest _restRequest)
 {
     IRestResponse _restResponse = null;
     for (int _idx = 0; _idx < 5; _idx++)
     {
         _restResponse = _restClient.Execute(_restRequest);
         if (_restResponse.StatusCode != HttpStatusCode.OK)
         {
             var _userInfo = userAuthWorker.GetCurrent();
             var _newInfo =
                 new AuthWorker(Options.OAuthUrl, Options.OAuthRedirectUrl, Options.OAuthSecret,
                     Options.OAuthAppId).RefreshToken(_userInfo.RefreshToken);
             if (!_newInfo.Success)
                 throw new Exception("Error while token refresh:" + _userInfo.RefreshToken+"," + _newInfo.ErrorMessage);
             _userInfo.AuthToken = _newInfo.Token.access_token;
             var _updateToken = userAuthWorker.UpdateToken(_userInfo);
             _restClient.Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(_updateToken.AuthToken);
             _restRequest.Parameters.RemoveAll(parameter => parameter.Name == "Authorization");
             _restResponse = _restClient.Execute(_restRequest);
         }
         if (_restResponse.StatusCode == HttpStatusCode.OK)
             return _restResponse;
         Thread.Sleep(5*1000);
     }
     return _restResponse;
 }
        /// <summary>
        /// Subscribe user to get push message
        /// </summary>
        /// <param name="deviceToken"></param>
        /// <param name="deviceType"></param>
        /// <param name="accessToken"></param>
        public void Subscribe(string deviceToken, DeviceType deviceType, string accessToken, ApplicationType? appType)
        {
            try
            {
               string userName = new AuthWorker(Options.OAuthUrl, Options.OAuthRedirectUrl, Options.OAuthSecret,
               Options.OAuthAppId).GetUserInfo(accessToken).username;

                if (userName != null)
                {
                    var sendInfo = mssqlDaoFactory.GetSendInfoDao().Find(userName);

                    if (sendInfo != null)
                        settingsService.SubscribePushNotification(deviceToken, deviceType, sendInfo, appType);
                }
                else
                    throw new ApplicationException(string.Format("Invalid access token {0}", accessToken));
            }
            catch (Exception e)
            {
                throw new ApplicationException(e.Message);
            }
        }