Esempio n. 1
0
        public bool IsWellKnownDb()
        {
            var serializer = new ApprovedDomainSerializer();
            var domains    = serializer.Get();

            return(domains.Any(domain => TenantConvention.GetTenant(domain.DomainName) == this.Tenant));
        }
        protected async Task <ActionResult> OnAuthenticatedAsync(LoginResult result, SignInInfo model = null)
        {
            if (!result.Status)
            {
                int delay = new Random().Next(1, 5) * 1000;

                await Task.Delay(delay).ConfigureAwait(false);

                return(new HttpStatusCodeResult(HttpStatusCode.Forbidden, JsonConvert.SerializeObject(result)));
            }


            Guid?applicationId = null;

            if (model != null)
            {
                applicationId = model.ApplicationId;
            }

            var loginView = await AppUsers.GetCurrentAsync(this.Tenant, result.LoginId).ConfigureAwait(false);

            var manager = new Provider(this.Tenant, applicationId, result.LoginId, loginView.UserId, loginView.OfficeId);
            var token   = manager.GetToken();

            await AccessTokens.SaveAsync(this.Tenant, token, this.RemoteUser.IpAddress, this.RemoteUser.UserAgent).ConfigureAwait(true);

            string domain = TenantConvention.GetDomain();

            this.AddAuthenticationCookie(domain, token);
            this.AddCultureCookie(domain, model?.Culture.Or("en-US"));

            return(this.Ok(token.ClientToken));
        }
Esempio n. 3
0
        public void App_BeginRequest(object sender, EventArgs e)
        {
            var context = FrapidHttpContext.GetCurrent();

            if (context == null)
            {
                return;
            }

            string domain = TenantConvention.GetDomain();

            Log.Verbose(
                $"Got a {context.Request.HttpMethod} request {context.Request.AppRelativeCurrentExecutionFilePath} on domain {domain}.");

            bool enforceSsl = TenantConvention.EnforceSsl(domain);

            if (!enforceSsl)
            {
                Log.Verbose($"SSL was not enforced on domain {domain}.");
                return;
            }

            if (context.Request.Url.Scheme == "https")
            {
                context.Response.AddHeader("Strict-Transport-Security", "max-age=31536000");
            }
            else if (context.Request.Url.Scheme == "http")
            {
                string path = "https://" + context.Request.Url.Host + context.Request.Url.PathAndQuery;
                context.Response.Status = "301 Moved Permanently";
                context.Response.AddHeader("Location", path);
            }
        }
Esempio n. 4
0
        public async Task RegisterAsync()
        {
            await Task.Delay(0).ConfigureAwait(false);

            var tenants = TenantConvention.GetTenants();
            var apps    = AppDiscovery.Discover().ToList();

            //Improving application startup time by loading this task on the background.
            new Thread(async() =>
            {
                Thread.CurrentThread.IsBackground = true;

                foreach (string tenant in tenants)
                {
                    foreach (var app in apps)
                    {
                        var updater = new Updater(tenant, app);

                        try
                        {
                            await updater.UpdateAsync().ConfigureAwait(true);
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Could not install updates for application \"{ApplicationName}\" on tenant {tenant} due to errors. Exception: {Exception}", updater.App.ApplicationName, tenant,
                                      ex);
                            throw;
                        }
                    }
                }
            }).Start();
        }
Esempio n. 5
0
        public void Execute(IJobExecutionContext context)
        {
            string fileName = DateTimeOffset.UtcNow.Ticks.ToString();
            var    domains  = TenantConvention.GetDomains();

            foreach (var domain in domains)
            {
                string tenant    = TenantConvention.GetDbNameByConvention(domain.DomainName);
                string directory = this.GetBackupDirectory(domain, tenant);


                var server = new DbServer(tenant);
                var agent  = this.GetAgent(server, fileName, tenant, directory);

                try
                {
                    agent.BackupAsync
                    (
                        done =>
                    {
                        var backup = new Resources(tenant, directory, fileName);

                        backup.AddTenantDataToBackup();
                        backup.Compress();
                        backup.Clean();
                    },
                        error => { Log.Error($"Could not backup because and error occurred. \n\n{error}"); })
                    .Wait();
                }
                catch (Exception ex)
                {
                    Log.Error("Exception occurred executing the backup job. {Exception}.", ex);
                }
            }
        }
