Beispiel #1
0
        public async Task CreateTrackDocumentAsync(Track mTrack, string tenantName = null, string trackName = null)
        {
            mTrack.Key = new TrackKey()
            {
                Type = TrackKeyType.KeyVaultRenewSelfSigned,
                ExternalName = await externalKeyLogic.CreateExternalKeyAsync(mTrack, tenantName, trackName)
            };

            await tenantRepository.CreateAsync(mTrack);
        }
Beispiel #2
0
        public async Task CreateTrackDocumentAsync(Track mTrack)
        {
            var certificate = await(RouteBinding.TenantName, mTrack.Name).CreateSelfSignedCertificateBySubjectAsync();

            mTrack.Key = new TrackKey()
            {
                Type = TrackKeyType.Contained,
                Keys = new List <TrackKeyItem> {
                    new TrackKeyItem {
                        Key = await certificate.ToFTJsonWebKeyAsync(true)
                    }
                }
            };
            await tenantRepository.CreateAsync(mTrack);
        }
Beispiel #3
0
        public async Task <User> CreateUser(string email, string password, List <Claim> claims = null)
        {
            logger.ScopeTrace($"Creating user '{email}', Route '{RouteBinding.Route}'.");

            ValidateEmail(email);

            var user = new User {
                UserId = Guid.NewGuid().ToString()
            };
            await user.SetIdAsync(new User.IdKey {
                TenantName = RouteBinding.TenantName, TrackName = RouteBinding.TrackName, Email = email
            });

            await secretHashLogic.AddSecretHashAsync(user, password);

            if (claims?.Count() > 0)
            {
                user.Claims = claims.ToClaimAndValues();
            }

            await ThrowIfUserExists(email);
            await ValidatePasswordPolicy(email, password);

            await tenantRepository.CreateAsync(user);

            logger.ScopeTrace($"User '{email}' created, with user id '{user.UserId}'.");

            return(user);
        }
Beispiel #4
0
        protected async Task <ActionResult <AParty> > Post(AParty party, Func <AParty, Task <bool> > validateApiModelAsync, Func <AParty, MParty, Task <bool> > validateModelAsync)
        {
            try
            {
                if (!await ModelState.TryValidateObjectAsync(party) || !await validateApiModelAsync(party))
                {
                    return(BadRequest(ModelState));
                }

                var mParty = mapper.Map <MParty>(party);
                if (!await(party is Api.IDownParty downParty ? validatePartyLogic.ValidateAllowUpPartiesAsync(ModelState, nameof(downParty.AllowUpPartyNames), mParty as DownParty) : Task.FromResult(true)))
                {
                    return(BadRequest(ModelState));
                }
                if (!await validateModelAsync(party, mParty))
                {
                    return(BadRequest(ModelState));
                }

                await tenantService.CreateAsync(mParty);

                return(Created(mapper.Map <AParty>(mParty)));
            }
            catch (CosmosDataException ex)
            {
                if (ex.StatusCode == HttpStatusCode.Conflict)
                {
                    logger.Warning(ex, $"Create '{typeof(AParty).Name}' by name '{party.Name}'.");
                    return(Conflict(typeof(AParty).Name, party.Name));
                }
                throw;
            }
        }
        protected async Task <ActionResult <AParty> > Post(AParty party, Func <AParty, ValueTask <bool> > apiModelActionAsync, Func <AParty, MParty, ValueTask <bool> > modelActionAsync)
        {
            try
            {
                if (!await ModelState.TryValidateObjectAsync(party) || !validateGenericPartyLogic.ValidateApiModelClaimTransforms(ModelState, party.ClaimTransforms) || !await apiModelActionAsync(party))
                {
                    return(BadRequest(ModelState));
                }

                var mParty = mapper.Map <MParty>(party);
                if (!(party is Api.IDownParty downParty ? await validateGenericPartyLogic.ValidateModelAllowUpPartiesAsync(ModelState, nameof(downParty.AllowUpPartyNames), mParty as DownParty) : true))
                {
                    return(BadRequest(ModelState));
                }
                if (!(await modelActionAsync(party, mParty)))
                {
                    return(BadRequest(ModelState));
                }

                await tenantRepository.CreateAsync(mParty);

                return(Created(mapper.Map <AParty>(mParty)));
            }
            catch (CosmosDataException ex)
            {
                if (ex.StatusCode == HttpStatusCode.Conflict)
                {
                    logger.Warning(ex, $"Conflict, Create '{typeof(AParty).Name}' by name '{party.Name}'.");
                    return(Conflict(typeof(AParty).Name, party.Name));
                }
                throw;
            }
        }
Beispiel #6
0
        public async Task <LoginUpParty> CreateMasterLoginDocumentAsync(string tenantName)
        {
            var mLoginUpParty = new LoginUpParty
            {
                Name              = loginName,
                EnableCreateUser  = false,
                EnableCancelLogin = false,
                SessionLifetime   = 0,
                PersistentSessionLifetimeUnlimited = false,
                LogoutConsent = LoginUpPartyLogoutConsent.IfRequired
            };
            await mLoginUpParty.SetIdAsync(new Party.IdKey {
                TenantName = tenantName?.ToLower(), TrackName = Constants.Routes.MasterTrackName, PartyName = loginName
            });

            await tenantRepository.CreateAsync(mLoginUpParty);

            return(mLoginUpParty);
        }
