/// <summary>
        /// Application specific configuration
        /// This method should initialize any IoC resources utilized by your web service classes.
        /// </summary>
        /// <param name="container"></param>
        public override void Configure(Container container)
        {
            //Config examples
            //this.Plugins.Add(new PostmanFeature());
            //this.Plugins.Add(new CorsFeature());

            SetConfig(new HostConfig
            {
                DebugMode = AppSettings.Get("DebugMode", false),
                AddRedirectParamsToQueryString = true
            });

            LogManager.LogFactory = new EventLogFactory("DiscourseAutoApprover", "Application");

            Plugins.Add(new RazorFormat());
            Plugins.Add(new ValidationFeature());
            container.Register(AppSettings);

            var client = new DiscourseClient(
                AppSettings.Get("DiscourseRemoteUrl", ""),
                AppSettings.Get("DiscourseAdminApiKey", ""),
                AppSettings.Get("DiscourseAdminUserName", ""));

            client.Login(AppSettings.Get("DiscourseAdminUserName", ""), AppSettings.Get("DiscourseAdminPassword", ""));
            container.Register <IDiscourseClient>(client);

            var serviceStackAccountClient = new ServiceStackAccountClient(AppSettings.GetString("CheckSubscriptionUrl"));

            container.Register <IServiceStackAccountClient>(serviceStackAccountClient);
        }
        public void Any(SyncSingleUser request)
        {
            if (request.UserId == null)
            {
                throw new HttpError(400, "BadRequest");
            }

            GetUserByIdResponse user;

            try
            {
                user = DiscourseClient.GetUserById(request.UserId);
            }
            catch (Exception e)
            {
                Log.Error("Failed to get user from Discourse - {0}".Fmt(e.Message), e);
                throw new HttpError(500, "Failed to get user from Discourse");
            }

            if (user == null)
            {
                throw HttpError.NotFound("User not found in Discourse");
            }
            // Email is ONLY populated when performing admin get all users as Discourse API allows it via show_emails
            // query string. Single user request doesn't have same rules..
            var emailResponse = DiscourseClient.GetUserEmail(request.UserId);

            user.User.Email = emailResponse.Email;

            var serviceStackSubscription = GetDiscourseUserServiceStackSubscription(user.User);

            UpdateDiscourseAccountStatus(user.User, serviceStackSubscription, 1000);
        }
        public object Any(SyncAccountsDaily request)
        {
            var users = DiscourseClient.AdminGetUsers(1000);

            foreach (var discourseUser in users)
            {
                //Don't process discourse administrators or already suspended users
                if (discourseUser.Admin || discourseUser.IsSuspended())
                {
                    continue;
                }

                UserServiceResponse existingCustomerSubscription;
                try
                {
                    existingCustomerSubscription = ServiceStackAccountClient.GetUserSubscription(discourseUser.Email);
                }
                catch (Exception e)
                {
                    Log.Error("Failed to check user {0} subscription. Retrying... - {2}".Fmt(discourseUser.Username, e.Message));
                    try
                    {
                        existingCustomerSubscription = ServiceStackAccountClient.GetUserSubscription(discourseUser.Email);
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Failed to check user {0} subscription. Cancelling sync. - {1}".Fmt(discourseUser.Username, ex.Message));
                        break;
                    }
                }

                //Skip users with valid SS subscriptions.
                if (existingCustomerSubscription.HasValidSubscription())
                {
                    continue;
                }

                try
                {
                    Thread.Sleep(2000);
                    //Existing user with active account but without a valid subscription
                    if (!discourseUser.NeedsApproval() && discourseUser.IsNotSuspended())
                    {
                        Log.Info("Suspending user '{0}'.".Fmt(discourseUser.Email));
                        SuspendUser(discourseUser);
                    }
                }
                catch (Exception e)
                {
                    Log.Error("Failed to suspend Discourse for user '{0}'. - {1}".Fmt(discourseUser.Email, e.Message));
                }
            }
            return(null);
        }
 private void SuspendUser(DiscourseUser user)
 {
     try
     {
         DiscourseClient.AdminSuspendUser(user.Id, 365, AppSettings.GetString("DiscourseSuspensionReason"));
     }
     catch (Exception)
     {
         //Try to login again and retry
         DiscourseClient.Login(AppSettings.Get("DiscourseAdminUserName", ""), AppSettings.Get("DiscourseAdminPassword", ""));
         DiscourseClient.AdminSuspendUser(user.Id, 365, AppSettings.GetString("DiscourseSuspensionReason"));
     }
 }
 private void UnsuspendUser(DiscourseUser user)
 {
     try
     {
         DiscourseClient.AdminUnsuspendUser(user.Id);
     }
     catch (Exception)
     {
         //Try to login again and retry
         DiscourseClient.Login(AppSettings.Get("DiscourseAdminUserName", ""), AppSettings.Get("DiscourseAdminPassword", ""));
         DiscourseClient.AdminUnsuspendUser(user.Id);
     }
 }
        public object Any(SyncAccountsHourly request)
        {
            var users = DiscourseClient.AdminGetUsers(1000);

            foreach (var discourseUser in users)
            {
                //Don't process discourse administrators or users already approved.
                if (discourseUser.Admin || (discourseUser.Suspended == null || discourseUser.Suspended == false))
                {
                    continue;
                }

                UserServiceResponse existingCustomerSubscription;
                try
                {
                    existingCustomerSubscription = ServiceStackAccountClient.GetUserSubscription(discourseUser.Email);
                }
                catch (Exception e)
                {
                    Log.Error("Failed to check user {0} subscription. Retrying... - {1}".Fmt(discourseUser.Username, e.Message));
                    try
                    {
                        existingCustomerSubscription = ServiceStackAccountClient.GetUserSubscription(discourseUser.Email);
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Failed to check user {0} subscription. Cancelling sync. - {1}".Fmt(discourseUser.Username, ex.Message));
                        break;
                    }
                }

                if (existingCustomerSubscription.HasValidSubscription())
                {
                    try
                    {
                        Thread.Sleep(2000);
                        if (discourseUser.Suspended == true)
                        {
                            Log.Info("Unsuspending user '{0}'.".Fmt(discourseUser.Email));
                            UnsuspendUser(discourseUser);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error("Failed to suspend Discourse for user '{0}'. - {1}".Fmt(discourseUser.Email, e.Message));
                    }
                }
            }
            return(null);
        }
        public void Any(SyncServiceStackCustomers request)
        {
            var users = DiscourseClient.AdminGetUsers(1000);

            foreach (var discourseUser in users)
            {
                //Don't process discourse administrators
                if (discourseUser.Admin)
                {
                    continue;
                }

                var existingCustomerSubscription = GetDiscourseUserServiceStackSubscription(discourseUser);

                UpdateDiscourseAccountStatus(discourseUser, existingCustomerSubscription);
            }
        }
        public void Any(SyncSingleUserByEmail request)
        {
            if (request.Email == null)
            {
                throw new HttpError(400, "MissingEmail");
            }

            // Filter value in discourse matches on various things, including email.
            // However, it will make on email within email, eg [email protected] vs [email protected] or [email protected] vs [email protected]..
            // To avoid abuse of the discourse generic filter, request.Email is validated to be an email address via `SyncSingleUserByEmailValidator`
            var users = DiscourseClient.AdminFindUsersByFilter(request.Email);

            var user = users.FirstOrDefault();

            if (user == null)
            {
                throw new HttpError(400, "Failed");
            }

            var serviceStackSubscription = GetDiscourseUserServiceStackSubscription(user);

            UpdateDiscourseAccountStatus(user, serviceStackSubscription, 1000);
        }