예제 #1
0
        public async Task CreateOrganizationAndProjectAsync(string userId) {
            if (await _tokenRepository.GetByIdAsync(TEST_API_KEY).AnyContext() != null)
                return;

            User user = await _userRepository.GetByIdAsync(userId, true).AnyContext();
            var organization = new Organization { Id = TEST_ORG_ID, Name = "Acme" };
            BillingManager.ApplyBillingPlan(organization, BillingManager.UnlimitedPlan, user);
            organization = await _organizationRepository.AddAsync(organization, true).AnyContext();

            var project = new Project { Id = TEST_PROJECT_ID, Name = "Disintegrating Pistol", OrganizationId = organization.Id };
            project.NextSummaryEndOfDayTicks = DateTime.UtcNow.Date.AddDays(1).AddHours(1).Ticks;
            project.Configuration.Settings.Add("IncludeConditionalData", "true");
            project.AddDefaultOwnerNotificationSettings(userId);
            project = await _projectRepository.AddAsync(project, true).AnyContext();

            await _tokenRepository.AddAsync(new Token {
                Id = TEST_API_KEY,
                OrganizationId = organization.Id,
                ProjectId = project.Id,
                CreatedUtc = DateTime.UtcNow,
                ModifiedUtc = DateTime.UtcNow,
                Type = TokenType.Access
            }).AnyContext();

            await _tokenRepository.AddAsync(new Token {
                Id = TEST_USER_API_KEY,
                UserId = user.Id,
                CreatedUtc = DateTime.UtcNow,
                ModifiedUtc = DateTime.UtcNow,
                Type = TokenType.Access
            }).AnyContext();

            user.OrganizationIds.Add(organization.Id);
            await _userRepository.SaveAsync(user, true).AnyContext();
        }
예제 #2
0
        public bool CanDownGrade(Organization organization, BillingPlan plan, User user, out string message) {
            if (organization == null || String.IsNullOrWhiteSpace(organization.Id)) {
                message = "Invalid Organization";
                return false;
            }

            long currentNumberOfUsers = _userRepository.GetByOrganizationId(organization.Id).Total + organization.Invites.Count;
            int maxUsers = plan.MaxUsers != -1 ? plan.MaxUsers : int.MaxValue;
            if (currentNumberOfUsers > maxUsers) {
                message = String.Format("Please remove {0} user{1} and try again.", currentNumberOfUsers - maxUsers, (currentNumberOfUsers - maxUsers) > 0 ? "s" : String.Empty);
                return false;
            }

            int maxProjects = plan.MaxProjects != -1 ? plan.MaxProjects : int.MaxValue;
            long projectCount = _projectRepository.GetCountByOrganizationId(organization.Id);
            if (projectCount > maxProjects) {
                message = String.Format("Please remove {0} project{1} and try again.", projectCount - maxProjects, (projectCount - maxProjects) > 0 ? "s" : String.Empty);
                return false;
            }

            // Ensure the user can't be apart of more than one free plan.
            if (String.Equals(plan.Id, FreePlan.Id) && user != null && _organizationRepository.GetByIds(user.OrganizationIds).Documents.Any(o => String.Equals(o.PlanId, FreePlan.Id))) {
                message = "You already have one free account. You are not allowed to create more than one free account.";
                return false;
            }

            message = String.Empty;
            return true;
        }
예제 #3
0
        public async Task<bool> CanAddUserAsync(Organization organization) {
            if (String.IsNullOrWhiteSpace(organization?.Id))
                return false;

            long numberOfUsers = (await _userRepository.GetByOrganizationIdAsync(organization.Id).AnyContext()).Total + organization.Invites.Count;
            return organization.MaxUsers <= -1 || numberOfUsers < organization.MaxUsers;
        }
예제 #4
0
        public bool CanAddUser(Organization organization) {
            if (organization == null || String.IsNullOrWhiteSpace(organization.Id))
                return false;

            long numberOfUsers = _userRepository.GetByOrganizationId(organization.Id).Total + organization.Invites.Count;
            return organization.MaxUsers <= -1 || numberOfUsers < organization.MaxUsers;
        }
        private void UpgradePlan(Organization organization) {
            var plan = BillingManager.GetBillingPlan(organization.PlanId);
            if (plan == null) {
                _logger.Error("Unable to find a valid plan for organization: {0}", organization.Id);
                return;
            }

            BillingManager.ApplyBillingPlan(organization, plan, user: null, updateBillingPrice: false);
        }
예제 #6
0
 public Task SendPaymentFailedAsync(User owner, Organization organization) {
     System.Net.Mail.MailMessage msg = _emailGenerator.GenerateMessage(new PaymentModel {
         Owner = owner,
         Organization = organization,
         BaseUrl = Settings.Current.BaseURL
     }, "PaymentFailed");
     msg.To.Add(owner.EmailAddress);
     
     return QueueMessageAsync(msg, "paymentfailed");
 }
