protected static string GetEncDecKey(UserConfigurationQuery q) { return($"{q.UserId}_{q.TokenId}"); }
/// <summary> /// Reads config details for a specified user characteristics - user uuid, token, etc. /// </summary> /// <param name="dbctx"></param> /// <param name="q"></param> /// <returns></returns> public static async Task <UserConfiguration> GetAsync <TDbCtx>( TDbCtx dbctx, UserConfigurationQuery q ) where TDbCtx : MapHiveDbContext, new() { if (q == null) { return(null); } var dbCtx = new TDbCtx(); //check if user is known MapHiveUser user = null; if (q.UserId.HasValue) { user = await new DataModel.MapHiveUser().ReadAsync(dbCtx, q.UserId.Value); } Token token = null; if (q.TokenId.HasValue) { token = await new DataModel.Token().ReadAsync(dbCtx, q.TokenId.Value, detached: true); } //Orgs IEnumerable <Organization> orgs = null; if (user != null) { //grab user orgs //FIXME - need to enable passing all the org assets here to - packages, apps, mods, data sources; see below for details orgs = await MapHiveUser.GetUserOrganizationsAsync(dbCtx, q.UserId.Value, (q.AppNames ?? string.Empty).Split(',')); } //Note: not likely to have both - user and token auth but in a case this is true, pull an org for token regardless the fact a user //may already have been 'served' above if (token != null) { var tokenOrg = dbCtx.Organizations.FirstOrDefault(org => org.Uuid == token.OrganizationId); if (tokenOrg != null) { var tmpOrgs = orgs?.ToList() ?? new List <Organization>(); //get an app token grants access too tokenOrg.Applications = await token.GetApplicationsAsync(dbCtx); tmpOrgs.Add(tokenOrg); orgs = tmpOrgs; } //also check if this is a master token and if the org for which to extract stuff has been provided explicitly! if (token.IsMaster && q.OrganizationId.HasValue) { //try to grab an org var explicitlyRequestedTokenOrg = await dbCtx.Organizations.FirstOrDefaultAsync(o => o.Uuid == q.OrganizationId); if (explicitlyRequestedTokenOrg != null) { var tmpOrgs = orgs?.ToList() ?? new List <Organization>(); //apps explicitlyRequestedTokenOrg.Applications = (await explicitlyRequestedTokenOrg.GetOrganizationAssetsAsync <Application>(dbCtx))?.assets.ToList(); ////mods //explicitlyRequestedTokenOrg.Modules = (await explicitlyRequestedTokenOrg.GetOrganizationAssetsAsync<Module>(dbCtx)).Item1.ToList(); ////and data sources //explicitlyRequestedTokenOrg.DataSources = (await explicitlyRequestedTokenOrg.GetOrganizationAssetsAsync<DataSource>(dbCtx)).Item1.ToList(); explicitlyRequestedTokenOrg.Owners = (await explicitlyRequestedTokenOrg.GetOwnersAsync(dbCtx)).ToList(); explicitlyRequestedTokenOrg.Admins = (await explicitlyRequestedTokenOrg.GetAdminsAsync(dbCtx)).ToList(); await explicitlyRequestedTokenOrg.ReadLicenseOptionsAsync(dbCtx); await explicitlyRequestedTokenOrg.LoadDatabasesAsync(dbCtx); tmpOrgs.Add(explicitlyRequestedTokenOrg); orgs = tmpOrgs; } } } //TODO - read asset links, packages and modules, so there is no need in re-reading them all over again! This will require some org assets related api changes //FIXME - so basically will need to improve the asset reading ;) foreach (var org in orgs ?? new Organization[0]) { //what we're interested in here are: //modules and data sources //Note: if there is an org present it should have the access to a specified app... //unless the app has not been specified... then all orgs a user is assigned to are returned. //Note: //GetUserOrganizations already reads requested apps to orgs, so there is no need to re-pull them here! //Same applies to token - when read it also reads the app //org.Applications = (await org.GetLinkedAssetsAsync<Application>(dbCtx)).ToList(); ////mods //org.Modules = (await org.GetOrganizationAssetsAsync<Module>(dbCtx)).Item1.ToList(); ////and data sources //org.DataSources = (await org.GetOrganizationAssetsAsync<DataSource>(dbCtx)).Item1.ToList(); org.Owners = (await org.GetOwnersAsync(dbCtx)).ToList(); org.Admins = (await org.GetAdminsAsync(dbCtx)).ToList(); org.Roles = (await org.GetOrgRolesAsync(dbCtx)).ToList(); await org.ReadLicenseOptionsAsync(dbCtx); await org.LoadDatabasesAsync(dbCtx); } //FIXME - same as above - make it possible to pass a list of org assets here //read user access to orgs / apps //this gathers info on user apps access for each org the user is assigned to if (user != null) { //user must be present as without one there is no app access really //Note: basically tokens grant direct access rights to apis and apis handle permissions on their own. foreach (var o in orgs ?? new Organization[0]) { foreach (var a in o.Applications) { a.OrgUserAppAccessCredentials = await o.GetUserAppAccessCredentialsAsync(dbCtx, user, a); //reset some properties to avoid circular refs when serializing; and to minimize payload too a.OrgUserAppAccessCredentials.User = null; a.OrgUserAppAccessCredentials.Application = null; a.OrgUserAppAccessCredentials.Organization = null; } } } var userCfg = new UserConfiguration { User = user, Orgs = orgs?.ToList(), Token = token }; //make sure do encrypt the dbs - this is sensitive shit after all userCfg.EncryptOrgDbs(q); return(userCfg); }
/// <summary> /// Encrypts org dbs /// </summary> /// <param name="q"></param> public void EncryptOrgDbs(UserConfigurationQuery q) { Orgs?.ForEach(org => org.EncryptDatabases(GetEncDecKey(q))); }