Esempio n. 6
0
        public async Task InstallAsync()
        {
            if (Installer.Tenant.Installer.InstalledApps.Contains(this.Installable))
            {
                return;
            }

            foreach (var dependency in this.Installable.Dependencies)
            {
                await new AppInstaller(this.Tenant, this.Database, this.WithoutSample, dependency).InstallAsync().ConfigureAwait(false);
            }

            this.Notify($"Installing module {this.Installable.ApplicationName}.");

            await this.CreateSchemaAsync().ConfigureAwait(false);

            await this.CreateMyAsync().ConfigureAwait(false);

            this.CreateOverride();
            Installer.Tenant.Installer.InstalledApps.Add(this.Installable);

            if (this.Installable.ApplicationName == "Frapid.Account")
            {
                var domain = TenantConvention.FindDomainByTenant(this.Tenant);
                await UserInstaller.CreateUserAsync(this.Tenant, domain).ConfigureAwait(false);
            }
        }
Esempio n. 7
0
        public async Task InstallAsync()
        {
            InstalledApps = new List <Installable>();

            string tenant = TenantConvention.GetTenant(this.Url);

            InstallerLog.Verbose($"Creating database {tenant}.");
            var db = new DbInstaller(tenant);
            await db.InstallAsync().ConfigureAwait(false);

            InstallerLog.Verbose("Getting installables.");
            var installables = GetInstallables(tenant);

            foreach (var installable in installables)
            {
                try
                {
                    InstallerLog.Verbose($"Installing module {installable.ApplicationName}.");
                    await new AppInstaller(tenant, tenant, installable).InstallAsync().ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    InstallerLog.Error(ex.Message);
                    InstallerLog.Error($"Could not install module {installable.ApplicationName}.");
                }
            }
        }
Esempio n. 8
0
        private void LogException(Exception ex)
        {
            string tenant = TenantConvention.GetTenant();
            var    meta   = AppUsers.GetCurrent();

            DefaultExceptionLogger.Log(tenant, meta.UserId, meta.Name, meta.OfficeName, ex.ToString());
        }
Esempio n. 9
0
        protected override void Initialize(RequestContext context)
        {
            string tenant      = TenantConvention.GetTenant();
            string clientToken = context.HttpContext.Request.GetClientToken();
            var    provider    = new Provider();
            var    token       = provider.GetToken(clientToken);

            if (token != null)
            {
                bool isValid = AccessTokens.IsValidAsync(tenant, token.ClientToken, context.HttpContext.GetClientIpAddress(), context.HttpContext.GetUserAgent()).GetAwaiter().GetResult();

                if (isValid)
                {
                    AppUsers.SetCurrentLoginAsync(tenant, token.LoginId).GetAwaiter().GetResult();
                    var loginView = AppUsers.GetCurrentAsync(tenant, token.LoginId).GetAwaiter().GetResult();

                    this.AppUser = new AppUser
                    {
                        Tenant          = tenant,
                        ClientToken     = token.ClientToken,
                        LoginId         = loginView.LoginId,
                        UserId          = loginView.UserId,
                        Name            = loginView.Name,
                        OfficeId        = loginView.OfficeId,
                        OfficeName      = loginView.OfficeName,
                        Email           = loginView.Email,
                        RoleId          = loginView.RoleId,
                        RoleName        = loginView.RoleName,
                        IsAdministrator = loginView.IsAdministrator
                    };

                    var identity = new ClaimsIdentity(token.GetClaims(), DefaultAuthenticationTypes.ApplicationCookie,
                                                      ClaimTypes.NameIdentifier, ClaimTypes.Role);
                    identity.AddClaim(new Claim(ClaimTypes.NameIdentifier,
                                                token.LoginId.ToString(CultureInfo.InvariantCulture)));

                    if (loginView.RoleName != null)
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Role, loginView.RoleName));
                    }

                    if (loginView.Email != null)
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Email, loginView.Email));
                    }

                    context.HttpContext.User = new ClaimsPrincipal(identity);
                }
            }

            if (this.AppUser == null)
            {
                this.AppUser = new AppUser
                {
                    Tenant = tenant
                };
            }

            base.Initialize(context);
        }