예제 #7
0
        public void SendPaymentFailed(User owner, Organization organization) {
            System.Net.Mail.MailMessage msg = _emailGenerator.GenerateMessage(new PaymentModel {
                Owner = owner,
                Organization = organization,
                BaseUrl = Settings.Current.BaseURL
            }, "PaymentFailed");
            msg.To.Add(owner.EmailAddress);

            QueueMessage(msg);
        }
예제 #8
0
 public Task SendAddedToOrganizationAsync(User sender, Organization organization, User user) {
     System.Net.Mail.MailMessage msg = _emailGenerator.GenerateMessage(new AddedToOrganizationModel {
         Sender = sender,
         Organization = organization,
         User = user,
         BaseUrl = Settings.Current.BaseURL
     }, "AddedToOrganization");
     msg.To.Add(user.EmailAddress);
     
     return QueueMessageAsync(msg, "addedtoorganization");
 }
예제 #9
0
        public void SendInvite(User sender, Organization organization, Invite invite) {
            System.Net.Mail.MailMessage msg = _emailGenerator.GenerateMessage(new InviteModel {
                Sender = sender,
                Organization = organization,
                Invite = invite,
                BaseUrl = Settings.Current.BaseURL
            }, "Invite");
            msg.To.Add(invite.EmailAddress);

            QueueMessage(msg);
        }
예제 #10
0
        public void SendAddedToOrganization(User sender, Organization organization, User user) {
            System.Net.Mail.MailMessage msg = _emailGenerator.GenerateMessage(new AddedToOrganizationModel {
                Sender = sender,
                Organization = organization,
                User = user,
                BaseUrl = Settings.Current.BaseURL
            }, "AddedToOrganization");
            msg.To.Add(user.EmailAddress);

            QueueMessage(msg);
        }
예제 #11
0
        public WebHookDataContext(Version version, Stack stack, Organization organization = null, Project project = null, bool isNew = false, bool isRegression = false) {
            if (version == null)
                throw new ArgumentException("Version cannot be null.", "version");

            if (stack == null)
                throw new ArgumentException("Stack cannot be null.", "stack");

            Version = version;
            Organization = organization;
            Project = project;
            Stack = stack;
            IsNew = isNew;
            IsRegression = isRegression;
        }
예제 #12
0
 public WebHookDataContext(Version version, PersistentEvent ev, Organization organization = null, Project project = null, Stack stack = null, bool isNew = false, bool isRegression = false) {
     if (version == null)
         throw new ArgumentException("Version cannot be null.", "version");
     
     if (ev == null)
         throw new ArgumentException("Event cannot be null.", "ev");
     
     Version = version;
     Organization = organization;
     Project = project;
     Stack = stack;
     Event = ev;
     IsNew = isNew;
     IsRegression = isRegression;
 }
예제 #13
0
        private async Task EnforceEventCountLimitsAsync(Organization organization) {
            Logger.Info().Message("Enforcing event count limits for organization '{0}' with Id: '{1}'", organization.Name, organization.Id).Write();

            try {
                int retentionDays = organization.RetentionDays;

                var nextPlan = BillingManager.GetBillingPlanByUpsellingRetentionPeriod(organization.RetentionDays);
                if (nextPlan != null)
                    retentionDays = nextPlan.RetentionDays;

                DateTime cutoff = DateTime.UtcNow.Date.SubtractDays(retentionDays);
                await _eventRepository.RemoveAllByDateAsync(organization.Id, cutoff).AnyContext();
            } catch (Exception ex) {
                Logger.Error().Message("Error enforcing limits: org={0} id={1} message=\"{2}\"", organization.Name, organization.Id, ex.Message).Exception(ex).Write();
            }
        }
예제 #14
0
        public static void ApplyBillingPlan(Organization organization, BillingPlan plan, User user = null, bool updateBillingPrice = true) {
            organization.PlanId = plan.Id;
            organization.PlanName = plan.Name;
            organization.PlanDescription = plan.Description;
            organization.BillingChangeDate = DateTime.Now;

            if (updateBillingPrice)
                organization.BillingPrice = plan.Price;

            organization.BillingChangedByUserId = user?.Id;
            organization.MaxUsers = plan.MaxUsers;
            organization.MaxProjects = plan.MaxProjects;
            organization.RetentionDays = plan.RetentionDays;
            organization.MaxEventsPerMonth = plan.MaxEventsPerMonth;
            organization.HasPremiumFeatures = plan.HasPremiumFeatures;
        }
        public async Task CanCreateUpdateRemove() {
            _repository.RemoveAll();
            Assert.Equal(0, _repository.Count());

            var organization = new Organization { Name = "Test Organization", PlanId = BillingManager.FreePlan.Id };
            Assert.Null(organization.Id);

            _repository.Add(organization);
            await _client.RefreshAsync();
            Assert.NotNull(organization.Id);
            
            organization = _repository.GetById(organization.Id);
            Assert.NotNull(organization);

            organization.Name = "New organization";
            _repository.Save(organization);

            _repository.Remove(organization.Id);
        }
