diff --git a/ClientWeb/ClientWeb.dpr b/ClientWeb/ClientWeb.dpr index a0ec3f3..3c72d6a 100644 --- a/ClientWeb/ClientWeb.dpr +++ b/ClientWeb/ClientWeb.dpr @@ -7,7 +7,8 @@ uses WEBLib.Forms, Main.View in 'Src\Main.View.pas' {MainView: TWebForm} {*.html}, Login.View in 'Src\Login.View.pas' {LoginView: TWebForm} {*.html}, - Clientes.Cadastrar.View in 'Src\ClientesCadastrar\Clientes.Cadastrar.View.pas' {ClientesCadastrarView: TWebForm} {*.html}; + Clientes.Cadastrar.View in 'Src\ClientesCadastrar\Clientes.Cadastrar.View.pas' {ClientesCadastrarView: TWebForm} {*.html}, + Configs in 'Src\Configs.pas'; {$R *.res} diff --git a/ClientWeb/ClientWeb.dproj b/ClientWeb/ClientWeb.dproj index d92705b..d8490ab 100644 --- a/ClientWeb/ClientWeb.dproj +++ b/ClientWeb/ClientWeb.dproj @@ -123,6 +123,7 @@ dfm TWebForm + diff --git a/ClientWeb/Src/Configs.pas b/ClientWeb/Src/Configs.pas new file mode 100644 index 0000000..38693da --- /dev/null +++ b/ClientWeb/Src/Configs.pas @@ -0,0 +1,10 @@ +unit Configs; + +interface + +var + Configs_Token: string; + +implementation + +end. diff --git a/ClientWeb/Src/Login.View.dfm b/ClientWeb/Src/Login.View.dfm index d347c3b..e8dfa69 100644 --- a/ClientWeb/Src/Login.View.dfm +++ b/ClientWeb/Src/Login.View.dfm @@ -61,4 +61,16 @@ object LoginView: TLoginView HeightPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000 end + object XDataWebConnection1: TXDataWebConnection + URL = 'http://localhost:2001/tms/auth/' + Connected = True + Left = 72 + Top = 16 + end + object XDataWebClient1: TXDataWebClient + Connection = XDataWebConnection1 + OnError = XDataWebClient1Error + Left = 216 + Top = 16 + end end diff --git a/ClientWeb/Src/Login.View.pas b/ClientWeb/Src/Login.View.pas index 95fe007..1aaff1c 100644 --- a/ClientWeb/Src/Login.View.pas +++ b/ClientWeb/Src/Login.View.pas @@ -5,7 +5,6 @@ interface uses System.SysUtils, System.Classes, - JS, Web, WEBLib.Graphics, WEBLib.Controls, @@ -13,8 +12,7 @@ interface WEBLib.Dialogs, Vcl.Controls, Vcl.StdCtrls, - WEBLib.StdCtrls, - Main.View; + WEBLib.StdCtrls, Main.View, XData.Web.Client, XData.Web.Connection, JS, Configs; type TLoginView = class(TWebForm) @@ -23,11 +21,16 @@ TLoginView = class(TWebForm) edtSenha: TWebEdit; btnEntrar: TWebButton; ckLembrarMe: TWebCheckBox; + [Async] + XDataWebConnection1: TXDataWebConnection; + XDataWebClient1: TXDataWebClient; + [Async] procedure btnEntrarClick(Sender: TObject); procedure WebFormShow(Sender: TObject); procedure edtLoginKeyPress(Sender: TObject; var Key: Char); procedure edtSenhaKeyPress(Sender: TObject; var Key: Char); procedure WebFormCreate(Sender: TObject); + procedure XDataWebClient1Error(Error: TXDataClientError); private public @@ -52,6 +55,16 @@ procedure TLoginView.WebFormShow(Sender: TObject); edtLogin.SetFocus; end; +procedure TLoginView.XDataWebClient1Error(Error: TXDataClientError); +begin + ShowMessage( + 'StatusCode: ' + Error.StatusCode.ToString + sLineBreak + + 'RequestUrl: ' + Error.RequestUrl + sLineBreak + + 'RequestId: ' + Error.RequestId + sLineBreak + + 'ErrorCode: ' + Error.ErrorCode + sLineBreak + + 'ErrorMessage: ' + Error.ErrorMessage); +end; + procedure TLoginView.edtLoginKeyPress(Sender: TObject; var Key: Char); begin if Key = #13 then @@ -65,21 +78,36 @@ procedure TLoginView.edtSenhaKeyPress(Sender: TObject; var Key: Char); end; procedure TLoginView.btnEntrarClick(Sender: TObject); +var + LResponse: TXDataClientResponse; begin - if edtLogin.Text <> 'admin' then + if Trim(edtLogin.Text).IsEmpty or Trim(edtSenha.Text).IsEmpty then begin - ShowMessage('Login inválido'); + ShowMessage('Login e senha devem ser informados'); edtLogin.SetFocus; Exit; end; - if edtSenha.Text <> 'admin' then + LResponse := TAwait.Exec( + XDataWebClient1.RawInvokeAsync('ILoginService.Login', [edtLogin.Text, edtSenha.Text])); + + if LResponse.StatusCode <> 200 then begin - ShowMessage('Senha inválido'); - edtSenha.SetFocus; + ShowMessage('Login ou senha informados são inválidos'); + edtLogin.SetFocus; Exit; end; + Configs_Token := string(TJSObject(LResponse.Result)['value']); + if Configs_Token.Trim.IsEmpty then + begin + ShowMessage('Token não pode ser recuperado'); + edtLogin.SetFocus; + Exit; + end; + + ShowMessage('Token: ' + Configs_Token); + MainView := TMainView.CreateNew; MainView.ShowModal; end; diff --git a/ClientWeb/Src/Main.View.dfm b/ClientWeb/Src/Main.View.dfm index 13c3361..5c37a58 100644 --- a/ClientWeb/Src/Main.View.dfm +++ b/ClientWeb/Src/Main.View.dfm @@ -916,6 +916,8 @@ object MainView: TMainView end object XDataWebConnection1: TXDataWebConnection URL = 'http://localhost:8000/tms/xdata' + OnError = XDataWebConnection1Error + OnRequest = XDataWebConnection1Request Left = 96 Top = 16 end diff --git a/ClientWeb/Src/Main.View.pas b/ClientWeb/Src/Main.View.pas index 1a20b5a..e752094 100644 --- a/ClientWeb/Src/Main.View.pas +++ b/ClientWeb/Src/Main.View.pas @@ -21,10 +21,22 @@ interface XData.Web.Connection, WEBLib.DB, JS, - Clientes.Cadastrar.View, VCL.TMSFNCTypes, VCL.TMSFNCUtils, VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes, System.Rtti, - VCL.TMSFNCDataGridCell, VCL.TMSFNCDataGridData, VCL.TMSFNCDataGridBase, VCL.TMSFNCDataGridCore, - VCL.TMSFNCDataGridRenderer, VCL.TMSFNCCustomControl, VCL.TMSFNCDataGrid, VCL.TMSFNCCustomComponent, - VCL.TMSFNCDataGridDatabaseAdapter; + Clientes.Cadastrar.View, + VCL.TMSFNCTypes, + VCL.TMSFNCUtils, + VCL.TMSFNCGraphics, + VCL.TMSFNCGraphicsTypes, + System.Rtti, + VCL.TMSFNCDataGridCell, + VCL.TMSFNCDataGridData, + VCL.TMSFNCDataGridBase, + VCL.TMSFNCDataGridCore, + VCL.TMSFNCDataGridRenderer, + VCL.TMSFNCCustomControl, + VCL.TMSFNCDataGrid, + VCL.TMSFNCCustomComponent, + VCL.TMSFNCDataGridDatabaseAdapter, + Configs; type TMainView = class(TWebForm) @@ -73,6 +85,8 @@ TMainView = class(TWebForm) [Async] procedure btnDeleteClick(Sender: TObject); procedure XDataWebClient1Error(Error: TXDataClientError); + procedure XDataWebConnection1Error(Error: TXDataWebConnectionError); + procedure XDataWebConnection1Request(Args: TXDataWebConnectionRequest); private function GetClientePreenchido(const AView: TClientesCadastrarView): TJSObject; public @@ -131,6 +145,16 @@ procedure TMainView.XDataWebClient1Error(Error: TXDataClientError); 'ErrorMessage: ' + Error.ErrorMessage); end; +procedure TMainView.XDataWebConnection1Error(Error: TXDataWebConnectionError); +begin + ShowMessage('StatusCode: ' + Error.ErrorMessage); +end; + +procedure TMainView.XDataWebConnection1Request(Args: TXDataWebConnectionRequest); +begin + Args.Request.Headers.SetValue('Authorization', 'Bearer ' + Configs_Token); +end; + procedure TMainView.btnGetNomeClick(Sender: TObject); var LResponse: TXDataClientResponse; @@ -142,6 +166,9 @@ procedure TMainView.btnGetNomeClick(Sender: TObject); Exit; end; + if not XDataWebConnection1.Connected then + XDataWebConnection1.Open; + LResponse := TAwait.Exec( XDataWebClient1.RawInvokeAsync('IClientesService.GetNome', [StrToIntDef(edtCodigo.Text, 0)])); @@ -159,6 +186,9 @@ procedure TMainView.btnGetClick(Sender: TObject); Exit; end; + if not XDataWebConnection1.Connected then + XDataWebConnection1.Open; + LResponse := TAwait.Exec( XDataWebClient1.RawInvokeAsync('IClientesService.Get', [StrToIntDef(edtCodigo.Text, 0)])); @@ -180,6 +210,9 @@ procedure TMainView.btnListarClick(Sender: TObject); var LResponse: TXDataClientResponse; begin + if not XDataWebConnection1.Connected then + XDataWebConnection1.Open; + LResponse := TAwait.Exec( XDataWebClient1.RawInvokeAsync('IClientesService.List', [])); @@ -200,6 +233,9 @@ procedure TMainView.btnDeleteClick(Sender: TObject); var LResponse: TXDataClientResponse; begin + if not XDataWebConnection1.Connected then + XDataWebConnection1.Open; + if await(TModalResult, MessageDlgAsync('Confirma realmente deletar o registro?', mtConfirmation, [mbYes, mbNo])) <> mrYes then Exit; diff --git a/DelphiWebGroup.groupproj b/DelphiWebGroup.groupproj index 5f167e3..a918b6a 100644 --- a/DelphiWebGroup.groupproj +++ b/DelphiWebGroup.groupproj @@ -9,6 +9,9 @@ + + + Default.Personality.12 @@ -35,14 +38,23 @@ + + + + + + + + + - + - + - + diff --git a/README.md b/README.md index e3ff83b..81d9477 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@
-## â–¶ï¸ Vídeos de criação do projeto no Youtube +## â–¶ï¸ Vídeos da criação do projeto no Youtube - [Delphi Web #01 - Apresentação e início da criação do back-end](https://www.youtube.com/watch?v=qrFUxkFV0vQ&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=1) - [Delphi Web #02 - Endpoint | Verbo Get | Get e List | Consultando dados na API](https://www.youtube.com/watch?v=j5RoRTDNx3o&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=2) - [Delphi Web #03 - Inserindo dados na API Rest | Verbos HTTP Post, Put e Delete | Postman](https://www.youtube.com/watch?v=dt23lMZmLpw&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=3) @@ -44,6 +44,11 @@ - [Delphi Web #13 - Post e Put com dados do formulário popup](https://www.youtube.com/watch?v=CpeKncJJ1wo&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=13) - [Delphi Web #14 - Ajustes no template Bootstrap](https://www.youtube.com/watch?v=xoStVXAkKGc&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=14) - [Delphi Web #15 - FNC Data Grid - Exibindo dados](https://www.youtube.com/watch?v=lKvuE54d4X0&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=15) +- [Delphi Web #16 - Desenvolvendo Web de forma RAD - Web Form Designer](https://www.youtube.com/watch?v=z5h350NwFso&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=16) + - [Repositório do projeto de demonstração do Web Form Designer](https://github.com/Code4Delphi/Web-Form-Designer) + - [Delphi Web #17 - O que é e como usar JWT no Delphi](https://www.youtube.com/watch?v=uYTB_q-C0MY&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=17) + - [Postagem no blog com tudo que você precisa saber sobre JWT no Delphi](https://code4delphi.com.br/blog/jwt-no-delphi-o-que-e-e-como-utilizar/) + - [Delphi Web #18 - O que é e como usar JWT no Delphi - Middleware JWT](https://www.youtube.com/watch?v=Jgo9vx5La_0&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=18)
diff --git a/Server/Src/XData.DM.dfm b/Server/Src/XData.DM.dfm index d27f8ac..46971e3 100644 --- a/Server/Src/XData.DM.dfm +++ b/Server/Src/XData.DM.dfm @@ -13,6 +13,11 @@ object XDataDM: TXDataDM end object XDataServer1Compress: TSparkleCompressMiddleware end + object XDataServer1JWT: TSparkleJwtMiddleware + ForbidAnonymousAccess = True + OnGetSecretEx = XDataServer1JWTGetSecretEx + OnForbidRequest = XDataServer1JWTForbidRequest + end end object SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher Left = 128 diff --git a/Server/Src/XData.DM.pas b/Server/Src/XData.DM.pas index fa5d414..a3677aa 100644 --- a/Server/Src/XData.DM.pas +++ b/Server/Src/XData.DM.pas @@ -10,7 +10,9 @@ interface XData.Server.Module, Sparkle.Comp.Server, Sparkle.Comp.HttpSysDispatcher, - XData.Comp.Server, Sparkle.Comp.CompressMiddleware, Sparkle.Comp.CorsMiddleware; + XData.Comp.Server, + Sparkle.Comp.CompressMiddleware, + Sparkle.Comp.CorsMiddleware, Sparkle.Comp.JwtMiddleware; type TXDataDM = class(TDataModule) @@ -18,6 +20,10 @@ TXDataDM = class(TDataModule) SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher; XDataServer1CORS: TSparkleCorsMiddleware; XDataServer1Compress: TSparkleCompressMiddleware; + XDataServer1JWT: TSparkleJwtMiddleware; + procedure XDataServer1JWTGetSecretEx(Sender: TObject; const JWT: TJWT; Context: THttpServerContext; + var Secret: TBytes); + procedure XDataServer1JWTForbidRequest(Sender: TObject; Context: THttpServerContext; var Forbid: Boolean); private public @@ -33,4 +39,16 @@ implementation {$R *.dfm} +procedure TXDataDM.XDataServer1JWTForbidRequest(Sender: TObject; Context: THttpServerContext; var Forbid: Boolean); +begin + if Context.Request.Uri.AbsolutePath.Contains('swagger') then + Forbid := False; +end; + +procedure TXDataDM.XDataServer1JWTGetSecretEx(Sender: TObject; const JWT: TJWT; Context: THttpServerContext; + var Secret: TBytes); +begin + Secret := TEncoding.UTF8.GetBytes('sua-chave-secreta-1234567890-12345'); +end; + end. diff --git a/ServerAuth/ServerAuth.dpr b/ServerAuth/ServerAuth.dpr new file mode 100644 index 0000000..0da9021 --- /dev/null +++ b/ServerAuth/ServerAuth.dpr @@ -0,0 +1,18 @@ +program ServerAuth; + +uses + Vcl.Forms, + ServerAuth.Main.View in 'Src\ServerAuth.Main.View.pas' {ServerAuthMainView}, + ServerAuth.XData.DM in 'Src\ServerAuth.XData.DM.pas' {ServerAuthXDataDM: TDataModule}, + LoginService in 'Src\LoginService\LoginService.pas', + LoginServiceImplementation in 'Src\LoginService\LoginServiceImplementation.pas'; + +{$R *.res} + +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.CreateForm(TServerAuthXDataDM, ServerAuthXDataDM); + Application.CreateForm(TServerAuthMainView, ServerAuthMainView); + Application.Run; +end. diff --git a/ServerAuth/ServerAuth.dproj b/ServerAuth/ServerAuth.dproj new file mode 100644 index 0000000..a85186d --- /dev/null +++ b/ServerAuth/ServerAuth.dproj @@ -0,0 +1,1122 @@ + + + {79CF7CA6-4D5B-496E-A39D-A4381CDA2C38} + 20.2 + VCL + True + Debug + Win32 + ServerAuth + 3 + Application + ServerAuth.dpr + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + 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 + ServerAuth + + + vclwinx;DataSnapServer;ACBr_BPeDabpeESCPOS;ACBr_TCP;ACBr_ONE;ACBr_NFCom;fs29;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;bsfd103Rio;ACBr_OpenSSL;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;aurelius;dbxcds;vcledge;FMX_FlexCel_Components;FmxTeeUI;VCLTMSFNCChartPkgDXE15;ACBr_BoletoRL;FlexCel_Pdf;DBXFirebirdDriver;ACBr_CTeDacteFR;FMXTMSFNCChartPkgDXE15;ACBr_NFCeECFVirtual;ACBr_DCeDACERL;FireDACSqliteDriver;DbxClientDriver;soapmidas;ACBr_NF3eDANF3eESCPOS;TeeUI;ACBr_PagFor;dbexpress;ACBr_Reinf;ACBr_NFSeXDanfseFPDF;inet;ACBr_BoletoFPDF;vcltouch;FMX_FlexCel_Core;FireDACDBXDriver;ACBr_NF3eDANF3eRL;fmxdae;tmsbcl;VCL_FlexCel_Core;CustomIPTransport;FireDACMSSQLDriver;C4DDateEdit;ZCore;ACBr_NFSeX;ZParseSql;C4DWizard;ACBr_NFe;frxPDF29;ACBr_CTeDacteRL;C4DMaskEdit;IndySystem;ACBr_Diversos;ACBr_GNREGuiaRL;BossExperts;frxe29;ZipMasterR;ACBr_NFSeXDanfseRL;ACBr_SAT;ACBr_CIOT;VirtualTreesR;ACBr_TEFD;fsDB29;VDOPrint;vclFireDAC;ACBr_SPED;ACBr_CTe;ACBr_SATWS;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;DelphiAIDeveloper;ACBr_SEF2;ACBr_LCDPR;ACBr_SATExtratoFPDF;FlexCel_Render;ZComponent;bindcompdbx;rtl;FireDACMySQLDriver;ACBr_NFeDanfeFR;ACBr_DCe;VCL_FlexCel_Components;frce;ACBr_BPe;DBXSqliteDriver;ACBr_Sintegra;DBXSybaseASEDriver;TMSWEBCorePkgDXE15;ACBr_Serial;ACBr_Comum;ACBr_MDFe;ACBr_NFeDanfeESCPOS;vclimg;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;dsnap;xdata;FireDACDb2Driver;DBXOracleDriver;DBXInformixDriver;ACBr_SATECFVirtual;fmxobj;bindcompvclsmp;DataSnapNativeClient;frx29;ACBr_SATExtratoFR;DatasnapConnectorsFreePascal;FMXTMSFNCUIPackPkgDXE15;frxIntIOIndy29;ACBr_NF3e;ACBr_PAF;ACBr_OpenDelivery;ACBr_NFeDanfeFPDF;ACBr_MDFeDamdfeFR;TMSFNCCorePkgDXE15;ACBr_SPEDImportar;FMXTMSFNCCorePkgDXE15;emshosting;sparkle;MSNPopUp_D104;frxDB29;FireDACCommonDriver;ACBr_ADRCST;ACBr_MTER;IndyIPClient;frxHTML29;bindcompvclwinx;ACBr_Convenio115;emsedge;bindcompfmx;inetdb;FireDACASADriver;ACBr_LFD;Tee;vclactnband;fmxFireDAC;FireDACInfxDriver;DBXMySQLDriver;fsADO29;VclSmp;ACBr_Ponto;DataSnapCommon;fmxase;DBXOdbcDriver;dbrtl;FireDACOracleDriver;Skia.Package.FMX;ACBre_Social;TeeDB;FlexCel_XlsAdapter;FireDACMSAccDriver;frxcs29;DataSnapIndy10ServerTransport;DataSnapConnectors;ACBr_ANe;ACBr_SATExtratoRL;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;ACBR_DeSTDA;PngComponentsD;ACBr_GNRE;ACBr_EDI;FireDACTDataDriver;Skia.Package.VCL;VCLTMSFNCUIPackPkgDXE15;vcldb;ACBr_Integrador;ACBr_PIXCD;FlexCel_Core;ACBr_BoletoFR;bindcomp;inetstn;IndyCore;RESTBackendComponents;ZPlain;frxIntIO29;FireDACADSDriver;RESTComponents;ACBr_NFSeXDANFSeFR;IndyIPServer;vcl;dsnapxml;adortl;dsnapcon;DataSnapClient;DataSnapProviderClient;ACBr_MDFeDamdfeRL;frxADO29;DBXDb2Driver;ACBr_Boleto;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;ACBr_BlocoX;ACBrBaaS;tethering;ACBr_SATExtratoESCPOS;ZDbc;bindcompvcl;ACBr_GTIN;CloudService;DBXSybaseASADriver;ACBr_OFX;ACBr_PAFNFCe;FMXTee;ACBr_DebitoAutomatico;ACBr_NFeDanfeRL;TMSWEBCorePkgLibDXE15;DSPack_DXE2;ACBr_GNREGuiaFR;VCLTMSFNCCorePkgDXE15;soaprtl;soapserver;FireDACIBDriver;$(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 + + + vclwinx;DataSnapServer;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;appanalytics;IndyProtocols;vclx;dbxcds;vcledge;FMX_FlexCel_Components;FmxTeeUI;VCLTMSFNCChartPkgDXE15;FlexCel_Pdf;DBXFirebirdDriver;FMXTMSFNCChartPkgDXE15;FireDACSqliteDriver;DbxClientDriver;soapmidas;TeeUI;dbexpress;inet;vcltouch;FMX_FlexCel_Core;FireDACDBXDriver;fmxdae;VCL_FlexCel_Core;CustomIPTransport;FireDACMSSQLDriver;ZCore;ZParseSql;IndySystem;ZipMasterR;VirtualTreesR;vclFireDAC;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;FlexCel_Render;ZComponent;bindcompdbx;rtl;FireDACMySQLDriver;VCL_FlexCel_Components;DBXSqliteDriver;DBXSybaseASEDriver;vclimg;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;dsnap;FireDACDb2Driver;DBXOracleDriver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;DatasnapConnectorsFreePascal;FMXTMSFNCUIPackPkgDXE15;TMSFNCCorePkgDXE15;FMXTMSFNCCorePkgDXE15;emshosting;FireDACCommonDriver;IndyIPClient;bindcompvclwinx;emsedge;bindcompfmx;inetdb;FireDACASADriver;Tee;vclactnband;fmxFireDAC;FireDACInfxDriver;DBXMySQLDriver;VclSmp;DataSnapCommon;fmxase;DBXOdbcDriver;dbrtl;FireDACOracleDriver;TeeDB;FlexCel_XlsAdapter;FireDACMSAccDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;PngComponentsD;FireDACTDataDriver;Skia.Package.VCL;VCLTMSFNCUIPackPkgDXE15;vcldb;FlexCel_Core;bindcomp;inetstn;IndyCore;RESTBackendComponents;ZPlain;FireDACADSDriver;RESTComponents;IndyIPServer;vcl;dsnapxml;adortl;dsnapcon;DataSnapClient;DataSnapProviderClient;DBXDb2Driver;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;tethering;ZDbc;bindcompvcl;CloudService;DBXSybaseASADriver;FMXTee;DSPack_DXE2;VCLTMSFNCCorePkgDXE15;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(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 + + + DEBUG;$(DCC_Define) + true + false + true + true + true + true + true + + + false + PerMonitorV2 + true + 1033 + + + PerMonitorV2 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + PerMonitorV2 + + + PerMonitorV2 + + + + MainSource + + +
ServerAuthMainView
+ dfm +
+ +
ServerAuthXDataDM
+ dfm + TDataModule +
+ + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + Application + + + + ServerAuth.dpr + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + ServerAuth.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + res\xml + 1 + + + res\xml + 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\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 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 + + + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 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 + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 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 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 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\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 + + + + + + + + + + + + + + + + + True + True + + + 12 + + + + +
diff --git a/ServerAuth/ServerAuth.res b/ServerAuth/ServerAuth.res new file mode 100644 index 0000000..089da62 Binary files /dev/null and b/ServerAuth/ServerAuth.res differ diff --git a/ServerAuth/Src/LoginService/LoginService.pas b/ServerAuth/Src/LoginService/LoginService.pas new file mode 100644 index 0000000..997a2a0 --- /dev/null +++ b/ServerAuth/Src/LoginService/LoginService.pas @@ -0,0 +1,21 @@ +unit LoginService; + +interface + +uses + XData.Service.Common; + +type + [ServiceContract] + ILoginService = interface(IInvokable) + ['{B9EC981F-FFC0-4171-8E46-8CAA2D301B21}'] + [HttpPost, Route('')] + function Login(const User, Password: string): string; + end; + +implementation + +initialization + RegisterServiceType(TypeInfo(ILoginService)); + +end. diff --git a/ServerAuth/Src/LoginService/LoginServiceImplementation.pas b/ServerAuth/Src/LoginService/LoginServiceImplementation.pas new file mode 100644 index 0000000..e337d75 --- /dev/null +++ b/ServerAuth/Src/LoginService/LoginServiceImplementation.pas @@ -0,0 +1,52 @@ +unit LoginServiceImplementation; + +interface + +uses + System.SysUtils, + XData.Server.Module, + XData.Service.Common, + LoginService, + Bcl.JOSE.Core.Builder, + Bcl.Jose.Core.JWA, + Bcl.JOSE.Core.JWT, + Bcl.JOSE.Core.JWK; + +type + [ServiceImplementation] + TLoginService = class(TInterfacedObject, ILoginService) + private + function Login(const User, Password: string): string; + end; + +implementation + +function TLoginService.Login(const User, Password: string): string; +var + JWT: TJWT; +begin + if (User <> 'admin') or (Password <> 'admin') then + raise Exception.Create('Usuário ou senha inválidos'); + + JWT := TJWT.Create; + try + //CLAIMS RESERVADAS + JWT.Claims.Issuer := 'Code4Delphi'; + JWT.Claims.Subject := '123'; + JWT.Claims.Expiration := Now + 100; + + //MINHAS CLAIMS + JWT.Claims.SetClaimOfType('usuario', User); + JWT.Claims.SetClaimOfType('admin', True); + JWT.Claims.SetClaimOfType('teste', 'asdf'); + + Result := TJOSE.SHA256CompactToken('sua-chave-secreta-1234567890-12345', JWT); + finally + JWT.Free; + end; +end; + +initialization + RegisterServiceType(TLoginService); + +end. diff --git a/ServerAuth/Src/ServerAuth.Main.View.dfm b/ServerAuth/Src/ServerAuth.Main.View.dfm new file mode 100644 index 0000000..12a1358 --- /dev/null +++ b/ServerAuth/Src/ServerAuth.Main.View.dfm @@ -0,0 +1,51 @@ +object ServerAuthMainView: TServerAuthMainView + Left = 0 + Top = 0 + Caption = 'ServerAuthMainView' + ClientHeight = 343 + ClientWidth = 545 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Segoe UI' + Font.Style = [] + Position = poScreenCenter + OnCreate = FormCreate + TextHeight = 15 + object btnStart: TButton + Left = 24 + Top = 16 + Width = 75 + Height = 25 + Caption = 'Start' + TabOrder = 0 + OnClick = btnStartClick + end + object btnStop: TButton + Left = 105 + Top = 16 + Width = 75 + Height = 25 + Caption = 'Stop' + TabOrder = 1 + OnClick = btnStopClick + end + object mmLog: TMemo + Left = 24 + Top = 64 + Width = 505 + Height = 257 + ScrollBars = ssVertical + TabOrder = 2 + end + object btnSwaggerDocumentacao: TButton + Left = 336 + Top = 16 + Width = 193 + Height = 25 + Caption = 'Abrir documenta'#231#227'o Swagger' + TabOrder = 3 + OnClick = btnSwaggerDocumentacaoClick + end +end diff --git a/ServerAuth/Src/ServerAuth.Main.View.pas b/ServerAuth/Src/ServerAuth.Main.View.pas new file mode 100644 index 0000000..402098e --- /dev/null +++ b/ServerAuth/Src/ServerAuth.Main.View.pas @@ -0,0 +1,88 @@ +unit ServerAuth.Main.View; + +interface + +uses + Winapi.Windows, + Winapi.Messages, + System.SysUtils, + System.Variants, + System.Classes, + ShellAPI, + Vcl.Graphics, + Vcl.Controls, + Vcl.Forms, + Vcl.Dialogs, + Vcl.StdCtrls, + ServerAuth.XData.DM; + +type + TServerAuthMainView = class(TForm) + btnStart: TButton; + btnStop: TButton; + mmLog: TMemo; + btnSwaggerDocumentacao: TButton; + procedure FormCreate(Sender: TObject); + procedure btnStartClick(Sender: TObject); + procedure btnStopClick(Sender: TObject); + procedure btnSwaggerDocumentacaoClick(Sender: TObject); + private + procedure AtualizarTela; + function GetServerBaseUrl: string; + public + end; + +var + ServerAuthMainView: TServerAuthMainView; + +implementation + +{$R *.dfm} + +procedure TServerAuthMainView.FormCreate(Sender: TObject); +begin + ReportMemoryLeaksOnShutdown := True; + Self.AtualizarTela; +end; + +function TServerAuthMainView.GetServerBaseUrl: string; +const + HTTP = 'http://+'; + HTTP_LOCALHOST = 'http://localhost'; +begin + Result := ServerAuthXDataDM.XDataServer1.BaseUrl.Replace(HTTP, HTTP_LOCALHOST, [rfIgnoreCase]); +end; + +procedure TServerAuthMainView.AtualizarTela; +begin + btnStop.Enabled := ServerAuthXDataDM.SparkleHttpSysDispatcher1.Active; + btnStart.Enabled := not btnStop.Enabled; + + if ServerAuthXDataDM.SparkleHttpSysDispatcher1.Active then + begin + mmLog.Lines.Add('Servidor iniciado em:'); + mmLog.Lines.Add(Self.GetServerBaseUrl); + mmLog.Lines.Add(Self.GetServerBaseUrl + '/LoginService/'); + end + else + mmLog.Lines.Add('Servidor parado'); +end; + +procedure TServerAuthMainView.btnStartClick(Sender: TObject); +begin + ServerAuthXDataDM.SparkleHttpSysDispatcher1.Start; + Self.AtualizarTela; +end; + +procedure TServerAuthMainView.btnStopClick(Sender: TObject); +begin + ServerAuthXDataDM.SparkleHttpSysDispatcher1.Stop; + Self.AtualizarTela; +end; + +procedure TServerAuthMainView.btnSwaggerDocumentacaoClick(Sender: TObject); +begin + ShellExecute(Handle, 'open', PChar(Self.GetServerBaseUrl + '/swaggerui'), nil, nil, SW_SHOWNORMAL); +end; + +end. diff --git a/ServerAuth/Src/ServerAuth.XData.DM.dfm b/ServerAuth/Src/ServerAuth.XData.DM.dfm new file mode 100644 index 0000000..b702148 --- /dev/null +++ b/ServerAuth/Src/ServerAuth.XData.DM.dfm @@ -0,0 +1,21 @@ +object ServerAuthXDataDM: TServerAuthXDataDM + Height = 480 + Width = 640 + object SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher + Left = 136 + Top = 80 + end + object XDataServer1: TXDataServer + BaseUrl = 'http://+:2001/tms/auth' + Dispatcher = SparkleHttpSysDispatcher1 + EntitySetPermissions = <> + SwaggerOptions.Enabled = True + SwaggerUIOptions.Enabled = True + Left = 136 + Top = 144 + object XDataServer1CORS: TSparkleCorsMiddleware + end + object XDataServer1Compress: TSparkleCompressMiddleware + end + end +end diff --git a/ServerAuth/Src/ServerAuth.XData.DM.pas b/ServerAuth/Src/ServerAuth.XData.DM.pas new file mode 100644 index 0000000..4458b08 --- /dev/null +++ b/ServerAuth/Src/ServerAuth.XData.DM.pas @@ -0,0 +1,36 @@ +unit ServerAuth.XData.DM; + +interface + +uses + System.SysUtils, + System.Classes, + Sparkle.HttpServer.Module, + Sparkle.HttpServer.Context, + XData.Server.Module, + Sparkle.Comp.Server, + XData.Comp.Server, + Sparkle.Comp.HttpSysDispatcher, Sparkle.Comp.CompressMiddleware, Sparkle.Comp.CorsMiddleware; + +type + TServerAuthXDataDM = class(TDataModule) + SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher; + XDataServer1: TXDataServer; + XDataServer1CORS: TSparkleCorsMiddleware; + XDataServer1Compress: TSparkleCompressMiddleware; + private + + public + + end; + +var + ServerAuthXDataDM: TServerAuthXDataDM; + +implementation + +{%CLASSGROUP 'Vcl.Controls.TControl'} + +{$R *.dfm} + +end.