Esempio n. 10
0
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string path = this.OverridePath.Or(filterContext.HttpContext.Request.FilePath);

            var    my       = AppUsers.GetCurrentAsync().Result;
            int    userId   = my.UserId;
            int    officeId = my.OfficeId;
            string culture  = my.Culture;

            string tenant = TenantConvention.GetTenant();

            var policy = Menu.GetAsync(tenant, userId, officeId, culture).Result;

            if (!policy.Any(x => x.Url.Equals(path)))
            {
                if (this.StatusResponse)
                {
                    filterContext.Result = new HttpUnauthorizedResult("Access is denied.");
                }
                else
                {
                    filterContext.Result = new RedirectResult("/account/sign-in");
                }
            }
        }
Esempio n. 11
0
        private static UpdateBase GetUpdater(string tenant, Installable app)
        {
            var site = TenantConvention.GetSite(tenant);

            if (site == null)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Not an approved domain.");
                Console.ForegroundColor = ConsoleColor.White;

                return(null);
            }

            string providerName = site.DbProvider;

            switch (providerName)
            {
            case "Npgsql":
                return(new PostgresqlUpdater(tenant, app));

            case "System.Data.SqlClient":
                return(new SqlServerUpdater(tenant, app));

            default:
                throw new SchemaUpdaterException("Frapid schema updater does not support provider " + providerName);
            }
        }
Esempio n. 12
0
        protected override bool IsAuthorized(HttpActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var user = context.RequestContext.Principal as ClaimsPrincipal;

            if (user?.Identity == null)
            {
                return(false);
            }

            long   loginId  = context.RequestContext.ReadClaim <long>("loginid");
            long   userId   = context.RequestContext.ReadClaim <int>("userid");
            long   officeId = context.RequestContext.ReadClaim <int>("officeid");
            string email    = context.RequestContext.ReadClaim <string>(ClaimTypes.Email);

            var    expriesOn   = new DateTime(context.RequestContext.ReadClaim <long>("exp"), DateTimeKind.Utc);
            string ipAddress   = context.Request.GetClientIpAddress();
            string userAgent   = context.Request.GetUserAgent();
            string clientToken = context.Request.GetBearerToken();
            string tenant      = TenantConvention.GetTenant();

            if (string.IsNullOrWhiteSpace(clientToken))
            {
                return(false);
            }


            if (loginId <= 0)
            {
                Log.Warning("Invalid login claims supplied. Access was denied to user {userId}/{email} for officeId {officeId} having the loginId {loginId}. Token: {clientToken}.", userId, email,
                            officeId, loginId, clientToken);
                Thread.Sleep(new Random().Next(1, 60) * 1000);
                return(false);
            }

            if (expriesOn <= DateTimeOffset.UtcNow)
            {
                Log.Debug("Token expired. Access was denied to user {userId}/{email} for officeId {officeId} having the loginId {loginId}. Token: {clientToken}.", userId, email, officeId, loginId,
                          clientToken);
                return(false);
            }


            bool isValid = AccessTokens.IsValidAsync(tenant, clientToken, ipAddress, userAgent).GetAwaiter().GetResult();

            if (expriesOn <= DateTimeOffset.UtcNow)
            {
                Log.Debug("Token invalid. Access was denied to user {userId}/{email} for officeId {officeId} having the loginId {loginId}. Token: {clientToken}.", userId, email, officeId, loginId,
                          clientToken);
                return(false);
            }

            return(isValid);
        }
Esempio n. 13
0
        public static string Get(string key, string tenant = "")
        {
            if (string.IsNullOrWhiteSpace(tenant))
            {
                tenant = TenantConvention.GetTenant();
            }

            return(ResourceManager.GetString(tenant, "Labels", key));
        }
Esempio n. 14
0
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string tenant = TenantConvention.GetTenant();
            var    meta   = AppUsers.GetCurrent(tenant);

            this.FrequencyDates = Dates.GetFrequencyDatesAsync(tenant, meta.OfficeId).Result;

            base.OnActionExecuting(filterContext);
        }
Esempio n. 15
0
        public static void Add(ApprovedDomain tenant)
        {
            string database = TenantConvention.GetDbNameByConvention(tenant.DomainName);

            using (var db = DbProvider.Get(FrapidDbServer.GetSuperUserConnectionString(database, database), database).GetDatabase())
            {
                var sql = new Sql("INSERT INTO account.installed_domains(domain_name, admin_email) SELECT @0, @1;", tenant.DomainName, tenant.AdminEmail);
                db.Execute(sql);
            }
        }
Esempio n. 16
0
        public static string GetProviderName(string tenant)
        {
            if (string.IsNullOrWhiteSpace(tenant))
            {
                return(string.Empty);
            }

            var site = TenantConvention.GetSite(tenant);

            return(site.DbProvider);
        }
