├── target └── .history ├── Fabric.Authorization.AccessControl ├── src │ ├── assets │ │ └── .gitkeep │ ├── app │ │ ├── app.component.html │ │ ├── navbar │ │ │ └── navbar.component.scss │ │ ├── constants │ │ │ └── principal-constants.ts │ │ ├── models │ │ │ ├── exception.model.ts │ │ │ ├── permissionRequestContext.model.ts │ │ │ ├── idpSearchResult.model.ts │ │ │ ├── changedDataEventArgs.model.ts │ │ │ ├── securableItem.model.ts │ │ │ ├── userPermissionResponse.model.ts │ │ │ ├── urlResponse.model.ts │ │ │ ├── role.model.ts │ │ │ ├── grain.model.ts │ │ │ ├── user.model.ts │ │ │ ├── fabricPrincipal.model.ts │ │ │ ├── authMemberSearchRequest.model.ts │ │ │ ├── group.model.ts │ │ │ └── authMemberSearchResult.model.ts │ │ ├── services │ │ │ ├── global │ │ │ │ ├── alert.service.mock.ts │ │ │ │ ├── odata.ts │ │ │ │ ├── config.service.spec.ts │ │ │ │ ├── alert.service.spec.ts │ │ │ │ ├── initializer.service.ts │ │ │ │ ├── auth.service.spec.ts │ │ │ │ ├── config.service.ts │ │ │ │ ├── auth.service.mock.ts │ │ │ │ └── initializer.service.spec.ts │ │ │ ├── fabric-auth-edwadmin.service.mock.ts │ │ │ ├── current-user.service.mock.ts │ │ │ ├── fabric-auth-role.service.mock.ts │ │ │ ├── fabric-base.service.ts │ │ │ ├── access-control-config.service.ts │ │ │ ├── about-app.service.ts │ │ │ ├── access-control-config.service.mock.ts │ │ │ ├── browser-requirements.service.spec.ts │ │ │ ├── interceptors │ │ │ │ ├── fabric-http-fake-discovery-interceptor.service.spec.ts │ │ │ │ ├── fabric-http-error-handler-interceptor.service.spec.ts │ │ │ │ ├── index.ts │ │ │ │ └── fabric-http-request-interceptor.service.spec.ts │ │ │ ├── name-display.service.ts │ │ │ ├── fabric-base.service.spec.ts │ │ │ ├── fabric-auth-role.service.spec.ts │ │ │ ├── guards │ │ │ │ ├── authentication.guard.ts │ │ │ │ └── authentication.guard.spec.ts │ │ │ └── browser-requirements.service.ts │ │ ├── modules │ │ │ └── access-control │ │ │ │ ├── member │ │ │ │ └── member.component.scss │ │ │ │ ├── grain-list │ │ │ │ ├── grain-list.component.scss │ │ │ │ └── grain-list.component.html │ │ │ │ └── input.directive.ts │ │ ├── app.component.ts │ │ ├── test │ │ │ └── app-switcher-config.mock.ts │ │ ├── logged-out │ │ │ ├── logged-out.component.scss │ │ │ ├── logged-out.component.ts │ │ │ ├── logged-out.component.html │ │ │ └── logged-out.component.spec.ts │ │ ├── not-found │ │ │ ├── not-found.component.scss │ │ │ ├── not-found.component.ts │ │ │ ├── not-found.component.html │ │ │ └── not-found.component.spec.ts │ │ └── no-cookies │ │ │ ├── no-cookies.component.scss │ │ │ └── no-cookies.component.spec.ts │ ├── favicon.ico │ ├── typings.d.ts │ ├── environments │ │ ├── environment.default.ts │ │ ├── environment.prod.ts │ │ ├── environment.dev.ts │ │ ├── environment.test.ts │ │ └── environment.ts │ ├── tsconfig.app.json │ ├── silent.html │ ├── tsconfig.spec.json │ ├── index.html │ ├── main.ts │ └── styles.scss ├── run-angular-tests.sh ├── run-functional-tests.sh ├── run-all-tests.sh ├── ng-package.json ├── Fabric.Authorization.AccessControl.csproj ├── public_api.ts ├── e2e │ ├── app.po.ts │ ├── tsconfig.e2e.json │ ├── hacks.ts │ └── pages │ │ └── member-list.page.ts ├── .editorconfig ├── tsconfig.json └── .gitignore ├── CODEOWNERS ├── Fabric.Authorization.API ├── .dockerignore ├── wwwroot │ └── swagger │ │ └── ui │ │ ├── swagger-ui.css.map │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── swagger-ui.js.map │ │ ├── swagger-ui-standalone-preset.js.map │ │ └── swagger-ui-bundle.js.map ├── scripts │ ├── run-all-tests.sh │ ├── run-unit-tests.sh │ ├── set-environment.sh │ ├── write-secrets.sh │ ├── set-environment-authz.sh │ ├── run-integration-tests.sh │ ├── read-secrets.sh │ ├── Fabric.Authorization.InstallPackage.nuspec │ ├── Fabric.Authorization.InstallPackage.targets │ ├── add-docs-to-github-repo.sh │ └── create-nuspec.sh ├── Documentation │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ └── build.gradle ├── Configuration │ ├── HostingOptions.cs │ ├── EncryptionCertificateSettings.cs │ ├── ApplicationInsights.cs │ ├── DefaultPropertySettings.cs │ ├── DiscoveryServiceSettings.cs │ └── AngularConventionBuilder.cs ├── Dockerfile ├── Connected Services │ └── Application Insights │ │ └── ConnectedService.json ├── Constants │ ├── StorageProviders.cs │ ├── TopLevelGrains.cs │ ├── AccessControl.cs │ ├── Claims.cs │ ├── HttpResponseHeaders.cs │ └── Scopes.cs ├── RemoteServices │ └── Identity │ │ ├── Models │ │ ├── UserSearchRequest.cs │ │ ├── GroupSearchRequest.cs │ │ ├── GroupSearchResponse.cs │ │ └── UserSearchResponse.cs │ │ └── Providers │ │ └── IIdentityServiceProvider.cs ├── Services │ ├── ICertificateService.cs │ ├── EventContextResolverService.cs │ └── GroupSearchService.cs ├── DependencyInjection │ ├── IPersistenceConfigurator.cs │ ├── SqlServerConfigurator.cs │ └── InMemoryConfigurator.cs ├── Infrastructure │ ├── NancyContextWrapper.cs │ └── Middleware │ │ └── AngularMiddlewareExtensions.cs ├── Program.cs ├── Modules │ ├── SearchModule.cs │ ├── DocsModule.cs │ └── RootModule.cs ├── Models │ └── Search │ │ └── Validators │ │ └── BaseSearchRequestValidator.cs ├── Extensions │ └── WebHostBuilderExtensions.cs ├── Swagger │ └── Parameters.cs └── Properties │ └── launchSettings.json ├── Fabric.Authorization.SqlServer ├── Tables │ ├── Grains.sql │ ├── Groups.sql │ ├── Roles.sql │ ├── Users.sql │ ├── Clients.sql │ ├── RoleUsers.sql │ ├── GroupRoles.sql │ ├── GroupUsers.sql │ ├── Permissions.sql │ ├── SecurableItems.sql │ ├── RolePermissions.sql │ ├── UserPermissions.sql │ └── EventLogs.sql └── Storage │ ├── HCFabricAuthorizationPrimary.sql │ ├── HCFabricAuthorizationLogFile1.sql │ ├── HCFabricAuthorizationData1.sql │ └── HCFabricAuthorizationIndex1.sql ├── Fabric.Authorization.UnitTests ├── Configuration │ └── identity.test.pfx ├── Groups │ ├── GroupModuleTests.cs │ ├── GroupServiceTests.cs │ └── GroupValidatorTests.cs └── Mocks │ ├── TestPrincipal.cs │ ├── TestIdentity.cs │ └── EventWriteMockExtensions.cs ├── docker-compose.override.yml ├── Fabric.Authorization.Domain ├── Models │ ├── ISoftDelete.cs │ ├── IIdentifiable.cs │ ├── Formatters │ │ ├── IIdentifierFormatter.cs │ │ └── Formatters.cs │ ├── EDW │ │ ├── EDWConstants.cs │ │ └── ObjectExtensions.cs │ ├── IUser.cs │ ├── ITrackable.cs │ ├── Client.cs │ ├── SecurableItem.cs │ ├── Grain.cs │ └── GranularPermission.cs ├── Services │ ├── IDbBootstrapper.cs │ ├── IEventContextResolverService.cs │ ├── IEventService.cs │ ├── GroupConstants.cs │ ├── IEDWAdminRoleSyncService.cs │ ├── RoleManagerConstants.cs │ └── GrainService.cs ├── Stores │ ├── IIdentifierFormatter.cs │ ├── IClientStore.cs │ ├── IEDWStore.cs │ ├── ISecurableItemStore.cs │ ├── IGrainStore.cs │ ├── IUserStore.cs │ ├── IdpIdentifierFormatter.cs │ ├── IGenericStore.cs │ ├── IPermissionStore.cs │ └── IRoleStore.cs ├── Constants │ ├── AccessControl.cs │ └── IdentityConstants.cs ├── Events │ ├── IEventWriter.cs │ ├── EntityBatchAuditEvent.cs │ ├── Event.cs │ ├── EntityAuditEvent.cs │ ├── SerilogEventWriter.cs │ └── EventTypes.cs ├── Resolvers │ ├── Models │ │ ├── ResolvedPermissionRole.cs │ │ ├── PermissionResolutionResult.cs │ │ └── PermissionResolutionRequest.cs │ └── Permissions │ │ └── IPermissionResolverService.cs ├── Validators │ ├── ValidationEnums.cs │ ├── GrainValidator.cs │ └── SecurableItemValidator.cs ├── Exceptions │ ├── UserNotFoundException.cs │ ├── IncompatibleRoleException.cs │ ├── InvalidPermissionException.cs │ ├── IncompatiblePermissionException.cs │ ├── CouldNotCompleteOperationException.cs │ ├── AlreadyExistsException.cs │ └── BadRequestException.cs └── Fabric.Authorization.Domain.csproj ├── Catalyst.Fabric.Authorization.Models ├── IIdentifiable.cs ├── RoleUserRequest.cs ├── UserInfoRequest.cs ├── ApiModelBase.cs ├── PermissionRoleApiModel.cs ├── UserPermissionsApiModel.cs ├── ResolvedPermissionApiModel.cs ├── Search │ ├── MemberSearchRequest.cs │ ├── SearchConstants.cs │ └── SearchRequest.cs ├── Enums │ └── AuthorizationEnum.cs ├── GroupUserRequest.cs ├── Requests │ ├── RoleApiRequest.cs │ ├── UserApiRequest.cs │ └── GroupApiRequest.cs ├── ITrackable.cs ├── UserApiModel.cs ├── Catalyst.Fabric.Authorization.Models.csproj ├── Error.cs ├── ModelExtensions.cs ├── ClientApiModel.cs ├── GroupRoleRequest.cs ├── GrainApiModel.cs ├── GroupUserApiModel.cs ├── SecurableItemApiModel.cs ├── PermissionApiModel.cs └── GroupRoleApiModel.cs ├── docker-compose.yml ├── Fabric.Authorization.Persistence.SqlServer ├── EntityModels │ ├── PermissionAction.cs │ ├── EDW │ │ ├── EDWIdentityRole.cs │ │ └── EDWIdentity.cs │ ├── GroupRole.cs │ ├── ChildGroup.cs │ ├── Client.cs │ ├── GroupUser.cs │ ├── RolePermission.cs │ ├── RoleUser.cs │ ├── Grain.cs │ └── UserPermission.cs ├── Configuration │ ├── IConnectionStrings.cs │ ├── EntityFrameworkSettings.cs │ └── ConnectionStrings.cs ├── Services │ ├── NoOpEventContextResolverService.cs │ ├── InMemorySecurityContext.cs │ └── InMemoryAuthorizationDbContext.cs ├── Stores │ ├── EDW │ │ └── ISecurityContext.cs │ └── SqlServerBaseStore.cs └── Mappers │ ├── PermissionMapperProfile.cs │ ├── GroupMapperProfile.cs │ ├── RoleMapper.cs │ ├── UserMapper.cs │ ├── GroupMapper.cs │ ├── GrainMapper.cs │ ├── ClientMapperProfile.cs │ ├── ClientMapper.cs │ ├── PermissionMapper.cs │ ├── SecurableItemMapper.cs │ ├── GrainMapperProfile.cs │ └── UserMapperProfile.cs ├── Fabric.Authorization.Persistence.CouchDb ├── Stores │ ├── IFormattableIdentifier.cs │ ├── CouchDBViews.cs │ ├── CouchDbSecurableItemStore.cs │ ├── CouchDBClientStore.cs │ └── CouchDbGrainStore.cs ├── Configuration │ ├── ICouchDbSettings.cs │ └── CouchDbSettings.cs ├── Services │ ├── DocumentDbHelpers.cs │ └── IDocumentDbService.cs ├── Fabric.Authorization.Persistence.CouchDb.csproj └── Events │ └── CouchDbEventWriter.cs ├── Catalyst.Fabric.Authorization.Client ├── AssemblyInfo.cs ├── ClientConstants.cs ├── AuthorizationException.cs └── Routes │ ├── BaseRoute.cs │ ├── RouteConstants.cs │ ├── MemberSearchRoute.cs │ ├── ClientRoute.cs │ └── SecurableItemRoute.cs ├── Catalyst.Fabric.Authorization.Client.FunctionalTests ├── ClientModel.cs ├── FunctionalTestSettings.cs ├── BaseTest.cs ├── FunctionalTestExtensions.cs └── Catalyst.Fabric.Authorization.Client.FunctionalTests.csproj ├── Fabric.Authorization.Persistence.InMemory ├── Services │ └── InMemoryDbBootstrapper.cs └── Fabric.Authorization.Persistence.InMemory.csproj ├── docker-compose.ci.build.yml ├── docker-compose.vs.release.yml ├── doc └── arch │ └── ADR-0000 Template.md ├── Fabric.Authorization.PerformanceTests ├── Dockerfile ├── create-userproperties.sh ├── entrypoint.sh └── appSettings.json ├── Fabric.Authorization.LibOwin └── Fabric.Authorization.LibOwin.csproj ├── Catalyst.Fabric.Authorization.Client.UnitTests ├── Routes │ ├── MemberSearchRouteTests.cs │ └── ClientRouteTests.cs └── Catalyst.Fabric.Authorization.Client.UnitTests.csproj ├── docker-compose.vs.debug.yml ├── Fabric.Authorization.IntegrationTests └── SqlServer │ ├── SqlServerUserTests.cs │ ├── SqlServerGroupsTests.cs │ ├── SqlServerRolesTests.cs │ ├── SqlServerClientTests.cs │ ├── SqlServerEdwAdminTests.cs │ ├── SqlServerPermissionsTests.cs │ ├── SqlServerDosTests.cs │ └── SqlServerMemberSearchTests.cs ├── Fabric.Authorization.FunctionalTests └── package.json └── docker-compose.dcproj /target/.history: -------------------------------------------------------------------------------- 1 | ensime 2 | exit 3 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @HealthCatalyst/platform-fabric-services 2 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/run-angular-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ng test --watch=false -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/run-functional-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | protractor ./protractor.conf.js -------------------------------------------------------------------------------- /Fabric.Authorization.API/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !scripts/* 3 | !*.sh 4 | !obj/Docker/publish/* 5 | !obj/Docker/empty/ 6 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/run-all-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./run-angular-tests.sh 4 | ./run-functional-tests.sh -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/navbar/navbar.component.scss: -------------------------------------------------------------------------------- 1 | @import "~@healthcatalyst/cashmere/scss/about-modal" 2 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/wwwroot/swagger/ui/swagger-ui.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"swagger-ui.css","sources":[],"mappings":"","sourceRoot":""} -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/constants/principal-constants.ts: -------------------------------------------------------------------------------- 1 | export const USER = 'user'; 2 | export const GROUP = 'group'; 3 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/run-all-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./run-unit-tests.sh 4 | ./run-integration-tests.sh 5 | ./run-functional-tests.sh 6 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/run-unit-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dotnet test ../../Fabric.Authorization.UnitTests/Fabric.Authorization.UnitTests.csproj 4 | 5 | -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/Grains.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/Grains.sql -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/Groups.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/Groups.sql -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/Roles.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/Roles.sql -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/Users.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/Users.sql -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.AccessControl/src/favicon.ico -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/Clients.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/Clients.sql -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/RoleUsers.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/RoleUsers.sql -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/exception.model.ts: -------------------------------------------------------------------------------- 1 | export class Exception { 2 | constructor(public statusCode: number, public message: string) {} 3 | } 4 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/GroupRoles.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/GroupRoles.sql -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/GroupUsers.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/GroupUsers.sql -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/Permissions.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/Permissions.sql -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/SecurableItems.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/SecurableItems.sql -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "public_api.ts" 5 | } 6 | } -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/RolePermissions.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/RolePermissions.sql -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/UserPermissions.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.SqlServer/Tables/UserPermissions.sql -------------------------------------------------------------------------------- /Fabric.Authorization.API/wwwroot/swagger/ui/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.API/wwwroot/swagger/ui/favicon-16x16.png -------------------------------------------------------------------------------- /Fabric.Authorization.API/wwwroot/swagger/ui/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.API/wwwroot/swagger/ui/favicon-32x32.png -------------------------------------------------------------------------------- /Fabric.Authorization.UnitTests/Configuration/identity.test.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.UnitTests/Configuration/identity.test.pfx -------------------------------------------------------------------------------- /docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | fabric.authorization.api: 5 | environment: 6 | - ASPNETCORE_ENVIRONMENT=Development 7 | ports: 8 | - "5004" 9 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/ISoftDelete.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Models 2 | { 3 | public interface ISoftDelete 4 | { 5 | bool IsDeleted { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Services/IDbBootstrapper.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Services 2 | { 3 | public interface IDbBootstrapper 4 | { 5 | void Setup(); 6 | } 7 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/IIdentifiable.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Models 2 | { 3 | public interface IIdentifiable 4 | { 5 | T Id { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/permissionRequestContext.model.ts: -------------------------------------------------------------------------------- 1 | export interface IPermissionRequestContext { 2 | requestedGrain: string; 3 | requestedSecurableItem: string; 4 | } 5 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/IIdentifiable.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models 2 | { 3 | public interface IIdentifiable 4 | { 5 | T Id { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Documentation/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HealthCatalyst/Fabric.Authorization/HEAD/Fabric.Authorization.API/Documentation/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IIdentifierFormatter.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Stores 2 | { 3 | public interface IIdentifierFormatter 4 | { 5 | string Format(string id); 6 | } 7 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Configuration/HostingOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Configuration 2 | { 3 | public class HostingOptions 4 | { 5 | public bool UseIis { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | fabric.authorization.api: 5 | image: fabric.authorization.api 6 | build: 7 | context: ./Fabric.Authorization.API 8 | dockerfile: Dockerfile 9 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/wwwroot/swagger/ui/swagger-ui.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;AA+nEA;;;;;;AAmgBA;AA2pHA;AA0pIA;AA09FA;AA0+CA;AAs0CA;AAgvCA","sourceRoot":""} -------------------------------------------------------------------------------- /Fabric.Authorization.API/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/core/aspnet:2.1 2 | ARG source 3 | WORKDIR /app 4 | EXPOSE 5004 5 | 6 | COPY ${source:-obj/Docker/publish} . 7 | 8 | ENTRYPOINT ["dotnet", "Fabric.Authorization.API.dll"] 9 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/Fabric.Authorization.AccessControl.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard1.6 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/Formatters/IIdentifierFormatter.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Models.Formatters 2 | { 3 | public interface IIdentifierFormatter 4 | { 5 | string Format(T entity); 6 | } 7 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/public_api.ts: -------------------------------------------------------------------------------- 1 | export { AccessControlModule } from './src/app/modules/access-control/access-control.module'; 2 | export { IAccessControlConfigService } from './src/app/services/access-control-config.service'; 3 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/PermissionAction.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 2 | { 3 | public enum PermissionAction 4 | { 5 | Allow, 6 | Deny 7 | } 8 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IClientStore.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.Domain.Models; 2 | 3 | namespace Fabric.Authorization.Domain.Stores 4 | { 5 | public interface IClientStore : IGenericStore 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Stores/IFormattableIdentifier.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Persistence.CouchDB.Stores 2 | { 3 | public interface IFormattableIdentifier 4 | { 5 | string FormatId(string id); 6 | } 7 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Constants/AccessControl.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Constants 2 | { 3 | public static class AccessControl 4 | { 5 | public static readonly string ClientId = "fabric-access-control"; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Events/IEventWriter.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Fabric.Authorization.Domain.Events 4 | { 5 | public interface IEventWriter 6 | { 7 | Task WriteEvent(Event evt); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.UnitTests/Groups/GroupModuleTests.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Modules; 2 | 3 | namespace Fabric.Authorization.UnitTests.Groups 4 | { 5 | public class GroupsModuleTests : ModuleTestsBase 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/idpSearchResult.model.ts: -------------------------------------------------------------------------------- 1 | import { IFabricPrincipal } from './fabricPrincipal.model'; 2 | 3 | export class IdPSearchResult { 4 | public principals: Array; 5 | public resultCount: number; 6 | } 7 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/alert.service.mock.ts: -------------------------------------------------------------------------------- 1 | export class AlertServiceMock { 2 | showSyncWarning: jasmine.Spy = jasmine.createSpy('showSyncWarning'); 3 | showError: jasmine.Spy = jasmine.createSpy('showError'); 4 | } 5 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/RoleUserRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models 2 | { 3 | public class RoleUserRequest 4 | { 5 | public string SubjectId { get; set; } 6 | public string IdentityProvider { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/UserInfoRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models 2 | { 3 | public class UserInfoRequest 4 | { 5 | public string Grain { get; set; } 6 | public string SecurableItem { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Configuration/EncryptionCertificateSettings.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Configuration 2 | { 3 | public class EncryptionCertificateSettings 4 | { 5 | public string EncryptionCertificateThumbprint { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/changedDataEventArgs.model.ts: -------------------------------------------------------------------------------- 1 | export interface IDataChangedEventArgs { 2 | memberAffected: string; 3 | memberType: string; 4 | action: string; 5 | changedDataType: string; 6 | changes: string[]; 7 | } 8 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Configuration/IConnectionStrings.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Persistence.SqlServer.Configuration 2 | { 3 | public interface IConnectionStrings 4 | { 5 | string AuthorizationDatabase { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Configuration/ApplicationInsights.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Configuration 2 | { 3 | public class ApplicationInsights 4 | { 5 | public string InstrumentationKey { get; set; } 6 | public bool Enabled { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/modules/access-control/member/member.component.scss: -------------------------------------------------------------------------------- 1 | @import "~@healthcatalyst/cashmere/scss/colors"; 2 | 3 | .hc-input { 4 | width: 300px; 5 | } 6 | 7 | .spinner { 8 | display: inline-block; 9 | margin-left: 20px; 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/environments/environment.default.ts: -------------------------------------------------------------------------------- 1 | /** default values for environment settings */ 2 | export const defaultEnvironment = { 3 | production: false, 4 | isGrainVisible: true 5 | }; 6 | 7 | export type Environment = typeof defaultEnvironment; 8 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | import { Environment, defaultEnvironment } from './environment.default'; 2 | 3 | export const environment = Object.assign>(defaultEnvironment, { 4 | production: true 5 | }); 6 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/wwwroot/swagger/ui/swagger-ui-standalone-preset.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA+tEA;AAo7GA;AAw0FA;;;;;;AAmZA;AAivFA;AAu+CA;AAo+CA;AAirCA;AAuyEA","sourceRoot":""} -------------------------------------------------------------------------------- /Fabric.Authorization.API/Documentation/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip 6 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/environments/environment.dev.ts: -------------------------------------------------------------------------------- 1 | import { Environment, defaultEnvironment } from './environment.default'; 2 | 3 | export const environment = Object.assign>(defaultEnvironment, { 4 | // add environment customizations here 5 | }); 6 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/environments/environment.test.ts: -------------------------------------------------------------------------------- 1 | import { Environment, defaultEnvironment } from './environment.default'; 2 | 3 | export const environment = Object.assign>(defaultEnvironment, { 4 | // add environment customizations here 5 | }); 6 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Catalyst.Fabric.Authorization.Client.UnitTests")] 4 | 5 | namespace Catalyst.Fabric.Authorization.Client 6 | { 7 | public class AssemblyInfo 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html' 6 | }) 7 | export class AppComponent { 8 | title = 'Fabric.Authorization.AccessControl Demo'; 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/securableItem.model.ts: -------------------------------------------------------------------------------- 1 | export interface ISecurableItem { 2 | id?: string; 3 | name: string; 4 | clientOwner: string; 5 | grain: string; 6 | securableItems: Array; 7 | createdBy: string; 8 | modifiedBy: string; 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/test/app-switcher-config.mock.ts: -------------------------------------------------------------------------------- 1 | import { APP_SWITCHER_CONFIG } from '@healthcatalyst/cashmere'; 2 | 3 | export const MockAppSwitcherConfig = 4 | { 5 | provide: APP_SWITCHER_CONFIG, 6 | useFactory: ()=>({discoveryServiceUri: "test.discoveryservice.uri"}) 7 | }; 8 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IEDWStore.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Stores 2 | { 3 | public interface IEDWStore 4 | { 5 | void AddIdentitiesToRole(string[] identities, string roleName); 6 | void RemoveIdentitiesFromRole(string[] identities, string roleName); 7 | } 8 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/ApiModelBase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class ApiModelBase 6 | { 7 | public IEnumerable PermissionRequestContexts { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/userPermissionResponse.model.ts: -------------------------------------------------------------------------------- 1 | import { IPermissionRequestContext } from './permissionRequestContext.model'; 2 | 3 | export interface IUserPermissionResponse { 4 | permissions: Array; 5 | permissionRequestContexts: Array; 6 | } 7 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Resolvers/Models/ResolvedPermissionRole.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Resolvers.Models 4 | { 5 | public class ResolvedPermissionRole 6 | { 7 | public Guid? Id { get; set; } 8 | public string Name { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Configuration/EntityFrameworkSettings.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Configuration 4 | { 5 | public class EntityFrameworkSettings 6 | { 7 | public LogEventLevel MinimumLogLevel { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/PermissionRoleApiModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class PermissionRoleApiModel : IIdentifiable 6 | { 7 | public Guid? Id { get; set; } 8 | public string Name { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/UserPermissionsApiModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class UserPermissionsApiModel : ApiModelBase 6 | { 7 | public IEnumerable Permissions { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.6.404.2", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/fabric-auth-edwadmin.service.mock.ts: -------------------------------------------------------------------------------- 1 | 2 | export class FabricAuthEdwadminServiceMock { 3 | syncUsersWithEdwAdmin: jasmine.Spy = jasmine.createSpy('syncUsersWithEdwAdmin'); 4 | syncGroupWithEdwAdmin: jasmine.Spy = jasmine.createSpy('syncGroupWithEdwAdmin'); 5 | } 6 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client.FunctionalTests/ClientModel.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client.FunctionalTests 2 | { 3 | public class ClientModel 4 | { 5 | public string access_token { get; set; } 6 | 7 | public string clientSecret { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/logged-out/logged-out.component.scss: -------------------------------------------------------------------------------- 1 | @import "~@healthcatalyst/cashmere/scss/colors"; 2 | 3 | .error-container{ 4 | margin: 100px auto; 5 | .logged-out-footer{ 6 | width: 215px; 7 | padding-bottom: 20px; 8 | margin: 0 auto; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/not-found/not-found.component.scss: -------------------------------------------------------------------------------- 1 | @import "~@healthcatalyst/cashmere/scss/colors"; 2 | 3 | .error-container{ 4 | margin: 100px auto; 5 | .logged-out-footer{ 6 | width: 215px; 7 | padding-bottom: 20px; 8 | margin: 0 auto; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/odata.ts: -------------------------------------------------------------------------------- 1 | export namespace OData { 2 | export interface IObject { 3 | '@odata.context': string; 4 | } 5 | 6 | export interface IArray extends IObject { 7 | '@odata.count': number; 8 | value: T[]; 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/EDW/EDWConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Fabric.Authorization.Domain.Models.EDW 6 | { 7 | public static class EDWConstants 8 | { 9 | public static readonly string EDWAdmin = "EDW Admin"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/ResolvedPermissionApiModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class ResolvedPermissionApiModel : PermissionApiModel 6 | { 7 | public IEnumerable Roles { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/no-cookies/no-cookies.component.scss: -------------------------------------------------------------------------------- 1 | @import "~@healthcatalyst/cashmere/scss/about-modal"; 2 | 3 | .error-container{ 4 | margin: 100px auto; 5 | .logged-out-footer{ 6 | width: 215px; 7 | padding-bottom: 20px; 8 | margin: 0 auto; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.UnitTests/Mocks/TestPrincipal.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | 3 | namespace Fabric.Authorization.UnitTests.Mocks 4 | { 5 | public class TestPrincipal : ClaimsPrincipal 6 | { 7 | public TestPrincipal(params Claim[] claims) : base (new TestIdentity(claims)) 8 | { } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Validators/ValidationEnums.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Validators 2 | { 3 | public class ValidationEnums 4 | { 5 | public enum ValidationState 6 | { 7 | Duplicate, 8 | MissingRequiredField, 9 | InvalidFieldValue 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Search/MemberSearchRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models.Search 2 | { 3 | public class MemberSearchRequest : SearchRequest 4 | { 5 | public string ClientId { get; set; } 6 | public string Grain { get; set; } 7 | public string SecurableItem { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Constants/StorageProviders.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Constants 2 | { 3 | public static class StorageProviders 4 | { 5 | public const string InMemory = "inmemory"; 6 | public const string CouchDb = "couchdb"; 7 | public const string SqlServer = "sqlserver"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.InMemory/Services/InMemoryDbBootstrapper.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.Domain.Services; 2 | 3 | namespace Fabric.Authorization.Persistence.InMemory.Services 4 | { 5 | public class InMemoryDbBootstrapper : IDbBootstrapper 6 | { 7 | public void Setup() 8 | { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /docker-compose.ci.build.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | ci-build: 5 | image: microsoft/aspnetcore-build:1.0-1.1 6 | volumes: 7 | - .:/src 8 | working_dir: /src 9 | command: /bin/bash -c "dotnet restore ./Fabric.Authorization.sln && dotnet publish ./Fabric.Authorization.sln -c Release -o ./obj/Docker/publish" 10 | -------------------------------------------------------------------------------- /docker-compose.vs.release.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | fabric.authorization.api: 5 | build: 6 | args: 7 | source: ${DOCKER_BUILD_SOURCE} 8 | volumes: 9 | - ~/clrdbg:/clrdbg:ro 10 | entrypoint: tail -f /dev/null 11 | labels: 12 | - "com.microsoft.visualstudio.targetoperatingsystem=linux" 13 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Constants/TopLevelGrains.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Constants 2 | { 3 | public static class TopLevelGrains 4 | { 5 | public static readonly string AppGrain = "app"; 6 | public static readonly string UserGrain = "user"; 7 | public static readonly string PatientGrain = "patient"; 8 | } 9 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/set-environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $COUCHDBCONTAINERNAME) 4 | echo "CouchDb Container running on $IP" 5 | echo "##vso[task.setvariable variable=CouchDbSettings__Server;]http://$IP:5984" 6 | echo "CouchDb Server URL: $COUCHDBSETTINGS_SERVER" -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/write-secrets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | installerSecretString=$1 4 | authClientSecretString=$2 5 | destinationFile=$3 6 | 7 | json="{\"installerSecret\":\""$installerSecretString"\", \"authClientSecret\":\""$authClientSecretString"\"}" 8 | 9 | echo -e $json 10 | echo $destinationFile 11 | echo $json > $destinationFile -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "jasminewd2", 11 | "node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/urlResponse.model.ts: -------------------------------------------------------------------------------- 1 | export class UrlResponse { 2 | constructor(identityUrl, accessControlUrl) { 3 | this.identityUrl = identityUrl; 4 | this.accessControlUrl = accessControlUrl; 5 | } 6 | 7 | public identityUrl: string; 8 | public accessControlUrl: string; 9 | } 10 | -------------------------------------------------------------------------------- /doc/arch/ADR-0000 Template.md: -------------------------------------------------------------------------------- 1 | # Title 2 | 3 | ## Context 4 | 5 | ## Decision 6 | 7 | ## Consequences 8 | 9 | 10 | ---- 11 | * Status: accepted / proposed / deprecated / superseded 12 | * Date: 2018- MM - DD 13 | * Related Items: 139268 14 | https://healthcatalyst.visualstudio.com/CAP/_workitems/edit/139268 15 | 16 | _Tags_ 17 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Search/SearchConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models.Search 2 | { 3 | public static class SearchConstants 4 | { 5 | public static readonly string[] AscendingSortKeys = {"asc", "ascending"}; 6 | public static readonly string[] DescendingSortKeys = {"desc", "descending"}; 7 | } 8 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Configuration/DefaultPropertySettings.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Configuration 2 | { 3 | public class DefaultPropertySettings 4 | { 5 | public string GroupSource { get; set; } 6 | public bool DualStoreEDWAdminPermissions { get; set; } 7 | public string IdentityProvider { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Constants/AccessControl.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Constants 2 | { 3 | public static class AccessControl 4 | { 5 | public static readonly string Path = "client"; 6 | public static readonly string Index = "index.html"; 7 | public static readonly string ClientRootToken = "CLIENT_ROOT"; 8 | } 9 | } -------------------------------------------------------------------------------- /Fabric.Authorization.PerformanceTests/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM healthcatalyst/fabric.docker.jmeter 2 | 3 | COPY Fabric.Authorization.Perf.jmx . 4 | COPY create-userproperties.sh . 5 | COPY appSettings.json /apdexcalc 6 | COPY entrypoint.sh . 7 | 8 | RUN chmod +x create-userproperties.sh \ 9 | && chmod +x entrypoint.sh 10 | 11 | ENTRYPOINT ./entrypoint.sh 12 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/IUser.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Models 2 | { 3 | public interface IUser 4 | { 5 | string SubjectId { get; set; } 6 | string IdentityProvider { get; set; } 7 | string IdentityProviderUserPrincipalName { get; set; } 8 | int? ParentUserId { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Services/IEventContextResolverService.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Services 2 | { 3 | public interface IEventContextResolverService 4 | { 5 | string Username { get; } 6 | string ClientId { get; } 7 | string Subject { get; } 8 | string RemoteIpAddress { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/RemoteServices/Identity/Models/UserSearchRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Fabric.Authorization.API.RemoteServices.Identity.Models 4 | { 5 | public class UserSearchRequest 6 | { 7 | public string ClientId { get; set; } 8 | public IEnumerable UserIds { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/role.model.ts: -------------------------------------------------------------------------------- 1 | export interface IRole { 2 | id?: string; 3 | parentRole?: string; 4 | childRoles?: Array; 5 | name: string; 6 | grain: string; 7 | securableItem: string; 8 | displayName?: string; 9 | description?: string; 10 | 11 | // Custom property 12 | selected?: boolean; 13 | } 14 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This is a dummy file to get the Angular tooling to work. 2 | // Don't make any changes here; instead, make changes in the environment-specific files. 3 | 4 | import { Environment, defaultEnvironment } from './environment.default'; 5 | 6 | export const environment: Environment = defaultEnvironment; 7 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Configuration/ConnectionStrings.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Persistence.SqlServer.Configuration 2 | { 3 | public class ConnectionStrings : IConnectionStrings 4 | { 5 | public string AuthorizationDatabase { get; set; } 6 | 7 | public string EDWAdminDatabase { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/grain.model.ts: -------------------------------------------------------------------------------- 1 | import { ISecurableItem } from './securableItem.model'; 2 | 3 | export interface IGrain { 4 | id?: string; 5 | name: string; 6 | securableItems: Array; 7 | createdBy: string; 8 | modifiedBy: string; 9 | requiredWriteScopes: Array; 10 | isShared: boolean; 11 | } 12 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client/ClientConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client 2 | { 3 | internal class ClientConstants 4 | { 5 | public const string ApplicationJson = "application/json"; 6 | 7 | public const string Grain = "grain"; 8 | 9 | public const string SecurableItem = "securableItem"; 10 | } 11 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/RemoteServices/Identity/Models/GroupSearchRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.RemoteServices.Identity.Models 2 | { 3 | public class GroupSearchRequest 4 | { 5 | public string IdentityProvider { get; set; } 6 | public string TenantId { get; set; } 7 | public string DisplayName { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Services/ICertificateService.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.X509Certificates; 2 | using Fabric.Authorization.API.Configuration; 3 | 4 | namespace Fabric.Authorization.API.Services 5 | { 6 | public interface ICertificateService 7 | { 8 | X509Certificate2 GetCertificate(EncryptionCertificateSettings settings); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "es2015", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts", 12 | "**/*.mock.ts", 13 | "**/*.mock.module.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Configuration/ICouchDbSettings.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Persistence.CouchDb.Configuration 2 | { 3 | public interface ICouchDbSettings 4 | { 5 | string DatabaseName { get; set; } 6 | string Server { get; set; } 7 | string Username { get; set; } 8 | string Password { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/DependencyInjection/IPersistenceConfigurator.cs: -------------------------------------------------------------------------------- 1 | using Nancy.TinyIoc; 2 | 3 | namespace Fabric.Authorization.API.DependencyInjection 4 | { 5 | public interface IPersistenceConfigurator 6 | { 7 | void ConfigureApplicationInstances(TinyIoCContainer container); 8 | void ConfigureRequestInstances(TinyIoCContainer container); 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/current-user.service.mock.ts: -------------------------------------------------------------------------------- 1 | export const mockCurrentUserPermissions: string[] = [ 2 | ]; 3 | 4 | export const mockAdminUserPermissions: string[] = [ 5 | 'dos/datamarts.manageauthorization' 6 | ]; 7 | 8 | export class CurrentUserServiceMock { 9 | getPermissions: jasmine.Spy = jasmine.createSpy('getPermissions'); 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/silent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/ITrackable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Models 4 | { 5 | public interface ITrackable 6 | { 7 | DateTime CreatedDateTimeUtc { get; set; } 8 | DateTime? ModifiedDateTimeUtc { get; set; } 9 | string CreatedBy { get; set; } 10 | string ModifiedBy { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/ISecurableItemStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Models; 4 | 5 | namespace Fabric.Authorization.Domain.Stores 6 | { 7 | public interface ISecurableItemStore 8 | { 9 | Task Get(string name); 10 | Task Get(Guid id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Services/DocumentDbHelpers.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Persistence.CouchDb.Services 2 | { 3 | public static class DocumentDbHelpers 4 | { 5 | public static string GetFullDocumentId(string documentId) 6 | { 7 | return $"{typeof(T).Name.ToLowerInvariant()}:{documentId}"; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Infrastructure/NancyContextWrapper.cs: -------------------------------------------------------------------------------- 1 | using Nancy; 2 | 3 | namespace Fabric.Authorization.API.Infrastructure 4 | { 5 | public class NancyContextWrapper 6 | { 7 | public NancyContextWrapper(NancyContext context) 8 | { 9 | Context = context; 10 | } 11 | 12 | public NancyContext Context { get; internal set; } 13 | } 14 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Services/IEventService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Events; 4 | 5 | namespace Fabric.Authorization.Domain.Services 6 | { 7 | public interface IEventService 8 | { 9 | Task RaiseEventAsync(Event evnt); 10 | Task RaiseEventsAsync(IEnumerable events); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Fabric.Authorization.UnitTests/Mocks/TestIdentity.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | using IdentityModel; 3 | 4 | namespace Fabric.Authorization.UnitTests.Mocks 5 | { 6 | public class TestIdentity : ClaimsIdentity 7 | { 8 | public TestIdentity(params Claim[] claims) : base(claims, "testauthentication", JwtClaimTypes.Name, JwtClaimTypes.Role) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Enums/AuthorizationEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Catalyst.Fabric.Authorization.Models.Enums 6 | { 7 | public static class AuthorizationEnum 8 | { 9 | public static readonly string AppGrain = "app"; 10 | public static readonly string DosGrain = "dos"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Resolvers/Permissions/IPermissionResolverService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Fabric.Authorization.Domain.Resolvers.Models; 3 | 4 | namespace Fabric.Authorization.Domain.Resolvers.Permissions 5 | { 6 | public interface IPermissionResolverService 7 | { 8 | Task Resolve(PermissionResolutionRequest resolutionRequest); 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Services/GroupConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Services 2 | { 3 | public static class GroupConstants 4 | { 5 | public static readonly string CustomSource = "Custom"; 6 | public static readonly string DirectorySource = "Directory"; 7 | 8 | public static readonly string[] ValidGroupSources = { CustomSource, DirectorySource }; 9 | } 10 | } -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Storage/HCFabricAuthorizationPrimary.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Do not change the database path or name variables. 3 | Any sqlcmd variables will be properly substituted during 4 | build and deployment. 5 | */ 6 | ALTER DATABASE [$(DatabaseName)] 7 | ADD FILE 8 | ( 9 | NAME = [HCFabricAuthorizationPrimary], 10 | FILENAME = '$(FabricAuthorizationDataMountPoint)\HC$(DatabaseName)Primary.mdf' 11 | ) -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IGrainStore.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Models; 4 | 5 | namespace Fabric.Authorization.Domain.Stores 6 | { 7 | public interface IGrainStore 8 | { 9 | Task Get(string name); 10 | Task> GetSharedGrains(); 11 | Task> GetAll(); 12 | } 13 | } -------------------------------------------------------------------------------- /Fabric.Authorization.PerformanceTests/create-userproperties.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | authserver=$1 4 | authport=$2 5 | identityserver=$3 6 | identityport=$4 7 | bobpassword=$5 8 | alicepassword=$6 9 | 10 | cat > user.properties << EOF 11 | identityserver=$identityserver 12 | identityport=$identityport 13 | authserver=$authserver 14 | authport=$authport 15 | bobpassword=$bobpassword 16 | alicepassword=$alicepassword 17 | EOF 18 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Configuration/CouchDbSettings.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Persistence.CouchDb.Configuration 2 | { 3 | public class CouchDbSettings : ICouchDbSettings 4 | { 5 | public string Server { get; set; } 6 | public string DatabaseName { get; set; } 7 | public string Username { get; set; } 8 | public string Password { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Search/SearchRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models.Search 2 | { 3 | public abstract class SearchRequest 4 | { 5 | public int? PageNumber { get; set; } 6 | public int? PageSize { get; set; } 7 | public string Filter { get; set; } 8 | public string SortKey { get; set; } 9 | public string SortDirection { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/GroupUserRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models 2 | { 3 | public class GroupUserRequest 4 | { 5 | public string GroupName { get; set; } 6 | public string TenantId { get; set; } 7 | public string GroupIdentityProvider { get; set; } 8 | public string SubjectId { get; set; } 9 | public string IdentityProvider { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Requests/RoleApiRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models.Requests 4 | { 5 | public class RoleIdentifierApiRequest 6 | { 7 | public Guid RoleId { get; set; } 8 | } 9 | 10 | public class RolePatchApiRequest 11 | { 12 | public string DisplayName { get; set; } 13 | public string Description { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Services/IEDWAdminRoleSyncService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Models; 4 | 5 | namespace Fabric.Authorization.Domain.Services 6 | { 7 | public interface IEDWAdminRoleSyncService 8 | { 9 | Task RefreshDosAdminRolesAsync(IEnumerable users); 10 | Task RefreshDosAdminRolesAsync(User user); 11 | } 12 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Services/RoleManagerConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Fabric.Authorization.Domain.Services 6 | { 7 | public static class RoleManagerConstants 8 | { 9 | public static string[] AdminRoleNames = { "datamartadmin", "jobadmin" }; 10 | 11 | public static string DosAdminGroupName = "DosAdmins"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IUserStore.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Models; 4 | 5 | namespace Fabric.Authorization.Domain.Stores 6 | { 7 | public interface IUserStore : IGenericStore 8 | { 9 | Task AddRolesToUser(User user, IList roles); 10 | Task DeleteRolesFromUser(User user, IList roles); 11 | } 12 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Events/EntityBatchAuditEvent.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Fabric.Authorization.Domain.Events 4 | { 5 | public class EntityBatchAuditEvent : Event 6 | { 7 | public IEnumerable Entities { get; set; } 8 | 9 | public EntityBatchAuditEvent(string name, IEnumerable entities) : base(name) 10 | { 11 | Entities = entities; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/ITrackable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Catalyst.Fabric.Authorization.Models 6 | { 7 | public interface ITrackable 8 | { 9 | DateTime CreatedDateTimeUtc { get; set; } 10 | DateTime? ModifiedDateTimeUtc { get; set; } 11 | string CreatedBy { get; set; } 12 | string ModifiedBy { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts", 15 | "polyfills.ts" 16 | ], 17 | "include": [ 18 | "**/*.spec.ts", 19 | "**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Storage/HCFabricAuthorizationLogFile1.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Do not change the database path or name variables. 3 | Any sqlcmd variables will be properly substituted during 4 | build and deployment. 5 | */ 6 | ALTER DATABASE [$(DatabaseName)] 7 | ADD LOG FILE 8 | ( 9 | NAME = [HCFabricAuthorizationLogFile1], 10 | FILENAME = '$(FabricAuthorizationLogMountPoint)\HC$(DatabaseName)LogFile1.ldf', 11 | SIZE = 100 MB, 12 | FILEGROWTH = 10% 13 | ) 14 | 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/user.model.ts: -------------------------------------------------------------------------------- 1 | import { IGroup } from './group.model'; 2 | import { IRole } from './role.model'; 3 | 4 | export interface IUser { 5 | id?: string; 6 | groups?: Array; 7 | roles?: Array; 8 | name?: string; 9 | identityProvider?: string; 10 | subjectId: string; 11 | identityProviderUserPrincipalName?: string; 12 | 13 | // custom property 14 | selected?: boolean; 15 | type?: string; 16 | } 17 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/fabric-auth-role.service.mock.ts: -------------------------------------------------------------------------------- 1 | import { IRole } from '../models/role.model'; 2 | 3 | export const mockRoles: IRole[] = [ 4 | { name: 'admin', grain: 'app', securableItem: 'foo' }, 5 | { name: 'superuser', grain: 'app', securableItem: 'foo' } 6 | ]; 7 | 8 | export class FabricAuthRoleServiceMock { 9 | getRolesBySecurableItemAndGrain: jasmine.Spy = jasmine.createSpy('getRolesBySecurableItemAndGrain'); 10 | } 11 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/EDW/ObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Models.EDW 4 | { 5 | public static class ObjectExtensions 6 | { 7 | public static void CheckWhetherArgumentIsNull(this object argument, string argumentName) 8 | { 9 | if (argument == null) 10 | { 11 | throw new ArgumentNullException(argumentName); 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/fabricPrincipal.model.ts: -------------------------------------------------------------------------------- 1 | export interface IFabricPrincipal { 2 | subjectId: string; 3 | firstName?: string; 4 | middleName?: string; 5 | lastName?: string; 6 | principalType: string; 7 | identityProvider?: string; 8 | tenantId?: string; 9 | tenantAlias?: string; 10 | externalIdentifier?: string; 11 | identityProviderUserPrincipalName?: string; 12 | 13 | // Custom Property 14 | selected?: boolean; 15 | } 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Resolvers/Models/PermissionResolutionResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Fabric.Authorization.Domain.Resolvers.Models 4 | { 5 | public class PermissionResolutionResult 6 | { 7 | public IEnumerable AllowedPermissions { get; set; } = new List(); 8 | public IEnumerable DeniedPermissions { get; set; } = new List(); 9 | } 10 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client.FunctionalTests/FunctionalTestSettings.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client.FunctionalTests 2 | { 3 | public class FunctionalTestSettings 4 | { 5 | public string IdentityBaseUrl { get; set; } 6 | 7 | public string AuthorizationBaseUrl { get; set; } 8 | 9 | public string InstallerClientSecret { get; set; } 10 | 11 | public string AuthClientSecret { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/EDW/EDWIdentityRole.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels.EDW 2 | { 3 | public class EDWIdentityRole 4 | { 5 | public int IdentityRoleID { get; set; } 6 | 7 | public int IdentityID { get; set; } 8 | 9 | public int RoleID { get; set; } 10 | 11 | public EDWIdentity EDWIdentity { get; set; } 12 | 13 | public EDWRole EDWRole { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.InMemory/Fabric.Authorization.Persistence.InMemory.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard1.3 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.PerformanceTests/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./create-userproperties.sh $AUTH_SERVER $AUTH_PORT $IDENTITY_SERVER $IDENTITY_PORT $BOB_PASSWORD $ALICE_PASSWORD 4 | mv user.properties /jmeter/apache-jmeter-3.2/bin/user.properties 5 | mkdir results 6 | mkdir results/output 7 | /jmeter/apache-jmeter-3.2/bin/jmeter -n -t /Fabric.Authorization.Perf.jmx -l /results/results.txt -e -o /results/output 8 | cd /apdexcalc 9 | dotnet /apdexcalc/Fabric.ApdexCalculator.dll /results/results.txt 10 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/wwwroot/swagger/ui/swagger-ui-bundle.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AA+4CA;;;;;;AAoIA;AAy2FA;AA8iCA;AA6lJA;AA81IA;AAwuGA;AA01FA;AAkjFA;AAs3FA;AAi+CA;AA29CA;AAmtCA;AAuyEA;;;;;AAwiDA;AA8zJA;;;;;;;;;;;;;;AAyoFA;AA+lIA;AA4oJA;AAqvHA;AA8nGA;AA+iEA;AAw3DA;AA4nDA;AAknBA;;;;;;AAg1FA;AAggGA;;;;;AA23CA;AAgsFA;AA6kDA;AA01CA;AA8yFA;AA61CA;AA0jFA;;;;;;;;;AA6pEA;AA2zIA;AAu7FA;AAmrFA;AAq/EA","sourceRoot":""} -------------------------------------------------------------------------------- /Fabric.Authorization.LibOwin/Fabric.Authorization.LibOwin.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard1.3 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client/AuthorizationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Catalyst.Fabric.Authorization.Models; 3 | 4 | namespace Catalyst.Fabric.Authorization.Client 5 | { 6 | public class AuthorizationException : Exception 7 | { 8 | public Error Details { get; set; } 9 | 10 | public AuthorizationException(Error errorMessage) 11 | : base(errorMessage.Message) 12 | { 13 | this.Details = errorMessage; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Constants/Claims.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Constants 2 | { 3 | public static class Claims 4 | { 5 | public static readonly string Scope = "scope"; 6 | public static readonly string ClientId = "client_id"; 7 | public static readonly string Sub = "sub"; 8 | public static readonly string IdentityProvider = "idp"; 9 | public static readonly string Groups = "groups"; 10 | public static readonly string Name = "name"; 11 | } 12 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/set-environment-authz.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | AUTHZIP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $AUTHORIZATIONCONTAINERNAME) 4 | echo "Authorization Container running on $AUTHZIP" 5 | echo "##vso[task.setvariable variable=FabricAuthorizationBaseUrl;]http://$AUTHZIP:5004" 6 | echo "Authorization Server URL (FABRICAUTHORIZATIONBASEURL): $FABRICAUTHORIZATIONBASEURL" 7 | echo "Authorization Server URL (FabricAuthorizationBaseUrl): $FabricAuthorizationBaseUrl" -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/config.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { ConfigService } from './config.service'; 4 | 5 | describe('ConfigService', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [ConfigService] 9 | }); 10 | }); 11 | 12 | it('should be created', inject([ConfigService], (service: ConfigService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/UserApiModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class UserApiModel 6 | { 7 | public string SubjectId { get; set; } 8 | 9 | public string IdentityProvider { get; set; } 10 | public string IdentityProviderUserPrincipalName { get; set; } 11 | 12 | public IEnumerable Groups { get; set; } 13 | public ICollection Roles { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Services/NoOpEventContextResolverService.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.Domain.Services; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Services 4 | { 5 | public class NoOpEventContextResolverService : IEventContextResolverService 6 | { 7 | public string Username { get; set; } 8 | public string ClientId { get; set; } 9 | public string Subject { get; set; } 10 | public string RemoteIpAddress { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/fabric-base.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | 3 | import { HttpClient } from '@angular/common/http'; 4 | import { IAccessControlConfigService } from './access-control-config.service'; 5 | 6 | @Injectable() 7 | export class FabricBaseService { 8 | constructor( 9 | protected httpClient: HttpClient, 10 | @Inject('IAccessControlConfigService') protected accessControlConfigService: IAccessControlConfigService 11 | ) { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "target": "es5", 11 | "typeRoots": [ 12 | "node_modules/@types" 13 | ], 14 | "lib": [ 15 | "es2017", 16 | "dom" 17 | ], 18 | "module": "es2015", 19 | "baseUrl": "./" 20 | } 21 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Catalyst.Fabric.Authorization.Models.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard1.6 5 | 1.0.0.0-local 6 | $(BUILD_BUILDNUMBER) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/run-integration-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | "/C/Program Files (x86)/Microsoft Visual Studio/2017/Professional/MSBuild/15.0/Bin/MSBuild.exe" ../../Fabric.Authorization.SqlServer/Fabric.Authorization.SqlServer.sqlproj 4 | cp ../../Fabric.Authorization.SqlServer/bin/Debug/Fabric.Authorization.SqlServer_Create.sql ../../Fabric.Authorization.IntegrationTests/bin/Debug/netcoreapp2.1/Fabric.Authorization.SqlServer_Create.sql 5 | 6 | dotnet test ../../Fabric.Authorization.IntegrationTests/Fabric.Authorization.IntegrationTests.csproj 7 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/modules/access-control/grain-list/grain-list.component.scss: -------------------------------------------------------------------------------- 1 | .right{ 2 | position: absolute; 3 | left:250px; top:92px; right:0; bottom:0; 4 | height: 100%; 5 | } 6 | 7 | .left { 8 | position:absolute; 9 | left:0; top:92px; bottom: 0; 10 | width: 250px; 11 | height: 100%; 12 | } 13 | 14 | .selected { 15 | font-weight: bold; 16 | color: #00aeff; 17 | } 18 | 19 | .icon { 20 | font-weight: bold; 21 | color: #00aeff; 22 | } 23 | 24 | a { 25 | color: #333; 26 | } 27 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Stores/EDW/ISecurityContext.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.Persistence.SqlServer.EntityModels.EDW; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.Stores.EDW 5 | { 6 | public interface ISecurityContext 7 | { 8 | DbSet EDWIdentities { get; set; } 9 | 10 | DbSet EDWRoles { get; set; } 11 | 12 | DbSet EDWIdentityRoles { get; set; } 13 | 14 | int SaveChanges(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client.UnitTests/Routes/MemberSearchRouteTests.cs: -------------------------------------------------------------------------------- 1 | using Catalyst.Fabric.Authorization.Client.Routes; 2 | using Xunit; 3 | 4 | namespace Catalyst.Fabric.Authorization.Client.UnitTests.Routes 5 | { 6 | public class MemberSearchRouteTests 7 | { 8 | [Fact] 9 | public void MemberSearchBuilderRoute_NoParameters_Success() 10 | { 11 | var route = new MemberSearchRouteBuilder().Route; 12 | Assert.Equal($"{RouteConstants.MemberCollectionRoute}", route); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Error.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models 2 | { 3 | public class Error 4 | { 5 | public string Code { get; set; } 6 | public string Message { get; set; } 7 | public string Target { get; set; } 8 | public Error[] Details { get; set; } 9 | public InnerError InnerError { get; set; } 10 | } 11 | 12 | public class InnerError 13 | { 14 | public string Code { get; set; } 15 | public InnerError innerError { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Requests/UserApiRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models.Requests 2 | { 3 | public class UserIdentifierApiRequest 4 | { 5 | public string IdentityProvider { get; set; } 6 | public string SubjectId { get; set; } 7 | } 8 | 9 | // TODO: add other user-related fields we may need in a User request (e.g., Name) 10 | public class UserApiRequest : UserIdentifierApiRequest 11 | { 12 | public string IdentityProviderUserPrincipalName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.AspNetCore.Hosting.Internal; 4 | 5 | namespace Fabric.Authorization.API 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | BuildWebHost(args).Run(); 12 | } 13 | 14 | public static IWebHost BuildWebHost(string[] args) => 15 | WebHost.CreateDefaultBuilder(args) 16 | .UseUrls("http://*:5004") 17 | .UseStartup() 18 | .Build(); 19 | } 20 | } -------------------------------------------------------------------------------- /docker-compose.vs.debug.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | fabric.authorization.api: 5 | image: fabric.authorization.api:dev 6 | build: 7 | args: 8 | source: ${DOCKER_BUILD_SOURCE} 9 | environment: 10 | - DOTNET_USE_POLLING_FILE_WATCHER=1 11 | volumes: 12 | - ./Fabric.Authorization.API:/app 13 | - ~/.nuget/packages:/root/.nuget/packages:ro 14 | - ~/clrdbg:/clrdbg:ro 15 | entrypoint: tail -f /dev/null 16 | labels: 17 | - "com.microsoft.visualstudio.targetoperatingsystem=linux" 18 | 19 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Exceptions/UserNotFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Exceptions 4 | { 5 | public class UserNotFoundException : Exception 6 | { 7 | public UserNotFoundException() 8 | { 9 | } 10 | 11 | public UserNotFoundException(string message) : base(message) 12 | { 13 | } 14 | 15 | public UserNotFoundException(string message, Exception innerException) : base(message, innerException) 16 | { 17 | } 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IdpIdentifierFormatter.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Stores 2 | { 3 | public class IdpIdentifierFormatter : IIdentifierFormatter 4 | { 5 | private const string BackslashReplacementChars = "::"; 6 | 7 | public string Format(string id) 8 | { 9 | return ReplaceBackslash(id).ToLower(); 10 | } 11 | 12 | private static string ReplaceBackslash(string id) 13 | { 14 | return id.Replace(@"\", BackslashReplacementChars); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Exceptions/IncompatibleRoleException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Exceptions 4 | { 5 | public class IncompatibleRoleException : Exception 6 | { 7 | public IncompatibleRoleException() 8 | { 9 | } 10 | 11 | public IncompatibleRoleException(string message) : base(message) 12 | { 13 | } 14 | 15 | public IncompatibleRoleException(string message, Exception innerException) : base(message, innerException) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Exceptions/InvalidPermissionException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Exceptions 4 | { 5 | public class InvalidPermissionException : Exception 6 | { 7 | public InvalidPermissionException() 8 | { 9 | } 10 | 11 | public InvalidPermissionException(string message) : base(message) 12 | { 13 | } 14 | 15 | public InvalidPermissionException(string message, Exception innerException) : base(message, innerException) 16 | { 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/ModelExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models 2 | { 3 | using System.Collections.Generic; 4 | 5 | public static class ModelExtensions 6 | { 7 | public static string ToString(this IEnumerable list, string separator) 8 | { 9 | return string.Join(separator, list); 10 | } 11 | 12 | public static string EnsureTrailingSlash(this string url) 13 | { 14 | return !url.EndsWith("/") ? $"{url}/" : url; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/RemoteServices/Identity/Providers/IIdentityServiceProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.API.RemoteServices.Identity.Models; 4 | 5 | namespace Fabric.Authorization.API.RemoteServices.Identity.Providers 6 | { 7 | public interface IIdentityServiceProvider 8 | { 9 | Task SearchUsersAsync(string clientId, IEnumerable subjectIds); 10 | Task SearchGroupAsync(GroupSearchRequest request); 11 | } 12 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/not-found/not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'app-not-found', 6 | templateUrl: './not-found.component.html', 7 | styleUrls: ['./not-found.component.scss'] 8 | }) 9 | export class NotFoundComponent implements OnInit { 10 | 11 | constructor(private router: Router) { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | goToHomepage() { 17 | this.router.navigateByUrl('/access-control'); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/logged-out/logged-out.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'app-logged-out', 6 | templateUrl: './logged-out.component.html', 7 | styleUrls: ['./logged-out.component.scss'] 8 | }) 9 | export class LoggedOutComponent implements OnInit { 10 | 11 | constructor(private router: Router) { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | goToHomepage() { 17 | this.router.navigateByUrl('/access-control'); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/modules/access-control/input.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, Renderer2, Input, OnChanges } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[highlight]' 5 | }) 6 | export class InputDirective implements OnChanges { 7 | 8 | @Input() highlight: boolean; 9 | 10 | constructor(private el: ElementRef, private renderer: Renderer2) { } 11 | 12 | ngOnChanges() { 13 | if (this.highlight === true) { 14 | this.renderer.setStyle(this.el.nativeElement, 'border', '1.5px solid red'); 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Events/Event.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Events 4 | { 5 | public abstract class Event 6 | { 7 | protected Event(string name) 8 | { 9 | Name = name; 10 | } 11 | 12 | public DateTime Timestamp { get; set; } 13 | public string Username { get; set; } 14 | public string ClientId { get; set; } 15 | public string Subject { get; set; } 16 | public string Name { get; set; } 17 | public string RemoteIpAddress { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/read-secrets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sourceFile=$1 4 | 5 | echo $sourceFile 6 | 7 | clientSecretJson=$(<$sourceFile) 8 | echo $clientSecretJson 9 | 10 | installersecret=$(echo $clientSecretJson | jq -r .installerSecret) 11 | authorizationclientsecret=$(echo $clientSecretJson | jq -r .authClientSecret) 12 | 13 | echo $installersecret 14 | echo $authorizationclientsecret 15 | 16 | echo "##vso[task.setvariable variable=FABRIC_INSTALLER_SECRET;]$installersecret" 17 | echo "##vso[task.setvariable variable=AUTH_CLIENT_SECRET;]$authorizationclientsecret" 18 | 19 | -------------------------------------------------------------------------------- /Fabric.Authorization.IntegrationTests/SqlServer/SqlServerUserTests.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Constants; 2 | using Fabric.Authorization.IntegrationTests.Modules; 3 | using Xunit; 4 | 5 | namespace Fabric.Authorization.IntegrationTests.SqlServer 6 | { 7 | [Collection("SqlServerTests")] 8 | public class SqlServerUserTests : UserTests 9 | { 10 | public SqlServerUserTests(IntegrationTestsFixture fixture, SqlServerIntegrationTestsFixture sqlFixture) : base(fixture, StorageProviders.SqlServer, sqlFixture.ConnectionStrings) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.IntegrationTests/SqlServer/SqlServerGroupsTests.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Constants; 2 | using Fabric.Authorization.IntegrationTests.Modules; 3 | using Xunit; 4 | 5 | namespace Fabric.Authorization.IntegrationTests.SqlServer 6 | { 7 | [Collection("SqlServerTests")] 8 | public class SqlServerGroupsTests : GroupsTests 9 | { 10 | public SqlServerGroupsTests(IntegrationTestsFixture fixture, SqlServerIntegrationTestsFixture sqlFixture) : base(fixture, StorageProviders.SqlServer, sqlFixture.ConnectionStrings) 11 | { 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Fabric.Authorization.IntegrationTests/SqlServer/SqlServerRolesTests.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Constants; 2 | using Fabric.Authorization.IntegrationTests.Modules; 3 | using Xunit; 4 | 5 | namespace Fabric.Authorization.IntegrationTests.SqlServer 6 | { 7 | [Collection("SqlServerTests")] 8 | public class SqlServerRolesTests : RolesTests 9 | { 10 | public SqlServerRolesTests(IntegrationTestsFixture fixture, SqlServerIntegrationTestsFixture sqlFixture) : base(fixture, StorageProviders.SqlServer, sqlFixture.ConnectionStrings) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/authMemberSearchRequest.model.ts: -------------------------------------------------------------------------------- 1 | export type SortDirection = 'asc' | 'ascending' | 'desc' | 'descending'; 2 | export type SortKey = 'name' | 'role' | 'lastlogin' | 'subjectid'; 3 | 4 | export interface IAuthMemberSearchRequest { 5 | pageNumber?: number; 6 | pageSize?: number; 7 | filter?: string; 8 | sortKey?: SortKey; 9 | sortDirection?: SortDirection; 10 | 11 | /** if omitted, must provide `grain` */ 12 | clientId?: string; 13 | /** if omitted, must provide `clientId` */ 14 | grain?: string; 15 | securableItem?: string; 16 | } 17 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Constants/IdentityConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain 2 | { 3 | public static class IdentityConstants 4 | { 5 | public static readonly string ActiveDirectory = "Windows"; 6 | public static readonly string AzureActiveDirectory = "AzureActiveDirectory"; 7 | 8 | public static readonly string[] ValidIdentityProviders = { ActiveDirectory, AzureActiveDirectory }; 9 | } 10 | 11 | public static class Identity 12 | { 13 | public static readonly string ClientName = "fabric-authorization-client"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Exceptions/IncompatiblePermissionException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Exceptions 4 | { 5 | public class IncompatiblePermissionException : Exception 6 | { 7 | public IncompatiblePermissionException() 8 | { 9 | } 10 | 11 | public IncompatiblePermissionException(string message) : base(message) 12 | { 13 | } 14 | 15 | public IncompatiblePermissionException(string message, Exception innerException) : base(message, innerException) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.IntegrationTests/SqlServer/SqlServerClientTests.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Constants; 2 | using Fabric.Authorization.IntegrationTests.Modules; 3 | using Xunit; 4 | 5 | namespace Fabric.Authorization.IntegrationTests.SqlServer 6 | { 7 | [Collection("SqlServerTests")] 8 | public class SqlServerClientTests : ClientTests 9 | { 10 | public SqlServerClientTests(IntegrationTestsFixture fixture, SqlServerIntegrationTestsFixture sqlFixture) : base(fixture, StorageProviders.SqlServer, sqlFixture.ConnectionStrings) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.UnitTests/Groups/GroupServiceTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace Fabric.Authorization.UnitTests.Groups 4 | { 5 | [Collection("Group Service Tests")] 6 | public class GroupServiceTests 7 | { 8 | [Fact] 9 | public void AddPermissionToGroup_Succeeds() 10 | { 11 | } 12 | 13 | [Fact] 14 | public void RemovePermissionFromGroup_Succeeds() 15 | { 16 | } 17 | 18 | [Fact] 19 | public void RemovePermissionFromGroup_ThrowsPermissionNotFoundException() 20 | { 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Configuration/DiscoveryServiceSettings.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Configuration 2 | { 3 | public class DiscoveryServiceSettings 4 | { 5 | public string DiscoveryServiceToken { get; set; } 6 | public string IdentityServiceToken { get; set; } 7 | public string AccessControlUIToken { get; set; } 8 | public bool UseDiscovery { get; set; } 9 | public bool UseOAuth2Authentication { get; set; } 10 | public string UseOAuth2AuthenticationToken { get; set; } 11 | public string Endpoint { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Fabric.Authorization.IntegrationTests/SqlServer/SqlServerEdwAdminTests.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Constants; 2 | using Fabric.Authorization.IntegrationTests.Modules; 3 | using Xunit; 4 | 5 | namespace Fabric.Authorization.IntegrationTests.SqlServer 6 | { 7 | [Collection("SqlServerTests")] 8 | public class SqlServerEdwAdminTests : EdwAdminTests 9 | { 10 | public SqlServerEdwAdminTests(IntegrationTestsFixture fixture, SqlServerIntegrationTestsFixture sqlFixture) : base(fixture, StorageProviders.SqlServer, sqlFixture.ConnectionStrings) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/ClientApiModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class ClientApiModel : ITrackable, IIdentifiable 6 | { 7 | public string Id { get; set; } 8 | public string Name { get; set; } 9 | public SecurableItemApiModel TopLevelSecurableItem { get; set; } 10 | public DateTime CreatedDateTimeUtc { get; set; } 11 | public DateTime? ModifiedDateTimeUtc { get; set; } 12 | public string CreatedBy { get; set; } 13 | public string ModifiedBy { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/access-control-config.service.ts: -------------------------------------------------------------------------------- 1 | import { IDataChangedEventArgs } from '../models/changedDataEventArgs.model'; 2 | import { Subject, Observable } from 'rxjs'; 3 | import { Exception } from '../models/exception.model'; 4 | 5 | export interface IAccessControlConfigService { 6 | clientId: string; 7 | identityProvider: string; 8 | grain: string; 9 | securableItem: string; 10 | fabricAuthApiUrl: string; 11 | fabricExternalIdpSearchApiUrl: Observable; 12 | dataChanged: Subject; 13 | errorRaised: Subject; 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Exceptions/CouldNotCompleteOperationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Exceptions 4 | { 5 | public class CouldNotCompleteOperationException : Exception 6 | { 7 | public CouldNotCompleteOperationException() 8 | { 9 | } 10 | 11 | public CouldNotCompleteOperationException(string message) : base(message) 12 | { 13 | } 14 | 15 | public CouldNotCompleteOperationException(string message, Exception innerException) : base(message, innerException) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.IntegrationTests/SqlServer/SqlServerPermissionsTests.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Constants; 2 | using Fabric.Authorization.IntegrationTests.Modules; 3 | using Xunit; 4 | 5 | namespace Fabric.Authorization.IntegrationTests.SqlServer 6 | { 7 | [Collection("SqlServerTests")] 8 | public class SqlServerPermissionsTests : PermissionsTests 9 | { 10 | public SqlServerPermissionsTests(IntegrationTestsFixture fixture, SqlServerIntegrationTestsFixture sqlFixture) : base(fixture, StorageProviders.SqlServer, sqlFixture.ConnectionStrings) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client/Routes/BaseRoute.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client.Routes 2 | { 3 | internal abstract class BaseRoute 4 | { 5 | protected abstract string CollectionType { get; } 6 | 7 | /// 8 | /// General note, do not add a forward slash to the beginning of a relative paths. it is for reference to this article: 9 | /// https://stackoverflow.com/questions/23438416/why-is-httpclient-baseaddress-not-working#23438417 10 | /// 11 | protected virtual string BaseRouteSegment => $"{CollectionType}"; 12 | } 13 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IGenericStore.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Models; 4 | 5 | namespace Fabric.Authorization.Domain.Stores 6 | { 7 | public interface IGenericStore 8 | where TEntity : ITrackable 9 | { 10 | Task Get(TKey id); 11 | 12 | Task Add(TEntity model); 13 | 14 | Task> GetAll(); 15 | 16 | Task Delete(TEntity model); 17 | 18 | Task Update(TEntity model); 19 | 20 | Task Exists(TKey id); 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Modules/SearchModule.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Services; 2 | using FluentValidation; 3 | using Serilog; 4 | 5 | namespace Fabric.Authorization.API.Modules 6 | { 7 | public abstract class SearchModule : FabricModule 8 | { 9 | protected SearchModule() 10 | { 11 | } 12 | 13 | protected SearchModule( 14 | string path, 15 | ILogger logger, 16 | AbstractValidator abstractValidator, 17 | AccessService accessService) : base(path, logger, abstractValidator, accessService) 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/not-found/not-found.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 404 8 | 9 | Sorry, we can't find the page you're looking for! 10 | 11 | 12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Resolvers/Models/PermissionResolutionRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Fabric.Authorization.Domain.Models; 3 | 4 | namespace Fabric.Authorization.Domain.Resolvers.Models 5 | { 6 | public class PermissionResolutionRequest 7 | { 8 | public string Grain { get; set; } 9 | public string SecurableItem { get; set; } 10 | public string IdentityProvider { get; set; } 11 | public string SubjectId { get; set; } 12 | public bool IncludeSharedPermissions { get; set; } 13 | public IEnumerable UserGroups { get; set; } = new List(); 14 | } 15 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IPermissionStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Fabric.Authorization.Domain.Models; 5 | 6 | namespace Fabric.Authorization.Domain.Stores 7 | { 8 | public interface IPermissionStore : IGenericStore 9 | { 10 | Task> GetPermissions(string grain, string securableItem = null, string permissionName = null); 11 | 12 | Task AddOrUpdateGranularPermission(GranularPermission granularPermission); 13 | 14 | Task GetGranularPermission(string userId); 15 | } 16 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/logged-out/logged-out.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Logged Out 8 | 9 | You have been logged out of the AccessControl application. 10 | 11 | 12 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/about-app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root' 5 | }) 6 | export class AboutAppService { 7 | 8 | surveyURL: string = "https://healthcatalyst.typeform.com/to/rhGG5U"; 9 | 10 | /* UPDATE THESE STRINGS WITH EACH DOS RELEASE */ 11 | dosVersion: string = "19.1"; 12 | docsLink: string = "https://docs.healthcatalyst.com/19-1/articles/dos-access-control/navigate-access-control.html"; 13 | releaseNotes: string = "https://community.healthcatalyst.com/dos/w/releases/4258/dos-19-1-what-changed"; 14 | 15 | constructor() { } 16 | } 17 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/Formatters/Formatters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Models.Formatters 4 | { 5 | public class UserIdentifierFormatter : IIdentifierFormatter 6 | { 7 | public string Format(IUser user) 8 | { 9 | if (user == null) 10 | { 11 | throw new ArgumentNullException(nameof(user), "user cannot be null"); 12 | } 13 | 14 | return !string.IsNullOrWhiteSpace(user.IdentityProvider) 15 | ? $"{user.SubjectId}:{user.IdentityProvider}" 16 | : user.SubjectId; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Storage/HCFabricAuthorizationData1.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Do not change the database path or name variables. 3 | Any sqlcmd variables will be properly substituted during 4 | build and deployment. 5 | */ 6 | 7 | ALTER DATABASE [$(DatabaseName)] 8 | ADD FILEGROUP [HCFabricAuthorizationData1] 9 | 10 | GO 11 | ALTER DATABASE [$(DatabaseName)] 12 | ADD FILE 13 | ( 14 | NAME = [HCFabricAuthorizationData1File1], 15 | FILENAME = '$(FabricAuthorizationDataMountPoint)\HC$(DatabaseName)Data1File1.ndf', 16 | SIZE = 100MB, 17 | MAXSIZE = 5GB, 18 | FILEGROWTH = 100MB 19 | ) 20 | 21 | TO FILEGROUP [HCFabricAuthorizationData1]; 22 | GO -------------------------------------------------------------------------------- /Fabric.Authorization.API/Infrastructure/Middleware/AngularMiddlewareExtensions.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Configuration; 2 | using Microsoft.AspNetCore.Builder; 3 | using Microsoft.AspNetCore.Hosting; 4 | 5 | namespace Fabric.Authorization.API.Infrastructure.Middleware 6 | { 7 | public static class AngularMiddlewareExtensions 8 | { 9 | public static IApplicationBuilder UseAngular(this IApplicationBuilder builder, IAppConfiguration appConfiguration, IHostingEnvironment hostingEnvironment) 10 | { 11 | return builder.UseMiddleware(appConfiguration, hostingEnvironment); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Models/Search/Validators/BaseSearchRequestValidator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Catalyst.Fabric.Authorization.Models.Search; 4 | using FluentValidation; 5 | 6 | namespace Fabric.Authorization.API.Models.Search.Validators 7 | { 8 | public class BaseSearchRequestValidator : AbstractValidator 9 | { 10 | protected readonly IEnumerable ValidSortDirections; 11 | 12 | public BaseSearchRequestValidator() 13 | { 14 | ValidSortDirections = SearchConstants.AscendingSortKeys.Concat(SearchConstants.DescendingSortKeys); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/group.model.ts: -------------------------------------------------------------------------------- 1 | import { IRole } from './role.model'; 2 | import { IUser } from './user.model'; 3 | 4 | export interface IGroup { 5 | id?: string; 6 | roles?: Array; 7 | users?: Array; 8 | groupName: string; 9 | groupSource: string; 10 | displayName?: string; 11 | description?: string; 12 | tenantId?: string; 13 | tenantAlias?: string; 14 | externalIdentifier?: string; 15 | domain?: string; 16 | identityProvider?: string; 17 | children?: Array; 18 | parents?: Array; 19 | 20 | // Custom Property 21 | selected?: boolean; 22 | type?: string; 23 | } 24 | -------------------------------------------------------------------------------- /Fabric.Authorization.FunctionalTests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fabric.authorization.functionaltests", 3 | "version": "1.0.0", 4 | "description": "functional test suite for the fabric.authorization api ", 5 | "main": "authorizationtests.js", 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "dependencies": { 10 | "chai": "^4.1.0", 11 | "chakram": "^1.5.0", 12 | "mocha": "^6.0.2", 13 | "phantomjs-prebuilt": "^2.1.16", 14 | "selenium-webdriver": "^3.5.0" 15 | }, 16 | "devDependencies": {}, 17 | "scripts": { 18 | "test": "mocha tests" 19 | }, 20 | "author": "Health Catalyst", 21 | "license": "ISC" 22 | } 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Extensions/WebHostBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Configuration; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace Fabric.Authorization.API.Extensions 5 | { 6 | public static class WebHostBuilderExtensions 7 | { 8 | public static IWebHostBuilder UseIisIntegrationIfConfigured(this IWebHostBuilder builder, 9 | IAppConfiguration appConfiguration) 10 | { 11 | if (appConfiguration.HostingOptions != null && appConfiguration.HostingOptions.UseIis) 12 | builder.UseIISIntegration(); 13 | return builder; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Storage/HCFabricAuthorizationIndex1.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Do not change the database path or name variables. 3 | Any sqlcmd variables will be properly substituted during 4 | build and deployment. 5 | */ 6 | ALTER DATABASE [$(DatabaseName)] 7 | ADD FILEGROUP [HCFabricAuthorizationIndex1] 8 | 9 | GO 10 | 11 | ALTER DATABASE [$(DatabaseName)] 12 | ADD FILE 13 | ( 14 | NAME = [HCFabricAuthorizationIndex1File1], 15 | FILENAME = '$(FabricAuthorizationDataMountPoint)\HC$(DatabaseName)Index1File1.ndf', 16 | SIZE = 500MB, 17 | MAXSIZE = 2GB, 18 | FILEGROWTH = 100MB 19 | ) 20 | 21 | TO FILEGROUP [HCFabricAuthorizationIndex1]; 22 | GO 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.IntegrationTests/SqlServer/SqlServerDosTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Fabric.Authorization.API.Constants; 5 | using Fabric.Authorization.IntegrationTests.Modules; 6 | using Xunit; 7 | 8 | namespace Fabric.Authorization.IntegrationTests.SqlServer 9 | { 10 | [Collection("SqlServerTests")] 11 | public class SqlServerDosTests : DosTests 12 | { 13 | public SqlServerDosTests(IntegrationTestsFixture fixture, SqlServerIntegrationTestsFixture sqlFixture) : base(fixture, StorageProviders.SqlServer, sqlFixture.ConnectionStrings) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/GroupRoleRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class GroupRoleRequest 6 | { 7 | public string GroupName { get; set; } 8 | public string TenantId { get; set; } 9 | public string IdentityProvider { get; set; } 10 | 11 | public Guid? RoleId { get; set; } 12 | 13 | /// 14 | /// Role ID (for backwards compatibility) 15 | /// 16 | public Guid? Id { get; set; } 17 | 18 | public string Grain { get; set; } 19 | 20 | public string SecurableItem { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Modules/DocsModule.cs: -------------------------------------------------------------------------------- 1 | using Nancy; 2 | using Nancy.Swagger.Services; 3 | 4 | namespace Fabric.Authorization.API.Modules 5 | { 6 | public class DocsModule : NancyModule 7 | { 8 | public DocsModule(ISwaggerMetadataProvider converter) : base("/v1/swagger/ui") 9 | { 10 | Get("/index", _ => GetSwaggerUrl()); 11 | Get("/swagger.json", _ => converter.GetSwaggerJson(Context).ToJson()); 12 | } 13 | 14 | private Response GetSwaggerUrl() 15 | { 16 | return Response.AsRedirect( 17 | $"index.html?url=swagger.json"); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/alert.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { ToasterModule } from '@healthcatalyst/cashmere'; 4 | import { OverlayModule } from '@angular/cdk/overlay'; 5 | import { AlertService } from './alert.service'; 6 | 7 | describe('AlertService', () => { 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({ 10 | imports: [ToasterModule,OverlayModule], 11 | providers: [AlertService] 12 | }); 13 | }); 14 | 15 | it('should be created', inject([AlertService], (service: AlertService) => { 16 | expect(service).toBeTruthy(); 17 | })); 18 | }); 19 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/initializer.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { IAuthService } from './auth.service'; 3 | import { ServicesService } from './services.service'; 4 | 5 | @Injectable() 6 | export class InitializerService { 7 | 8 | constructor(@Inject('IAuthService')private authService: IAuthService, private servicesService: ServicesService) { } 9 | 10 | initialize() { 11 | return this.authService.initialize().then(() => { 12 | return this.servicesService.initialize(); 13 | }).then(() => { 14 | console.log('Initializer service completed'); 15 | }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Events/EntityAuditEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Events 2 | { 3 | public class EntityAuditEvent : Event 4 | { 5 | public EntityAuditEvent(string name, string entityId) : base(name) 6 | { 7 | EntityId = entityId; 8 | EntityType = typeof(T).FullName; 9 | } 10 | 11 | public EntityAuditEvent(string name, string entityId, T entity) : this(name, entityId) 12 | { 13 | Entity = entity; 14 | } 15 | 16 | public string EntityId { get; set; } 17 | public string EntityType { get; set; } 18 | public T Entity { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Events/SerilogEventWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Serilog; 4 | 5 | namespace Fabric.Authorization.Domain.Events 6 | { 7 | public class SerilogEventWriter : IEventWriter 8 | { 9 | private readonly ILogger _logger; 10 | 11 | public SerilogEventWriter(ILogger logger) 12 | { 13 | _logger = logger ?? throw new ArgumentNullException(nameof(logger)); 14 | } 15 | 16 | public Task WriteEvent(Event evt) 17 | { 18 | _logger.Information("{Name}, Details: {@details}", evt.Name, evt); 19 | return Task.CompletedTask; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.IntegrationTests/SqlServer/SqlServerMemberSearchTests.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Constants; 2 | using Fabric.Authorization.IntegrationTests.Modules; 3 | using Xunit; 4 | 5 | namespace Fabric.Authorization.IntegrationTests.SqlServer 6 | { 7 | [Collection("SqlServerTests")] 8 | public class SqlServerMemberSearchTests : MemberSearchTests 9 | { 10 | public SqlServerMemberSearchTests(MemberSearchFixture fixture, SqlServerIntegrationTestsFixture sqlFixture) : base(fixture) 11 | { 12 | fixture.ConnectionStrings = sqlFixture.ConnectionStrings; 13 | Fixture.Initialize(StorageProviders.SqlServer); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Validators/GrainValidator.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.Domain.Models; 2 | using FluentValidation; 3 | 4 | namespace Fabric.Authorization.Domain.Validators 5 | { 6 | public class GrainValidator : AbstractValidator 7 | { 8 | public GrainValidator() 9 | { 10 | ConfigureRules(); 11 | } 12 | 13 | private void ConfigureRules() 14 | { 15 | RuleFor(item => item.Name) 16 | .NotEmpty() 17 | .WithMessage("Please specify a Name for the Grain.") 18 | .WithState(s => ValidationEnums.ValidationState.MissingRequiredField); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Constants/HttpResponseHeaders.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.API.Constants 4 | { 5 | public static class HttpResponseHeaders 6 | { 7 | public static readonly string Location = "Location"; 8 | 9 | public static Tuple[] CorsHeaders { get; } = 10 | { 11 | new Tuple("Access-Control-Allow-Origin", "*"), 12 | new Tuple("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization"), 13 | new Tuple("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE") 14 | }; 15 | } 16 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client/Routes/RouteConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client.Routes 2 | { 3 | internal static class RouteConstants 4 | { 5 | public const string UserRoute = "user"; 6 | public const string UserCollectionRoute = "users"; 7 | public const string ClientCollectionRoute = "clients"; 8 | public const string PermissionCollectionRoute = "permissions"; 9 | public const string GroupCollectionRoute = "groups"; 10 | public const string RoleCollectionRoute = "roles"; 11 | public const string MemberCollectionRoute = "members"; 12 | public const string SecurableItemCollectionRoute = "securableitems"; 13 | } 14 | } -------------------------------------------------------------------------------- /Fabric.Authorization.SqlServer/Tables/EventLogs.sql: -------------------------------------------------------------------------------- 1 | 2 | CREATE TABLE [dbo].[EventLogs] 3 | ( 4 | [Id] int IDENTITY(1,1) NOT NULL, 5 | [Message] nvarchar(max) NULL, 6 | [MessageTemplate] nvarchar(max) NULL, 7 | [Level] nvarchar(128) NULL, 8 | [TimeStamp] datetimeoffset(7) NOT NULL, -- use datetime for SQL Server pre-2008 9 | [Exception] nvarchar(max) NULL, 10 | [Properties] xml NULL, 11 | [LogEvent] nvarchar(max) NULL 12 | 13 | CONSTRAINT [PK_Logs] 14 | PRIMARY KEY CLUSTERED ([Id] ASC) 15 | WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 16 | ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 17 | ON [HCFabricAuthorizationData1] 18 | 19 | ) ON [HCFabricAuthorizationData1]; -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Fabric.Authorization.AccessControl 6 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/GrainApiModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Catalyst.Fabric.Authorization.Models 5 | { 6 | public class GrainApiModel 7 | { 8 | public Guid Id { get; set; } 9 | public string Name { get; set; } 10 | public List SecurableItems { get; set; } 11 | public DateTime CreatedDateTimeUtc { get; set; } 12 | public string CreatedBy { get; set; } 13 | public DateTime? ModifiedDateTimeUtc { get; set; } 14 | public string ModifiedBy { get; set; } 15 | public ICollection RequiredWriteScopes { get; set; } 16 | public bool IsShared { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Validators/SecurableItemValidator.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.Domain.Models; 2 | using FluentValidation; 3 | 4 | namespace Fabric.Authorization.Domain.Validators 5 | { 6 | public class SecurableItemValidator : AbstractValidator 7 | { 8 | public SecurableItemValidator() 9 | { 10 | ConfigureRules(); 11 | } 12 | 13 | private void ConfigureRules() 14 | { 15 | RuleFor(item => item.Name) 16 | .NotEmpty() 17 | .WithMessage("Please specify a Name for the SecurableItem.") 18 | .WithState(s => ValidationEnums.ValidationState.MissingRequiredField); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Stores/CouchDBViews.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Fabric.Authorization.Persistence.CouchDb.Stores 4 | { 5 | public class CouchDbViews 6 | { 7 | //the properties in this class need to be lowercase because couchDb design document properties are case sensitive 8 | 9 | // ReSharper disable once InconsistentNaming 10 | public string id { get; set; } 11 | // ReSharper disable once InconsistentNaming 12 | public string language { get; set; } = "javascript"; 13 | 14 | // ReSharper disable once InconsistentNaming 15 | public Dictionary> views { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/GroupUserApiModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class GroupUserApiModel : IIdentifiable 6 | { 7 | public Guid? Id { get; set; } 8 | 9 | public string GroupName { get; set; } 10 | 11 | public string DisplayName { get; set; } 12 | 13 | public string Description { get; set; } 14 | 15 | /// 16 | /// Group source (e.g., Custom, Windows, Google). For custom groups, use "Custom". 17 | /// 18 | public string GroupSource { get; set; } 19 | 20 | public IEnumerable Users { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Events/EventTypes.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.Domain.Events 2 | { 3 | public static class EventTypes 4 | { 5 | public static readonly string EntityCreatedEvent = "EntityCreated"; 6 | public static readonly string ChildEntityCreatedEvent = "ChildEntityCreated"; 7 | public static readonly string EntityUpdatedEvent = "EntityUpdated"; 8 | public static readonly string EntityBatchUpdatedEvent = "EntityBatchUpdated"; 9 | public static readonly string EntityDeletedEvent = "EntityDeleted"; 10 | public static readonly string ChildEntityDeletedEvent = "ChildEntityDeleted"; 11 | public static readonly string EntityReadEvent = "EntityRead"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client.FunctionalTests/BaseTest.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | 3 | namespace Catalyst.Fabric.Authorization.Client.FunctionalTests 4 | { 5 | public abstract class BaseTest 6 | { 7 | protected AuthorizationClient _authorizationClient; 8 | protected HttpClient _client; 9 | protected readonly FunctionalTestFixture fixture; 10 | 11 | protected BaseTest(FunctionalTestFixture fixture) 12 | { 13 | this.fixture = fixture; 14 | this._client = new HttpClient 15 | { 16 | BaseAddress = fixture.BaseUrl 17 | }; 18 | 19 | this._authorizationClient = new AuthorizationClient(this._client); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Configuration/AngularConventionBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Nancy; 4 | using Nancy.Responses; 5 | 6 | namespace Fabric.Authorization.API.Configuration 7 | { 8 | public class AngularConventionBuilder 9 | { 10 | public static Func AddAngularRoot(string angularRootDirectory, string indexFile) 11 | { 12 | return (ctx, appRoot) => 13 | { 14 | if (!ctx.Request.Path.StartsWith($"/{angularRootDirectory}/")) return null; 15 | var file = Path.Combine(appRoot, angularRootDirectory, indexFile); 16 | return new GenericFileResponse(file, ctx); 17 | }; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/access-control-config.service.mock.ts: -------------------------------------------------------------------------------- 1 | import { Subject, Observable, of } from 'rxjs'; 2 | import { IAccessControlConfigService } from './access-control-config.service'; 3 | import { IDataChangedEventArgs } from '../models/changedDataEventArgs.model'; 4 | import { Exception } from '../models/exception.model'; 5 | 6 | export class MockAccessControlConfigService implements IAccessControlConfigService { 7 | clientId: string; 8 | identityProvider: string; 9 | grain: string; 10 | securableItem: string; 11 | fabricAuthApiUrl = 'auth'; 12 | fabricExternalIdpSearchApiUrl = of('idpss'); 13 | dataChanged = new Subject(); 14 | errorRaised: Subject; 15 | } 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Stores/IRoleStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Fabric.Authorization.Domain.Models; 5 | 6 | namespace Fabric.Authorization.Domain.Stores 7 | { 8 | public interface IRoleStore : IGenericStore 9 | { 10 | Task> GetRoles(string grain, string securableItem = null, string roleName = null); 11 | Task AddPermissionsToRole(Role role, ICollection allowPermissions, ICollection denyPermissions); 12 | Task RemovePermissionsFromRole(Role role, Guid[] permissionIds); 13 | Task RemovePermissionFromRoles(Guid permissionId, string grain, string securableItem = null); 14 | } 15 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/PermissionMapperProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 4 | { 5 | public class PermissionMapperProfile : Profile 6 | { 7 | public PermissionMapperProfile() 8 | { 9 | CreateMap() 10 | .ForMember(x => x.Id, opt => opt.MapFrom(src => src.PermissionId)) 11 | .ForMember(x => x.SecurableItem, opt => opt.MapFrom(src => src.SecurableItem.Name)) 12 | .ReverseMap() 13 | .ForPath(x => x.SecurableItem.Name, opt => opt.Ignore()) 14 | .ForMember(x => x.Id, opt => opt.Ignore()); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/GroupMapperProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using Fabric.Authorization.Persistence.SqlServer.EntityModels; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 5 | { 6 | public class GroupMapperProfile : Profile 7 | { 8 | public GroupMapperProfile() 9 | { 10 | CreateMap() 11 | .ForMember(x => x.Id, opt => opt.MapFrom(src => src.GroupId)) 12 | .ForMember(x => x.Roles, opt => opt.MapFrom(src => src.Roles)) 13 | .ForMember(x => x.Users, opt => opt.MapFrom(src => src.Users)) 14 | .ReverseMap() 15 | .ForMember(x => x.Id, opt => opt.Ignore()); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client/Routes/MemberSearchRoute.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client.Routes 2 | { 3 | internal class MemberSearchRoute : BaseRoute 4 | { 5 | protected override string CollectionType { get; } = RouteConstants.MemberCollectionRoute; 6 | 7 | public override string ToString() 8 | { 9 | return BaseRouteSegment; 10 | } 11 | } 12 | 13 | internal class MemberSearchRouteBuilder 14 | { 15 | private readonly MemberSearchRoute _memberSearchRoute; 16 | 17 | public MemberSearchRouteBuilder() 18 | { 19 | _memberSearchRoute = new MemberSearchRoute(); 20 | } 21 | 22 | public string Route => _memberSearchRoute.ToString(); 23 | } 24 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/browser-requirements.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { BrowserRequirementsService } from './browser-requirements.service'; 4 | 5 | describe('BrowserRequirementsService', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [BrowserRequirementsService] 9 | }); 10 | }); 11 | 12 | it('should be created', inject([BrowserRequirementsService], (service: BrowserRequirementsService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | 16 | it('should return true', inject([BrowserRequirementsService], (service: BrowserRequirementsService) => { 17 | expect(service.cookiesEnabled()).toBeTruthy(); 18 | })); 19 | }); 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/models/authMemberSearchResult.model.ts: -------------------------------------------------------------------------------- 1 | import { IRole } from './role.model'; 2 | 3 | export type AuthMemberSearchResultEntityType = 4 | | 'User' 5 | | 'DirectoryGroup' 6 | | 'CustomGroup'; 7 | 8 | export interface IAuthMemberSearchResponse { 9 | totalCount: number; 10 | results: IAuthMemberSearchResult[]; 11 | } 12 | 13 | export interface IAuthMemberSearchResult { 14 | subjectId: string; 15 | identityProvider: string; 16 | roles: Array; 17 | groupName: string; 18 | firstName: string; 19 | middleName: string; 20 | lastName: string; 21 | displayName: string; 22 | lastLoginDateTimeUtc?: string | Date; 23 | entityType: AuthMemberSearchResultEntityType; 24 | name?: string; 25 | tenantId?: string; 26 | } 27 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Fabric.Authorization.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | Full 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/Client.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Models 4 | { 5 | public class Client : ITrackable, ISoftDelete, IIdentifiable 6 | { 7 | public string Id { get; set; } 8 | public string Name { get; set; } 9 | public SecurableItem TopLevelSecurableItem { get; set; } 10 | public bool IsDeleted { get; set; } 11 | public DateTime CreatedDateTimeUtc { get; set; } 12 | public DateTime? ModifiedDateTimeUtc { get; set; } 13 | public string CreatedBy { get; set; } 14 | public string ModifiedBy { get; set; } 15 | 16 | public override string ToString() 17 | { 18 | return $"Id={Id}, Name={Name}"; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/GroupRole.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Fabric.Authorization.Domain.Models; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 5 | { 6 | public class GroupRole : ITrackable, ISoftDelete 7 | { 8 | public int Id { get; set; } 9 | public Guid GroupId { get; set; } 10 | public Guid RoleId { get; set; } 11 | 12 | public bool IsDeleted { get; set; } 13 | public string CreatedBy { get; set; } 14 | public DateTime CreatedDateTimeUtc { get; set; } 15 | public DateTime? ModifiedDateTimeUtc { get; set; } 16 | public string ModifiedBy { get; set; } 17 | 18 | public Group Group { get; set; } 19 | public Role Role { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/RoleMapper.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 4 | { 5 | public static class RoleMapper 6 | { 7 | public static Domain.Models.Role ToModel(this EntityModels.Role entity) 8 | { 9 | return entity == null ? null : Mapper.Map(entity); 10 | } 11 | 12 | public static EntityModels.Role ToEntity(this Domain.Models.Role model) 13 | { 14 | return model == null ? null : Mapper.Map(model); 15 | } 16 | 17 | public static void ToEntity(this Domain.Models.Role model, EntityModels.Role entity) 18 | { 19 | Mapper.Map(model, entity); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/UserMapper.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 4 | { 5 | public static class UserMapper 6 | { 7 | public static Domain.Models.User ToModel(this EntityModels.User entity) 8 | { 9 | return entity == null ? null : Mapper.Map(entity); 10 | } 11 | 12 | public static EntityModels.User ToEntity(this Domain.Models.User model) 13 | { 14 | return model == null ? null : Mapper.Map(model); 15 | } 16 | 17 | public static void ToEntity(this Domain.Models.User model, EntityModels.User entity) 18 | { 19 | Mapper.Map(model, entity); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Services/InMemorySecurityContext.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.Persistence.SqlServer.Configuration; 2 | using Fabric.Authorization.Persistence.SqlServer.Stores.EDW; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace Fabric.Authorization.Persistence.SqlServer.Services 6 | { 7 | public class InMemorySecurityContext : SecurityContext 8 | { 9 | public InMemorySecurityContext(ConnectionStrings connectionStrings) 10 | : base(connectionStrings) 11 | { 12 | } 13 | 14 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 15 | { 16 | optionsBuilder.UseInMemoryDatabase(databaseName: ConnectionStrings.EDWAdminDatabase); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/GroupMapper.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 4 | { 5 | public static class GroupMapper 6 | { 7 | public static Domain.Models.Group ToModel(this EntityModels.Group entity) 8 | { 9 | return entity == null ? null : Mapper.Map(entity); 10 | } 11 | 12 | public static EntityModels.Group ToEntity(this Domain.Models.Group model) 13 | { 14 | return model == null ? null : Mapper.Map(model); 15 | } 16 | 17 | public static void ToEntity(this Domain.Models.Group model, EntityModels.Group entity) 18 | { 19 | Mapper.Map(model, entity); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.UnitTests/Mocks/EventWriteMockExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Events; 4 | using Moq; 5 | 6 | namespace Fabric.Authorization.UnitTests.Mocks 7 | { 8 | public static class EventWriteMockExtensions 9 | { 10 | public static Mock SetupWriteEvent(this Mock mockEventWriter, List events) 11 | { 12 | mockEventWriter.Setup(eventWriter => eventWriter.WriteEvent(It.IsAny())) 13 | .Returns((Event evt) => 14 | { 15 | events.Add(evt); 16 | return Task.CompletedTask; 17 | }); 18 | return mockEventWriter; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/auth.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { AuthService } from './auth.service'; 4 | import { ServicesService } from '../global/services.service'; 5 | import { ConfigService } from '../global/config.service'; 6 | import { HttpClientTestingModule } from '@angular/common/http/testing'; 7 | 8 | describe('AuthService', () => { 9 | beforeEach(() => { 10 | TestBed.configureTestingModule({ 11 | providers: [AuthService, ServicesService, ConfigService], 12 | imports: [HttpClientTestingModule] 13 | }); 14 | }); 15 | 16 | it( 17 | 'should create', 18 | inject([AuthService], (service: AuthService) => { 19 | expect(service).toBeTruthy(); 20 | }) 21 | ); 22 | }); 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/GrainMapper.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 4 | { 5 | public static class GrainMapper 6 | { 7 | public static Domain.Models.Grain ToModel(this EntityModels.Grain entity) 8 | { 9 | return entity == null ? null : Mapper.Map(entity); 10 | } 11 | 12 | public static EntityModels.Grain ToEntity(this Domain.Models.Grain model) 13 | { 14 | return model == null ? null : Mapper.Map(model); 15 | } 16 | 17 | public static void ToEntity(this Domain.Models.Grain model, EntityModels.Grain entity) 18 | { 19 | Mapper.Map(model, entity); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/ChildGroup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Fabric.Authorization.Domain.Models; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 5 | { 6 | public class ChildGroup : ITrackable, ISoftDelete 7 | { 8 | public int Id { get; set; } 9 | public Guid ParentGroupId { get; set; } 10 | public Guid ChildGroupId { get; set; } 11 | 12 | public bool IsDeleted { get; set; } 13 | public string CreatedBy { get; set; } 14 | public DateTime CreatedDateTimeUtc { get; set; } 15 | public DateTime? ModifiedDateTimeUtc { get; set; } 16 | public string ModifiedBy { get; set; } 17 | 18 | public Group Parent { get; set; } 19 | public Group Child { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client.FunctionalTests/FunctionalTestExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client.FunctionalTests 2 | { 3 | using System; 4 | using System.Text; 5 | using Newtonsoft.Json; 6 | 7 | public static class FunctionalTestExtensions 8 | { 9 | public static string ToJson(this object value) 10 | { 11 | return JsonConvert.SerializeObject(value); 12 | } 13 | 14 | public static T FromJson(this string value) 15 | { 16 | return JsonConvert.DeserializeObject(value); 17 | } 18 | 19 | public static string ToBase64Encoded(this string value) 20 | { 21 | return Convert.ToBase64String(Encoding.UTF8.GetBytes(value)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client.UnitTests/Routes/ClientRouteTests.cs: -------------------------------------------------------------------------------- 1 | using Catalyst.Fabric.Authorization.Client.Routes; 2 | using Xunit; 3 | 4 | namespace Catalyst.Fabric.Authorization.Client.UnitTests.Routes 5 | { 6 | public class ClientRouteTests 7 | { 8 | [Fact] 9 | public void ClientRouteBuilder_NoClientId_Success() 10 | { 11 | var route = new ClientRouteBuilder().Route; 12 | Assert.Equal($"{RouteConstants.ClientCollectionRoute}", route); 13 | } 14 | 15 | [Fact] 16 | public void ClientRouteBuilder_WithClientId_Success() 17 | { 18 | var route = new ClientRouteBuilder().ClientId("client_id").Route; 19 | Assert.Equal($"{RouteConstants.ClientCollectionRoute}/client_id", route); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Fabric.Authorization.Persistence.CouchDb.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard1.3 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Stores/CouchDbSecurableItemStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Models; 4 | using Fabric.Authorization.Domain.Stores; 5 | 6 | namespace Fabric.Authorization.Persistence.CouchDb.Stores 7 | { 8 | public class CouchDbSecurableItemStore : ISecurableItemStore 9 | { 10 | public Task Get(string name) 11 | { 12 | var item = new SecurableItem 13 | { 14 | Name = name, 15 | ClientOwner = string.Empty 16 | }; 17 | return Task.FromResult(item); 18 | } 19 | 20 | public Task Get(Guid id) 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Fabric.Authorization.PerformanceTests/appSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "measures": [ 3 | { 4 | "name": "Get Bobs Permissions", 5 | "tolerationThreshold": "500", 6 | "frustrationThreshold": "1500" 7 | }, 8 | { 9 | "name": "Get Alice's Permissions", 10 | "tolerationThreshold": "500", 11 | "frustrationThreshold": "1500" 12 | }, 13 | { 14 | "name": "Create Role", 15 | "tolerationThreshold": "1000", 16 | "frustrationThreshold": "2000" 17 | }, 18 | { 19 | "name": "Create Permission", 20 | "tolerationThreshold": "500", 21 | "frustrationThreshold": "1500" 22 | }, 23 | { 24 | "name": "Associate Permission To Role", 25 | "tolerationThreshold": "500", 26 | "frustrationThreshold": "1500" 27 | } 28 | ] 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/interceptors/fabric-http-fake-discovery-interceptor.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { FabricHttpFakeDiscoveryInterceptorService } from './fabric-http-fake-discovery-interceptor.service'; 4 | import { ConfigService } from '../global/config.service'; 5 | 6 | describe('FabricHttpFakeDiscoveryInterceptorService', () => { 7 | beforeEach(() => { 8 | TestBed.configureTestingModule({ 9 | providers: [ 10 | FabricHttpFakeDiscoveryInterceptorService, 11 | ConfigService 12 | ] 13 | }); 14 | }); 15 | 16 | it('should be created', inject([FabricHttpFakeDiscoveryInterceptorService], (service: FabricHttpFakeDiscoveryInterceptorService) => { 17 | expect(service).toBeTruthy(); 18 | })); 19 | }); 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/ClientMapperProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 4 | { 5 | public class ClientMapperProfile : Profile 6 | { 7 | public ClientMapperProfile() 8 | { 9 | CreateMap() 10 | .ForMember(x => x.Id, opt => opt.MapFrom(src => src.ClientId)) 11 | .ReverseMap() 12 | .ForPath(x => x.ClientId, opt => opt.MapFrom(x => x.Id)) 13 | .ForMember(x => x.TopLevelSecurableItem, opt => opt.MapFrom(src => src.TopLevelSecurableItem)) 14 | .ForMember(x => x.Id, opt => opt.Ignore()) 15 | .ForMember(x => x.SecurableItemId, opt => opt.Ignore()); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | import { BrowserRequirementsService } from './app/services/browser-requirements.service'; 8 | import { bootstrapNoCookiesAppModule } from './app/no-cookies.app.module'; 9 | 10 | if (environment.production) { 11 | enableProdMode(); 12 | } 13 | 14 | const browserRequirementsService = new BrowserRequirementsService(); 15 | if (browserRequirementsService.cookiesEnabled()) { 16 | platformBrowserDynamic() 17 | .bootstrapModule(AppModule) 18 | .catch(err => console.log(err)); 19 | } else { 20 | bootstrapNoCookiesAppModule(); 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/Client.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Fabric.Authorization.Domain.Models; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 5 | { 6 | public class Client : ITrackable, ISoftDelete 7 | { 8 | public int Id { get; set; } 9 | public string ClientId { get; set; } 10 | public string Name { get; set; } 11 | public Guid SecurableItemId { get; set; } 12 | 13 | public DateTime CreatedDateTimeUtc { get; set; } 14 | public DateTime? ModifiedDateTimeUtc { get; set; } 15 | public string CreatedBy { get; set; } 16 | public string ModifiedBy { get; set; } 17 | public bool IsDeleted { get; set; } 18 | 19 | public SecurableItem TopLevelSecurableItem { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/config.service.ts: -------------------------------------------------------------------------------- 1 | import { Observable, of } from 'rxjs'; 2 | import { Injectable } from '@angular/core'; 3 | 4 | function getWindow(): any { 5 | return window; 6 | } 7 | 8 | @Injectable() 9 | export class ConfigService { 10 | 11 | constructor() { } 12 | 13 | public getUseOAuthAuthentication(): Observable { 14 | return of(getWindow().useOAuthAuthentication); 15 | } 16 | 17 | public getDiscoveryServiceRoot(): Observable { 18 | return of(getWindow().discoveryServiceRoot); 19 | } 20 | 21 | public getIdentityServiceRoot(): Observable { 22 | return of(getWindow().identityServiceRoot); 23 | } 24 | 25 | public getAccessControlServiceRoot(): Observable { 26 | return of(getWindow().accessControlServiceRoot); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/ClientMapper.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 5 | { 6 | public static class ClientMapper 7 | { 8 | public static Domain.Models.Client ToModel(this EntityModels.Client entity) 9 | { 10 | return entity == null ? null : Mapper.Map(entity); 11 | } 12 | 13 | public static EntityModels.Client ToEntity(this Domain.Models.Client model) 14 | { 15 | return model == null ? null : Mapper.Map(model); 16 | } 17 | 18 | public static void ToEntity(this Domain.Models.Client model, EntityModels.Client entity) 19 | { 20 | Mapper.Map(model, entity); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/GroupUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Fabric.Authorization.Domain.Models; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 5 | { 6 | public class GroupUser : ITrackable, ISoftDelete 7 | { 8 | public int Id { get; set; } 9 | public string SubjectId { get; set; } 10 | public string IdentityProvider { get; set; } 11 | public Guid GroupId { get; set; } 12 | 13 | public DateTime CreatedDateTimeUtc { get; set; } 14 | public DateTime? ModifiedDateTimeUtc { get; set; } 15 | public string CreatedBy { get; set; } 16 | public string ModifiedBy { get; set; } 17 | public bool IsDeleted { get; set; } 18 | 19 | public User User { get; set; } 20 | public Group Group { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/PermissionMapper.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 4 | { 5 | public static class PermissionMapper 6 | { 7 | public static Domain.Models.Permission ToModel(this EntityModels.Permission entity) 8 | { 9 | return entity == null ? null : Mapper.Map(entity); 10 | } 11 | 12 | public static EntityModels.Permission ToEntity(this Domain.Models.Permission model) 13 | { 14 | return model == null ? null : Mapper.Map(model); 15 | } 16 | 17 | public static void ToEntity(this Domain.Models.Permission model, EntityModels.Permission entity) 18 | { 19 | Mapper.Map(model, entity); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/SecurableItemApiModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Catalyst.Fabric.Authorization.Models.Enums; 4 | 5 | namespace Catalyst.Fabric.Authorization.Models 6 | { 7 | public class SecurableItemApiModel : ITrackable, IIdentifiable 8 | { 9 | public Guid? Id { get; set; } 10 | public string Name { get; set; } 11 | public string ClientOwner { get; set; } 12 | public string Grain { get; set; } = AuthorizationEnum.AppGrain; 13 | public ICollection SecurableItems { get; set; } 14 | public DateTime CreatedDateTimeUtc { get; set; } 15 | public DateTime? ModifiedDateTimeUtc { get; set; } 16 | public string CreatedBy { get; set; } 17 | public string ModifiedBy { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/name-display.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { IFabricPrincipal} from '../models/fabricPrincipal.model'; 3 | import { USER, GROUP } from '../constants/principal-constants'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class NameDisplayService { 9 | constructor() { } 10 | 11 | getPrincipalNameToDisplay(principal: IFabricPrincipal): string { 12 | if (principal.principalType.toLowerCase() === USER) { 13 | return principal.identityProviderUserPrincipalName || principal.subjectId; 14 | } else if (principal.principalType.toLowerCase() === GROUP) { 15 | if (!principal.tenantAlias) { 16 | return principal.subjectId; 17 | } 18 | return principal.subjectId + '@' + principal.tenantAlias; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # user-specific files 12 | src/environments/environment.user.ts 13 | 14 | # IDEs and editors 15 | /.idea 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # IDE - VSCode 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | 30 | # misc 31 | /.sass-cache 32 | /connect.lock 33 | /coverage 34 | /libpeerconnection.log 35 | npm-debug.log 36 | testem.log 37 | /typings 38 | 39 | # e2e 40 | /e2e/*.js 41 | /e2e/*.map 42 | 43 | # System Files 44 | .DS_Store 45 | Thumbs.db 46 | 47 | # ngpackgr 48 | /.ng_pkg_build 49 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/RolePermission.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Fabric.Authorization.Domain.Models; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 5 | { 6 | public class RolePermission : ITrackable, ISoftDelete 7 | { 8 | public int Id { get; set; } 9 | public Guid RoleId { get; set; } 10 | public Guid PermissionId { get; set; } 11 | public PermissionAction PermissionAction { get; set; } 12 | 13 | public bool IsDeleted { get; set; } 14 | public string CreatedBy { get; set; } 15 | public DateTime CreatedDateTimeUtc { get; set; } 16 | public DateTime? ModifiedDateTimeUtc { get; set; } 17 | public string ModifiedBy { get; set; } 18 | 19 | public Role Role { get; set; } 20 | public Permission Permission { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/EDW/EDWIdentity.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels.EDW 5 | { 6 | public class EDWIdentity 7 | { 8 | public EDWIdentity() 9 | { 10 | this.EDWIdentityRoles = new List(); 11 | this.EDWRoles = new List(); 12 | } 13 | 14 | /// 15 | /// identity field 16 | /// 17 | public int Id { get; set; } 18 | 19 | public string Name { get; set; } 20 | 21 | public ICollection EDWIdentityRoles { get; set; } 22 | 23 | [NotMapped] 24 | public ICollection EDWRoles { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/SecurableItemMapper.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 4 | { 5 | public static class SecurableItemMapper 6 | { 7 | public static Domain.Models.SecurableItem ToModel(this EntityModels.SecurableItem entity) 8 | { 9 | return entity == null ? null : Mapper.Map(entity); 10 | } 11 | 12 | public static EntityModels.SecurableItem ToEntity(this Domain.Models.SecurableItem model) 13 | { 14 | return model == null ? null : Mapper.Map(model); 15 | } 16 | 17 | public static void ToEntity(this Domain.Models.SecurableItem model, EntityModels.SecurableItem entity) 18 | { 19 | Mapper.Map(model, entity); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Stores/SqlServerBaseStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Fabric.Authorization.Domain.Services; 3 | using Fabric.Authorization.Persistence.SqlServer.Services; 4 | 5 | namespace Fabric.Authorization.Persistence.SqlServer.Stores 6 | { 7 | public abstract class SqlServerBaseStore 8 | { 9 | protected IAuthorizationDbContext AuthorizationDbContext; 10 | protected IEventService EventService; 11 | 12 | protected SqlServerBaseStore(IAuthorizationDbContext authorizationDbContext, IEventService eventService) 13 | { 14 | AuthorizationDbContext = authorizationDbContext ?? 15 | throw new ArgumentNullException(nameof(authorizationDbContext)); 16 | 17 | EventService = eventService ?? throw new ArgumentNullException(nameof(eventService)); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/Fabric.Authorization.InstallPackage.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fabric.Authorization.InstallPackage 5 | $version$ 6 | Health Catalyst 7 | Health Catalyst 8 | false 9 | Install package for Fabric.Authorization 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/fabric-base.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { HttpClientTestingModule } from '@angular/common/http/testing'; 4 | import { FabricBaseService } from './fabric-base.service'; 5 | import { MockAccessControlConfigService } from './access-control-config.service.mock'; 6 | 7 | describe('FabricAuthBaseService', () => { 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({ 10 | providers: [FabricBaseService, { 11 | provide: 'IAccessControlConfigService', 12 | useClass: MockAccessControlConfigService 13 | }], 14 | imports: [HttpClientTestingModule] 15 | }); 16 | }); 17 | 18 | it( 19 | 'should be created', 20 | inject([FabricBaseService], (service: FabricBaseService) => { 21 | expect(service).toBeTruthy(); 22 | }) 23 | ); 24 | }); 25 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/GrainMapperProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using Microsoft.EntityFrameworkCore.Internal; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 5 | { 6 | public class GrainMapperProfile : Profile 7 | { 8 | private readonly char _separator = ';'; 9 | public GrainMapperProfile() 10 | { 11 | //entity to model 12 | CreateMap() 13 | .ForMember(x => x.Id, opt => opt.MapFrom(src => src.GrainId)) 14 | .ForMember(x => x.RequiredWriteScopes, opt => opt.MapFrom(src => src.RequiredWriteScopes.Split(_separator))) 15 | .ReverseMap() 16 | .ForMember(x => x.RequiredWriteScopes, opt => opt.MapFrom(src => src.RequiredWriteScopes.Join(_separator.ToString()))); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Swagger/Parameters.cs: -------------------------------------------------------------------------------- 1 | using Swagger.ObjectModel; 2 | 3 | namespace Fabric.Authorization.API.Swagger 4 | { 5 | public static class Parameters 6 | { 7 | public static readonly Parameter GrainParameter = new Parameter 8 | { 9 | Name = "grain", 10 | Description = "The top level grain to return permissions for", 11 | Required = true, 12 | Type = "string", 13 | In = ParameterIn.Path 14 | }; 15 | 16 | public static readonly Parameter SecurableItemParameter = new Parameter 17 | { 18 | Name = "securableItem", 19 | Description = "The specific securableItem within the grain to return permissions for", 20 | Required = true, 21 | Type = "string", 22 | In = ParameterIn.Path 23 | }; 24 | } 25 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Exceptions/AlreadyExistsException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Exceptions 4 | { 5 | public class AlreadyExistsException : Exception 6 | { 7 | private T Model { get; set; } 8 | 9 | public AlreadyExistsException() 10 | { 11 | } 12 | 13 | public AlreadyExistsException(T model) 14 | { 15 | this.Model = model; 16 | } 17 | 18 | public AlreadyExistsException(string message) : base(message) 19 | { 20 | } 21 | 22 | public AlreadyExistsException(T model, string message) : base(message) 23 | { 24 | this.Model = model; 25 | } 26 | 27 | public AlreadyExistsException(T model, string message, Exception inner) : base(message, inner) 28 | { 29 | this.Model = model; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Exceptions/BadRequestException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Fabric.Authorization.Domain.Exceptions 4 | { 5 | public class BadRequestException : Exception 6 | { 7 | private readonly T _model; 8 | 9 | public T Model => _model; 10 | 11 | public BadRequestException() 12 | { 13 | } 14 | 15 | public BadRequestException(T model) 16 | { 17 | _model = model; 18 | } 19 | 20 | public BadRequestException(T model, string message) : base(message) 21 | { 22 | _model = model; 23 | } 24 | 25 | public BadRequestException(string message) : base(message) 26 | { 27 | } 28 | 29 | public BadRequestException(T model, string message, Exception inner) : base(message, inner) 30 | { 31 | _model = model; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/RoleUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Fabric.Authorization.Domain.Models; 5 | 6 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 7 | { 8 | public class RoleUser : ITrackable, ISoftDelete 9 | { 10 | public int Id { get; set; } 11 | public string SubjectId { get; set; } 12 | public string IdentityProvider { get; set; } 13 | public Guid RoleId { get; set; } 14 | 15 | public DateTime CreatedDateTimeUtc { get; set; } 16 | public DateTime? ModifiedDateTimeUtc { get; set; } 17 | public string CreatedBy { get; set; } 18 | public string ModifiedBy { get; set; } 19 | public bool IsDeleted { get; set; } 20 | 21 | public User User { get; set; } 22 | public Role Role { get; set; } 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Mappers/UserMapperProfile.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using AutoMapper; 3 | using Fabric.Authorization.Domain.Models.Formatters; 4 | 5 | namespace Fabric.Authorization.Persistence.SqlServer.Mappers 6 | { 7 | public class UserMapperProfile : Profile 8 | { 9 | public UserMapperProfile() 10 | { 11 | CreateMap() 12 | .ForMember(x => x.Id, opt => opt.MapFrom(src => new UserIdentifierFormatter().Format(src))) 13 | .ForMember(x => x.Groups, opt => opt.MapFrom(src => src.Groups)) 14 | .ForMember(x => x.Permissions, opt => opt.MapFrom(src => src.Permissions)) 15 | .ForMember(x => x.Roles, opt => opt.MapFrom(src => src.Roles)) 16 | .ReverseMap() 17 | .ForMember(x => x.Id, opt => opt.Ignore()); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/e2e/hacks.ts: -------------------------------------------------------------------------------- 1 | import { browser } from 'protractor'; 2 | 3 | // Taken from from Atlas project 4 | /** 5 | * This is a HACK to tell Protractor that it's OK to continue the test. 6 | * For some reason, in Atlas the NgZone will never say it has no pending 7 | * macro tasks, so we go in and hard code that to `false` 8 | */ 9 | export async function tellNgZoneItHasNoPendingMacroTasks() { 10 | await browser.waitForAngularEnabled(false); 11 | const script = ` 12 | const __testability = window.getAngularTestability( 13 | document.querySelector('app-root') 14 | ); 15 | __testability._ngZone.hasPendingMacrotasks = false; 16 | __testability.whenStable(() => console.log('zone stable')); 17 | `; 18 | 19 | await browser.executeScript(script); 20 | await browser.waitForAngularEnabled(true); 21 | } 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/not-found/not-found.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import {RouterTestingModule} from '@angular/router/testing'; 3 | 4 | import { NotFoundComponent } from './not-found.component'; 5 | 6 | describe('NotFoundComponent', () => { 7 | let component: NotFoundComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ NotFoundComponent ], 13 | imports: [RouterTestingModule] 14 | }) 15 | .compileComponents(); 16 | })); 17 | 18 | beforeEach(() => { 19 | fixture = TestBed.createComponent(NotFoundComponent); 20 | component = fixture.componentInstance; 21 | fixture.detectChanges(); 22 | }); 23 | 24 | it('should create', () => { 25 | expect(component).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/Fabric.Authorization.InstallPackage.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SetupContent\Fabric.Authorization.InstallPackage.zip 5 | Always 6 | 7 | 8 | SetupContent\Fabric.Authorization.SqlServer.dacpac 9 | Always 10 | 11 | 12 | SetupContent\Fabric.Authorization.SqlServer.publish.xml 13 | Always 14 | 15 | 16 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Constants/Scopes.cs: -------------------------------------------------------------------------------- 1 | namespace Fabric.Authorization.API.Constants 2 | { 3 | public static class Scopes 4 | { 5 | public static readonly string ReadScope = "fabric/authorization.read"; 6 | public static readonly string WriteScope = "fabric/authorization.write"; 7 | public static readonly string InternalScope = "fabric/authorization.internal"; 8 | public static readonly string ManageClientsScope = "fabric/authorization.manageclients"; 9 | public static readonly string ManageDosScope = "fabric/authorization.dos.write"; 10 | } 11 | 12 | public static class IdentityScopes 13 | { 14 | public static readonly string SearchUsersScope = "fabric/identity.searchusers"; 15 | } 16 | 17 | public static class IdentityProviderSearchScopes 18 | { 19 | public static readonly string SearchUsersScope = "fabric/idprovider.searchusers"; 20 | } 21 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/RemoteServices/Identity/Models/GroupSearchResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net; 3 | 4 | namespace Fabric.Authorization.API.RemoteServices.Identity.Models 5 | { 6 | public class IdentityGroup 7 | { 8 | public string ExternalIdentifier { get; set; } 9 | public string GroupName { get; set; } 10 | public string TenantId { get; set; } 11 | public string IdentityProvider { get; set; } 12 | public string PrincipalType { get; set; } 13 | } 14 | 15 | public class GroupSearchResponse 16 | { 17 | public IEnumerable Principals { get; set; } 18 | public int ResultCount { get; set; } 19 | } 20 | 21 | public class FabricIdentityGroupResponse 22 | { 23 | public HttpStatusCode HttpStatusCode { get; set; } 24 | public IEnumerable Results { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/logged-out/logged-out.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import {RouterTestingModule} from '@angular/router/testing'; 3 | 4 | import { LoggedOutComponent } from './logged-out.component'; 5 | 6 | describe('LoggedOutComponent', () => { 7 | let component: LoggedOutComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ LoggedOutComponent ], 13 | imports: [RouterTestingModule] 14 | }) 15 | .compileComponents(); 16 | })); 17 | 18 | beforeEach(() => { 19 | fixture = TestBed.createComponent(LoggedOutComponent); 20 | component = fixture.componentInstance; 21 | fixture.detectChanges(); 22 | }); 23 | 24 | it('should create', () => { 25 | expect(component).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/fabric-auth-role.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { FabricAuthRoleService } from './fabric-auth-role.service'; 4 | import { HttpClientTestingModule } from '@angular/common/http/testing'; 5 | import { MockAccessControlConfigService } from './access-control-config.service.mock'; 6 | 7 | describe('FabricAuthRoleService', () => { 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({ 10 | providers: [FabricAuthRoleService, 11 | { 12 | provide: 'IAccessControlConfigService', 13 | useClass: MockAccessControlConfigService 14 | }], 15 | imports: [HttpClientTestingModule] 16 | }); 17 | }); 18 | 19 | it( 20 | 'should be created', 21 | inject([FabricAuthRoleService], (service: FabricAuthRoleService) => { 22 | expect(service).toBeTruthy(); 23 | }) 24 | ); 25 | }); 26 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/Grain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Fabric.Authorization.Domain.Models; 4 | 5 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 6 | { 7 | public class Grain : ITrackable, ISoftDelete 8 | { 9 | public int Id { get; set; } 10 | public Guid GrainId { get; set; } 11 | public string Name { get; set; } 12 | public bool IsShared { get; set; } 13 | public string RequiredWriteScopes { get; set; } 14 | public ICollection SecurableItems { get; set; } = new List(); 15 | 16 | public DateTime CreatedDateTimeUtc { get; set; } 17 | public DateTime? ModifiedDateTimeUtc { get; set; } 18 | public string CreatedBy { get; set; } 19 | public string ModifiedBy { get; set; } 20 | public bool IsDeleted { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/EntityModels/UserPermission.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Fabric.Authorization.Domain.Models; 3 | 4 | namespace Fabric.Authorization.Persistence.SqlServer.EntityModels 5 | { 6 | public class UserPermission : ITrackable, ISoftDelete 7 | { 8 | public int Id { get; set; } 9 | public string SubjectId { get; set; } 10 | public string IdentityProvider { get; set; } 11 | public Guid PermissionId { get; set; } 12 | public PermissionAction PermissionAction { get; set; } 13 | 14 | public bool IsDeleted { get; set; } 15 | public string CreatedBy { get; set; } 16 | public DateTime CreatedDateTimeUtc { get; set; } 17 | public DateTime? ModifiedDateTimeUtc { get; set; } 18 | public string ModifiedBy { get; set; } 19 | 20 | public User User { get; set; } 21 | public Permission Permission { get; set; } 22 | } 23 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client.UnitTests/Catalyst.Fabric.Authorization.Client.UnitTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.1 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client.FunctionalTests/Catalyst.Fabric.Authorization.Client.FunctionalTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.1 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Modules/RootModule.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Configuration; 2 | using Nancy; 3 | using Fabric.Authorization.API.Constants; 4 | using Fabric.Authorization.Domain.Models; 5 | 6 | namespace Fabric.Authorization.API.Modules 7 | { 8 | public class RootModule : NancyModule 9 | { 10 | private readonly IAppConfiguration _appConfiguration; 11 | public RootModule(IAppConfiguration appConfiguration): base("/v1") 12 | { 13 | _appConfiguration = appConfiguration; 14 | Get("/", _ => Redirect(), null, "Redirect"); 15 | Get($"/{AccessControl.Path}", _ => Redirect(), null, "Redirect"); 16 | } 17 | 18 | private dynamic Redirect() 19 | { 20 | var redirectUri = $"{_appConfiguration.ApplicationEndpoint.EnsureTrailingSlash()}{AccessControl.Path}/{AccessControl.Index}"; 21 | return Response.AsRedirect(redirectUri); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.SqlServer/Services/InMemoryAuthorizationDbContext.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.Domain.Services; 2 | using Fabric.Authorization.Persistence.SqlServer.Configuration; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.Extensions.Logging; 5 | 6 | namespace Fabric.Authorization.Persistence.SqlServer.Services 7 | { 8 | public class InMemoryAuthorizationDbContext : AuthorizationDbContext 9 | { 10 | public InMemoryAuthorizationDbContext(IEventContextResolverService eventContextResolverService, ConnectionStrings connectionStrings, ILoggerFactory loggerFactory) 11 | : base(eventContextResolverService, connectionStrings, loggerFactory) 12 | { 13 | } 14 | 15 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 16 | { 17 | optionsBuilder.UseInMemoryDatabase(databaseName: ConnectionStrings.AuthorizationDatabase); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iis": { 6 | "applicationUrl": "http://localhost/AuthorizationDev", 7 | "sslPort": 0 8 | }, 9 | "iisExpress": { 10 | "applicationUrl": "http://localhost:2871/", 11 | "sslPort": 0 12 | } 13 | }, 14 | "profiles": { 15 | "IIS Express": { 16 | "commandName": "IISExpress", 17 | "launchBrowser": true, 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "Fabric.Authorization.API": { 23 | "commandName": "Project" 24 | }, 25 | "IIS": { 26 | "commandName": "IIS", 27 | "launchBrowser": true, 28 | "launchUrl": "http://localhost/AuthorizationDev", 29 | "environmentVariables": { 30 | "ASPNETCORE_ENVIRONMENT": "Development" 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Services/EventContextResolverService.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Constants; 2 | using Fabric.Authorization.API.Infrastructure; 3 | using Fabric.Authorization.Domain.Services; 4 | using IdentityModel; 5 | using Nancy; 6 | 7 | namespace Fabric.Authorization.API.Services 8 | { 9 | public class EventContextResolverService : IEventContextResolverService 10 | { 11 | private readonly NancyContext _context; 12 | 13 | public EventContextResolverService(NancyContextWrapper contextWrapper) 14 | { 15 | _context = contextWrapper.Context; 16 | } 17 | 18 | public string Username => _context?.CurrentUser?.Identity.Name; 19 | public string ClientId => _context?.CurrentUser?.FindFirst(Claims.ClientId)?.Value; 20 | public string Subject => _context?.CurrentUser?.FindFirst(JwtClaimTypes.Subject)?.Value; 21 | public string RemoteIpAddress => _context?.Request?.UserHostAddress; 22 | } 23 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/SecurableItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Fabric.Authorization.Domain.Models 5 | { 6 | public class SecurableItem : ITrackable, IIdentifiable, ISoftDelete 7 | { 8 | public SecurableItem() 9 | { 10 | SecurableItems = new List(); 11 | } 12 | 13 | public Guid Id { get; set; } 14 | 15 | public string Name { get; set; } 16 | 17 | public string ClientOwner { get; set; } 18 | 19 | public ICollection SecurableItems { get; set; } 20 | 21 | public string Grain { get; set; } 22 | 23 | public DateTime CreatedDateTimeUtc { get; set; } 24 | 25 | public DateTime? ModifiedDateTimeUtc { get; set; } 26 | 27 | public string CreatedBy { get; set; } 28 | 29 | public string ModifiedBy { get; set; } 30 | 31 | public bool IsDeleted { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/PermissionApiModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Catalyst.Fabric.Authorization.Models 4 | { 5 | public class PermissionApiModel : ITrackable, IIdentifiable 6 | { 7 | public Guid? Id { get; set; } 8 | 9 | public string Grain { get; set; } 10 | 11 | public string SecurableItem { get; set; } 12 | 13 | public string Name { get; set; } 14 | 15 | public DateTime CreatedDateTimeUtc { get; set; } 16 | 17 | public DateTime? ModifiedDateTimeUtc { get; set; } 18 | 19 | public string CreatedBy { get; set; } 20 | 21 | public string ModifiedBy { get; set; } 22 | 23 | public PermissionAction PermissionAction { get; set; } 24 | 25 | public override string ToString() 26 | { 27 | return $"{Grain}/{SecurableItem}.{Name}"; 28 | } 29 | } 30 | 31 | public enum PermissionAction 32 | { 33 | Allow, 34 | Deny 35 | } 36 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/GroupRoleApiModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Catalyst.Fabric.Authorization.Models 5 | { 6 | public class GroupRoleApiModel : IIdentifiable 7 | { 8 | public Guid? Id { get; set; } 9 | 10 | public string GroupName { get; set; } 11 | 12 | public string IdentityProvider { get; set; } 13 | 14 | public string DisplayName { get; set; } 15 | 16 | public string Description { get; set; } 17 | 18 | public IEnumerable Roles { get; set; } 19 | 20 | /// 21 | /// Group source (e.g., Custom or Directory). 22 | /// 23 | public string GroupSource { get; set; } 24 | 25 | public string TenantId { get; set; } 26 | 27 | public IEnumerable Parents { get; set; } 28 | public IEnumerable Children { get; set; } 29 | } 30 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/DependencyInjection/SqlServerConfigurator.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Configuration; 2 | using Fabric.Authorization.Persistence.SqlServer.Services; 3 | using Fabric.Authorization.Persistence.SqlServer.Stores.EDW; 4 | using Nancy.TinyIoc; 5 | 6 | namespace Fabric.Authorization.API.DependencyInjection 7 | { 8 | public class SqlServerConfigurator : BaseSqlServerConfigurator 9 | { 10 | public SqlServerConfigurator(IAppConfiguration appConfiguration) : base(appConfiguration) 11 | { 12 | } 13 | 14 | protected override TinyIoCContainer.RegisterOptions RegisterDatabaseContext(TinyIoCContainer container) 15 | { 16 | return container.Register(); 17 | } 18 | 19 | protected override TinyIoCContainer.RegisterOptions RegisterEDWDatabaseContext(TinyIoCContainer container) 20 | { 21 | return container.Register(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/Grain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Fabric.Authorization.Domain.Models 5 | { 6 | public class Grain : ITrackable, IIdentifiable, ISoftDelete 7 | { 8 | public Grain() 9 | { 10 | SecurableItems = new List(); 11 | RequiredWriteScopes = new List(); 12 | } 13 | 14 | public Guid Id { get; set; } 15 | 16 | public string Name { get; set; } 17 | 18 | public bool IsShared { get; set; } 19 | 20 | public ICollection SecurableItems { get; set; } 21 | 22 | public ICollection RequiredWriteScopes { get; set; } 23 | 24 | public DateTime CreatedDateTimeUtc { get; set; } 25 | public DateTime? ModifiedDateTimeUtc { get; set; } 26 | public string CreatedBy { get; set; } 27 | public string ModifiedBy { get; set; } 28 | public bool IsDeleted { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/guards/authentication.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; 3 | import { Observable } from 'rxjs'; 4 | import { IAuthService } from '../global/auth.service'; 5 | 6 | @Injectable() 7 | export class AuthenticationGuard implements CanActivate { 8 | constructor(@Inject('IAuthService')private authService: IAuthService) {} 9 | 10 | canActivate( 11 | next: ActivatedRouteSnapshot, 12 | state: RouterStateSnapshot): Observable | Promise | boolean { 13 | return this.authService.isUserAuthenticated().then((result) => { 14 | if (result) { 15 | return true; 16 | } else { 17 | if (window.location.href.indexOf('/logged-out') < 0) { 18 | sessionStorage.setItem('redirect', window.location.href); 19 | } 20 | this.authService.login(); 21 | return false; 22 | } 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/guards/authentication.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async, inject } from '@angular/core/testing'; 2 | import { HttpClientTestingModule } from '@angular/common/http/testing'; 3 | 4 | import { AuthenticationGuard } from './authentication.guard'; 5 | import { AuthService } from '../global/auth.service'; 6 | import { ServicesService } from '../global/services.service'; 7 | import { ConfigService } from '../global/config.service'; 8 | 9 | describe('AuthenticationGuard', () => { 10 | beforeEach(() => { 11 | TestBed.configureTestingModule({ 12 | imports: [HttpClientTestingModule], 13 | providers: [ 14 | AuthenticationGuard, 15 | ServicesService, 16 | ConfigService, 17 | { 18 | provide: 'IAuthService', 19 | useClass: AuthService 20 | } 21 | ] 22 | }); 23 | }); 24 | 25 | it('should ...', inject([AuthenticationGuard], (guard: AuthenticationGuard) => { 26 | expect(guard).toBeTruthy(); 27 | })); 28 | }); 29 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/auth.service.mock.ts: -------------------------------------------------------------------------------- 1 | import { IAuthService } from '../global/auth.service'; 2 | import { UserManager, User } from 'oidc-client'; 3 | 4 | export class MockAuthService implements IAuthService { 5 | userManager: UserManager; 6 | identityClientSettings: any; 7 | clientId: string; 8 | authority: string; 9 | 10 | initialize(): Promise{ 11 | return new Promise((resolve) =>{ 12 | resolve(true); 13 | }) 14 | } 15 | 16 | login(){ 17 | return; 18 | } 19 | 20 | logout(){ 21 | return 22 | } 23 | 24 | handleSigninRedirectCallback(){ 25 | return; 26 | } 27 | 28 | getUser(): Promise{ 29 | const user = {}; 30 | user.profile = {"sub": ''}; 31 | return new Promise((resolve) =>{ 32 | resolve(user); 33 | }); 34 | } 35 | 36 | isUserAuthenticated(): Promise { 37 | return new Promise((resolve) =>{ 38 | resolve(true); 39 | }) 40 | } 41 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/interceptors/fabric-http-error-handler-interceptor.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { FabricHttpErrorHandlerInterceptorService } from './fabric-http-error-handler-interceptor.service'; 4 | import { AlertService } from '../global/alert.service'; 5 | import { ToasterModule } from '@healthcatalyst/cashmere'; 6 | import { OverlayModule } from '@angular/cdk/overlay'; 7 | 8 | describe('FabricHttpErrorHandlerInterceptorService', () => { 9 | beforeEach(() => { 10 | TestBed.configureTestingModule({ 11 | imports: [ToasterModule, OverlayModule], 12 | providers: [ 13 | FabricHttpErrorHandlerInterceptorService, 14 | AlertService 15 | ] 16 | }); 17 | }); 18 | 19 | it( 20 | 'should be created', 21 | inject( 22 | [FabricHttpErrorHandlerInterceptorService], 23 | (service: FabricHttpErrorHandlerInterceptorService) => { 24 | expect(service).toBeTruthy(); 25 | } 26 | ) 27 | ); 28 | }); 29 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Stores/CouchDBClientStore.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Fabric.Authorization.Domain.Models; 3 | using Fabric.Authorization.Domain.Services; 4 | using Fabric.Authorization.Domain.Stores; 5 | using Fabric.Authorization.Persistence.CouchDb.Services; 6 | using Serilog; 7 | 8 | namespace Fabric.Authorization.Persistence.CouchDb.Stores 9 | { 10 | public class CouchDbClientStore : CouchDbGenericStore, IClientStore 11 | { 12 | public CouchDbClientStore(IDocumentDbService dbService, ILogger logger, 13 | IEventContextResolverService eventContextResolverService) : base(dbService, logger, 14 | eventContextResolverService) 15 | { 16 | } 17 | 18 | public override async Task Add(Client client) 19 | { 20 | return await Add(client.Id, client); 21 | } 22 | 23 | public override async Task Delete(Client client) 24 | { 25 | await Delete(client.Id, client); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/DependencyInjection/InMemoryConfigurator.cs: -------------------------------------------------------------------------------- 1 | using Fabric.Authorization.API.Configuration; 2 | using Fabric.Authorization.Persistence.SqlServer.Services; 3 | using Fabric.Authorization.Persistence.SqlServer.Stores.EDW; 4 | using Nancy.TinyIoc; 5 | using System; 6 | 7 | namespace Fabric.Authorization.API.DependencyInjection 8 | { 9 | public class InMemoryConfigurator : BaseSqlServerConfigurator 10 | { 11 | public InMemoryConfigurator(IAppConfiguration appConfiguration) : base(appConfiguration) 12 | { 13 | } 14 | 15 | protected override TinyIoCContainer.RegisterOptions RegisterDatabaseContext(TinyIoCContainer container) 16 | { 17 | return container.Register(); 18 | } 19 | 20 | protected override TinyIoCContainer.RegisterOptions RegisterEDWDatabaseContext(TinyIoCContainer container) 21 | { 22 | return container.Register(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/global/initializer.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { InitializerService } from './initializer.service'; 4 | import { IAuthService } from './auth.service'; 5 | import { MockAuthService } from './auth.service.mock'; 6 | import { ServicesService } from './services.service'; 7 | import { HttpClientTestingModule } from '@angular/common/http/testing'; 8 | import { ConfigService } from './config.service'; 9 | 10 | describe('InitializerService', () => { 11 | beforeEach(() => { 12 | TestBed.configureTestingModule({ 13 | imports: [HttpClientTestingModule], 14 | providers: [InitializerService, 15 | ServicesService, 16 | ConfigService, 17 | { 18 | provide: 'IAuthService', 19 | useClass: MockAuthService 20 | } 21 | ] 22 | }); 23 | }); 24 | 25 | it('should be created', inject([InitializerService], (service: InitializerService) => { 26 | expect(service).toBeTruthy(); 27 | })); 28 | }); 29 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client/Routes/ClientRoute.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client.Routes 2 | { 3 | internal class ClientRoute : BaseRoute 4 | { 5 | protected override string CollectionType { get; } = RouteConstants.ClientCollectionRoute; 6 | 7 | public string ClientId { get; set; } 8 | 9 | public override string ToString() 10 | { 11 | return !string.IsNullOrEmpty(ClientId) 12 | ? $"{BaseRouteSegment}/{ClientId}" 13 | : $"{BaseRouteSegment}"; 14 | } 15 | } 16 | 17 | internal class ClientRouteBuilder 18 | { 19 | private readonly ClientRoute _clientRoute; 20 | 21 | public ClientRouteBuilder() 22 | { 23 | _clientRoute = new ClientRoute(); 24 | } 25 | 26 | public ClientRouteBuilder ClientId(string clientId) 27 | { 28 | _clientRoute.ClientId = clientId; 29 | return this; 30 | } 31 | 32 | public string Route => _clientRoute.ToString(); 33 | } 34 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Services/GrainService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Fabric.Authorization.Domain.Models; 5 | using Fabric.Authorization.Domain.Stores; 6 | 7 | namespace Fabric.Authorization.Domain.Services 8 | { 9 | public class GrainService 10 | { 11 | private readonly IGrainStore _grainStore; 12 | 13 | public GrainService(IGrainStore grainStore) 14 | { 15 | _grainStore = grainStore ?? throw new ArgumentNullException(nameof(grainStore)); 16 | } 17 | 18 | public async Task GetGrain(string name) 19 | { 20 | return await _grainStore.Get(name); 21 | } 22 | 23 | public async Task> GetAllGrains() 24 | { 25 | return await _grainStore.GetAll(); 26 | } 27 | 28 | public async Task> GetSharedGrains() 29 | { 30 | return await _grainStore.GetSharedGrains(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docker-compose.dcproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2112edde-e830-4e0a-af00-4a211772fd32 5 | True 6 | http://localhost:{ServicePort} 7 | fabric.authorization.api 8 | Linux 9 | 2.2 10 | 11 | 12 | 13 | 14 | docker-compose.yml 15 | 16 | 17 | docker-compose.yml 18 | 19 | 20 | docker-compose.yml 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/browser-requirements.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class BrowserRequirementsService { 8 | 9 | constructor() { } 10 | 11 | cookiesEnabled(): boolean { 12 | const userAgent = window.navigator.userAgent; 13 | const isIE = (userAgent.indexOf('MSIE') > -1 || userAgent.indexOf('Trident') > -1); 14 | if (isIE && document.cookie && document.cookie.length > 0) { 15 | return true; 16 | } else if (isIE === false && typeof navigator.cookieEnabled !== 'undefined' && navigator.cookieEnabled) { 17 | return true; 18 | } 19 | if (!document.cookie || document.cookie === '') { 20 | const originalCookieValue = document.cookie; 21 | document.cookie = 'testCookie'; 22 | const testCookieMatched = (document.cookie.indexOf('testCookie') !== -1); 23 | document.cookie = originalCookieValue; 24 | return testCookieMatched; 25 | } 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/Services/GroupSearchService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Fabric.Authorization.API.RemoteServices.Identity.Models; 3 | using Fabric.Authorization.API.RemoteServices.Identity.Providers; 4 | 5 | namespace Fabric.Authorization.API.Services 6 | { 7 | public class GroupSearchService 8 | { 9 | private readonly IIdentityServiceProvider _identitySearchProvider; 10 | 11 | public GroupSearchService(IIdentityServiceProvider identitySearchProvider) 12 | { 13 | _identitySearchProvider = identitySearchProvider; 14 | } 15 | 16 | public async Task GetGroupAsync(string identityProvider, string groupName, string tenantId = null) 17 | { 18 | var result = await _identitySearchProvider.SearchGroupAsync(new GroupSearchRequest 19 | { 20 | IdentityProvider = identityProvider, 21 | TenantId = tenantId, 22 | DisplayName = groupName 23 | }); 24 | 25 | return result; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/add-docs-to-github-repo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Cloning Git Wiki repo..." 4 | REPO="https://$1@github.com/HealthCatalyst/Fabric.Authorization.wiki.git" 5 | git clone $REPO 6 | 7 | echo "Moving MD files to Fabric.Authorization.wiki..." 8 | mv overview.md API-Reference-Overview.md 9 | mv paths.md API-Reference-Resources.md 10 | mv definitions.md API-Reference-Models.md 11 | mv security.md API-Reference-Security.md 12 | 13 | sed -i 's/overview.md/API-Reference-Overview/g' *.md 14 | sed -i 's/paths.md/API-Reference-Resources/g' *.md 15 | sed -i 's/definitions.md/API-Reference-Models/g' *.md 16 | sed -i 's/security.md/API-Reference-Security/g' *.md 17 | 18 | mv *.md Fabric.Authorization.wiki 19 | 20 | echo "Changing directory..." 21 | cd Fabric.Authorization.wiki 22 | 23 | echo "-----Present directory = $(pwd)-----" 24 | 25 | git config user.name "HealthCatalystDevTest" 26 | git config user.email "testIdPHC@gmail.com" 27 | git add *.md 28 | 29 | echo "committing files" 30 | git commit -m 'update API documentation' 31 | echo "pushing files to github" 32 | git push origin master -------------------------------------------------------------------------------- /Fabric.Authorization.Domain/Models/GranularPermission.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Fabric.Authorization.Domain.Models 5 | { 6 | public class GranularPermission : ITrackable, ISoftDelete, IIdentifiable 7 | { 8 | public GranularPermission() 9 | { 10 | DeniedPermissions = new List(); 11 | AdditionalPermissions = new List(); 12 | } 13 | 14 | public string Id { get; set; } 15 | 16 | public IEnumerable DeniedPermissions { get; set; } 17 | 18 | public IEnumerable AdditionalPermissions { get; set; } 19 | 20 | public bool IsDeleted { get; set; } 21 | 22 | public DateTime CreatedDateTimeUtc { get; set; } 23 | 24 | public DateTime? ModifiedDateTimeUtc { get; set; } 25 | 26 | public string CreatedBy { get; set; } 27 | 28 | public string ModifiedBy { get; set; } 29 | 30 | public override string ToString() 31 | { 32 | return $"{Id}"; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Events/CouchDbEventWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Domain.Events; 4 | using Fabric.Authorization.Persistence.CouchDb.Services; 5 | 6 | namespace Fabric.Authorization.Persistence.CouchDb.Events 7 | { 8 | public class CouchDbEventWriter : IEventWriter 9 | { 10 | private readonly IDocumentDbService _documentDbService; 11 | private readonly IEventWriter _innerEventWriter; 12 | public CouchDbEventWriter(IDocumentDbService documentDbService, IEventWriter innerEventWriter) 13 | { 14 | _documentDbService = documentDbService ?? throw new ArgumentNullException(nameof(documentDbService)); 15 | _innerEventWriter = innerEventWriter ?? throw new ArgumentNullException(nameof(innerEventWriter)); 16 | } 17 | public async Task WriteEvent(Event evt) 18 | { 19 | await _innerEventWriter.WriteEvent(evt); 20 | await _documentDbService.AddDocument(Guid.NewGuid().ToString(), evt).ConfigureAwait(false); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Stores/CouchDbGrainStore.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Fabric.Authorization.Domain.Models; 5 | using Fabric.Authorization.Domain.Stores; 6 | 7 | namespace Fabric.Authorization.Persistence.CouchDb.Stores 8 | { 9 | public class CouchDbGrainStore : IGrainStore 10 | { 11 | public Task Get(string name) 12 | { 13 | // this allows for backward compatibility with CouchDb backed versions. 14 | // this implementation will be removed once we convert clients over to the sql server backed version. 15 | return Task.FromResult(default(Grain)); 16 | } 17 | 18 | public Task> GetSharedGrains() 19 | { 20 | // this allows for backward compatibility with CouchDb backed versions. 21 | // this implementation will be removed once we convert clients over to the sql server backed version. 22 | return Task.FromResult(new List().AsEnumerable()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Fabric.Authorization.Persistence.CouchDb/Services/IDocumentDbService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Fabric.Authorization.Persistence.CouchDb.Stores; 4 | 5 | namespace Fabric.Authorization.Persistence.CouchDb.Services 6 | { 7 | public interface IDocumentDbService 8 | { 9 | Task GetDocument(string documentId); 10 | 11 | Task> GetDocuments(string documentType); 12 | 13 | Task GetDocumentCount(string documentType); 14 | 15 | Task AddDocument(string documentId, T documentObject); 16 | 17 | Task UpdateDocument(string documentId, T documentObject); 18 | 19 | Task DeleteDocument(string documentId); 20 | 21 | Task AddViews(string documentId, CouchDbViews views); 22 | 23 | Task> GetDocuments(string designdoc, string viewName, Dictionary customParams); 24 | 25 | Task> GetDocuments(string designdoc, string viewName, string customParams); 26 | 27 | Task Initialize(); 28 | 29 | Task SetupDefaultUser(); 30 | } 31 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/RemoteServices/Identity/Models/UserSearchResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | 5 | namespace Fabric.Authorization.API.RemoteServices.Identity.Models 6 | { 7 | /// 8 | /// Represents the response from Fabric.Identity when searching for user(s) by 9 | /// 1 or more subject IDs. 10 | /// 11 | public class UserSearchResponse 12 | { 13 | public string SubjectId { get; set; } 14 | public DateTime? LastLoginDate { get; set; } 15 | public string FirstName { get; set; } 16 | public string MiddleName { get; set; } 17 | public string LastName { get; set; } 18 | 19 | public override string ToString() 20 | { 21 | return $"SubjectId={SubjectId}, FirstName={FirstName}, MiddleName={MiddleName}, LastName={LastName}, LastLoginDateTimeUtc={LastLoginDate}"; 22 | } 23 | } 24 | 25 | public class FabricIdentityUserResponse 26 | { 27 | public HttpStatusCode HttpStatusCode { get; set; } 28 | public IEnumerable Results { get; set; } 29 | } 30 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/interceptors/index.ts: -------------------------------------------------------------------------------- 1 | /* "Barrel" of Http Interceptors */ 2 | import { HTTP_INTERCEPTORS } from '@angular/common/http'; 3 | import { FabricHttpRequestInterceptorService } from './fabric-http-request-interceptor.service'; 4 | import { FabricHttpErrorHandlerInterceptorService } from './fabric-http-error-handler-interceptor.service'; 5 | import { FabricHttpFakeDiscoveryInterceptorService } from './fabric-http-fake-discovery-interceptor.service'; 6 | import { environment } from '../../../environments/environment' 7 | 8 | /** Http interceptor providers in outside-in order */ 9 | export const httpInterceptorProviders = []; 10 | if (!environment.production) { 11 | httpInterceptorProviders.push({ 12 | provide: HTTP_INTERCEPTORS, 13 | useClass: FabricHttpFakeDiscoveryInterceptorService, 14 | multi: true 15 | }); 16 | } 17 | httpInterceptorProviders.push({ 18 | provide: HTTP_INTERCEPTORS, 19 | useClass: FabricHttpRequestInterceptorService, 20 | multi: true 21 | }); 22 | httpInterceptorProviders.push({ 23 | provide: HTTP_INTERCEPTORS, 24 | useClass: FabricHttpErrorHandlerInterceptorService, 25 | multi: true 26 | }); 27 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/e2e/pages/member-list.page.ts: -------------------------------------------------------------------------------- 1 | import { browser, protractor, element, by } from 'protractor'; 2 | import { tellNgZoneItHasNoPendingMacroTasks } from '../hacks'; 3 | import { MemberPage } from './member.page'; 4 | 5 | export class MemberListPage { 6 | async getMemberListPage() { 7 | await browser.get(browser.baseUrl); 8 | await tellNgZoneItHasNoPendingMacroTasks(); 9 | } 10 | 11 | getAddButton() { return element(by.buttonText('Add')); } 12 | 13 | async navigateToMemberPage() { 14 | const until = protractor.ExpectedConditions; 15 | const addButton = this.getAddButton(); 16 | await browser 17 | .wait(until.presenceOf(addButton), browser.allScriptsTimeout, 'Add button on main page was not found'); // wait until loaded... 18 | await addButton.click(); 19 | 20 | const userGroupLink = element(by.linkText('Directory Group or User')); 21 | await browser 22 | .wait(until.presenceOf(userGroupLink), browser.allScriptsTimeout, 'Link to member page was not found'); 23 | await userGroupLink.click(); 24 | return new MemberPage(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/modules/access-control/grain-list/grain-list.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{node.name}} 7 | 8 | 9 | {{node.name}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Client/Routes/SecurableItemRoute.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Client.Routes 2 | { 3 | internal class SecurableItemRoute : BaseRoute 4 | { 5 | protected override string CollectionType { get; } = RouteConstants.SecurableItemCollectionRoute; 6 | 7 | public string SecurableItemId { get; set; } 8 | 9 | public override string ToString() 10 | { 11 | return !string.IsNullOrEmpty(SecurableItemId) 12 | ? $"{BaseRouteSegment}/{SecurableItemId}" 13 | : BaseRouteSegment; 14 | } 15 | } 16 | 17 | internal class SecurableItemRouteBuilder 18 | { 19 | private readonly SecurableItemRoute _securableItemRoute; 20 | 21 | public SecurableItemRouteBuilder() 22 | { 23 | _securableItemRoute = new SecurableItemRoute(); 24 | } 25 | 26 | public SecurableItemRouteBuilder SecurableItemId(string securableItemId) 27 | { 28 | _securableItemRoute.SecurableItemId = securableItemId; 29 | return this; 30 | } 31 | 32 | public string Route => _securableItemRoute.ToString(); 33 | } 34 | } -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/styles.scss: -------------------------------------------------------------------------------- 1 | $fa-font-path: '../node_modules/font-awesome/fonts'; 2 | @import '../node_modules/font-awesome/scss/font-awesome'; 3 | 4 | $FontPathOpenSans: "../node_modules/typeface-open-sans/files"; 5 | @import '../node_modules/typeface-open-sans/index.css'; 6 | 7 | @import "~@healthcatalyst/cashmere/scss/cashmere"; 8 | 9 | /////////// #TODO: Fix Cashmere in IE 10 | input.hc-input, div.input-icon { 11 | height: 35px !important; 12 | width: 375px !important; 13 | } 14 | .hc-input{ 15 | color: #333; 16 | font-size: 1rem; 17 | line-height: 32px; 18 | border: 1.5px solid #ccc; 19 | font-family: inherit; 20 | padding: 0 12px; 21 | } 22 | hc-icon.filter { 23 | color: #a1a1a1; 24 | position: relative; 25 | right: 35px; 26 | pointer-events: none; 27 | } 28 | .hc-inner-button, .hc-left-button, .hc-right-button { 29 | min-width: 15px !important; 30 | } 31 | .spinner { 32 | z-index: 20000; 33 | } 34 | /////////// #endtodo 35 | body { 36 | font-family: "Open Sans", sans-serif; 37 | margin: 0; 38 | background-color: $slate-gray-100; 39 | } 40 | 41 | button { 42 | // ie reset for default button color 43 | background-color: #DCDCDC; 44 | } 45 | -------------------------------------------------------------------------------- /Fabric.Authorization.UnitTests/Groups/GroupValidatorTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Xunit; 3 | 4 | namespace Fabric.Authorization.UnitTests.Groups 5 | { 6 | public class GroupValidatorTests 7 | { 8 | [Theory, MemberData(nameof(GroupRequestData))] 9 | public void GroupValidator_ValidateGroup_ReturnsInvalidIfModelNotValid(string grain, string securableItem, string groupName, int errorCount) 10 | { 11 | // To be implemented 12 | } 13 | 14 | [Fact] 15 | public void GroupValidator_ValidateGroup_ReturnsValid() 16 | { 17 | // To be implemented 18 | } 19 | 20 | public static IEnumerable GroupRequestData => new[] 21 | { 22 | new object[] { "app", "patientsafety", "", 1}, 23 | new object[] {"app", "", "", 2}, 24 | new object[] {"", "", "", 3}, 25 | new object[] {"app", "patientsafety", null, 1}, 26 | new object[] {"app", null, null, 2}, 27 | new object[] {null, null, null, 3}, 28 | new object[] {"app", "patientsafety", "admin", 1} 29 | }; 30 | } 31 | } -------------------------------------------------------------------------------- /Catalyst.Fabric.Authorization.Models/Requests/GroupApiRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Catalyst.Fabric.Authorization.Models.Requests 2 | { 3 | public class GroupIdentifierApiRequest 4 | { 5 | public string GroupName { get; set; } 6 | public string TenantId { get; set; } 7 | public string IdentityProvider { get; set; } 8 | 9 | public override string ToString() 10 | { 11 | return $"IdP = {IdentityProvider}, TenantId = {TenantId}, GroupName = {GroupName}"; 12 | } 13 | } 14 | 15 | public class GroupPostApiRequest : GroupPatchApiRequest 16 | { 17 | public string GroupName { get; set; } 18 | public string IdentityProvider { get; set; } 19 | public string GroupSource { get; set; } 20 | public string TenantId { get; set; } 21 | public string ExternalIdentifier { get; set; } 22 | } 23 | 24 | public class GroupPatchApiRequest 25 | { 26 | public string DisplayName { get; set; } 27 | public string Description { get; set; } 28 | } 29 | 30 | public class GroupSearchApiRequest 31 | { 32 | public string Name { get; set; } 33 | public string Type { get; set; } 34 | } 35 | } -------------------------------------------------------------------------------- /Fabric.Authorization.API/Documentation/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' } 5 | } 6 | 7 | dependencies { 8 | classpath 'io.github.swagger2markup:swagger2markup-gradle-plugin:1.3.1' 9 | } 10 | } 11 | 12 | apply plugin: 'io.github.swagger2markup' 13 | 14 | 15 | convertSwagger2markup { 16 | 17 | def url = "${System.env.FABRICAUTHORIZATIONBASEURL}" 18 | if (url?.trim()) { 19 | logger.info("----------HOST NAME = ${url}----------") 20 | swaggerInput "${url}/swagger/ui/swagger.json" 21 | } 22 | else { 23 | throw new GradleException("FABRICAUTHORIZATIONBASEURL environment variable is required.") 24 | } 25 | 26 | def dir = "${System.env.AUTHORIZATIONMARKDOWNDIRECTORY}" 27 | if (!dir?.trim()) { 28 | dir = "${buildDir}/markdown" 29 | } 30 | 31 | logger.info("----------OUTPUT DIR = ${dir}----------") 32 | outputDir file(dir) 33 | 34 | config = ['swagger2markup.markupLanguage' : 'MARKDOWN', 35 | 'swagger2markup.pathsGroupedBy' : 'TAGS', 36 | 'swagger2markup.interDocumentCrossReferencesEnabled' : true] 37 | } 38 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/no-cookies/no-cookies.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import {RouterTestingModule} from '@angular/router/testing'; 3 | import { NavbarModule, PopModule, IconModule, ModalModule, AppSwitcherModule } from '@healthcatalyst/cashmere'; 4 | import { MockAppSwitcherConfig } from '../test/app-switcher-config.mock'; 5 | import { NoCookiesComponent } from './no-cookies.component'; 6 | 7 | describe('NoCookiesComponent', () => { 8 | let component: NoCookiesComponent; 9 | let fixture: ComponentFixture; 10 | 11 | beforeEach(async(() => { 12 | TestBed.configureTestingModule({ 13 | declarations: [ NoCookiesComponent ], 14 | imports: [RouterTestingModule, NavbarModule, PopModule, IconModule, ModalModule, AppSwitcherModule], 15 | providers: [MockAppSwitcherConfig] 16 | }) 17 | .compileComponents(); 18 | })); 19 | 20 | beforeEach(() => { 21 | fixture = TestBed.createComponent(NoCookiesComponent); 22 | component = fixture.componentInstance; 23 | fixture.detectChanges(); 24 | }); 25 | 26 | it('should create', () => { 27 | expect(component).toBeTruthy(); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /Fabric.Authorization.API/scripts/create-nuspec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | version=$1 3 | artifactPath=$2 4 | echo "current directory: ${PWD}" 5 | echo "version set to: $version" 6 | echo "path to artifacts: $artifactPath" 7 | cat > Fabric.Authorization.API.nuspec << EOF 8 | 9 | 10 | 11 | 12 | Fabric.Authorization.InstallPackage 13 | $version 14 | Health Catalyst 15 | Health Catalyst 16 | false 17 | Install package for Fabric.Authorization 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | EOF 27 | -------------------------------------------------------------------------------- /Fabric.Authorization.AccessControl/src/app/services/interceptors/fabric-http-request-interceptor.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | import { 3 | HttpHandler, 4 | HttpClient } from '@angular/common/http'; 5 | import { FabricHttpRequestInterceptorService } from './fabric-http-request-interceptor.service'; 6 | import { AuthService } from '../global/auth.service'; 7 | import { ServicesService } from '../global/services.service'; 8 | import { ConfigService } from '../global/config.service'; 9 | 10 | describe('FabricHttpRequestInterceptorService', () => { 11 | beforeEach(() => { 12 | TestBed.configureTestingModule({ 13 | providers: [ 14 | FabricHttpRequestInterceptorService, 15 | HttpClient, 16 | HttpHandler, 17 | ServicesService, 18 | ConfigService, 19 | { 20 | provide: 'IAuthService', 21 | useClass: AuthService 22 | } 23 | ] 24 | }); 25 | }); 26 | 27 | it( 28 | 'should be created', 29 | inject( 30 | [FabricHttpRequestInterceptorService], 31 | (service: FabricHttpRequestInterceptorService) => { 32 | expect(service).toBeTruthy(); 33 | } 34 | ) 35 | ); 36 | }); 37 | --------------------------------------------------------------------------------