From 4f2e494e5f3a29fadd73c59d63a3c6b320ccf8f2 Mon Sep 17 00:00:00 2001 From: Thulio Bittencourt Date: Wed, 7 Apr 2021 19:04:55 -0300 Subject: [PATCH] Initial Commit --- README.md | 24 +- RbacProjectGroup.groupproj | 48 + Safety4Delphi.dpk | 37 + Safety4Delphi.dproj | 846 ++++++++++++++++ Safety4Delphi.res | Bin 0 -> 664 bytes assets/logo.fw.png | Bin 0 -> 106972 bytes samples/RbacSample.dpr | 15 + samples/RbacSample.dproj | 922 ++++++++++++++++++ samples/RbacSample.res | Bin 0 -> 112124 bytes samples/Unit1.dfm | 120 +++ samples/Unit1.pas | 317 ++++++ src/Safety4D.Groups.Actions.pas | 61 ++ src/Safety4D.Groups.ListActions.pas | 98 ++ src/Safety4D.Groups.NotActions.pas | 61 ++ src/Safety4D.Groups.Register.pas | 116 +++ src/Safety4D.Groups.pas | 116 +++ src/Safety4D.Interfaces.pas | 178 ++++ ...D.Resources.Group.Provider.Actions.Msg.pas | 74 ++ ...ety4D.Resources.Group.Provider.Actions.pas | 66 ++ src/Safety4D.Resources.Group.Provider.pas | 79 ++ src/Safety4D.Resources.Group.pas | 73 ++ src/Safety4D.Resources.Register.pas | 65 ++ src/Safety4D.Resources.pas | 110 +++ ...ety4D.UserKey.Register.PermissionGroup.pas | 77 ++ src/Safety4D.UserKey.Register.pas | 74 ++ src/Safety4D.UserKey.pas | 99 ++ src/Safety4D.Validation.pas | 154 +++ src/Safety4D.pas | 262 +++++ 28 files changed, 4090 insertions(+), 2 deletions(-) create mode 100644 RbacProjectGroup.groupproj create mode 100644 Safety4Delphi.dpk create mode 100644 Safety4Delphi.dproj create mode 100644 Safety4Delphi.res create mode 100644 assets/logo.fw.png create mode 100644 samples/RbacSample.dpr create mode 100644 samples/RbacSample.dproj create mode 100644 samples/RbacSample.res create mode 100644 samples/Unit1.dfm create mode 100644 samples/Unit1.pas create mode 100644 src/Safety4D.Groups.Actions.pas create mode 100644 src/Safety4D.Groups.ListActions.pas create mode 100644 src/Safety4D.Groups.NotActions.pas create mode 100644 src/Safety4D.Groups.Register.pas create mode 100644 src/Safety4D.Groups.pas create mode 100644 src/Safety4D.Interfaces.pas create mode 100644 src/Safety4D.Resources.Group.Provider.Actions.Msg.pas create mode 100644 src/Safety4D.Resources.Group.Provider.Actions.pas create mode 100644 src/Safety4D.Resources.Group.Provider.pas create mode 100644 src/Safety4D.Resources.Group.pas create mode 100644 src/Safety4D.Resources.Register.pas create mode 100644 src/Safety4D.Resources.pas create mode 100644 src/Safety4D.UserKey.Register.PermissionGroup.pas create mode 100644 src/Safety4D.UserKey.Register.pas create mode 100644 src/Safety4D.UserKey.pas create mode 100644 src/Safety4D.Validation.pas create mode 100644 src/Safety4D.pas diff --git a/README.md b/README.md index ac5e74d..237c522 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,22 @@ -# safety4d -Application Rules Management Framework inspired by the RBAC concept +

+ + router4d + +

+
+

+ + + + + + + +