Esempio n. 17
0
        private string GetKey(string key)
        {
            string prefix = TenantConvention.GetTenant();

            if (!key.StartsWith(prefix))
            {
                key = prefix + "/" + key;
            }

            return(key);
        }
Esempio n. 18
0
        /// <summary>
        /// This investigates and serves static resources present in the tenant's wwwroot folder.
        /// </summary>
        private void ServeRequestAsTenantResource()
        {
            string tenant = TenantConvention.GetTenant();
            string file   = TenantStaticContentHelper.GetFile(tenant, FrapidHttpContext.GetCurrent());

            if (!string.IsNullOrWhiteSpace(file))
            {
                //We found the requested file on the tenant's "wwwroot" directory.
                FrapidHttpContext.GetCurrent().RewritePath(file);
            }
        }
Esempio n. 19
0
        public override void Initialize()
        {
            this.DomainName = this.Line.GetTokenOn(5);

            if (string.IsNullOrWhiteSpace(this.DomainName))
            {
                return;
            }

            this.Tenant = TenantConvention.GetDbNameByConvention(this.DomainName);
        }
Esempio n. 20
0
        private void App_PostAuthenticateRequest(object sender, EventArgs eventArgs)
        {
            string tenant = TenantConvention.GetTenant();
            string file   = TenantStaticContentHelper.GetFile(tenant, FrapidHttpContext.GetCurrent());

            if (!string.IsNullOrWhiteSpace(file))
            {
                //We found the requested file on the tenant's "wwwroot" directory.
                FrapidHttpContext.GetCurrent().RewritePath(file);
            }
        }
Esempio n. 21
0
        protected override void OnActionExecuting(ActionExecutingContext context)
        {
            if (this.Request?.Url != null)
            {
                this.CurrentDomain  = this.Request.Url.DnsSafeHost;
                this.CurrentPageUrl = this.Request.Url.AbsoluteUri;
                this.Tenant         = TenantConvention.GetTenant(this.CurrentDomain);
            }

            this.RemoteUser = RemoteUser.Get(this.HttpContext);
            this.Initialize(context.RequestContext);
        }
Esempio n. 22
0
        public async Task <ActionResult> IndexAsync()
        {
            string domain = TenantConvention.GetBaseDomain(this.HttpContext, true);

            if (string.IsNullOrWhiteSpace(domain))
            {
                return(this.Failed(Resources.CouldNotGenerateSiteMap, HttpStatusCode.InternalServerError));
            }
            string siteMap = await SiteMapGenerator.GetAsync(this.Tenant, domain).ConfigureAwait(false);

            return(this.Content(siteMap, "text/xml", Encoding.UTF8));
        }
        protected override bool AuthorizeCore(HttpContextBase context)
        {
            string tenant     = TenantConvention.GetTenant();
            bool   authorized = AuthorizationManager.IsAuthorizedAsync(tenant, context).Result;

            if (!authorized)
            {
                FrapidHttpContext.GetCurrent().User = new GenericPrincipal(new GenericIdentity(string.Empty), null);
            }

            return(authorized);
        }
Esempio n. 24
0
        private string GetDomainName()
        {
            var context = this.HttpContext;

            string domain = this.HttpContext?.Request?.Url?.DnsSafeHost;

            if (string.IsNullOrWhiteSpace(domain))
            {
                domain = TenantConvention.GetBaseDomain(context, false);
            }

            return(domain);
        }
