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)); }
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); } }
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(); }
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); } } }
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); } }
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}."); } } }
private void LogException(Exception ex) { string tenant = TenantConvention.GetTenant(); var meta = AppUsers.GetCurrent(); DefaultExceptionLogger.Log(tenant, meta.UserId, meta.Name, meta.OfficeName, ex.ToString()); }
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); }
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"); } } }
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); } }
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); }
public static string Get(string key, string tenant = "") { if (string.IsNullOrWhiteSpace(tenant)) { tenant = TenantConvention.GetTenant(); } return(ResourceManager.GetString(tenant, "Labels", key)); }
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); }
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); } }
public static string GetProviderName(string tenant) { if (string.IsNullOrWhiteSpace(tenant)) { return(string.Empty); } var site = TenantConvention.GetSite(tenant); return(site.DbProvider); }
private string GetKey(string key) { string prefix = TenantConvention.GetTenant(); if (!key.StartsWith(prefix)) { key = prefix + "/" + key; } return(key); }
/// <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); } }
public override void Initialize() { this.DomainName = this.Line.GetTokenOn(5); if (string.IsNullOrWhiteSpace(this.DomainName)) { return; } this.Tenant = TenantConvention.GetDbNameByConvention(this.DomainName); }
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); } }
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); }
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); }
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); }
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); } }
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); }
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(); }
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); } }
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); } }