Beispiel #7
0
        public async Task CreateMasterTrackDocumentAsync(string tenantName)
        {
            var mTrack = new Track
            {
                Name                          = Constants.Routes.MasterTrackName,
                SequenceLifetime              = 1800,
                MaxFailingLogins              = 5,
                FailingLoginCountLifetime     = 36000,
                FailingLoginObservationPeriod = 600,
                PasswordLength                = 8,
                CheckPasswordComplexity       = true,
                CheckPasswordRisk             = true
            };
            await mTrack.SetIdAsync(new Track.IdKey {
                TenantName = tenantName?.ToLower(), TrackName = Constants.Routes.MasterTrackName
            });

            var certificate = await(tenantName.ToLower(), mTrack.Name).CreateSelfSignedCertificateBySubjectAsync();

            mTrack.Key = new TrackKey()
            {
                Type = TrackKeyType.Contained,
                Keys = new List <TrackKeyItem> {
                    new TrackKeyItem {
                        Key = await certificate.ToFTJsonWebKeyAsync(true)
                    }
                }
            };

            await tenantRepository.CreateAsync(mTrack);
        }
Beispiel #8
0
        public async Task <ActionResult <Api.Tenant> > PostTenant([FromBody] Api.CreateTenantRequest tenant)
        {
            try
            {
                if (!await ModelState.TryValidateObjectAsync(tenant))
                {
                    return(BadRequest(ModelState));
                }
                tenant.Name = tenant.Name.ToLower();
                tenant.AdministratorEmail = tenant.AdministratorEmail?.ToLower();

                var mTenant = mapper.Map <Tenant>(tenant);
                await tenantRepository.CreateAsync(mTenant);

                await masterTenantLogic.CreateMasterTrackDocumentAsync(tenant.Name);

                var mLoginUpParty = await masterTenantLogic.CreateMasterLoginDocumentAsync(tenant.Name);

                await masterTenantLogic.CreateFirstAdminUserDocumentAsync(tenant.Name, tenant.AdministratorEmail, tenant.AdministratorPassword, tenant.ConfirmAdministratorAccount);

                await masterTenantLogic.CreateMasterFoxIDsControlApiResourceDocumentAsync(tenant.Name);

                await masterTenantLogic.CreateMasterControlClientDocmentAsync(tenant.Name, tenant.ControlClientBaseUri, mLoginUpParty);

                await CreateTrackDocumentAsync(tenant.Name, "test");
                await CreateTrackDocumentAsync(tenant.Name, "-"); // production

                return(Created(mapper.Map <Api.Tenant>(mTenant)));
            }
            catch (AccountException aex)
            {
                ModelState.TryAddModelError(nameof(tenant.AdministratorPassword), aex.Message);
                return(BadRequest(ModelState, aex));
            }
            catch (CosmosDataException ex)
            {
                if (ex.StatusCode == HttpStatusCode.Conflict)
                {
                    logger.Warning(ex, $"Conflict, Create '{typeof(Api.Tenant).Name}' by name '{tenant.Name}'.");
                    return(Conflict(typeof(Api.Tenant).Name, tenant.Name));
                }
                throw;
            }
        }
        private async Task CreateAndValidateMasterTenantDocumentAsync()
        {
            var masterTenant = new Tenant();
            await masterTenant.SetIdAsync(new Tenant.IdKey {
                TenantName = Constants.Routes.MasterTenantName
            });

            try
            {
                _ = await tenantRepository.GetAsync <Tenant>(masterTenant.Id);
            }
            catch (CosmosDataException ex)
            {
                if (ex.StatusCode != HttpStatusCode.NotFound)
                {
                    throw new Exception($"{masterTenant.Id} document exists.");
                }
            }

            await tenantRepository.CreateAsync(masterTenant);
        }
Beispiel #10
0
        public async Task <User> CreateUser(string email, string password, bool changePassword = false, List <Claim> claims = null, string tenantName = null, string trackName = null, bool checkUserAndPasswordPolicy = true, bool confirmAccount = true, bool emailVerified = false, bool disableAccount = false)
        {
            logger.ScopeTrace($"Creating user '{email}', Route '{RouteBinding?.Route}'.");

            email = email?.ToLower();
            ValidateEmail(email);

            var user = new User {
                UserId = Guid.NewGuid().ToString(), ConfirmAccount = confirmAccount, EmailVerified = emailVerified, DisableAccount = disableAccount
            };
            var userIdKey = new User.IdKey {
                TenantName = tenantName ?? RouteBinding.TenantName, TrackName = trackName ?? RouteBinding.TrackName, Email = email?.ToLower()
            };
            await user.SetIdAsync(userIdKey);

            await secretHashLogic.AddSecretHashAsync(user, password);

            if (claims?.Count() > 0)
            {
                user.Claims = claims.ToClaimAndValues();
            }

            if (checkUserAndPasswordPolicy)
            {
                if (await tenantRepository.ExistsAsync <User>(await User.IdFormat(userIdKey)))
                {
                    throw new UserExistsException($"User '{email}' already exists.");
                }
                await ValidatePasswordPolicy(email, password);
            }
            user.ChangePassword = changePassword;
            await tenantRepository.CreateAsync(user);

            logger.ScopeTrace($"User '{email}' created, with user id '{user.UserId}'.");

            return(user);
        }