Esempio n. 25
0
        public static async Task <RssChannel> GetRssChannelAsync(string tenant, HttpContext context, string categoryAlias,
                                                                 int pageNumber)
        {
            string url       = context.Request.Url.DnsSafeHost;
            string title     = Configuration.Get("BlogTitle", tenant);
            string copyright = Configuration.Get("RssCopyrightText", tenant);
            int    ttl       = Configuration.Get("RssTtl", tenant).To <int>();
            int    limit     = Configuration.Get("RssPageSize", tenant).To <int>();
            int    offset    = (pageNumber - 1) * limit;

            List <PublishedContentView> contents;
            string category = string.Empty;

            if (!string.IsNullOrWhiteSpace(categoryAlias))
            {
                contents =
                    (await Contents.GetBlogContentsAsync(tenant, categoryAlias, limit, offset).ConfigureAwait(false))
                    .ToList();
                category = contents.Select(x => x.CategoryName).FirstOrDefault();
            }
            else
            {
                contents = (await Contents.GetBlogContentsAsync(tenant, limit, offset).ConfigureAwait(false)).ToList();
            }


            string domain = TenantConvention.GetBaseDomain(new HttpContextWrapper(context), true);

            var items = contents.Select(view => new RssItem
            {
                Title         = view.Title,
                Description   = view.Contents,
                Link          = UrlHelper.CombineUrl(domain, "/blog/" + view.CategoryAlias + "/" + view.Alias),
                Ttl           = ttl,
                Category      = view.CategoryName,
                PublishDate   = view.PublishOn,
                LastBuildDate = view.LastEditedOn
            }).ToList();

            var channel = new RssChannel
            {
                Title       = title,
                Description = "Category: " + category,
                Link        = UrlHelper.CombineUrl(domain, "/blog"),
                Items       = items,
                Copyright   = copyright,
                Category    = category
            };

            return(channel);
        }
        protected override void OnActionExecuting(ActionExecutingContext context)
        {
            base.OnActionExecuting(context);

            this.SetLayout();

            this.CurrentDomain = this.Request.Url?.DnsSafeHost;
            bool isStatic = TenantConvention.IsStaticDomain(this.CurrentDomain);

            if (isStatic)
            {
                //Static domains are strictly used for content caching only.
                context.Result = new HttpNotFoundResult(Resources.TheRequestedPageDoesNotExist);
            }
        }
Esempio n. 27
0
        protected override void Initialize(HttpControllerContext context)
        {
            this.Tenant = TenantConvention.GetTenant();

            string clientToken = context.Request.GetBearerToken();
            var    provider    = new Provider();
            var    token       = provider.GetToken(clientToken);


            if (token != null)
            {
                AppUsers.SetCurrentLoginAsync(this.Tenant, token.LoginId).Wait();
                var loginView = AppUsers.GetCurrentAsync(this.Tenant, token.LoginId).Result;

                this.AppUser = new AppUser
                {
                    Tenant          = this.Tenant,
                    ClientToken     = token.ClientToken,
                    LoginId         = token.LoginId,
                    UserId          = loginView.UserId,
                    Name            = loginView.Name,
                    OfficeId        = loginView.OfficeId,
                    OfficeName      = loginView.OfficeName,
                    Email           = loginView.Email,
                    RoleId          = loginView.RoleId,
                    RoleName        = loginView.RoleName,
                    IsAdministrator = loginView.IsAdministrator
                };

                var identity = new ClaimsIdentity(token.GetClaims());

                identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, token.LoginId.ToString(CultureInfo.InvariantCulture)));

                if (this.AppUser.RoleName != null)
                {
                    identity.AddClaim(new Claim(ClaimTypes.Role, this.AppUser.RoleName));
                }

                if (this.AppUser.Email != null)
                {
                    identity.AddClaim(new Claim(ClaimTypes.Email, this.AppUser.Email));
                }

                context.RequestContext.Principal = new ClaimsPrincipal(identity);
            }

            base.Initialize(context);
        }
Esempio n. 28
0
        private void CreateResource(Installable app)
        {
            Console.WriteLine("Creating resource on " + app.ApplicationName);
            var approved = new ApprovedDomainSerializer().Get().FirstOrDefault();

            if (approved == null)
            {
                return;
            }

            string tenant = TenantConvention.GetTenant(approved.DomainName);

            var writer = new ResourceWriter(tenant, app);

            writer.WriteAsync().GetAwaiter().GetResult();
        }
Esempio n. 29
0
        public async Task RegisterAsync()
        {
            try
            {
                var installed = new InstalledDomainSerializer();

                foreach (var domain in installed.Get())
                {
                    string database = TenantConvention.GetDbNameByConvention(domain.DomainName);
                    await InstalledDomains.AddAsync(database, domain.DomainName, domain.AdminEmail).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Could not execute AddInstalledDomainProcedure. Exception: {Exception}", ex);
            }
        }
Esempio n. 30
0
        private static UpdateBase GetUpdater(string tenant, Installable app)
        {
            var    site         = TenantConvention.GetSite(tenant);
            string providerName = site.DbProvider;

            switch (providerName)
            {
            case "Npgsql":
                return(new PostgresqlUpdater(tenant, app));

            case "System.Data.SqlClient":
                return(new SqlServerUpdater(tenant, app));

            default:
                throw new SchemaUpdaterException("Frapid schema updater does not support provider " + providerName);
            }
        }