Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | {3373} ensure inherited TSQLAuthUser class will be used to create the TSQLRestClientURI.SessionUser field instance |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
02bb7882b503217939cdf996139df453 |
User & Date: | ab 2017-01-31 18:15:23 |
2017-02-01
| ||
17:23 | {3374} new SplitRight() function check-in: 59e3d1e1ed user: ab tags: trunk | |
2017-01-31
| ||
18:15 | {3373} ensure inherited TSQLAuthUser class will be used to create the TSQLRestClientURI.SessionUser field instance check-in: 02bb7882b5 user: ab tags: trunk | |
2017-01-30
| ||
19:24 | {3372} new TSQLRestClientURI.SessionHeartbeatSeconds property also ensuring that sicClientDriven and sicSession instances are renewed check-in: fe6aa68421 user: ab tags: trunk | |
Changes to SQLite3/mORMot.pas.
9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 ..... 14890 14891 14892 14893 14894 14895 14896 14897 14898 14899 14900 14901 14902 14903 14904 14905 14906 14907 ..... 14966 14967 14968 14969 14970 14971 14972 14973 14974 14975 14976 14977 14978 14979 14980 14981 14982 14983 14984 ..... 16055 16056 16057 16058 16059 16060 16061 16062 16063 16064 16065 16066 16067 16068 ..... 16119 16120 16121 16122 16123 16124 16125 16126 16127 16128 16129 16130 16131 16132 16133 16134 16135 16136 16137 ..... 17053 17054 17055 17056 17057 17058 17059 17060 17061 17062 17063 17064 17065 17066 17067 17068 17069 17070 17071 17072 17073 17074 17075 17076 17077 17078 17079 17080 17081 17082 17083 17084 ..... 32504 32505 32506 32507 32508 32509 32510 32511 32512 32513 32514 32515 32516 32517 ..... 37479 37480 37481 37482 37483 37484 37485 37486 37487 37488 37489 37490 37491 37492 37493 37494 37495 ..... 50902 50903 50904 50905 50906 50907 50908 50909 50910 50911 50912 50913 50914 50915 50916 ..... 51158 51159 51160 51161 51162 51163 51164 51165 51166 51167 51168 51169 51170 51171 51172 |
/// add the class if it doesn't exist yet as itself or as inherited class // - similar to AddTable(), but any class inheriting from the supplied type // will be considered as sufficient // - return the class which has been added, or was already there as // inherited, so that could be used for further instance creation: // ! fSQLAuthUserClass := Model.AddTableInherited(TSQLAuthUser); function AddTableInherited(aTable: TSQLRecordClass): pointer; /// get the index of aTable in Tables[] // - returns -1 if the table is not in the model function GetTableIndex(aTable: TSQLRecordClass): integer; overload; /// get the index of any class inherithing from aTable in Tables[] // - returns -1 if no table is matching in the model function GetTableIndexInheritsFrom(aTable: TSQLRecordClass): integer; /// get the index of aTable in Tables[] ................................................................................ property Ident: RawUTF8 index 50 read fIdent write fIdent stored AS_UNIQUE; /// the number of minutes a session is kept alive property SessionTimeout: integer read fSessionTimeOut write fSessionTimeOut; /// a textual representation of a TSQLAccessRights buffer property AccessRights: RawUTF8 index 1600 read fAccessRights write fAccessRights; end; /// class-reference type (metaclass) of the table containing the available // user access rights for authentication, defined as a group TSQLAuthGroupClass = class of TSQLAuthGroup; /// table containing the Users registered for authentication // - this class should be added to the TSQLModel, together with TSQLAuthGroup, // to allow authentication support // - you can inherit from it to add your custom properties to each user info: // TSQLModel will search for any class inheriting from TSQLAuthUser to manage // per-user authorization data // - by default, it won't be accessible remotely by anyone; to enhance security, ................................................................................ /// some custom data, associated to the User // - Server application may store here custom data // - its content is not used by the framework but 'may' be used by your // application property Data: TSQLRawBlob read fData write fData; end; /// class-reference type (metaclass) of a table containing the Users // registered for authentication // - see also TSQLRestServer.OnAuthenticationUserRetrieve custom event TSQLAuthUserClass = class of TSQLAuthUser; /// class used to maintain in-memory sessions // - this is not a TSQLRecord table so won't be remotely accessible, for // performance and security reasons // - the User field is a true instance, copy of the corresponding database // content (for better speed) // - you can inherit from this class, to add custom session process TAuthSession = class(TSynPersistent) ................................................................................ procedure FindServiceAll(const aServiceName: RawUTF8; aWriter: TTextWriter); overload; /// the number of milliseconds after which an entry expires // - is 0 by default, meaning no expiration // - you can set it to a value so that any service URI registered with // RegisterFromJSON() AFTER this property modification may expire property TimeOut: integer read fTimeOut write fTimeOut; end; /// class-reference type (metaclass) of a REST server TSQLRestServerClass = class of TSQLRestServer; /// some options for TSQLRestServer process // - read-only rsoNoAJAXJSON indicates that JSON data is transmitted in "not // expanded" format: you should NEVER change this option by including ................................................................................ // - any published method of descendants must match TSQLRestServerCallBack // prototype, and is expected to be thread-safe TSQLRestServer = class(TSQLRest) protected fVirtualTableDirect: boolean; fHandleAuthentication: boolean; fBypassORMAuthentication: TSQLURIMethods; fAfterCreation: boolean; fOptions: TSQLRestServerOptions; /// the TSQLAuthUser and TSQLAuthGroup classes, as defined in model fSQLAuthUserClass: TSQLAuthUserClass; fSQLAuthGroupClass: TSQLAuthGroupClass; /// how in-memory sessions are handled fSessionClass: TAuthSessionClass; /// will contain the in-memory representation of some static tables // - this array has the same length as the associated Model.Tables[] // - fStaticData[] will contain pure in-memory tables, not declared as // SQLite3 virtual tables, therefore not available from joined SQL statements fStaticData: TSQLRestDynArray; ................................................................................ // from URI() will call directly the corresponding TSQLRestStorage // instance, for better speed for most used RESTful operations; but complex // SQL requests (e.g. joined SELECT) will rely on the main SQL engine // - if set to false, will use the main SQLite3 engine for all statements // (should not to be used normaly, because it will add unnecessary overhead) property StaticVirtualTableDirect: boolean read fVirtualTableDirect write fVirtualTableDirect; /// the class inheriting from TSQLAuthUser, as defined in the model // - during authentication, this class will be used for every TSQLAuthUser // table access // - see also the OnAuthenticationUserRetrieve optional event handler property SQLAuthUserClass: TSQLAuthUserClass read fSQLAuthUserClass; /// the class inheriting from TSQLAuthGroup, as defined in the model // - during authentication, this class will be used for every TSQLAuthGroup // table access property SQLAuthGroupClass: TSQLAuthGroupClass read fSQLAuthGroupClass; /// the class inheriting from TSQLRecordTableDeleted, as defined in the model // - during authentication, this class will be used for storing a trace of // every deletion of table rows containing a TRecordVersion published field property SQLRecordVersionDeleteTable: TSQLRecordTableDeletedClass read fSQLRecordVersionDeleteTable; /// the class inheriting from TAuthSession to handle in-memory sessions // - since all sessions data remain in memory, ensure they are not taking // too much resource (memory or process time) property SessionClass: TAuthSessionClass read fSessionClass write fSessionClass; published { standard method-based services } /// REST service accessible from ModelRoot/Stat URI to gather detailed information // - returns the current execution statistics of this server, as a JSON object // - this method will require an authenticated client, for safety // - by default, will return the high-level information of this server // - will return human-readable JSON layout if ModelRoot/Stat/json is used, or // the corresponding XML content if ModelRoot/Stat/xml is used ................................................................................ begin ndx := GetTableIndexInheritsFrom(aTable); if ndx<0 then if not AddTable(aTable,@ndx) then raise EModelException.CreateUTF8('%.AddTableInherited(%)',[self,aTable]); result := Tables[ndx]; end; constructor TSQLModel.Create(CloneFrom: TSQLModel); var i: integer; begin if CloneFrom=nil then raise EModelException.CreateUTF8('%.Create(CloneFrom=nil)',[self]); fTables := CloneFrom.fTables; ................................................................................ begin if aModel=nil then raise EORMException.CreateUTF8('%.Create(Model=nil)',[self]); // specific server initialization fStatLevels := SERVERDEFAULTMONITORLEVELS; fVirtualTableDirect := true; // faster direct Static call by default fSessions := TObjectListLocked.Create; // needed by AuthenticationRegister() below fModel := aModel; fSQLAuthUserClass := TSQLAuthUser; fSQLAuthGroupClass := TSQLAuthGroup; fSQLRecordVersionDeleteTable := TSQLRecordTableDeleted; for t := 0 to high(Model.Tables) do if fModel.Tables[t].RecordProps.RecordVersionField<>nil then begin fSQLRecordVersionDeleteTable := fModel.AddTableInherited(TSQLRecordTableDeleted); break; end; fSessionClass := TAuthSession; ................................................................................ key: RawUTF8; begin result := false; if Sender=nil then exit; try Sender.SessionClose; // ensure Sender.SessionUser=nil U := TSQLAuthUser.Create; try U.LogonName := trim(aUserName); U.DisplayName := U.LogonName; if aPasswordKind<>passClear then U.PasswordHashHexa := aPassword else if aHashSalt='' then U.PasswordPlain := aPassword else // compute SHA256('salt'+aPassword) ................................................................................ if aPasswordKind<>passClear then raise ESecurityException.CreateUTF8('%.ClientSetUser(%) expects passClear', [self,Sender]); Sender.SessionClose; // ensure Sender.SessionUser=nil try // inherited ClientSetUser() won't fit with Auth() method below ClientSetUserHttpOnly(Sender,aUserName,aPassword); Sender.fSessionAuthentication := self; // to enable ClientSessionSign() U := TSQLAuthUser.Create; try U.LogonName := trim(aUserName); res := ClientGetSessionKey(Sender,U,[]); if res<>'' then result := Sender.SessionCreate(self,U,res); finally U.Free; |
> > > < < < < < < < < < > > > > > > > > > < < > > < < < < < < < < < > > > > > > > > > > > > > > > > > > < > | | |
9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 ..... 14893 14894 14895 14896 14897 14898 14899 14900 14901 14902 14903 14904 14905 14906 ..... 14965 14966 14967 14968 14969 14970 14971 14972 14973 14974 14975 14976 14977 14978 ..... 16049 16050 16051 16052 16053 16054 16055 16056 16057 16058 16059 16060 16061 16062 16063 16064 16065 16066 16067 16068 16069 16070 16071 ..... 16122 16123 16124 16125 16126 16127 16128 16129 16130 16131 16132 16133 16134 16135 16136 16137 16138 16139 16140 ..... 17056 17057 17058 17059 17060 17061 17062 17063 17064 17065 17066 17067 17068 17069 17070 17071 17072 17073 17074 17075 17076 17077 17078 17079 17080 17081 17082 17083 17084 17085 17086 17087 ..... 32507 32508 32509 32510 32511 32512 32513 32514 32515 32516 32517 32518 32519 32520 32521 32522 32523 32524 32525 32526 32527 32528 32529 ..... 37491 37492 37493 37494 37495 37496 37497 37498 37499 37500 37501 37502 37503 37504 37505 37506 37507 ..... 50914 50915 50916 50917 50918 50919 50920 50921 50922 50923 50924 50925 50926 50927 50928 ..... 51170 51171 51172 51173 51174 51175 51176 51177 51178 51179 51180 51181 51182 51183 51184 |
/// add the class if it doesn't exist yet as itself or as inherited class // - similar to AddTable(), but any class inheriting from the supplied type // will be considered as sufficient // - return the class which has been added, or was already there as // inherited, so that could be used for further instance creation: // ! fSQLAuthUserClass := Model.AddTableInherited(TSQLAuthUser); function AddTableInherited(aTable: TSQLRecordClass): pointer; /// return any class inheriting from the given table in the model // - if the model does not contain such table, supplied aTable is returned function GetTableInherited(aTable: TSQLRecordClass): TSQLRecordClass; /// get the index of aTable in Tables[] // - returns -1 if the table is not in the model function GetTableIndex(aTable: TSQLRecordClass): integer; overload; /// get the index of any class inherithing from aTable in Tables[] // - returns -1 if no table is matching in the model function GetTableIndexInheritsFrom(aTable: TSQLRecordClass): integer; /// get the index of aTable in Tables[] ................................................................................ property Ident: RawUTF8 index 50 read fIdent write fIdent stored AS_UNIQUE; /// the number of minutes a session is kept alive property SessionTimeout: integer read fSessionTimeOut write fSessionTimeOut; /// a textual representation of a TSQLAccessRights buffer property AccessRights: RawUTF8 index 1600 read fAccessRights write fAccessRights; end; /// table containing the Users registered for authentication // - this class should be added to the TSQLModel, together with TSQLAuthGroup, // to allow authentication support // - you can inherit from it to add your custom properties to each user info: // TSQLModel will search for any class inheriting from TSQLAuthUser to manage // per-user authorization data // - by default, it won't be accessible remotely by anyone; to enhance security, ................................................................................ /// some custom data, associated to the User // - Server application may store here custom data // - its content is not used by the framework but 'may' be used by your // application property Data: TSQLRawBlob read fData write fData; end; /// class used to maintain in-memory sessions // - this is not a TSQLRecord table so won't be remotely accessible, for // performance and security reasons // - the User field is a true instance, copy of the corresponding database // content (for better speed) // - you can inherit from this class, to add custom session process TAuthSession = class(TSynPersistent) ................................................................................ procedure FindServiceAll(const aServiceName: RawUTF8; aWriter: TTextWriter); overload; /// the number of milliseconds after which an entry expires // - is 0 by default, meaning no expiration // - you can set it to a value so that any service URI registered with // RegisterFromJSON() AFTER this property modification may expire property TimeOut: integer read fTimeOut write fTimeOut; end; /// class-reference type (metaclass) of a table containing the Users // registered for authentication // - see also TSQLRestServer.OnAuthenticationUserRetrieve custom event TSQLAuthUserClass = class of TSQLAuthUser; /// class-reference type (metaclass) of the table containing the available // user access rights for authentication, defined as a group TSQLAuthGroupClass = class of TSQLAuthGroup; /// class-reference type (metaclass) of a REST server TSQLRestServerClass = class of TSQLRestServer; /// some options for TSQLRestServer process // - read-only rsoNoAJAXJSON indicates that JSON data is transmitted in "not // expanded" format: you should NEVER change this option by including ................................................................................ // - any published method of descendants must match TSQLRestServerCallBack // prototype, and is expected to be thread-safe TSQLRestServer = class(TSQLRest) protected fVirtualTableDirect: boolean; fHandleAuthentication: boolean; fBypassORMAuthentication: TSQLURIMethods; /// the TSQLAuthUser and TSQLAuthGroup classes, as defined in model fSQLAuthUserClass: TSQLAuthUserClass; fSQLAuthGroupClass: TSQLAuthGroupClass; fAfterCreation: boolean; fOptions: TSQLRestServerOptions; /// how in-memory sessions are handled fSessionClass: TAuthSessionClass; /// will contain the in-memory representation of some static tables // - this array has the same length as the associated Model.Tables[] // - fStaticData[] will contain pure in-memory tables, not declared as // SQLite3 virtual tables, therefore not available from joined SQL statements fStaticData: TSQLRestDynArray; ................................................................................ // from URI() will call directly the corresponding TSQLRestStorage // instance, for better speed for most used RESTful operations; but complex // SQL requests (e.g. joined SELECT) will rely on the main SQL engine // - if set to false, will use the main SQLite3 engine for all statements // (should not to be used normaly, because it will add unnecessary overhead) property StaticVirtualTableDirect: boolean read fVirtualTableDirect write fVirtualTableDirect; /// the class inheriting from TSQLRecordTableDeleted, as defined in the model // - during authentication, this class will be used for storing a trace of // every deletion of table rows containing a TRecordVersion published field property SQLRecordVersionDeleteTable: TSQLRecordTableDeletedClass read fSQLRecordVersionDeleteTable; /// the class inheriting from TAuthSession to handle in-memory sessions // - since all sessions data remain in memory, ensure they are not taking // too much resource (memory or process time) property SessionClass: TAuthSessionClass read fSessionClass write fSessionClass; /// the class inheriting from TSQLAuthUser, as defined in the model // - during authentication, this class will be used for every TSQLAuthUser // table access // - see also the OnAuthenticationUserRetrieve optional event handler property SQLAuthUserClass: TSQLAuthUserClass read fSQLAuthUserClass; /// the class inheriting from TSQLAuthGroup, as defined in the model // - during authentication, this class will be used for every TSQLAuthGroup // table access property SQLAuthGroupClass: TSQLAuthGroupClass read fSQLAuthGroupClass; published { standard method-based services } /// REST service accessible from ModelRoot/Stat URI to gather detailed information // - returns the current execution statistics of this server, as a JSON object // - this method will require an authenticated client, for safety // - by default, will return the high-level information of this server // - will return human-readable JSON layout if ModelRoot/Stat/json is used, or // the corresponding XML content if ModelRoot/Stat/xml is used ................................................................................ begin ndx := GetTableIndexInheritsFrom(aTable); if ndx<0 then if not AddTable(aTable,@ndx) then raise EModelException.CreateUTF8('%.AddTableInherited(%)',[self,aTable]); result := Tables[ndx]; end; function TSQLModel.GetTableInherited(aTable: TSQLRecordClass): TSQLRecordClass; var ndx: integer; begin ndx := GetTableIndexInheritsFrom(aTable); if ndx<0 then result := aTable else result := Tables[ndx]; end; constructor TSQLModel.Create(CloneFrom: TSQLModel); var i: integer; begin if CloneFrom=nil then raise EModelException.CreateUTF8('%.Create(CloneFrom=nil)',[self]); fTables := CloneFrom.fTables; ................................................................................ begin if aModel=nil then raise EORMException.CreateUTF8('%.Create(Model=nil)',[self]); // specific server initialization fStatLevels := SERVERDEFAULTMONITORLEVELS; fVirtualTableDirect := true; // faster direct Static call by default fSessions := TObjectListLocked.Create; // needed by AuthenticationRegister() below fSQLAuthUserClass := TSQLAuthUser; fSQLAuthGroupClass := TSQLAuthGroup; fModel := aModel; fSQLRecordVersionDeleteTable := TSQLRecordTableDeleted; for t := 0 to high(Model.Tables) do if fModel.Tables[t].RecordProps.RecordVersionField<>nil then begin fSQLRecordVersionDeleteTable := fModel.AddTableInherited(TSQLRecordTableDeleted); break; end; fSessionClass := TAuthSession; ................................................................................ key: RawUTF8; begin result := false; if Sender=nil then exit; try Sender.SessionClose; // ensure Sender.SessionUser=nil U := TSQLAuthUser(Sender.Model.GetTableInherited(TSQLAuthUser).Create); try U.LogonName := trim(aUserName); U.DisplayName := U.LogonName; if aPasswordKind<>passClear then U.PasswordHashHexa := aPassword else if aHashSalt='' then U.PasswordPlain := aPassword else // compute SHA256('salt'+aPassword) ................................................................................ if aPasswordKind<>passClear then raise ESecurityException.CreateUTF8('%.ClientSetUser(%) expects passClear', [self,Sender]); Sender.SessionClose; // ensure Sender.SessionUser=nil try // inherited ClientSetUser() won't fit with Auth() method below ClientSetUserHttpOnly(Sender,aUserName,aPassword); Sender.fSessionAuthentication := self; // to enable ClientSessionSign() U := TSQLAuthUser(Sender.Model.GetTableInherited(TSQLAuthUser).Create); try U.LogonName := trim(aUserName); res := ClientGetSessionKey(Sender,U,[]); if res<>'' then result := Sender.SessionCreate(self,U,res); finally U.Free; |
Changes to SynopseCommit.inc.
1 |
'1.18.3372'
|
| |
1 |
'1.18.3373'
|