You are not logged in.
if I write SETUSER ('Domain \ Username', 'password') works, but if I write SETUSER ('','') everything seems to work but if I try to query a table in the db asks me to authenticate again
after I have authenticated with SetUser('','') if I try to run a simple command ,an error occurs in this line of code:
" if (result.Lo<>HTML_FORBIDDEN) or not Assigned(OnAuthentificationFailed) then " because result.Lo=403
function TSQLRestClientURI.URI(const url, method: RawUTF8;
Resp, Head, SendData: PRawUTF8): Int64Rec;
var Retry: integer;
aUserName, aPassword: string;
aResp: RawUTF8;
begin
if self=nil then begin
Int64(result) := HTML_UNAVAILABLE;
exit;
end;
if fServerTimeStampOffset=0 then begin
fServerTimeStampOffset := 0.0001; // avoid endless recursive call
if CallBackGet('TimeStamp',[],aResp)=HTML_SUCCESS then
SetServerTimeStamp(GetInt64(pointer(aResp)));
end;
for Retry := -1 to MaximumAuthentificationRetry do begin
result := InternalURI(SessionSign(url),method,Resp,Head,SendData);
if (result.Lo<>HTML_FORBIDDEN) or not Assigned(OnAuthentificationFailed) then
break;
// "403 Forbidden" in case of authentication failure -> try relog
if not OnAuthentificationFailed(Retry+2,aUserName,aPassword) or
not SetUser(StringToUTF8(aUserName),StringToUTF8(aPassword)) then
break;
end;
end;the version [78837c4156] already contains the following routine:
function TSQLRestServer.Auth(var aParams: TSQLRestServerCallBackParams): Integer;
procedure CreateNewSession(var User: TSQLAuthUser; var aParams: TSQLRestServerCallBackParams);
var Session: TAuthSession;
begin
Session := TAuthSession.Create(self,User);
try
aParams.Resp := JSONEncode(['result',Session.fPrivateSalt,'logonname',User.LogonName]);
User := nil; // will be freed by TAuthSession.Destroy
if fSessions=nil then
fSessions := TObjectList.Create;
fSessions.Add(Session);
Session := nil; // will be freed by fSessions
finally
Session.Free;
end;
end;
var aUserName, aPassWord, aClientNonce, aSalt: RawUTF8;
User: TSQLAuthUser;
aSessionID: cardinal;
i: integer;
{$ifdef SSPIAUTH}
SecCtxId: Cardinal;
InDataEnc: RawUTF8;
CtxArr: TDynArray;
Now: QWord;
SecCtxIdx: Integer;
OutData: RawByteString;
{$endif}
begin
result := HTML_NOTFOUND;
if not UrlDecodeNeedParameters(aParams.Parameters,'UserName') then
exit;
EnterCriticalSection(fSessionCriticalSection);
try
if UrlDecodeNeedParameters(aParams.Parameters,'Session') then begin
// GET ModelRoot/auth?UserName=...&Session=... -> release session
while aParams.Parameters<>nil do begin
UrlDecodeValue(aParams.Parameters,'USERNAME=',aUserName);
UrlDecodeCardinal(aParams.Parameters,'SESSION=',aSessionID,@aParams.Parameters);
end;
if (fSessions<>nil) and
// allow only to delete its own session - ticket [7723fa7ebd]
(aSessionID=aParams.Context.Session) then
for i := 0 to fSessions.Count-1 do
with TAuthSession(fSessions.List[i]) do
if fIDCardinal=aSessionID then begin
SessionDelete(i);
result := HTML_SUCCESS; // mark success
break;
end;
exit; // unknown session -> error 404
end else
if UrlDecodeNeedParameters(aParams.Parameters,'PassWord,ClientNonce') then begin
// GET ModelRoot/auth?UserName=...&PassWord=...&ClientNonce=... -> handshaking
while aParams.Parameters<>nil do begin
UrlDecodeValue(aParams.Parameters,'USERNAME=',aUserName);
UrlDecodeValue(aParams.Parameters,'PASSWORD=',aPassWord);
UrlDecodeValue(aParams.Parameters,'CLIENTNONCE=',aClientNonce,@aParams.Parameters);
end;
User := TSQLAuthUser.Create(self,'LogonName=?',[aUserName]);
try
if User.fID=0 then
exit; // unknown user -> error 404
// check if match TSQLRestClientURI.SetUser() algorithm
aSalt := aClientNonce+User.LogonName+User.PasswordHashHexa;
if (aPassWord<>SHA256(Model.Root+Nonce(false)+aSalt)) and
// if didn't try with current nonce, try with previous 5 minutes nonce
(aPassWord<>SHA256(Model.Root+Nonce(true)+aSalt)) then
Exit;
// now client is authenticated -> create a session
CreateNewSession(User,aParams);
finally
User.Free;
end;
{$ifdef SSPIAUTH}
end else
if UrlDecodeNeedParameters(aParams.Parameters,'ID,DATA') then begin
// GET ModelRoot/auth?UserName=&id=...&data=... -> windows SSPI auth
while aParams.Parameters<>nil do begin
UrlDecodeCardinal(aParams.Parameters,'ID=',SecCtxId);
UrlDecodeValue(aParams.Parameters,'DATA=',InDataEnc,@aParams.Parameters);
end;
EnterCriticalSection(fSSPIAuthCriticalSection);
try
CtxArr.Init(TypeInfo(TSecContexts), fSSPIAuthContexts);
// check for outdated auth context
Now := GetTickCount;
// for i := High(fSSPIAuthContexts) downto 0 do
// if (Now>QWord(fSSPIAuthContexts[i].Created)+QWord(30000)) or
// (fSSPIAuthContexts[i].Created<Int64Rec(Now).Lo) then begin
// // outdated or 49 days GetTickCount value rollback
// FreeSecContext(fSSPIAuthContexts[i]);
// CtxArr.Delete(i);
// end;
for i := High(fSSPIAuthContexts) downto 0 do
if Now < fSSPIAuthContexts[i].Created then // 32 bit overflow occured
fSSPIAuthContexts[i].Created := Now else
if Now>QWord(fSSPIAuthContexts[i].Created)+QWord(30000) then begin
// free outdated context
FreeSecContext(fSSPIAuthContexts[i]);
CtxArr.Delete(i);
end;
// if no auth context specified, create a new one
SecCtxIdx := -1;
if SecCtxId <> 0 then begin
for i := 0 to High(fSSPIAuthContexts) do
if fSSPIAuthContexts[i].ID = SecCtxId then begin
SecCtxIdx := i;
break;
end;
// invalid or outdated id
if SecCtxIdx<0 then
exit;
end;
if SecCtxIdx<0 then begin
// 1st call: create SecCtxId
if High(fSSPIAuthContexts)>MAXSSPIAUTHCONTEXTS then begin
{$ifdef WITHLOG}
SQLite3Log.Family.SynLog.Log(sllUserAuth,
'Too many Windows Authenticated session in pending state: MAXSSPIAUTHCONTEXTS=%',
[MAXSSPIAUTHCONTEXTS],self);
{$endif}
exit;
end;
SecCtxIdx := CtxArr.New; // add a new entry to fSSPIAuthContexts[]
InvalidateSecContext(fSSPIAuthContexts[SecCtxIdx]);
fSSPIAuthContexts[SecCtxIdx].ID := fSSPIAuthCounter;
Inc(fSSPIAuthCounter);
end;
// // call SSPI provider
if ServerSSPIAuth(fSSPIAuthContexts[SecCtxIdx], Base64ToBin(InDataEnc), OutData) then begin
aParams.Resp := JSONEncode(['result','','id',fSSPIAuthContexts[SecCtxIdx].ID,
'data',BinToBase64(OutData)]);
Result := HTML_SUCCESS;
exit; // 1st call: send back OutData to the client
end;
// 2nd call: user was authenticated -> release used context
ServerSSPIAuthUser(fSSPIAuthContexts[SecCtxIdx], aUserName);
{$ifdef WITHLOG}
SQLite3Log.Family.SynLog.Log(sllUserAuth,
'Windows Authentication success for %',[aUserName],self);
{$endif}
FreeSecContext(fSSPIAuthContexts[SecCtxIdx]);
CtxArr.Delete(SecCtxIdx);
finally
LeaveCriticalSection(fSSPIAuthCriticalSection);
end;
if aUserName = '' then
exit;
// now client is authenticated -> create a session for aUserName
User := TSQLAuthUser.Create(self,'LogonName=?',[aUserName]);
try
if User.fID=0 then
exit;
CreateNewSession(User,aParams);
finally
User.Free;
end;
{$endif}
end else
// only UserName=... -> return hexadecimal nonce content valid for 5 minutes
aParams.Resp := JSONEncodeResult([Nonce(false)]);
finally
LeaveCriticalSection(fSessionCriticalSection);
end;
result := HTML_SUCCESS;
end;in my code I setUser( username ='', and Password='') is wrong?
I understand,if I want to signin as ActiveDirectory I must to write username = blank password = blank and as disclosed in the notes:
// - if SSPIAUTH conditional is defined, and aUserName='', a Windows
// authentication will be performed - in this case, aPassword is ignored and
// table TSQLAuthUser shall contain an entry for the logged Windows user,
// with the LoginName in form 'DomainName\UserName'
I have installed this release [78837c4156] and I use this code for connecting to database " ADatabase.SetUser('' ,'') "
this is my code
procedure TFrmToolBarMain.FormCreate(Sender: TObject);
begin
....
resultLogin := ShowLogin(currentClient,GetUserFromWindows); //read user and domain of my pc
.....
end;
function TFrmToolBarMain.ShowLogin(var ADatabase:TSQLRestClientUri;UserName:String;Password:String=''):Boolean;
var
aUserName,aDomain:string;
begin
result := false;
if Assigned(ADatabase.SessionUser) and (sametext(ADatabase.SessionUser.LogonName,UserName)) then
result := true;
//read user and domain of my pc
if not(result) and GetCurrentUserAndDomain(aUserName,aDomain) then
begin
if sametext(UserName,aUserName) then
result := ADatabase.SetUser('' ,'')
end;
if not(result) and TLoginForm.Login('Accesso','Inserire i dati d''accesso',UserName,Password,true,'') then
begin
result := ADatabase.SetUser(UserName ,PassWord);
end;
end;unfortunately there is still an error I'm trying to access a server function and asks me to authenticate as if I had not signed in, but I call this function in the event OnSetUser
Server function:
function TFileServer.PropValue(var aParams: TSQLRestServerCallBackParams): Integer;
var
sPropName:RawUTF8;
Value:RawUTF8;
// NuvRegistry1 : TNuvRegistry;
begin
SQLite3Log.Add.Log(sllInfo,'Start PropValue');
if not UrlDecodeNeedParameters(aParams.Parameters,'PROPNAME') then begin
result := 404; // invalid Request
{$ifNdef SERVICE}
writeln('invalid Request');
{$ENDIF}
SQLite3Log.Add.Log(sllInfo,'Invalid Request - 404');from Client :
procedure TFrmToolBarMain.OnSetUser(Sender: TObject);
var
U : TSQLAuthUser;
AUser : TSQLUser;
sStatusLicense:String;
label GotoCheckLicense;
begin
AUser:=nil;
if CurrentClient.SessionUser<>nil then
begin
if CurrentClient.SessionUser.LogonName<>'' then
begin
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!from Here I was sent the event "OnAuthentificationFailed"
ServerTempDir := UTF8ToString(currentClient.CallBackGetResult('PropValue',['propname',_lbServerTempDir])); if length(ServerTempDir)>0 then
begin
if not (RightStr(ServerTempDir,1)='\') then
ServerTempDir := format('%s\',[ServerTempDir]);
end;
...ok now it is all clear
thanks
a strange thing happens if I run the debug line U.LogonName: = Values [3];
is assigned blank and SessionUser = nil else if I do F8 from delphi and I do not read the line to debug I get the correct result the SessionUser <> nil and SessionUser.logonname <> blank. Is there any timeout? Do not take me for a madman
if U.LogonName='' then begin
{$ifdef SSPIAUTH} // try Windows authentication with the current logged user
InvalidateSecContext(SecCtx);
try
while ClientSSPIAuth(SecCtx, InData, OutData) do begin
// 1st call will return SecCtxId, 2nd call aSessionKey
if CallBackGet('auth',['UserName','','id',SecCtxId,'data',BinToBase64(OutData)],
Response,nil,0)<>HTML_SUCCESS then
exit;
JSONDecode(Response,['result','id','data','logonname'], Values);
aSessionKey := Values[0];
U.LogonName := Values[3]; Here I read blank
if aSessionKey<>'' then
break;
SecCtxId := Values[1];
InData := Base64ToBin(Values[2]);
end;
finally
FreeSecContext(SecCtx);
end;
// authenticated by Windows on the server side: use the returned
// aSessionKey to sign the URI, as usual
{$else}not this time not work I do not think the code is run, an error occurs first
...
// now client is authenticated -> create a session for aUserName
User := TSQLAuthUser.Create(self,'LogonName=?',[aUserName]);
try
if User.fID=0 then
exit;
CreateNewSession(User,aParams);
finally
User.Free;
end;very well, but now the SessionUser.LogonName is blank, how do I read the name of SessionUser?
hello this topic interesting to me you found a solution?
corchi72
ok Thanks
Unfortunately I just verified that I can not change the password of the Administrator are not TSQLAuthUser sen. Right?
var
APassword:String;
AAuthUser:TSQLAuthUser;
begin
if Assigned(CurrentClient) and Assigned(CurrentClient.SessionUser) then
begin
try
AAuthUser := TSQLAuthUser.Create(CurrentClient, 'LogonName=?', [CurrentClient.SessionUser.LogonName]);
if AAuthUser.ID>0 then
begin
APassword := Dialogs.InputBox('Change password', 'New password:','');
if length(trim(APassword))>0 then
begin
AAuthUser.PasswordPlain := APassword;
CurrentClient.Update(AAuthUser);
end;
end;
finally
AAuthUser.Free;
end;
end;
end;ok thanks I think I will manage the user and password as I always have.
however, I would ask how you managed to change password of each user, ie the user can change the password alone has the right or privilege to be administrator?
Can I use window authentication to authenticate to the server automatically without synopse I'll be prompted for the password.
It seems a little difficult but I need this for NT users
I wanted to use the active directory of windows to signin as in MySQL
thanks
ok thanks!
the error is in the fact that is assigned the value of a variable regardless of the parameter "aHandleUserAuthentication "
fHandleAuthentication := (fAuthUserIndex>=0) and (fAuthGroupIndex>=0);I would write:
if aHandleUserAuthentication and (not (fAuthUserIndex>=0) and (fAuthGroupIndex>=0)) then begin
// we need both AuthUser+AuthGroup tables for authentication -> create now
if fAuthUserIndex<0 then
aModel.AddTable(TSQLAuthUser,@fAuthUserIndex);
if fAuthGroupIndex<0 then
aModel.AddTable(TSQLAuthGroup,@fAuthGroupIndex);
fHandleAuthentication := true;
end;I'm sorry but I did not understand I always declare or not? because before in older versions did not serve its reporting the two tables "TSQLAuthUser, TSQLAuthGroup" in the model, because they were created and added to the model if you indicated the parameter "aHandleUserAuthentication" (as shown in the code above), but now in addition to indicating the parameter "aHandleUserAuthentication "is required to manually add the two tables" TSQLAuthUser, TSQLAuthGroup "otherwise the error occurs in the subject. you is?
FileTabs: array[0..10] of TFileRibbonTabParameters = (
(
// (Table: TSQLAuthUser; Select: REL_SELECT; Group: GROUP_MAIN; FieldWidth: 'IddId'; Actions: DEF_ACTIONS),
// (Table: TSQLAuthGroup; Select: REL_SELECT; Group: GROUP_MAIN; FieldWidth: 'IddId'; Actions: DEF_ACTIONS),
(Table: TSQLOption; Select: REL_SELECT; Group: GROUP_MAIN; FieldWidth: 'IddId'; Actions: DEF_ACTIONS),
(Table: TSQLConnection; Select: REL_SELECT; Group: GROUP_MAIN; FieldWidth: 'IddId'; Actions: DEF_ACTIONS),
....
)with the latest versions occurs the error "missing class in Model" when I try to add a user in the table TSQLAuthUser. If, however, point to the name of the two tables in my Model works.
But I have seen this piece of code in the file SQLite3Commons and in theory it should not be necessary to inform it if I put the parameter "HandleAuthentication = True".
I ask this because I use the same model to create a local connection (without authentication) and if I point out the tables and TSQLAuthUser TSQLAuthGroup the program I change the parameter "HandleAuthentication from False to True" with all the consequences.
constructor TSQLRestServer.Create(aModel: TSQLModel; aHandleUserAuthentication: boolean);
var i,n: integer;
C: PtrInt;
M: PMethodInfo;
// RI: PReturnInfo; // such RTTI info not available at least in Delphi 7
begin
// specific server initialization
fVirtualTableDirect := true; // faster direct Static call by default
fAuthUserIndex := aModel.GetTableIndex(TSQLAuthUser);
fAuthGroupIndex := aModel.GetTableIndex(TSQLAuthGroup);
fHandleAuthentication := (fAuthUserIndex>=0) and (fAuthGroupIndex>=0);
if aHandleUserAuthentication and (not fHandleAuthentication) then begin
// we need both AuthUser+AuthGroup tables for authentication -> create now
if fAuthUserIndex<0 then
aModel.AddTable(TSQLAuthUser,@fAuthUserIndex);
if fAuthGroupIndex<0 then
aModel.AddTable(TSQLAuthGroup,@fAuthGroupIndex);
fHandleAuthentication := true;
end;
...thanks corchi
I wrote a client / server and the server is a service.
Then I wrote a client that reads data from the server and processes them.
Now my requirement is if a client can communicate with another client directly or must pass through the server, if server communicate via a server how do I send a message to a particular client?
Sorry for the turn of phrase, but basically I do make a statement to a remote client. how can I do?
Client -> Server -> Client
thanks
perfect now the code is compiled. thank you!
Hi, this morning I downloaded the latest version "[967322735e] Leaf" and while compiling the code I get the following error:
[DCC Hint] cxCalc.pas(494): H2443 Inline function 'Point' has not been expanded because unit 'System.Types' is not specified in USES list
[DCC Error] SQLite3Commons.pas(11895): E2010 Incompatible types: 'PUTF8Char' and 'PAnsiChar'
[DCC Fatal Error] SQLite3.pas(454): F2063 Could not compile used unit 'SQLite3Commons.pas'
tkLString{$ifdef FPC},tkAString{$endif}: begin
GetLongStrProp(Instance,pointer(@self),tmp);
if CaseInsensitive then
if PropType^=TypeInfo(RawUTF8) then
result := crc32(0,Up,UTF8UpperCopy255(Up,tmp)-Up) else
if PropType^=TypeInfo(TSQLRawBlob) then // binary is case sensitive
result := crc32(0,pointer(tmp),length(tmp)) else
result := crc32(0,Up,UpperCopy255(Up,tmp)-Up) else
result := crc32(0,pointer(tmp),length(tmp));
exit;
end;thanks corchi
thank, but There is already an example?
ok ok the my project is composed by :
1)client.exe
2)Server.exe
3)ServerManagement.exe it is realy a client, that I use to connect to server, where It show all SessionUsers into a listbox. In this listbox I select a item,and then I can to decide to close eventuali open sessions
So I must to ask to the server to close a session user from a client not from a Server
Thanks for your answers ab,lele9
ok
ok, thanks.
sorry i want to ask you how to close session user connection from client and from server
from client I close User connection with FreeAndnil(clientDB)
from server I close User connection with this code:
procedure TFrmServerManage.SessionClose(LogonName:RawUTF8;SessionID:cardinal);
var tmp: RawUTF8;
begin
if (Client<>nil) and (Client.SessionUser<>nil) then begin
// notify session closed to server
Client.CallBackGet('auth',['UserName',LogonName,'Session',SessionID],tmp);
end;
end;is right?
It is what I tried to do but I can not communicate with the server before they are connected with username and password,so before I must to do setUSer and after I can read the "Sessions.Count".
{Client}
function TFrmToolBarMain.ShowLogin( ADatabase:TSQLRestClientUri;UserName:String;Password:String):Boolean;
var
AUser :TSQLUser;
CheckLicense:RawUTF8;
begin
result := false;
if TLoginForm.Login('Login,'Insert username and password',UserName,Password,true,'') then
begin
result := ADatabase.SetUser(UserName ,PassWord);
if result then
if length(ADatabase.CallBackGetResult('CheckLicense',['LogonName',StringtoUTF8(UserName)]))=0 then
Application.Terminate;
end
end
....
{server}
function TFileServer.CheckLicense(
var aParams: TSQLRestServerCallBackParams): Integer;
var
sLogonName:RawUTF8;
i:Integer;
begin
SQLite3Log.Enter.Log(sllInfo,'Check License');
if not UrlDecodeNeedParameters(aParams.Parameters,'LogonName') then begin
result := 404; // invalid Request
SQLite3Log.Enter.Log(sllInfo,'Invalid Request - 404');
exit;
end;
while aParams.Parameters<>nil do begin
UrlDecodeValue (aParams.Parameters,'LogonName=',sLogonName,@aParams.Parameters);
end;
SQLite3Log.Enter.Log(sllInfo,format('Read LogonName: %s',[sLogonName]));
if (fSessions.Count>NumberUsers) then //const NumberUsers=5
begin
SQLite3Log.Enter.Log(sllInfo,'Superato numero massimo di accessi - 405');
result := 405; // superato numero massimo di accessi
end
else
begin
SQLite3Log.Enter.Log(sllInfo,format('Accessi rimanenti: %d',[NumberUsers-fSessions.Count]));
aParams.Resp := JSONEncodeResult([NumberUsers-fSessions.Count]);
result := 200;
end;
end;I mean, I want to limit connections to the server to 5.10 concurrent users, it is possible?
I want to create a server with license
thanks
sorry but I did not run the server as Administrator of the machine
thanks corchi
the server is installed on a windows server 2008 machine and the client in win7 64-bit, in all its machines are disabled firewall.
I have tried to reverse the programs I put the server in my pc and the client to the server 2008 and it works, you have any ideas?
Delphi XE2, error is
unit SynCrtSock;
function TWinHttpAPI.Request(const url, method: TSockData;
KeepAlive: cardinal; const InHeader, InData, InDataType: TSockData;
out OutHeader, OutData: TSockData): integer;
var aData, aDataEncoding, aAcceptEncoding, aURL: TSockData;
Bytes, DataLen, Read: DWORD;
i: integer;
begin
..
3802: result := InternalGetInfo32(HTTP_QUERY_STATUS_CODE);
...
Thread Start: Thread ID: 2644. Process Project04Client.exe (4332)
Process Start: C:\Users\Documents\Synopse OpenSource\SQLite3\Samples\04 - HTTP Client-Server\Project04Client.exe. Base Address: $00400000. Process Project04Client.exe (4332)
Module Load: Project04Client.exe. Has Debug Info. Base Address: $00400000. Process Project04Client.exe (4332)
Module Load: ntdll.dll. No Debug Info. Base Address: $776B0000. Process Project04Client.exe (4332)
Module Load: KERNEL32.dll. No Debug Info. Base Address: $76940000. Process Project04Client.exe (4332)
Module Load: KERNELBASE.dll. No Debug Info. Base Address: $76540000. Process Project04Client.exe (4332)
Module Load: OLEAUT32.dll. No Debug Info. Base Address: $76C80000. Process Project04Client.exe (4332)
Module Load: ole32.dll. No Debug Info. Base Address: $750B0000. Process Project04Client.exe (4332)
Module Load: msvcrt.dll. No Debug Info. Base Address: $766B0000. Process Project04Client.exe (4332)
Module Load: GDI32.dll. No Debug Info. Base Address: $76B00000. Process Project04Client.exe (4332)
Module Load: USER32.dll. No Debug Info. Base Address: $74E00000. Process Project04Client.exe (4332)
Module Load: ADVAPI32.dll. No Debug Info. Base Address: $764A0000. Process Project04Client.exe (4332)
Module Load: SECHOST.dll. No Debug Info. Base Address: $76470000. Process Project04Client.exe (4332)
Module Load: RPCRT4.dll. No Debug Info. Base Address: $76B90000. Process Project04Client.exe (4332)
Module Load: SspiCli.dll. No Debug Info. Base Address: $74D90000. Process Project04Client.exe (4332)
Module Load: CRYPTBASE.dll. No Debug Info. Base Address: $74D80000. Process Project04Client.exe (4332)
Module Load: LPK.dll. No Debug Info. Base Address: $77680000. Process Project04Client.exe (4332)
Module Load: USP10.dll. No Debug Info. Base Address: $76D50000. Process Project04Client.exe (4332)
Module Load: MSIMG32.dll. No Debug Info. Base Address: $74650000. Process Project04Client.exe (4332)
Module Load: VERSION.dll. No Debug Info. Base Address: $742F0000. Process Project04Client.exe (4332)
Module Load: COMCTL32.dll. No Debug Info. Base Address: $73DA0000. Process Project04Client.exe (4332)
Module Load: SHLWAPI.dll. No Debug Info. Base Address: $75050000. Process Project04Client.exe (4332)
Module Load: SHELL32.dll. No Debug Info. Base Address: $75220000. Process Project04Client.exe (4332)
Module Load: WINSPOOL.DRV. No Debug Info. Base Address: $74290000. Process Project04Client.exe (4332)
Module Load: WINHTTP.dll. No Debug Info. Base Address: $685A0000. Process Project04Client.exe (4332)
Module Load: webio.dll. No Debug Info. Base Address: $68610000. Process Project04Client.exe (4332)
Module Load: apphelp.dll. No Debug Info. Base Address: $73930000. Process Project04Client.exe (4332)
Module Load: NULL.dll. No Debug Info. Base Address: $72190000. Process Project04Client.exe (4332)
Module Load: USERENV.dll. No Debug Info. Base Address: $73110000. Process Project04Client.exe (4332)
Module Load: profapi.dll. No Debug Info. Base Address: $74B60000. Process Project04Client.exe (4332)
Module Load: MPR.dll. No Debug Info. Base Address: $72320000. Process Project04Client.exe (4332)
Module Load: IMM32.dll. No Debug Info. Base Address: $76040000. Process Project04Client.exe (4332)
Module Load: MSCTF.dll. No Debug Info. Base Address: $76130000. Process Project04Client.exe (4332)
Module Load: UxTheme.dll. No Debug Info. Base Address: $74180000. Process Project04Client.exe (4332)
Module Load: dwmapi.dll. No Debug Info. Base Address: $74160000. Process Project04Client.exe (4332)
Module Load: WTSAPI32.dll. No Debug Info. Base Address: $73200000. Process Project04Client.exe (4332)
Module Load: WINSTA.dll. No Debug Info. Base Address: $73240000. Process Project04Client.exe (4332)
Thread Start: Thread ID: 1752. Process Project04Client.exe (4332)
Thread Start: Thread ID: 3440. Process Project04Client.exe (4332)
Module Load: WS2_32.dll. No Debug Info. Base Address: $76D10000. Process Project04Client.exe (4332)
Module Load: NSI.dll. No Debug Info. Base Address: $74DF0000. Process Project04Client.exe (4332)
Module Load: CRYPTSP.dll. No Debug Info. Base Address: $74BB0000. Process Project04Client.exe (4332)
Module Load: CREDSSP.dll. No Debug Info. Base Address: $72770000. Process Project04Client.exe (4332)
Module Unload: CRYPTSP.dll. Process Project04Client.exe (4332)
Module Load: MSWSOCK.dll. No Debug Info. Base Address: $74A50000. Process Project04Client.exe (4332)
Module Load: WSHTCPIP.dll. No Debug Info. Base Address: $74870000. Process Project04Client.exe (4332)
Module Load: WSHIP6.dll. No Debug Info. Base Address: $74860000. Process Project04Client.exe (4332)
Module Load: DNSAPI.dll. No Debug Info. Base Address: $747E0000. Process Project04Client.exe (4332)
Thread Start: Thread ID: 1536. Process Project04Client.exe (4332)
Thread Start: Thread ID: 380. Process Project04Client.exe (4332)
Module Load: IPHLPAPI.DLL. No Debug Info. Base Address: $74BE0000. Process Project04Client.exe (4332)
Module Load: WINNSI.DLL. No Debug Info. Base Address: $74BD0000. Process Project04Client.exe (4332)
Module Load: rasadhlp.dll. No Debug Info. Base Address: $731B0000. Process Project04Client.exe (4332)
Module Load: fwpuclnt.dll. No Debug Info. Base Address: $72A70000. Process Project04Client.exe (4332)
Thread Start: Thread ID: 4656. Process Project04Client.exe (4332)
First chance exception at $7654B9BC. Exception class EOSError with message
'System Error. Code: 12152.
'.
Process Project04Client.exe (4332)
sorry but I do not work anymore setuser authentication (). The error occurs in the subject 12002.
I also tried the example No. 4 :"Synopse OpenSource \ SQLite3 \ Samples \ 04 - HTTP Client-Server" and does not work.
It only works if I run both the client and the server at localhost
my code does not work
client
program Project04Client;
...
Server := 'terminal2008';
Form1.Database := TSQLite3HttpClient.Create(Server,'888',Form1.Model);
TSQLite3HttpClient(Form1.Database).SetUser('User','synopse');
Application.Run;
TSQLite3HttpClient(Form1.Database).SetUser('User','synopse');
Application.Run;
end.
server
unit Unit2;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
Model := CreateSampleModel;
DB := TSQLRestServerDB.Create(Model,ChangeFileExt(paramstr(0),'.db3'),true);
DB.CreateMissingTables(0);
Server := TSQLite3HttpServer.Create('888',[DB]);
end;it certainly.
thanks corchi
ok thanks, I had also put the user but I think I can recover it from clientDB.sessionuser
I had written:
function TSQLRestClientURI.SetUser(const aUserName, aPassword: RawUTF8;
aHashedPassword: Boolean=false): boolean;
var aNonce, aClientNonce, aSessionKey: RawUTF8;
i: integer;
U: TSQLAuthUser;
begin
result := false;
if self=nil then
exit;
fSessionID := 0;
fSessionIDHexa8 := '';
fSessionPrivateKey := 0;
FreeAndNil(fSessionUser);
if (self=nil) or (aUserName='') then
exit;
U := TSQLAuthUser.Create;
try
U.LogonName := trim(aUserName);
if aHashedPassword then
U.PasswordHashHexa := aPassword else
U.PasswordPlain := aPassword; // PasswordHashHexa := SHA256('salt'+aPassword);
aNonce := CallBackGetResult('auth',['UserName',U.LogonName]);
if aNonce='' then
exit;
aClientNonce := SHA256(NowToString);
aSessionKey := CallBackGetResult('auth',['UserName',U.LogonName,'Password',
Sha256(Model.Root+aNonce+aClientNonce+U.LogonName+U.PasswordHashHexa),
'ClientNonce',aClientNonce]);
i := PosEx(RawUTF8('+'),aSessionKey,1);
if i=0 then
exit; // expect SessionID+HexaSessionPrivateKey
fSessionID := GetCardinal(pointer(aSessionKey));
if fSessionID=0 then
exit;
fSessionIDHexa8 := CardinalToHex(fSessionID);
fSessionPrivateKey := crc32(crc32(0,Pointer(aSessionKey),length(aSessionKey)),
pointer(U.PasswordHashHexa),length(U.PasswordHashHexa));
fSessionUser := U;
OnSuccessfulAuthentication(U);
U := nil;
result := true;
finally
U.Free;
end;
end;
procedure TFrmToolBarMain.OnSuccessfulAuthentication(AuthUser:TSQLAuthUser);
var
U : TSQLAuthUser;
begin
if Assigned(CurrentUser) then currentUser.Free;
try
U := TSQLAuthUser.Create(CurrentClient, 'LogonName=:("%"):', [AuthUser.LogonName]);
CurrentUser := TSQLUser.Create(CurrentClient, 'AuthUserID=:("%"):', [U.ID]);
if Assigned(CurrentUser) then
begin
CurrentUser.AuthUser := U;
CurrentUser.EnabledManagement := CurrentUser.IsAdmin(CurrentClient);
CurrentUser.EnabledSupervisor := CurrentUser.IsSupervisor(CurrentClient);
end;
SetActions(currentUser,false,nil); //this i setting my main menu
if Assigned(CurrentClient) then
Caption:= format('%s - %s', [format(AppName, [GetVersion(Application.ExeName)]), CurrentClient.SessionUser.LogonName ])
else
Caption:= format(AppName, [GetVersion(Application.ExeName)]);
finally
end;
end;sorry but I would ask a favor, to place the event OnSetUser into SETUSER function so I can change the main menu, depending on the user entered? I ask this because in the function of OnAuthentificationFailed if I continue to go wrong password should I disable the actions of the main menu
thanks corchi
I have a problem when the user session expires after 60 minutes the query that I do give me blank result and I do not know whether it is due to the fact that the user session has expired or there are no records that satisfy the query.
thanks corchi
I sorry, but your example number 10 not working, it not generated any sqlite files and even the log file
I have developed a program using the example "Synopse OpenSource \ SQLite3 \ Samples \ 04 - HTTP Client-Server" creating a server-type Console Application. Now I would like to turn the server on a service, what should I write? I ask this because I have created a "Service appliaction" with delphi and then I added the connection to the server SQLite but it don't work
the zipped file "Synopse OpenSource-4f2294edaa12cdaf" does not contain the latest changes below
@@ -10216,9 +10216,11 @@
procedure TPropInfo.CopyValue(Source, Dest: TObject);
var Value: RawByteString;
S,D: TObject;
+{$ifndef LVCL}
i: integer;
+{$endif}
label I64, Int;
begin
if (@self<>nil) and (Source<>nil) and (Dest<>Source) and (Dest<>nil) then
// (PPointer(Source)^=PPointer(Dest)^) then // allow parent into child e.g.
@@ -20579,9 +20581,9 @@
if not (ifHasGuid in IntfFlags) then
raise Exception.CreateFmt('%s interface has no GUID',[ShortName]) else begin
UID[j] := @Guid;
for i := 0 to fList.Count-1 do
- if IsEqualGUID(TServiceFactory(fList.List^[i]).InterfaceIID,Guid) then
+ if IsEqualGUID(TServiceFactory(fList.List[i]).InterfaceIID,Guid) then
raise Exception.CreateFmt('%s GUID already registered',[ShortName]);
end;
// check that all interfaces are implemented by this class
C := aImplementationClass;
@@ -20636,9 +20638,9 @@
if dot=0 then
aInterfaceName := aURI else
aInterfaceName := Copy(aURI,1,dot-1);
for i := 0 to fList.Count-1 do begin
- result := fList.List^[i];
+ result := fList.List[i];
if (aInterfaceName=result.fInterfaceMangledURI) or
IdemPropNameU(aInterfaceName,result.fInterfaceURI) then begin
if dot=0 then
aURI := '' else
@@ -20653,9 +20655,9 @@
function TServiceContainer.Service(aIndex: integer): TServiceFactory;
begin
if (Self=nil) or (Cardinal(aIndex)>=Cardinal(fList.Count)) then
result := nil else
- result := fList.List^[aIndex];
+ result := fList.List[aIndex];
end;
{ TServiceFactoryServer }how do I connect my classes of my Model (FileTables) to jvstringgrid with liveBindings?It's possible?
Thank corchi72
hi, I also bought Delphi x2 and I wanted to compile my program to 64 bit, but there is an error in the file SynCommons, you plan to move to 64 bits?
ok thanks , I like this solution
I created a form for entering login and password that will be used to access the session.
I would like to see the original password in the form, because I want to change the password, what should I write to decrypt the encrypted password with " PasswordHashHexa: = SHA256 ('salt' + value);"
thanks corchi
I'm putting a new property AuthUser :TSQLAuthUser in my current class TSQLUser class and then let you know.
thanks
but I must insert manually the users into the table AuthUser or exist a form with the loginform?
ok thanks. but it means that when I create a user in the class TSQLUser then I have to create it TSQLAuthUser in the class? The new class must be written as:
TSQLUser = Class(TSQLFile)
public
AuthUser :TSQLAuthUser //that I use for the connection?
endSorry I have decided to use the access session and then I convert my current class in TSQLUser TSQLAuthUser.
I tried to derive my class TSQLUser = Class (TSQLAuthUser) but does not work, so now I decided to change the current class TSQLAuthUser to add the fields Name, Last Name and Email etc. ...
The question is what is the right solution to implement the class and the class TSQLAuthUser TSQLAuthGroup?
Thanks corchi72
i use the function TSQLRestClientURI.CallBackGetResult but it does not work anymore, i suppose because i don't use session access. now i don't want to migrate all code to session access, what can i do?
client
...
try
ServerTempDir := UTF8ToString(HttpClient.CallBackGetResult('PropValue',['propname',_lbServerTempDir]));
if length(ServerTempDir)>0 then
begin
if not (RightStr(ServerTempDir,1)='\') then
ServerTempDir := format('%s\',[ServerTempDir]);
end;
except
end;
...server
var
ServerTempDir :String;
...
ServerTempDir := GetTempDir;
writeln(format('Server Temp directory is %s',[ServerTempDir]));
Server := TFileServer.Create(ServerName,inttostr(ServerHttpPort),SQLiteFilename);
write('Press [Enter] to close the server.');
...thanks
After many failed attempts carryover below the code on the server side and client-side code, please tell me where wrong because I do not see any records in the database MSSQL.
Thanks
Client side
/// a HTTP/1.1 client to access SynFile
TFileClient = class(TSQLite3HttpClient)
public
/// initialize the Client for a specified network Server name
constructor Create(const aServer: AnsiString;SeverPort: AnsiString); reintroduce;
/// used internaly to retrieve a given action
function OnSetAction(TableIndex, ToolbarIndex: integer; TestEnabled: boolean;
var Action): string;
/// client-side access to the remote RESTful service
procedure AddAuditTrail(aEvent: TFileEvent; aAssociatedRecord: TSQLRecord);
end;
...
constructor TFileClient.Create(const aServer: AnsiString;SeverPort: AnsiString);
var
i:Integer;
fModel: TSQLModel;
begin
fModel:= CreateFileModel(self);
inherited Create(aServer,SeverPort,fModel);
ForceBlobTransfert := true;
end;Server side
/// a server to access SynFile data content
TFileServer = class(TSQLRestserverDB)
private
fTempAuditTrail: TSQLAuditTrail;
procedure DeleteAssociatedRelations(aEvent: TFileEvent;
const aMessage: RawUTF8; aAssociatedRecord: TRecordReference);
function DeleteField(Table: TSQLRecordClass; Where: integer;
const FieldName: shortstring; FieldValue: integer;
ByID: boolean): boolean;
function AfterDeleteForceCoherency(Table: TSQLRecordClass;
aID: integer): boolean;override;
public
/// the runing HTTP/1.1 server
Server: TSQLite3HttpServer;
/// create the database and HTTP/1.1 server
constructor Create(const ServerName,SeverPort: AnsiString;const aFilename: AnsiString); reintroduce;
/// release used memory and data
destructor Destroy; override;
/// add a row to the TSQLAuditTrail table
procedure AddAuditTrail(aEvent: TFileEvent; const aMessage: RawUTF8='';
aAssociatedRecord: TRecordReference=0);
/// database server-side trigger which will add an event to the
// TSQLAuditTrail table
function OnDatabaseUpdateEvent(Sender: TSQLRestServer;
Event: TSQLEvent; aTable: TSQLRecordClass; aID: integer): boolean;
published
/// a RESTful service used from the client side to add an event
// to the TSQLAuditTrail table
// - an optional database record can be specified in order to be
// associated with the event
function Event(aRecord: TSQLRecord;
aParameters: PUTF8Char; const aSentData: RawUTF8;
var aResp, aHead: RawUTF8): Integer;
function DataAsXML(aRecord: TSQLRecord; aParameters: PUTF8Char;
const aSentData: RawUTF8; out aResp, aHead: RawUTF8): Integer;
function DataAsHex(aRecord: TSQLRecord; aParameters: PUTF8Char;
const aSentData: RawUTF8; out aResp, aHead: RawUTF8): Integer;
function Sum(aRecord: TSQLRecord; aParameters: PUTF8Char;
const aSentData: RawUTF8; var aResp, aHead: RawUTF8): Integer;
function XMLAsData(aRecord: TSQLRecord; aParameters: PUTF8Char;
const aSentData: RawUTF8; out aResp, aHead: RawUTF8): Integer;
function PropValue(aRecord: TSQLRecord; aParameters: PUTF8Char;
const aSentData: RawUTF8; out aResp, aHead: RawUTF8): Integer;
end;
...
constructor TFileServer.Create(const ServerName,SeverPort: AnsiString;const aFilename: AnsiString);
var
i:Integer;
fModel :TSQLModel;
begin
try
writeln(format('file server is %s',[aFilename]));
fModel := CreateFileModel(self);
Props := TOleDBMSSQLConnectionProperties.Create('SQL2008\SQL2008','MyDB','','');
for i := 0 to high(FileTabsEx) do
begin
if FileTabsEx[i] = TSQLUSer then
VirtualTableExternalRegister(fModel,FileTabsEx[i],Props,'Utenti')
else
VirtualTableExternalRegister(fModel,FileTabsEx[i],Props,'');
end;
inherited Create(fModel);
self.ServerTimeStamp;
Server := TSQLite3HttpServer.Create(SeverPort,[self],ServerName);
AddAuditTrail(feServerStarted);
OnUpdateEvent := OnDatabaseUpdateEvent;
with Self do
try
if ExportServer then
writeln('Background server is running.'#10) else
writeln('Error launching the server'#10);
finally
end;
except
on E: Exception do
begin
writeln('Error launching the server' +#10+E.Message);
// handle initialization error here
end;
end;
end;Main form Client side
...
Client := TFileClient.Create(ServerName,ServerHttpPort);Too bad because I have created a model that has 48 classes (tables) with only 13 derive from TSQLRecordSigne and all the others derive from TSQLRecordMany, therefore I conclude that I not being able to use the tables of relationship and so I can not use an external db, If I understand you right.
I had already tried, but I think that TSQLRecordMany not work,