예제 #16
0
        public static void ApplyBillingPlan(Organization organization, BillingPlan plan, User user = null, bool updateBillingPrice = true) {
            organization.PlanId = plan.Id;
            organization.PlanName = plan.Name;
            organization.PlanDescription = plan.Description;
            organization.BillingChangeDate = DateTime.Now;

            if (updateBillingPrice)
                organization.BillingPrice = plan.Price;

            if (user != null)
                organization.BillingChangedByUserId = user.Id;

            organization.MaxUsers = plan.MaxUsers;
            organization.MaxProjects = plan.MaxProjects;
            organization.RetentionDays = plan.RetentionDays;
            organization.MaxEventsPerMonth = plan.MaxEventsPerMonth;
            organization.HasPremiumFeatures = plan.HasPremiumFeatures;

            organization.SetMonthlyUsage(organization.GetCurrentMonthlyTotal(), organization.GetCurrentMonthlyBlocked(), organization.GetCurrentMonthlyTooBig());
        }
예제 #17
0
        public async Task<ChangePlanResult> CanDownGradeAsync(Organization organization, BillingPlan plan, User user) {
            if (String.IsNullOrWhiteSpace(organization?.Id))
                return ChangePlanResult.FailWithMessage("Invalid Organization");

            long currentNumberOfUsers = (await _userRepository.GetByOrganizationIdAsync(organization.Id).AnyContext()).Total + organization.Invites.Count;
            int maxUsers = plan.MaxUsers != -1 ? plan.MaxUsers : int.MaxValue;
            if (currentNumberOfUsers > maxUsers)
                return ChangePlanResult.FailWithMessage($"Please remove {currentNumberOfUsers - maxUsers} user{((currentNumberOfUsers - maxUsers) > 0 ? "s" : String.Empty)} and try again.");

            int maxProjects = plan.MaxProjects != -1 ? plan.MaxProjects : int.MaxValue;
            long projectCount = await _projectRepository.GetCountByOrganizationIdAsync(organization.Id).AnyContext();
            if (projectCount > maxProjects)
                return ChangePlanResult.FailWithMessage($"Please remove {projectCount - maxProjects} project{((projectCount - maxProjects) > 0 ? "s" : String.Empty)} and try again.");

            // Ensure the user can't be apart of more than one free plan.
            if (String.Equals(plan.Id, FreePlan.Id) && user != null && (await _organizationRepository.GetByIdsAsync(user.OrganizationIds)).Documents.Any(o => String.Equals(o.PlanId, FreePlan.Id)))
                return ChangePlanResult.FailWithMessage("You already have one free account. You are not allowed to create more than one free account.");
            
            return new ChangePlanResult { Success = true };
        }
        public async Task CanAddAndGetByCached() {
            var cache = IoC.GetInstance<ICacheClient>() as InMemoryCacheClient;
            Assert.NotNull(cache);
            await cache.RemoveAllAsync();
            
            var organization = new Organization { Name = "Test Organization", PlanId = BillingManager.FreePlan.Id };
            Assert.Null(organization.Id);

            Assert.Equal(0, cache.Count);
            await _repository.AddAsync(organization, true);
            Assert.NotNull(organization.Id);
            Assert.Equal(1, cache.Count);

            await cache.RemoveAllAsync();
            Assert.Equal(0, cache.Count);
            await _repository.GetByIdAsync(organization.Id, true);
            Assert.NotNull(organization.Id);
            Assert.Equal(1, cache.Count);

            await _repository.RemoveAllAsync();
            Assert.Equal(0, cache.Count);
        }
        private async Task SendOverageNotificationsAsync(Organization organization, bool isOverHourlyLimit, bool isOverMonthlyLimit) {
            var results = await _userRepository.GetByOrganizationIdAsync(organization.Id).AnyContext();
            foreach (var user in results.Documents) {
                if (!user.IsEmailAddressVerified) {
                    _logger.Info("User {0} with email address {1} has not been verified.", user.Id, user.EmailAddress);
                    continue;
                }

                if (!user.EmailNotificationsEnabled) {
                    _logger.Info().Message("User {0} with email address {1} has email notifications disabled.", user.Id, user.EmailAddress);
                    continue;
                }

                _logger.Trace("Sending email to {0}...", user.EmailAddress);
                await _mailer.SendOrganizationNoticeAsync(user.EmailAddress, new OrganizationNotificationModel {
                    Organization = organization,
                    IsOverHourlyLimit = isOverHourlyLimit,
                    IsOverMonthlyLimit = isOverMonthlyLimit
                }).AnyContext();
            }

            _logger.Trace().Message("Done sending email.");
        }