+ +# Router4Delphi +Framework para Controle de Regras de Acesso do Usuários inspirado no conceito RBAC. + +## Instalação + +Basta registrar no Library Path do seu Delphi o caminho da pasta SRC da Biblioteca \ No newline at end of file diff --git a/RbacProjectGroup.groupproj b/RbacProjectGroup.groupproj new file mode 100644 index 0000000..bc04a61 --- /dev/null +++ b/RbacProjectGroup.groupproj @@ -0,0 +1,48 @@ + + + {828C2011-D2F0-4E90-9828-5C6F0E3E803D} + + + + + + + + + + + Default.Personality.12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Safety4Delphi.dpk b/Safety4Delphi.dpk new file mode 100644 index 0000000..e19f28d --- /dev/null +++ b/Safety4Delphi.dpk @@ -0,0 +1,37 @@ +package Safety4Delphi; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$ENDIF IMPLICITBUILDING} +{$IMPLICITBUILD ON} + +requires + rtl; + +contains + Rbac4D in 'src\Rbac4D.pas', + Rbac4D.Interfaces in 'src\Rbac4D.Interfaces.pas'; + +end. diff --git a/Safety4Delphi.dproj b/Safety4Delphi.dproj new file mode 100644 index 0000000..1c49582 --- /dev/null +++ b/Safety4Delphi.dproj @@ -0,0 +1,846 @@ + + + {76E3723F-A2C6-4C46-B750-A446551153AE} + Safety4Delphi.dpk + 19.2 + None + True + Debug + Win32 + 1 + Package + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + true + true + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + All + Safety4Delphi + + + None + + + None + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + Safety4Delphi.dpk + + + + + + true + + + + + true + + + + + true + + + + + Safety4Delphi.bpl + true + + + + + 1 + + + 0 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + False + False + True + False + + + 12 + + + + + diff --git a/Safety4Delphi.res b/Safety4Delphi.res new file mode 100644 index 0000000000000000000000000000000000000000..172924ecf1f9da6d70d7daa08f69b79ae91424bd GIT binary patch literal 664 zcmaiy%}T>i5QR@l7S@Hh>`Gj?mKL%R3Q~wl!9Uti+(~Vt2GX>|3i@!qjeFm~_}z(@ z{w(yu+)iiCoSd0El5~hwRc*K%r`7QJeK3LL+G>U#)M`YyBMo)WeWn3kUpKnuf1mpt z-<^-}>sxa5HHZH_wXEa_edaf$Hv$2COO?u0=n1w=xl))5J!%dxF-%*L+B(4^G&n`E z_Nevvn3@+&jAsE~Mr~oA8EOnuO6;9Fhs(9lGYG-9v&JzZSHiNY?dTYcH|b6X;BP_A z(OSYhLuqW^nGlCX$0(pJ_Av3|Sj>v8vi-BA4nZv0WJG3a`hWT<}r}eb;Aw Ir`#U=0AJc#&Hw-a literal 0 HcmV?d00001 diff --git a/assets/logo.fw.png b/assets/logo.fw.png new file mode 100644 index 0000000000000000000000000000000000000000..2f26e01ff9a49a6dab65e2d6d6cc23adbe38c9b1 GIT binary patch literal 106972 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 + + {94E1E924-4B2D-49BF-9361-D6402259FADC} + 19.2 + VCL + True + Debug + Win32 + 1 + Application + RbacSample.dpr + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + RbacSample + + + DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;bindcompvclsmp;emsclientfiredac;tethering;svnui;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;inetdb;CEF4Delphi;emsedge;fmx;FireDACIBDriver;fmxdae;vcledge;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;TBGWebCharts;IndySystem;FireDACDb2Driver;bindcompvclwinx;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;bindcompvclsmp;emsclientfiredac;tethering;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;DBXOracleDriver;inetdb;CEF4Delphi;emsedge;fmx;FireDACIBDriver;fmxdae;vcledge;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;bindcompvclwinx;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + true + PerMonitorV2 + D:\Projetos\Componentes\RBAC4D\src;$(DCC_UnitSearchPath) + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + true + PerMonitorV2 + + + + MainSource + + +
Form1
+ dfm +
+ + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + Delphi.Personality.12 + Application + + + + RbacSample.dpr + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + CEF4Delphi + + + + + + RbacSample.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + True + False + + + 12 + + + + + diff --git a/samples/RbacSample.res b/samples/RbacSample.res new file mode 100644 index 0000000000000000000000000000000000000000..3eafdff9e216cb5d92bbb56509bad695fdacf7cf GIT binary patch literal 112124 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 + + + + + //Buscar grupo de permissões + TRbac4D + .New + .getFunctionDefinitions; //TArray + + + //Busar Resources + TRbac4D + .New + .getResourcesGroup('GroupName'); //TArray + + + //Como validar o acesso a um recurso + TRbac4D + .New + .validateAccess + .roleName('operador') + .group('housex') + .provider('user') + .resource('Actions.getSaldo') + .Execute; //Boolean + + + //Atribuir as Roles na instancia global + TRbac4D + .New + .roleName('operador|marketing|gerente'); + + + TRbac4D + .New + .loadConfiguration(aJsonString); + + TRbac4D + .New + .saveConfiguration; //Retorna JsonString; + + *} +end; + +procedure TForm1.Button1Click(Sender: TObject); +begin + TSafety4D + .New + .groupPermission + .groupRegister + .add('Gerente') + .description('Permissões completa de gestão do Sistema') + .actions + .add('*') + .&end + .notActions + .add('users.delete') + .add('users.write') + .&end + .&end + + .groupRegister + .add('Comercial') + .description('Permissões de Recursos Comerciais') + .actions + .add('*') + .&end + .notActions + .add('users.delete') + .add('users.write') + .&end + .&end + .&end; +end; + +procedure TForm1.Button2Click(Sender: TObject); +begin + TSafety4D + .New + .userKey + .registerUserKey + .Add('Fulano de Tal') + .addPermission('Gerente') + .&end + .Add('Beltrano') + .addPermission('Comercial') + .&end + .&end + .&end; + + _GetUserKeys; +end; + +procedure TForm1.Button3Click(Sender: TObject); +var + aJsonSafety4D : TJsonObject; +begin + aJsonSafety4D := TJSONObject.Create; + try + TSafety4D.New.getConfig(aJsonSafety4D); + + Memo1.Lines.Clear; + Memo1.Lines.Add(TJson.Format(aJsonSafety4D)); + finally + aJsonSafety4D.Free; + end; + +end; + +procedure TForm1.Button4Click(Sender: TObject); +begin + RegisterResources; +end; + +procedure TForm1.Button5Click(Sender: TObject); +begin + TSafety4D.New.SaveToStorage(); +end; + +procedure TForm1.Button6Click(Sender: TObject); +var + JSONValue : TJsonValue; + LFileName: string; +begin + LFileName := ChangeFileExt(ParamStr(0), '.s4d'); + JSONValue := TJSONObject.ParseJSONValue(TFile.ReadAllText(LFileName)); + try + TSafety4D.New.LoadConfig(JSONValue as TJSONObject); + finally + JSONValue.Free; + end; +end; + +procedure TForm1.Button7Click(Sender: TObject); +begin + _GetGroupsPermissions; +end; + +procedure TForm1.Button8Click(Sender: TObject); +begin + try + TSafety4D.New + .Validation + .userKey('{34C940ED-50E7-4CE3-B701-03CF1E15F28B}') + .application('delphitohero') + .resource('users') + .action(edit1.Text) + .validate; + ShowMessage('Usuario Autorizado'); + except on e : Exception do + raise Exception.Create(e.Message); + end; +end; + +procedure TForm1.RegisterResources; +begin + TSafety4D + .New + .resources + .registerResources + .resourcesGroupName + .add('delphitohero') + .providerName + .add('users') + .actions + .add('read') + .description('read-only') + .errormsg('not permit') + .&end + .add('write') + .description('read-write') + .errormsg('not write data') + .&end + .add('delete') + .description('delete-data') + .errormsg('not delete data') + .&end + .add('view') + .description('view data') + .errormsg('not view data') + .&end + .&end + .&end + .&end + .&end + .&end; +end; + +end. diff --git a/src/Safety4D.Groups.Actions.pas b/src/Safety4D.Groups.Actions.pas new file mode 100644 index 0000000..72046e6 --- /dev/null +++ b/src/Safety4D.Groups.Actions.pas @@ -0,0 +1,61 @@ +unit Safety4D.Groups.Actions; + +interface + +uses + System.Generics.Collections, + Safety4D.Interfaces; + +type + TSafety4DGroupActions = class(TInterfacedObject, iSafety4DGroupActions) + private + [weak] + FParent : iSafety4DGroupRegister; + FList : TList; + public + constructor Create(aParent : iSafety4DGroupRegister); + destructor Destroy; override; + class function New(aParent : iSafety4DGroupRegister) : iSafety4DGroupActions; + function add ( aValue : String ) : iSafety4DGroupActions; + function getActions : TList; + function &End : iSafety4DGroupRegister; + end; + +implementation + +{ TSafety4DGroupActions } + +function TSafety4DGroupActions.&end : iSafety4DGroupRegister; +begin + Result := FParent; +end; + +function TSafety4DGroupActions.add(aValue: String): iSafety4DGroupActions; +begin + Result := Self; + FList.Add(aValue); +end; + +function TSafety4DGroupActions.getActions: TList; +begin + Result := FList; +end; + +constructor TSafety4DGroupActions.Create(aParent : iSafety4DGroupRegister); +begin + FParent := aParent; + FList := TList.Create; +end; + +destructor TSafety4DGroupActions.Destroy; +begin + FList.DisposeOf; + inherited; +end; + +class function TSafety4DGroupActions.New(aParent : iSafety4DGroupRegister): iSafety4DGroupActions; +begin + Result := Self.Create(aParent); +end; + +end. diff --git a/src/Safety4D.Groups.ListActions.pas b/src/Safety4D.Groups.ListActions.pas new file mode 100644 index 0000000..a296ad7 --- /dev/null +++ b/src/Safety4D.Groups.ListActions.pas @@ -0,0 +1,98 @@ +unit Safety4D.Groups.ListActions; + +interface + +uses + Safety4D.Interfaces; + +type + TSafety4DGroupsListActions = class(TInterfacedObject, iSafety4DGroupListActions) + private + [weak] + FParent : iSafety4DGroupRegister; + FActions : iSafety4DGroupActions; + FNotActions : iSafety4DGroupNotActions; + FDescription : String; + FKey : String; + public + constructor Create(aParent : iSafety4DGroupRegister); + destructor Destroy; override; + class function New(aParent : iSafety4DGroupRegister) : iSafety4DGroupListActions; + function actions : iSafety4DGroupActions; + function notActions : iSafety4DGroupNotActions; + function description ( aValue : String ) : iSafety4DGroupListActions; overload; + function description : String; overload; + function key ( aValue : String ) : iSafety4DGroupListActions; overload; + function key : string; overload; + function &End : iSafety4DGroupRegister; + end; + +implementation + +uses + Safety4D.Groups.Actions, Safety4D.Groups.NotActions; + +{ TSafety4DGroupsListActions } + +function TSafety4DGroupsListActions.&end : iSafety4DGroupRegister; +begin + Result := FParent; +end; + +function TSafety4DGroupsListActions.key: string; +begin + Result := FKey; +end; + +function TSafety4DGroupsListActions.key( + aValue: String): iSafety4DGroupListActions; +begin + Result := Self; + FKey := aValue; +end; + +function TSafety4DGroupsListActions.actions: iSafety4DGroupActions; +begin + if not Assigned(FActions) then + FActions := TSafety4DGroupActions.New(FParent); + + Result := FActions; +end; + +constructor TSafety4DGroupsListActions.Create(aParent : iSafety4DGroupRegister); +begin + FParent := aParent; +end; + +function TSafety4DGroupsListActions.description: String; +begin + Result := FDescription; +end; + +function TSafety4DGroupsListActions.description( + aValue: String): iSafety4DGroupListActions; +begin + Result := Self; + FDescription := aValue; +end; + +destructor TSafety4DGroupsListActions.Destroy; +begin + + inherited; +end; + +class function TSafety4DGroupsListActions.New(aParent : iSafety4DGroupRegister): iSafety4DGroupListActions; +begin + Result := Self.Create(aParent); +end; + +function TSafety4DGroupsListActions.notActions: iSafety4DGroupNotActions; +begin + if not Assigned(FNotActions) then + FNotActions := TSafety4DGroupNotActions.New(FParent); + + Result := FNotActions; +end; + +end. diff --git a/src/Safety4D.Groups.NotActions.pas b/src/Safety4D.Groups.NotActions.pas new file mode 100644 index 0000000..92f7228 --- /dev/null +++ b/src/Safety4D.Groups.NotActions.pas @@ -0,0 +1,61 @@ +unit Safety4D.Groups.NotActions; + +interface + +uses + System.Generics.Collections, + Safety4D.Interfaces; + +type + TSafety4DGroupNotActions = class(TInterfacedObject, iSafety4DGroupNotActions) + private + [weak] + FParent : iSafety4DGroupRegister; + FList : TList; + public + constructor Create(aParent : iSafety4DGroupRegister); + destructor Destroy; override; + class function New(aParent : iSafety4DGroupRegister) : iSafety4DGroupNotActions; + function add ( aValue : String ) : iSafety4DGroupNotActions; + function getNotActions : TList; + function &End : iSafety4DGroupRegister; + end; + +implementation + +{ TSafety4DGroupNotActions } + +function TSafety4DGroupNotActions.&end : iSafety4DGroupRegister; +begin + Result := FParent; +end; + +function TSafety4DGroupNotActions.add(aValue: String): iSafety4DGroupNotActions; +begin + Result := Self; + FList.Add(aValue); +end; + +function TSafety4DGroupNotActions.getNotActions: TList; +begin + Result := FList; +end; + +constructor TSafety4DGroupNotActions.Create(aParent : iSafety4DGroupRegister); +begin + FParent := aParent; + FList := TList.Create; +end; + +destructor TSafety4DGroupNotActions.Destroy; +begin + FList.DisposeOf; + inherited; +end; + +class function TSafety4DGroupNotActions.New(aParent : iSafety4DGroupRegister): iSafety4DGroupNotActions; +begin + Result := Self.Create(aParent); +end; + +end. diff --git a/src/Safety4D.Groups.Register.pas b/src/Safety4D.Groups.Register.pas new file mode 100644 index 0000000..1b408bf --- /dev/null +++ b/src/Safety4D.Groups.Register.pas @@ -0,0 +1,116 @@ +unit Safety4D.Groups.Register; + +interface + +uses + System.Generics.Collections, + Safety4D.Interfaces, + System.JSON; + +type + TSafety4DGroupRegister = class(TInterfacedObject, iSafety4DGroupRegister) + private + [weak] + FParent : iSafety4DGroup; + FActions : iSafety4DGroupListActions; + FList : TDictionary; + public + constructor Create(aParent : iSafety4DGroup); + destructor Destroy; override; + class function New(aParent : iSafety4DGroup) : iSafety4DGroupRegister; + function add ( aRoleName : String ) : iSafety4DGroupRegister; + function description (aValue : String ) : iSafety4DGroupRegister; overload; + function description : String; overload; + function key ( aValue : String ) : iSafety4DGroupRegister; overload; + function key : String; overload; + function actions : iSafety4DGroupActions; + function notActions : iSafety4DGroupNotActions; + function getGroupsRegisters : TDictionary; + function &end : iSafety4DGroup; + end; + +implementation + +uses + Safety4D.Groups.Actions, + Safety4D.Groups.NotActions, + Safety4D.Groups.ListActions, + System.SysUtils, + System.StrUtils; + +{ TSafety4DGroups } + +function TSafety4DGroupRegister.&end: iSafety4DGroup; +begin + Result := FParent; +end; + +function TSafety4DGroupRegister.getGroupsRegisters: TDictionary; +begin + Result := FList; +end; + +function TSafety4DGroupRegister.key: String; +begin + Result := FActions.key; +end; + +function TSafety4DGroupRegister.key(aValue: String): iSafety4DGroupRegister; +begin + Result := Self; + FActions.key(aValue); +end; + +function TSafety4DGroupRegister.actions: iSafety4DGroupActions; +begin + Result := FActions.actions; +end; + +function TSafety4DGroupRegister.add(aRoleName: String): iSafety4DGroupRegister; +var + aGuid : String; +begin + aGuid := TGuid.NewGuid.ToString; + if ContainsText(aRoleName, '{') and ContainsText(aRoleName, '}') then + aGuid := aRoleName; + + Result := Self; + FList.Add(aGuid, TSafety4DGroupsListActions.New(Self)); + FActions := FList.Items[aGuid]; + FActions.key(aRoleName); +end; + +constructor TSafety4DGroupRegister.Create(aParent : iSafety4DGroup); +begin + FParent := aParent; + FList := TDictionary.Create; +end; + +function TSafety4DGroupRegister.description: String; +begin + Result := FActions.description; +end; + +function TSafety4DGroupRegister.description( + aValue: String): iSafety4DGroupRegister; +begin + Result := FActions.description(aValue).&end; +end; + +destructor TSafety4DGroupRegister.Destroy; +begin + FList.DisposeOf; + inherited; +end; + +class function TSafety4DGroupRegister.New(aParent : iSafety4DGroup) : iSafety4DGroupRegister; +begin + Result := Self.Create(aParent); +end; + +function TSafety4DGroupRegister.notActions: iSafety4DGroupNotActions; +begin + Result := FActions.notActions; +end; + +end. diff --git a/src/Safety4D.Groups.pas b/src/Safety4D.Groups.pas new file mode 100644 index 0000000..03d39fc --- /dev/null +++ b/src/Safety4D.Groups.pas @@ -0,0 +1,116 @@ +unit Safety4D.Groups; + +interface + +uses + Safety4D.Interfaces, System.JSON; + +type + TSafety4DGroups = class(TInterfacedObject, iSafety4DGroup) + private + [weak] + FParent : iSafety4D; + FgroupRegister : iSafety4DGroupRegister; + public + constructor Create(aParent : iSafety4D); + destructor Destroy; override; + class function New(aParent : iSafety4D) : iSafety4DGroup; + function groupRegister : iSafety4DGroupRegister; + function getGroups (var aJson : TJsonObject ) : iSafety4DGroup; + function getGroupPermission ( aValue : String ) : iSafety4DGroupListActions; + function &End : iSafety4D; + end; + +implementation + +uses + Safety4D.Groups.Register; + +{ TSafety4DGroups } + +function TSafety4DGroups.&end : iSafety4D; +begin + Result := FParent; +end; + +function TSafety4DGroups.getGroupPermission( + aValue: String): iSafety4DGroupListActions; +begin + FgroupRegister.getGroupsRegisters.TryGetValue(aValue, Result); +end; + +function TSafety4DGroups.getGroups( + var aJson: TJsonObject): iSafety4DGroup; +var + aJsonActions : TJsonArray; + aJsonGroups : TJsonObject; + aJsonGroup : TJsonObject; +begin + Result := Self; + for var group in FgroupRegister.getGroupsRegisters do + begin + aJson.AddPair(group.Key, TJsonObject.Create); + aJsonGroup := aJson.GetValue(group.Key); + aJsonGroup + .AddPair('key', group.Value.key) + .AddPair('description', group.Value.description) + .AddPair('Actions', TJSONArray.Create) + .AddPair('NotActions', TJSONArray.Create); + + for var Action in group.Value.actions.getActions do + begin + aJsonActions := aJsonGroup.GetValue('Actions'); + aJsonActions.Add(Action); + end; + + for var NotAction in group.Value.notActions.getNotActions do + begin + aJsonActions := aJsonGroup.GetValue('NotActions'); + aJsonActions.Add(NotAction); + end; + end; +// aJson +// .AddPair('Key', FKey) +// .AddPair('RoleName', FRoleName) +// .AddPair('Description', FDescription) +// .AddPair('Actions', TJSONArray.Create) +// .AddPair('NotActions', TJSONArray.Create); + +// for var Action in FActions.getActions do +// begin +// aJsonActions := aJson.GetValue('Actions'); +// aJsonActions.Add(Action); +// end; + +// for var NotAction in FNotActions.getNotActions do +// begin +// aJsonActions := aJson.GetValue('NotActions'); +// aJsonActions.Add(NotAction); +// end; + +end; + +function TSafety4DGroups.groupRegister: iSafety4DGroupRegister; +begin + if not Assigned(FgroupRegister) then + FgroupRegister := TSafety4DGroupRegister.New(Self); + Result := FgroupRegister; +end; + +constructor TSafety4DGroups.Create(aParent : iSafety4D); +begin + FParent := aParent; +end; + +destructor TSafety4DGroups.Destroy; +begin + + inherited; +end; + +class function TSafety4DGroups.New(aParent : iSafety4D): iSafety4DGroup; +begin + Result := Self.Create(aParent); +end; + +end. diff --git a/src/Safety4D.Interfaces.pas b/src/Safety4D.Interfaces.pas new file mode 100644 index 0000000..03ee417 --- /dev/null +++ b/src/Safety4D.Interfaces.pas @@ -0,0 +1,178 @@ +unit Safety4D.Interfaces; + +interface + +uses + System.Generics.Collections, + System.JSON; + +type + iSafety4DResourcesRegister = interface; + iSafety4DResourcesGroup = interface; + iSafety4DResourcesGroupProvider = interface; + iSafety4DResourcesGroupProviderActions = interface; + iSafety4DResources = interface; + iSafety4DResourcesGroupProviderActionsMsg = interface; + iSafety4DGroup = interface; + iSafety4DUserKey = interface; + iSafety4DValidation = interface; + + + iSafety4D = interface + ['{055941C3-EBA3-4D4E-ADB0-75C9FCE6DF18}'] + function Validation : iSafety4DValidation; + function resources : iSafety4DResources; + function groupPermission : iSafety4DGroup; + function userKey : iSafety4DUserKey; + function getConfig (var aJson : TJsonObject ) : iSafety4D; + function SaveToStorage ( aPath : String = '' ) : iSafety4D; + function LoadConfig ( aJson : TJsonObject ) : iSafety4D; + end; + + iSafety4DValidation = interface + ['{3EB75190-778C-4E0B-ABE7-A17A78103C5B}'] + function userKey( aValue : String ) : iSafety4DValidation; overload; + function userKey : String; overload; + function resource ( aValue : String ) : iSafety4DValidation; overload; + function resource : string; overload; + function action ( aValue : String ) : iSafety4DValidation; overload; + function action : string; overload; + function application ( aValue : String ) : iSafety4DValidation; overload; + function application : string; overload; + function validate : boolean; + function &end : iSafety4D; + end; + + {$region 'Resources'} + + iSafety4DResources = interface + ['{B6BDB9F9-0E07-42C2-82BF-B3425CA2C3FA}'] + function registerResources : iSafety4DResourcesRegister; + function getResource ( var aJson : TJsonObject ) : iSafety4DResources; + function exists ( aApplication : String; aResource : String; aAction : String ) : Boolean; + function &end : iSafety4D; + end; + + iSafety4DResourcesRegister = interface + ['{11448984-3C63-45C5-8F8A-3B6D679B93A9}'] + function resourcesGroupName : iSafety4DResourcesGroup; + function getResourceGroups : TDictionary; + function &end : iSafety4DResources; + end; + + iSafety4DResourcesGroup = interface + ['{02F44B1B-3AEB-4DCB-BB60-6959EB46830D}'] + function add ( aValue : String ) : iSafety4DResourcesGroup; + function providerName : iSafety4DResourcesGroupProvider; + function getResourcesGroupList : TDictionary; + function &end : iSafety4DResourcesRegister; + end; + + iSafety4DResourcesGroupProvider = interface + ['{FB08025C-9831-4616-AFEE-22D40F25147D}'] + function add(aValue : String) : iSafety4DResourcesGroupProvider; + function getProviderNames : TDictionary; + function actions : iSafety4DResourcesGroupProviderActions; + function &end : iSafety4DResourcesGroup; + end; + + iSafety4DResourcesGroupProviderActions = interface + ['{94AAE52D-4317-4262-9E1A-DB04D8A95E68}'] + function add(aValue : String) : iSafety4DResourcesGroupProviderActionsMsg; + function getActions : TDictionary; + function &end : iSafety4DResourcesGroupProvider; + end; + + iSafety4DResourcesGroupProviderActionsMsg = interface + ['{36CAC0FD-138E-41CE-A483-3D2AE768AACD}'] + function description( aValue : String ) : iSafety4DResourcesGroupProviderActionsMsg; overload; + function errormsg ( aValue : String ) : iSafety4DResourcesGroupProviderActionsMsg; overload; + function description : String; overload; + function errormsg : String; overload; + function &end : iSafety4DResourcesGroupProviderActions; + end; + {$endregion} + + {$region 'Group'} + iSafety4DGroupActions = interface; + iSafety4DGroupNotActions = interface; + iSafety4DGroupRegister = interface; + iSafety4DGroupListActions = interface; + + iSafety4DGroup = interface + ['{F3E9A643-5FA7-49FA-994A-430B7DDE9FBF}'] + function groupRegister : iSafety4DGroupRegister; + function getGroups (var aJson : TJsonObject ) : iSafety4DGroup; + function getGroupPermission ( aValue : String ) : iSafety4DGroupListActions; + function &end : iSafety4D; + end; + + iSafety4DGroupRegister = interface + function add ( aRoleName : String ) : iSafety4DGroupRegister; + function actions : iSafety4DGroupActions; + function notActions : iSafety4DGroupNotActions; + function key ( aValue : String ) : iSafety4DGroupRegister; overload; + function key : String; overload; + function description (aValue : String ) : iSafety4DGroupRegister; overload; + function description : String; overload; + function getGroupsRegisters : TDictionary; + function &end : iSafety4DGroup; + end; + + iSafety4DGroupListActions = interface + function key ( aValue : String ) : iSafety4DGroupListActions; overload; + function key : string; overload; + function description ( aValue : String ) : iSafety4DGroupListActions; overload; + function description : String; overload; + function actions : iSafety4DGroupActions; + function notActions : iSafety4DGroupNotActions; + function &end : iSafety4DGroupRegister; + end; + + iSafety4DGroupActions = interface + function add ( aValue : String ) : iSafety4DGroupActions; + function getActions : TList; + function &end : iSafety4DGroupRegister; + end; + + iSafety4DGroupNotActions = interface + function add ( aValue : String ) : iSafety4DGroupNotActions; + function getNotActions : TList; + function &end : iSafety4DGroupRegister; + end; + + {$endregion} + + {$region 'userkey'} + iSafety4DUserKeyRegister = interface; + iSafety4DUserKeyRegisterGroupPermission = interface; + + iSafety4DUserKey = interface + ['{89576374-693F-44F5-9B96-42DECA780927}'] + function registerUserKey : iSafety4DUserKeyRegister; + function getUserKey (var aJson : TJsonObject ) : iSafety4DUserKey; + function getUserKeyPermissions (aUserKey : String) : TArray; + function exists ( aUserKey : String ) : Boolean; + function &end : iSafety4D; + end; + + iSafety4DUserKeyRegister = interface + ['{ACA41435-459E-4394-849B-E260B7993068}'] + function add ( aValue : String ) : iSafety4DUserKeyRegisterGroupPermission; + function GetUserKeyRegister : TDictionary; + function &end : iSafety4DUserKey; + end; + + iSafety4DUserKeyRegisterGroupPermission = interface + ['{5D217EF2-579D-48AB-BCF9-432E68BFACD8}'] + function description ( aValue : String ) : iSafety4DUserKeyRegisterGroupPermission; overload; + function description : String; overload; + function addPermission ( aValue : String ) : iSafety4DUserKeyRegisterGroupPermission; + function GetPermissions : TList; + function &end : iSafety4DUserKeyRegister; + end; + {$endregion} + +implementation + +end. diff --git a/src/Safety4D.Resources.Group.Provider.Actions.Msg.pas b/src/Safety4D.Resources.Group.Provider.Actions.Msg.pas new file mode 100644 index 0000000..d34ac83 --- /dev/null +++ b/src/Safety4D.Resources.Group.Provider.Actions.Msg.pas @@ -0,0 +1,74 @@ +unit Safety4D.Resources.Group.Provider.Actions.Msg; + +interface + +uses + Safety4D.Interfaces; + +type + TSafety4DResourcesGroupProviderActionsMsg = class(TInterfacedObject, iSafety4DResourcesGroupProviderActionsMsg) + private + [weak] + FParent : iSafety4DResourcesGroupProviderActions; + FDescription : String; + FErrorMsg : String; + public + constructor Create(aParent : iSafety4DResourcesGroupProviderActions); + destructor Destroy; override; + class function New(aParent : iSafety4DResourcesGroupProviderActions) : iSafety4DResourcesGroupProviderActionsMsg; + function description( aValue : String ) : iSafety4DResourcesGroupProviderActionsMsg; overload; + function errormsg ( aValue : String ) : iSafety4DResourcesGroupProviderActionsMsg; overload; + function description : String; overload; + function errormsg : String; overload; + function &End : iSafety4DResourcesGroupProviderActions; + end; + +implementation + +{ TSafety4DResourcesGroupProviderActionsMsg } + +function TSafety4DResourcesGroupProviderActionsMsg.&end : iSafety4DResourcesGroupProviderActions; +begin + Result := FParent; +end; + +function TSafety4DResourcesGroupProviderActionsMsg.errormsg: String; +begin + Result := FErrorMsg; +end; + +function TSafety4DResourcesGroupProviderActionsMsg.errormsg(aValue: String): iSafety4DResourcesGroupProviderActionsMsg; +begin + Result := Self; + FErrorMsg := aValue; +end; + +constructor TSafety4DResourcesGroupProviderActionsMsg.Create(aParent : iSafety4DResourcesGroupProviderActions); +begin + FParent := aParent; +end; + +function TSafety4DResourcesGroupProviderActionsMsg.description( + aValue: String): iSafety4DResourcesGroupProviderActionsMsg; +begin + Result := Self; + FDescription := aValue; +end; + +function TSafety4DResourcesGroupProviderActionsMsg.description: String; +begin + Result := FDescription; +end; + +destructor TSafety4DResourcesGroupProviderActionsMsg.Destroy; +begin + + inherited; +end; + +class function TSafety4DResourcesGroupProviderActionsMsg.New(aParent : iSafety4DResourcesGroupProviderActions): iSafety4DResourcesGroupProviderActionsMsg; +begin + Result := Self.Create(aParent); +end; + +end. diff --git a/src/Safety4D.Resources.Group.Provider.Actions.pas b/src/Safety4D.Resources.Group.Provider.Actions.pas new file mode 100644 index 0000000..e509505 --- /dev/null +++ b/src/Safety4D.Resources.Group.Provider.Actions.pas @@ -0,0 +1,66 @@ +unit Safety4D.Resources.Group.Provider.Actions; + +interface + +uses + Safety4D.Interfaces, + System.Generics.Collections; + +type + TSafety4DResourcesGroupProviderActions = class(TInterfacedObject, iSafety4DResourcesGroupProviderActions) + private + [weak] + FParent : iSafety4DResourcesGroupProvider; + FActionList : TDictionary; + FActionsMsg : iSafety4DResourcesGroupProviderActionsMsg; + public + constructor Create(aParent : iSafety4DResourcesGroupProvider); + destructor Destroy; override; + class function New(aParent : iSafety4DResourcesGroupProvider) : iSafety4DResourcesGroupProviderActions; + function add(aValue : String) : iSafety4DResourcesGroupProviderActionsMsg; + function getActions : TDictionary; + function &end : iSafety4DResourcesGroupProvider; + end; + +implementation + +uses + Safety4D.Resources.Group.Provider.Actions.Msg; + +{ TSafety4DProviderName } + +function TSafety4DResourcesGroupProviderActions.&end: iSafety4DResourcesGroupProvider; +begin + Result := FParent; +end; + +function TSafety4DResourcesGroupProviderActions.getActions: TDictionary; +begin + Result := FActionList; +end; + +function TSafety4DResourcesGroupProviderActions.add( + aValue: String): iSafety4DResourcesGroupProviderActionsMsg; +begin + FActionList.Add(aValue, TSafety4DResourcesGroupProviderActionsMsg.New(Self)); + Result := FActionList.Items[aValue]; +end; + +constructor TSafety4DResourcesGroupProviderActions.Create(aParent : iSafety4DResourcesGroupProvider); +begin + FParent := aParent; + FActionList := TDictionary.Create; +end; + +destructor TSafety4DResourcesGroupProviderActions.Destroy; +begin + FActionList.DisposeOf; + inherited; +end; + +class function TSafety4DResourcesGroupProviderActions.New(aParent : iSafety4DResourcesGroupProvider): iSafety4DResourcesGroupProviderActions; +begin + Result := Self.Create(aParent); +end; + +end. diff --git a/src/Safety4D.Resources.Group.Provider.pas b/src/Safety4D.Resources.Group.Provider.pas new file mode 100644 index 0000000..06617fb --- /dev/null +++ b/src/Safety4D.Resources.Group.Provider.pas @@ -0,0 +1,79 @@ +unit Safety4D.Resources.Group.Provider; + +interface + +uses + System.Generics.Collections, + Safety4D.Interfaces; + +type + TSafety4DResourcesGroupProvider = class(TInterfacedObject, iSafety4DResourcesGroupProvider) + private + [weak] + FParent : iSafety4DResourcesGroup; + FProviderName : String; + FProviderNameList : TDictionary; + public + constructor Create(aParent : iSafety4DResourcesGroup); + destructor Destroy; override; + class function New(aParent : iSafety4DResourcesGroup) : iSafety4DResourcesGroupProvider; + function add(aValue : String) : iSafety4DResourcesGroupProvider; + function getProviderNames : TDictionary; + function actions : iSafety4DResourcesGroupProviderActions; + function &End : iSafety4DResourcesGroup; + end; + +implementation + +uses + Safety4D.Resources.Group.Provider.Actions; + +{ TSafety4DProviderName } + +function TSafety4DResourcesGroupProvider.&end : iSafety4DResourcesGroup; +begin + Result := FParent; +end; + +function TSafety4DResourcesGroupProvider.getProviderNames: TDictionary; +begin + Result := FProviderNameList; +end; + +function TSafety4DResourcesGroupProvider.actions: iSafety4DResourcesGroupProviderActions; +begin + Result := FProviderNameList.Items[FProviderName]; +end; + +function TSafety4DResourcesGroupProvider.add(aValue: String): iSafety4DResourcesGroupProvider; +begin + Result := Self; + FProviderName := aValue; + FProviderNameList.Add(aValue, TSafety4DResourcesGroupProviderActions.New(Self)); +// FProviderNameList +// .Items[aValue] +// .add('*') +// .add('read') +// .add('write') +// .add('delete') +// .add('view'); +end; + +constructor TSafety4DResourcesGroupProvider.Create(aParent : iSafety4DResourcesGroup); +begin + FParent := aParent; + FProviderNameList := TDictionary.Create; +end; + +destructor TSafety4DResourcesGroupProvider.Destroy; +begin + FProviderNameList.DisposeOf; + inherited; +end; + +class function TSafety4DResourcesGroupProvider.New(aParent : iSafety4DResourcesGroup): iSafety4DResourcesGroupProvider; +begin + Result := Self.Create(aParent); +end; + +end. diff --git a/src/Safety4D.Resources.Group.pas b/src/Safety4D.Resources.Group.pas new file mode 100644 index 0000000..3fd9a35 --- /dev/null +++ b/src/Safety4D.Resources.Group.pas @@ -0,0 +1,73 @@ +unit Safety4D.Resources.Group; + +interface + +uses + System.Generics.Collections, + Safety4D.Interfaces; + +type + TSafety4DResourcesGroup = class(TInterfacedObject, iSafety4DResourcesGroup) + private + [weak] + FParent : iSafety4DResourcesRegister; + FResourceGroup : String; + FResourceGroupNameList : TDictionary; + public + constructor Create(aParent : iSafety4DResourcesRegister); + destructor Destroy; override; + class function New(aParent : iSafety4DResourcesRegister) : iSafety4DResourcesGroup; + function add ( aValue : String ) : iSafety4DResourcesGroup; + function getResourcesGroupList : TDictionary; + function providerName : iSafety4DResourcesGroupProvider; + function &end : iSafety4DResourcesRegister; + end; + +implementation + +{ TSafety4DResourcesGrupName } + +uses + Safety4D.Resources.Group.Provider; + +function TSafety4DResourcesGroup.&end : iSafety4DResourcesRegister; +begin + Result := FParent; +end; + +function TSafety4DResourcesGroup.getResourcesGroupList: TDictionary; +begin + Result := FResourceGroupNameList; +end; + +function TSafety4DResourcesGroup.add( + aValue: String): iSafety4DResourcesGroup; +begin + Result := Self; + FResourceGroup := aValue; + FResourceGroupNameList.Add(aValue, TSafety4DResourcesGroupProvider.New(Self)); +end; + +constructor TSafety4DResourcesGroup.Create(aParent : iSafety4DResourcesRegister); +begin + FParent := aParent; + FResourceGroupNameList := TDictionary.Create; +end; + +destructor TSafety4DResourcesGroup.Destroy; +begin + FResourceGroupNameList.DisposeOf; + inherited; +end; + +class function TSafety4DResourcesGroup.New(aParent : iSafety4DResourcesRegister): iSafety4DResourcesGroup; +begin + Result := Self.Create(aParent); +end; + +function TSafety4DResourcesGroup.providerName: iSafety4DResourcesGroupProvider; +begin + Result := FResourceGroupNameList.Items[FResourceGroup]; +end; + +end. diff --git a/src/Safety4D.Resources.Register.pas b/src/Safety4D.Resources.Register.pas new file mode 100644 index 0000000..343e5df --- /dev/null +++ b/src/Safety4D.Resources.Register.pas @@ -0,0 +1,65 @@ +unit Safety4D.Resources.Register; + +interface + +uses + System.Generics.Collections, + Safety4D.Interfaces; + +type + TSafety4DResourcesRegister = class(TInterfacedObject, iSafety4DResourcesRegister) + private + [weak] + FParent : iSafety4DResources; + FResourceGroupName : iSafety4DResourcesGroup; + public + constructor Create(aParent : iSafety4DResources); + destructor Destroy; override; + class function New(aParent : iSafety4DResources) : iSafety4DResourcesRegister; + function resourcesGroupName : iSafety4DResourcesGroup; + function getResourceGroups : TDictionary; + function &End : iSafety4DResources; + end; + +implementation + +uses + Safety4D.Resources.Group; + +{ TSafety4DRegisterResources } + +function TSafety4DResourcesRegister.&end : iSafety4DResources; +begin + Result := FParent; +end; + +function TSafety4DResourcesRegister.getResourceGroups: TDictionary; +begin + Result := FResourceGroupName.getResourcesGroupList; +end; + +constructor TSafety4DResourcesRegister.Create(aParent : iSafety4DResources); +begin + FParent := aParent; +end; + +destructor TSafety4DResourcesRegister.Destroy; +begin + + inherited; +end; + +class function TSafety4DResourcesRegister.New(aParent : iSafety4DResources) : iSafety4DResourcesRegister; +begin + Result := Self.Create(aParent); +end; + +function TSafety4DResourcesRegister.resourcesGroupName: iSafety4DResourcesGroup; +begin + if not assigned(FResourceGroupName) then + FResourceGroupName := TSafety4DResourcesGroup.New(Self); + + Result := FResourceGroupName; +end; + +end. diff --git a/src/Safety4D.Resources.pas b/src/Safety4D.Resources.pas new file mode 100644 index 0000000..5fd3f56 --- /dev/null +++ b/src/Safety4D.Resources.pas @@ -0,0 +1,110 @@ +unit Safety4D.Resources; + +interface + +uses + System.JSON, + Safety4D.Interfaces; + +type + TSafety4DResources = class(TInterfacedObject, iSafety4DResources) + private + [weak] + FParent : iSafety4D; + FRegisterResources : iSafety4DResourcesRegister; + public + constructor Create(aParent : iSafety4D); + destructor Destroy; override; + class function New(aParent : iSafety4D) : iSafety4DResources; + function registerResources : iSafety4DResourcesRegister; + function getResource ( var aJson : TJsonObject ) : iSafety4DResources; + function exists ( aApplication : String; aResource : String; aAction : String ) : Boolean; + function &End : iSafety4D; + end; + +implementation + +uses + Safety4D.Resources.Register, System.SysUtils; + +{ TSafety4DResources } + +function TSafety4DResources.&end : iSafety4D; +begin + Result := FParent; +end; + +function TSafety4DResources.exists( aApplication : String; aResource : String; aAction : String ) : Boolean; +var + iResource : iSafety4DResourcesGroupProvider; + iResourceActions : iSafety4DResourcesGroupProviderActions; + iActionMessage : iSafety4DResourcesGroupProviderActionsMsg; +begin + Result := False; + + if not FRegisterResources.getResourceGroups.TryGetValue(aApplication, iResource) then + raise Exception.Create('Unregistered Application'); + + if not iResource.getProviderNames.TryGetValue(aResource, iResourceActions) then + raise Exception.Create('Unregistered resource'); + + if not iResourceActions.getActions.TryGetValue(aAction, iActionMessage) then + raise Exception.Create('unregistered action'); +end; + +function TSafety4DResources.getResource( + var aJson: TJsonObject): iSafety4DResources; +var + aJsonResources : TJsonObject; + aJsonGroup : TJsonObject; + aJsonProvider : TJsonObject; + aJsonActions : TJsonObject; +begin + Result := Self; + //aJson.AddPair('resources', TJSONArray.Create.Add(TJSONObject.Create)); + for var Resource in FRegisterResources.getResourceGroups do + begin + //aJsonResources := (aJson.GetValue('resources').Items[0] as TJsonObject); + aJson.AddPair(Resource.Key, TJSONObject.Create); + for var Provider in Resource.Value.getProviderNames do + begin + aJsonGroup := aJson.GetValue(Resource.Key); + aJsonGroup.AddPair(Provider.Key, TJSONObject.Create); + aJsonProvider := aJsonGroup.GetValue(Provider.Key); + aJsonProvider.AddPair('actions', TJSONObject.Create); + for var Action in Provider.Value.getActions do + begin + aJsonActions := aJsonProvider.GetValue('actions'); + aJsonActions.AddPair(Action.Key, TJsonObject.Create); + aJsonActions.GetValue(Action.Key).AddPair('description', Action.Value.description); + aJsonActions.GetValue(Action.Key).AddPair('errormsg', Action.Value.errormsg); + end; + end; + end; +end; + +constructor TSafety4DResources.Create(aParent : iSafety4D); +begin + FParent := aParent; +end; + +destructor TSafety4DResources.Destroy; +begin + + inherited; +end; + +class function TSafety4DResources.New(aParent : iSafety4D): iSafety4DResources; +begin + Result := Self.Create(aParent); +end; + +function TSafety4DResources.registerResources: iSafety4DResourcesRegister; +begin + if not assigned(FRegisterResources) then + FRegisterResources := TSafety4DResourcesRegister.New(Self); + + Result := FRegisterResources; +end; + +end. diff --git a/src/Safety4D.UserKey.Register.PermissionGroup.pas b/src/Safety4D.UserKey.Register.PermissionGroup.pas new file mode 100644 index 0000000..1d32180 --- /dev/null +++ b/src/Safety4D.UserKey.Register.PermissionGroup.pas @@ -0,0 +1,77 @@ +unit Safety4D.UserKey.Register.PermissionGroup; + +interface + +uses + System.Generics.Collections, + Safety4D.Interfaces; + +type + TSafety4DUserKeyRegisterPermissionGroup = class(TInterfacedObject, iSafety4DUserKeyRegisterGroupPermission) + private + [weak] + FParent : iSafety4DUserKeyRegister; + FList : TList; + FDescription : String; + public + constructor Create(aParent : iSafety4DUserKeyRegister); + destructor Destroy; override; + class function New(aParent : iSafety4DUserKeyRegister) : iSafety4DUserKeyRegisterGroupPermission; + function addPermission ( aValue : String ) : iSafety4DUserKeyRegisterGroupPermission; + function description ( aValue : String ) : iSafety4DUserKeyRegisterGroupPermission; overload; + function description : String; overload; + function GetPermissions : TList; + function &End : iSafety4DUserKeyRegister; + end; + +implementation + +{ TSafety4DUserKeyRegisterPermissionGroup } + +function TSafety4DUserKeyRegisterPermissionGroup.&end : iSafety4DUserKeyRegister; +begin + Result := FParent; +end; + +function TSafety4DUserKeyRegisterPermissionGroup.GetPermissions: TList; +begin + Result := FList; +end; + +function TSafety4DUserKeyRegisterPermissionGroup.addPermission( + aValue: String): iSafety4DUserKeyRegisterGroupPermission; +begin + Result := Self; + FList.Add(aValue); +end; + +constructor TSafety4DUserKeyRegisterPermissionGroup.Create(aParent : iSafety4DUserKeyRegister); +begin + FParent := aParent; + FList := TList.Create; +end; + +function TSafety4DUserKeyRegisterPermissionGroup.description: String; +begin + Result := FDescription; +end; + +function TSafety4DUserKeyRegisterPermissionGroup.description( + aValue: String): iSafety4DUserKeyRegisterGroupPermission; +begin + Result := Self; + FDescription := aValue; +end; + +destructor TSafety4DUserKeyRegisterPermissionGroup.Destroy; +begin + FList.DisposeOf; + inherited; +end; + +class function TSafety4DUserKeyRegisterPermissionGroup.New(aParent : iSafety4DUserKeyRegister): iSafety4DUserKeyRegisterGroupPermission; +begin + Result := Self.Create(aParent); +end; + +end. diff --git a/src/Safety4D.UserKey.Register.pas b/src/Safety4D.UserKey.Register.pas new file mode 100644 index 0000000..278959b --- /dev/null +++ b/src/Safety4D.UserKey.Register.pas @@ -0,0 +1,74 @@ +unit Safety4D.UserKey.Register; + +interface + +uses + System.Generics.Collections, + Safety4D.Interfaces; + +type + TSafety4DUserKeyRegister = class(TInterfacedObject, iSafety4DUserKeyRegister) + private + [weak] + FParent : iSafety4DUserKey; + FList : TDictionary; + public + constructor Create(aParent : iSafety4DUserKey); + destructor Destroy; override; + class function New(aParent : iSafety4DUserKey) : iSafety4DUserKeyRegister; + function GetUserKeyRegister : TDictionary; + function add ( aValue : String ) : iSafety4DUserKeyRegisterGroupPermission; + function &End : iSafety4DUserKey; + end; + +implementation + +uses + Safety4D.UserKey.Register.PermissionGroup, + System.SysUtils, + System.StrUtils; + +{ TSafety4DUserKeyRegister } + +function TSafety4DUserKeyRegister.&end : iSafety4DUserKey; +begin + Result := FParent; +end; + +function TSafety4DUserKeyRegister.GetUserKeyRegister: TDictionary; +begin + Result := FList; +end; + +function TSafety4DUserKeyRegister.add( + aValue: String): iSafety4DUserKeyRegisterGroupPermission; +var + aGuid : String; +begin + aGuid := TGuid.NewGuid.ToString; + + if ContainsText(aValue, '{') and ContainsText(aValue, '}') then + aGuid := aValue; + + FList.Add(aGuid, TSafety4DUserKeyRegisterPermissionGroup.New(Self)); + Result := FList.Items[aGuid].description(aValue); +end; + +constructor TSafety4DUserKeyRegister.Create(aParent : iSafety4DUserKey); +begin + FParent := aParent; + FList := TDictionary.Create; +end; + +destructor TSafety4DUserKeyRegister.Destroy; +begin + FList.DisposeOf; + inherited; +end; + +class function TSafety4DUserKeyRegister.New(aParent : iSafety4DUserKey): iSafety4DUserKeyRegister; +begin + Result := Self.Create(aParent); +end; + +end. diff --git a/src/Safety4D.UserKey.pas b/src/Safety4D.UserKey.pas new file mode 100644 index 0000000..c125d0f --- /dev/null +++ b/src/Safety4D.UserKey.pas @@ -0,0 +1,99 @@ +unit Safety4D.UserKey; + +interface + +uses + Safety4D.Interfaces, System.JSON; + +type + TSafety4DUserKey = class(TInterfacedObject, iSafety4DUserKey) + private + [weak] + FParent : iSafety4D; + FRegisterUserKey : iSafety4DUserKeyRegister; + public + constructor Create(aParent : iSafety4D); + destructor Destroy; override; + class function New(aParent : iSafety4D) : iSafety4DUserKey; + function registerUserKey : iSafety4DUserKeyRegister; + function getUserKey (var aJson : TJsonObject ) : iSafety4DUserKey; + function exists ( aUserKey : String ) : Boolean; + function getUserKeyPermissions(aUserKey : String) : TArray; + function &End : iSafety4D; + end; + +implementation + +uses + Safety4D.UserKey.Register, System.SysUtils; + +{ TSafety4DUserKey } + +function TSafety4DUserKey.&end : iSafety4D; +begin + Result := FParent; +end; + +function TSafety4DUserKey.exists(aUserKey: String): Boolean; +var + iUser : iSafety4DUserKeyRegisterGroupPermission; +begin + if not FRegisterUserKey.GetUserKeyRegister.TryGetValue(aUserKey, iUser) then + raise Exception.Create('User key not registered'); +end; + +function TSafety4DUserKey.getUserKey(var aJson: TJsonObject): iSafety4DUserKey; +var + aJsonRegister : TJsonObject; + aJsonPermission : TJsonArray; +begin + for var userRegister in FRegisterUserKey.GetUserKeyRegister do + begin + aJson.AddPair(userRegister.Key, TJsonObject.Create); + aJsonRegister := aJson.GetValue(userRegister.Key); + aJsonRegister.AddPair('description', userRegister.Value.description); + aJsonRegister.AddPair('permissionGroups', TJsonArray.Create); + + for var Permission in userRegister.Value.GetPermissions do + begin + aJsonPermission := aJsonRegister.GetValue('permissionGroups'); + aJsonPermission.Add(Permission); + end; + + end; + +end; + +function TSafety4DUserKey.getUserKeyPermissions(aUserKey : String): TArray; +var + iUserPermitions : iSafety4DUserKeyRegisterGroupPermission; +begin + if FRegisterUserKey.GetUserKeyRegister.TryGetValue(aUserKey, iUserPermitions) then + Result := iUserPermitions.GetPermissions.ToArray; +end; + +constructor TSafety4DUserKey.Create(aParent : iSafety4D); +begin + FParent := aParent; +end; + +destructor TSafety4DUserKey.Destroy; +begin + + inherited; +end; + +class function TSafety4DUserKey.New(aParent : iSafety4D): iSafety4DUserKey; +begin + Result := Self.Create(aParent); +end; + +function TSafety4DUserKey.registerUserKey: iSafety4DUserKeyRegister; +begin + if not Assigned(FRegisterUserKey) then + FRegisterUserKey := TSafety4DUserKeyRegister.New(Self); + + Result := FRegisterUserKey; +end; + +end. diff --git a/src/Safety4D.Validation.pas b/src/Safety4D.Validation.pas new file mode 100644 index 0000000..f690cdb --- /dev/null +++ b/src/Safety4D.Validation.pas @@ -0,0 +1,154 @@ +unit Safety4D.Validation; + +interface + +uses + Safety4D.Interfaces; + +type + TSafety4DValidation = class(TInterfacedObject, iSafety4DValidation) + private + [weak] + FParent : iSafety4D; + FuserKey : String; + FResource : String; + FAction : String; + FApplication : String; + public + constructor Create(aParent : iSafety4D); + destructor Destroy; override; + class function New(aParent : iSafety4D) : iSafety4DValidation; + function userKey( aValue : String ) : iSafety4DValidation; overload; + function userKey : String; overload; + function resource ( aValue : String ) : iSafety4DValidation; overload; + function resource : string; overload; + function action ( aValue : String ) : iSafety4DValidation; overload; + function action : string; overload; + function application ( aValue : String ) : iSafety4DValidation; overload; + function application : string; overload; + function validate : boolean; + function &End : iSafety4D; + end; + +implementation + +uses + System.SysUtils; + +{ TSafety4DValidation } + +function TSafety4DValidation.&end : iSafety4D; +begin + Result := FParent; +end; + +function TSafety4DValidation.action(aValue: String): iSafety4DValidation; +begin + Result := Self; + FAction := aValue; +end; + +function TSafety4DValidation.action: string; +begin + Result := FAction; +end; + +function TSafety4DValidation.application: string; +begin + Result := FApplication; +end; + +function TSafety4DValidation.application(aValue: String): iSafety4DValidation; +begin + Result := Self; + FApplication := aValue; +end; + +constructor TSafety4DValidation.Create(aParent : iSafety4D); +begin + FParent := aParent; +end; + +destructor TSafety4DValidation.Destroy; +begin + + inherited; +end; + +class function TSafety4DValidation.New(aParent : iSafety4D): iSafety4DValidation; +begin + Result := Self.Create(aParent); +end; + +function TSafety4DValidation.resource: string; +begin + Result := FResource; +end; + +function TSafety4DValidation.resource(aValue: String): iSafety4DValidation; +begin + Result := Self; + FResource := aValue; +end; + +function TSafety4DValidation.userKey(aValue: String): iSafety4DValidation; +begin + Result := Self; + FuserKey := aValue; +end; + +function TSafety4DValidation.userKey: String; +begin + Result := FuserKey; +end; + +function TSafety4DValidation.validate: boolean; +var + aTeste : String; + FAllAcess : Boolean; + FAllBlock : Boolean; + iGroupPermission : iSafety4DGroupListActions; +begin + Result := False; + FAllAcess := False; + FAllBlock := False; + try + FParent.resources.exists(FApplication, FResource, FAction); + FParent.userKey.exists(FuserKey); + + for var UserPermission in FParent.userKey.getUserKeyPermissions(FuserKey) do + begin + aTeste := UserPermission; + iGroupPermission := FParent.groupPermission.getGroupPermission(UserPermission); + + for var aAction in iGroupPermission.actions.getActions do + begin + if UpperCase(aAction) = UpperCase(FResource+'.'+FAction) then + begin + Result := True; + exit; + end; + + if aAction = '*' then + FAllAcess := True; + end; + + for var aNotAction in iGroupPermission.notActions.getNotActions do + begin + if UpperCase(aNotAction) = UpperCase(FResource+'.'+FAction) then + raise Exception.Create('Access not allowed to these resources'); + + if aNotAction = '*' then + FAllBlock := True; + end; + + if not Result and FAllAcess then Result := FAllAcess; + if not Result and FAllBlock then + raise Exception.Create('Access not allowed to these resources'); + end; + except on e : Exception do + raise Exception.Create(e.Message); + end; +end; + +end. diff --git a/src/Safety4D.pas b/src/Safety4D.pas new file mode 100644 index 0000000..02a6353 --- /dev/null +++ b/src/Safety4D.pas @@ -0,0 +1,262 @@ +unit Safety4D; + +interface + +uses + Safety4D.Interfaces, System.JSON; + +type + TSafety4D = class(TInterfacedObject, iSafety4D) + private + FResources : iSafety4DResources; + FGroupPermission : iSafety4DGroup; + FuserKey : iSafety4DUserKey; + FValidation : iSafety4DValidation; + procedure __loadResourcesJson(var aJson : TJsonObject); + procedure __loadGroupPermissionJson(var aJson : TJsonObject); + procedure __loadUserKeysJson(var aJson : TJsonObject); + public + constructor Create; + destructor Destroy; override; + class function New : iSafety4D; + function Validation : iSafety4DValidation; + function resources : iSafety4DResources; + function groupPermission : iSafety4DGroup; + function userKey : iSafety4DUserKey; + function getConfig (var aJson : TJsonObject ) : iSafety4D; + function SaveToStorage ( aPath : String = '' ) : iSafety4D; + function LoadConfig ( aJson : TJsonObject ) : iSafety4D; + end; + +var + vSafety4D : iSafety4D; + +implementation + +uses + Safety4D.Resources.Register, + Safety4D.Resources, + Safety4D.Groups, + Safety4D.UserKey, + System.SysUtils, + System.Classes, + Rest.Json, Safety4D.Validation; + +{ TSafety4D } + +constructor TSafety4D.Create; +begin + +end; + +destructor TSafety4D.Destroy; +begin + + inherited; +end; + +function TSafety4D.getConfig(var aJson: TJsonObject): iSafety4D; +var + aResource, aGroup, aUser : TJsonObject; +begin + Result := Self; + aJson + .AddPair('resources', TJSONObject.Create) + .AddPair('groupPermission', TJSONObject.Create) + .AddPair('userKeys', TJSONObject.Create); + aResource := aJson.GetValue('resources'); + aGroup := aJson.GetValue('groupPermission'); + aUser := aJson.GetValue('userKeys'); + FResources.getResource(aResource); + FGroupPermission.getGroups(aGroup); + FuserKey.getUserKey(aUser); +end; + +function TSafety4D.groupPermission: iSafety4DGroup; +begin + if not Assigned(FGroupPermission) then + FGroupPermission := TSafety4DGroups.New(self); + + Result := FGroupPermission; +end; + +function TSafety4D.LoadConfig(aJson: TJsonObject): iSafety4D; +var + aJsonResources : TJsonObject; + aJsonGroupPermission : TJsonObject; + aJsonUserKeys : TJsonObject; + aTeste: string; +begin + aTeste := aJson.ToString; + if aJson.TryGetValue('resources', aJsonResources) then + __loadResourcesJson(aJsonResources); + + if aJson.TryGetValue('groupPermission', aJsonGroupPermission) then + __loadGroupPermissionJson(aJsonGroupPermission); + + if aJson.TryGetValue('userKeys', aJsonUserKeys) then + __loadUserKeysJson(aJsonUserKeys); +end; + +class function TSafety4D.New: iSafety4D; +begin + if not Assigned(vSafety4D) then + vSafety4D := Self.Create; + + Result := vSafety4D; +end; + +function TSafety4D.resources: iSafety4DResources; +begin + if not Assigned(FResources) then + FResources := TSafety4DResources.New(Self); + + Result := FResources; +end; + +function TSafety4D.SaveToStorage(aPath: String): iSafety4D; +var + aJsonResult : TJsonObject; + StrList : TStringList; +begin + if Trim(aPath) = '' then + aPath := ChangeFileExt(ParamStr(0), '.s4d'); + aJsonResult := TJsonObject.Create; + StrList := TStringList.Create; + try + Self.getConfig(aJsonResult); + StrList.Add(TJson.Format(aJsonResult)); + StrList.SaveToFile(aPath); + finally + StrList.DisposeOf; + aJsonResult.DisposeOf; + end; +end; + +function TSafety4D.userKey: iSafety4DUserKey; +begin + if not assigned(FuserKey) then + FuserKey := TSafety4DUserKey.New(Self); + + Result := FuserKey; +end; + +function TSafety4D.Validation: iSafety4DValidation; +begin + if not Assigned(FValidation) then + FValidation := TSafety4DValidation.New(Self); + + Result := FValidation; +end; + +procedure TSafety4D.__loadGroupPermissionJson(var aJson: TJsonObject); +var + I : Integer; + FGroupName : String; + aJsonGroup : TJsonObject; + iAction : iSafety4DGroupActions; + iNotAction : iSafety4DGroupNotActions; + aJsonActions : TJsonArray; + aJsonNotActions : TJsonArray; + X: Integer; +begin + for I := 0 to Pred(aJson.Count) do + begin + FGroupName := aJson.Get(I).JsonString.Value; + aJsonGroup := aJson.Get(I).JsonValue as TJsonObject; + aJsonActions := aJsonGroup.GetValue('Actions'); + aJsonNotActions := aJsonGroup.GetValue('NotActions'); + + iAction := + groupPermission + .groupRegister + .add(FGroupName) + .description(aJsonGroup.GetValue('description')) + .key(aJsonGroup.GetValue('key')) + .actions; + + for X := 0 to Pred(aJsonActions.Count) do + begin + iAction.add(aJsonActions.Get(X).Value); + end; + + iNotAction := iAction.&end.notActions; + + for X := 0 to Pred(aJsonNotActions.Count) do + begin + iNotAction.add(aJsonNotActions.Get(X).Value); + end; + end; +end; + +procedure TSafety4D.__loadResourcesJson(var aJson : TJsonObject); +var + I: Integer; + FGroupName: string; + FProviderName : String; + aJsonGroup : TJsonObject; + aJsonProvider : TJsonObject; + aJsonActions : TJsonObject; + J: Integer; + iProviderAction : iSafety4DResourcesGroupProviderActions; + K: Integer; +begin + for I := 0 to Pred(aJson.Count) do + begin + FGroupName := aJson.Get(I).JsonString.Value; + aJsonGroup := aJson.Get(I).JsonValue as TJSONObject; + for J := 0 to Pred(aJsonGroup.Count) do + begin + FProviderName := aJsonGroup.Get(J).JsonString.Value; + aJsonProvider := aJsonGroup.Get(I).JsonValue as TJSONObject; + aJsonActions := aJsonProvider.GetValue('actions'); + + iProviderAction := + resources + .registerResources + .resourcesGroupName + .add(FGroupName) + .providerName + .add(FProviderName) + .actions; + + for K := 0 to Pred(aJsonActions.Count) do + begin + iProviderAction + .add(aJsonActions.Get(K).JsonString.Value) + .description(aJsonActions.Get(K).JsonValue.GetValue('description')) + .errormsg(aJsonActions.Get(K).JsonValue.GetValue('errormsg')) + end; + end; + end; +end; + +procedure TSafety4D.__loadUserKeysJson(var aJson: TJsonObject); +var + I : Integer; + FGroupName : String; + aJsonGroup : TJsonObject; + aJsonPermission : TJsonArray; + X: Integer; + iPermissionGroup : iSafety4DUserKeyRegisterGroupPermission; +begin + for I := 0 to Pred(aJson.Count) do + begin + FGroupName := aJson.Get(I).JsonString.Value; + aJsonGroup := aJson.Get(I).JsonValue as TJsonObject; + aJsonPermission := aJsonGroup.GetValue('permissionGroups'); + + iPermissionGroup := + userKey + .registerUserKey + .add(FGroupName) + .description(aJsonGroup.GetValue('description')); + + for X := 0 to Pred(aJsonPermission.Count) do + begin + iPermissionGroup.addPermission(aJsonPermission.Get(X).Value); + end; + end; +end; + +end.