예제 #20
0
        public static Organization GenerateOrganization(bool generateId = false, string name = null, string id = null, string inviteEmail = null, bool isSuspended = false) {
            var organization = new Organization {
                Id = id.IsNullOrEmpty() ? generateId ? ObjectId.GenerateNewId().ToString() : TestConstants.OrganizationId : id,
                Name = name ?? $"Organization{id}"
            };

            BillingManager.ApplyBillingPlan(organization, BillingManager.UnlimitedPlan);

            if (!String.IsNullOrEmpty(inviteEmail)) {
                organization.Invites.Add(new Invite {
                    EmailAddress = inviteEmail,
                    Token = Guid.NewGuid().ToString()
                });
            }

            if (isSuspended) {
                organization.IsSuspended = true;
                organization.SuspensionCode = SuspensionCode.Abuse;
                organization.SuspendedByUserId = TestConstants.UserId;
                organization.SuspensionDate = DateTime.Now;
            }

            return organization;
        }
예제 #21
0
 public Task SendPaymentFailedAsync(User owner, Organization organization) {
     return Task.CompletedTask;
 }
예제 #22
0
 public void SendInvite(User sender, Organization organization, Invite invite) {}
예제 #23
0
 public void SendPaymentFailed(User owner, Organization organization) {}
예제 #24
0
        public async Task CreateInternalOrganizationAndProjectAsync(string userId) {
            if (await _tokenRepository.GetByIdAsync(INTERNAL_API_KEY).AnyContext() != null)
                return;

            User user = await _userRepository.GetByIdAsync(userId, true).AnyContext();
            var organization = new Organization { Name = "Exceptionless" };
            BillingManager.ApplyBillingPlan(organization, BillingManager.UnlimitedPlan, user);
            organization = await _organizationRepository.AddAsync(organization, true).AnyContext();

            var project = new Project { Id = INTERNAL_PROJECT_ID, Name = "API", OrganizationId = organization.Id };
            project.NextSummaryEndOfDayTicks = DateTime.UtcNow.Date.AddDays(1).AddHours(1).Ticks;
            project.AddDefaultOwnerNotificationSettings(userId);
            project = await _projectRepository.AddAsync(project, true).AnyContext();

            await _tokenRepository.AddAsync(new Token {
                Id = INTERNAL_API_KEY,
                OrganizationId = organization.Id,
                ProjectId = project.Id,
                CreatedUtc = DateTime.UtcNow,
                ModifiedUtc = DateTime.UtcNow,
                Type = TokenType.Access
            }).AnyContext();

            user.OrganizationIds.Add(organization.Id);
            await _userRepository.SaveAsync(user, true).AnyContext();
        }
예제 #25
0
 public void SendAddedToOrganization(User sender, Organization organization, User user) {}
예제 #26
0
        public string CreateDefaultOrganizationAndProject(User user) {
            string organizationId = user.OrganizationIds.FirstOrDefault();
            if (!String.IsNullOrEmpty(organizationId)) {
                var defaultProject = _projectRepository.GetByOrganizationId(user.OrganizationIds.First(), useCache: true).Documents.FirstOrDefault();
                if (defaultProject != null)
                    return defaultProject.Id;
            } else {
                var organization = new Organization {
                    Name = "Default Organization"
                };
                BillingManager.ApplyBillingPlan(organization, Settings.Current.EnableBilling ? BillingManager.FreePlan : BillingManager.UnlimitedPlan, user);
                _organizationRepository.Add(organization);
                organizationId = organization.Id;
            }

            var project = new Project { Name = "Default Project", OrganizationId = organizationId };
            project.NextSummaryEndOfDayTicks = DateTime.UtcNow.Date.AddDays(1).AddHours(1).Ticks;
            project.AddDefaultOwnerNotificationSettings(user.Id);
            project = _projectRepository.Add(project);
            
            _tokenRepository.Add(new Token {
                Id = StringExtensions.GetNewToken(),
                OrganizationId = organizationId,
                ProjectId = project.Id,
                CreatedUtc = DateTime.UtcNow,
                ModifiedUtc = DateTime.UtcNow,
                Type = TokenType.Access
            });

            if (!user.OrganizationIds.Contains(organizationId)) {
                user.OrganizationIds.Add(organizationId);
                _userRepository.Save(user, true);
            }

            return project.Id;
        }
예제 #27
0
 public Task SendInviteAsync(User sender, Organization organization, Invite invite) {
     return Task.CompletedTask;
 }
예제 #28
0
 public Task SendAddedToOrganizationAsync(User sender, Organization organization, User user) {
     return Task.CompletedTask;
 }