Send credentials in SOAP header - authentication

I'm trying to develop a small program in Delphi xe10.3 to get data from a web service using SOAP.
The WSDL is https://www1.gsis.gr/wsaade/RgWsPublic2/RgWsPublic2?WSDL.
I did import it into Delphi.
The problem I’m facing is that I couldn’t find a working way to pass the credentials (basic authentication) into request header even I did use some methods I found on the web. The service responds that there are not credentials into request.
I want to mention that this is my first try to use SOAP technology and I have been confused. It will be appreciated if someone could help me to resolve this issue.
The code is :
procedure TForm1.EchoClick(Sender: TObject);
var Service : RgWsPublic2Service_Interface;
httpRio : THTTPRIO;
inpr : rg_ws_public2_input_rtType2;
ddate : TXSDate;
ReturnInfo : Result;
AskedInfo : rg_ws_public2_basic_rtType2;
ErrorStr : string;
begin
httpRio := THTTPRIO.Create(nil);
ReturnInfo := Result.Create;
ddate := TXSdate.Create;
ddate.AsDate := date;
inpr := rg_ws_public2_input_rtType2.Create;
inpr.afm_called_by := ed_myAfm.Text;
inpr.afm_called_for := ed_ClientAfm.Text;
inpr.as_on_date := ddate;
httpRio.HTTPWebNode.UserName := Ed_usname.Text;
httpRio.HTTPWebNode.Password := Ed_pass.Text;
Service := GetRgWsPublic2Service_Interface(true,'',httpRio);
ReturnInfo := Service.rgWsPublic2AfmMethod(inpr);
ErrorStr := ReturnInfo.rg_ws_public2_result_rtType.error_rec.error_code+' / '+
ReturnInfo.rg_ws_public2_result_rtType.error_rec.error_descr;
if ErrorStr <> '' then
begin
memo1.Lines.Add('Error!!!!');
memo1.Lines.Add(ErrorStr);
end
else
begin
memo1.Lines.Text := ReturnInfo.rg_ws_public2_result_rtType.ToString;
AskedInfo := ReturnInfo.rg_ws_public2_result_rtType.basic_rec;
EdEnterpriceName.Text := AskedInfo.onomasia;
mm_DoyInfo.Text := AskedInfo.doy+' / '+AskedInfo.doy_descr;
end;
ReturnInfo.Destroy;
ddate.Destroy;
end;

Related

Opening a program using Remote Desktop on Windows server 2008 r2 from a program e written in Delphi 11.2

if PageControl1.ActivePage.Pageindex = 0 then
begin
rdp13 := TMsRdpClient7NotSafeForScripting.Create(Self);
with Rdp13 do
begin
Rdp13.align:= alclient;
Rdp13.BringToFront;
Rdp13.Server := s ;
Rdp13.UserName := 'xxx';
Rdp13.AdvancedSettings2.ClearTextPassword:= 'tttt';
Rdp13.RemoteProgram2.RemoteProgramMode:=True;
Rdp13.Connect;
RDP13.Onconnected := OnRDPConnect ;
procedure TForm2.Button7Click(Sender: TObject);
begin
rdp13.RemoteProgram.ServerStartProgram('C:\Program Files (x86)\xxxxxxx.exe', '', 'C:\Program Files (x86)\xxxxxx', false, '', false);
end ;
I can connect,but when use rdp13.RemoteProgram2.RemoteProgramMode:=True;
I always get a blank screen after connect.
Help Please

FTX FIX protocol returns "Invalid signature" message

I have been trying to to implement a FIX Client in Go to interact with FTX. To send the initial logon message, FTX's API doc asks the client to include a signature in the message.
In the return message from the FTX, it says "Invalid signature".
Below is my implementation for generating the signature:
func signatureGenerator(msgType, msgSeqNum, senderCompID, targetCompID string) string {
timeNow := time.Now().UTC().Format("20060102-15:04:05")
message := [][]byte{[]byte(timeNow),
[]byte(msgType),
[]byte(msgSeqNum),
[]byte(senderCompID),
[]byte(targetCompID)}
SOH := []byte{0x01}
signature := bytes.Join(message, SOH)
signSha256 := hmac.New(sha256.New, []byte(userInfo.CLIENT_API_SECRET))
signSha256.Write(signature)
strSig := hex.EncodeToString(signSha256.Sum(nil))
return strSig
}

TInputDirWizardPage with Radio Buttons

I need a setup page with two radio buttons. Clicking the second button should enable an input to define a path (Like it's done in TInputDirWizardPage).
Is it possible to customize TInputDirWizardPage for my needs?
Or do I need to build a CustomPage and define the controls by myself?
If the second question will be answered with yes, how am I able to use the "directory input" (from the TInputDirWizardPage), or is it also neccessary to build this on my own?
As you correctly guessed you have several options:
Start with TWizardPage and build everything from scratch
Start with TInputDirWizardPage and add the radio buttons
Start with TInputOptionWizardPage and add the edit box
The second option probably involves least customization. Though it needs a hack from Is it possible to allow a user to skip a TInputDirWizardPage in Inno Setup?
{ WORKAROUND }
{ Checkboxes and Radio buttons created on runtime do }
{ not scale their height automatically. }
{ See https://stackoverflow.com/q/30469660/850848 }
procedure ScaleFixedHeightControl(Control: TButtonControl);
begin
Control.Height := ScaleY(Control.Height);
end;
var
Page: TInputDirWizardPage;
DefaultLocationButton: TRadioButton;
CustomLocationButton: TRadioButton;
OldNextButtonOnClick: TNotifyEvent;
procedure LocationButtonClick(Sender: TObject);
begin
Page.Edits[0].Enabled := CustomLocationButton.Checked;
Page.Buttons[0].Enabled := CustomLocationButton.Checked;
end;
procedure NextButtonOnClick(Sender: TObject);
var
PrevDir: string;
begin
{ Do not validate, when "default location" is selected }
if (WizardForm.CurPageID = Page.ID) and DefaultLocationButton.Checked then
begin
PrevDir := Page.Values[0];
Page.Values[0] := GetWinDir; { Force value to pass validation }
OldNextButtonOnClick(Sender);
Page.Values[0] := PrevDir;
end
else
begin
OldNextButtonOnClick(Sender);
end;
end;
procedure InitializeWizard();
begin
Page := CreateInputDirPage(
wpWelcome,
'Select Personal Data Location', 'Where should personal data files be stored?',
'', False, 'New Folder');
Page.Add('');
DefaultLocationButton := TRadioButton.Create(WizardForm);
DefaultLocationButton.Parent := Page.Surface;
DefaultLocationButton.Top := Page.Edits[0].Top;
DefaultLocationButton.Caption := 'Use default location';
DefaultLocationButton.Checked := True;
DefaultLocationButton.OnClick := #LocationButtonClick;
ScaleFixedHeightControl(DefaultLocationButton);
CustomLocationButton := TRadioButton.Create(WizardForm);
CustomLocationButton.Parent := Page.Surface;
CustomLocationButton.Top :=
DefaultLocationButton.Top + DefaultLocationButton.Height + ScaleY(8);
CustomLocationButton.Caption := 'Use custom location';
CustomLocationButton.OnClick := #LocationButtonClick;
ScaleFixedHeightControl(DefaultLocationButton);
Page.Buttons[0].Top :=
Page.Buttons[0].Top +
((CustomLocationButton.Top + CustomLocationButton.Height + ScaleY(8)) -
Page.Edits[0].Top);
Page.Edits[0].Top :=
CustomLocationButton.Top + CustomLocationButton.Height + ScaleY(8);
Page.Edits[0].Left := Page.Edits[0].Left + ScaleX(16);
Page.Edits[0].Width := Page.Edits[0].Width - ScaleX(16);
Page.Edits[0].TabOrder := CustomLocationButton.TabOrder + 1;
Page.Buttons[0].TabOrder := Page.Edits[0].TabOrder + 1;
LocationButtonClick(nil); { Update edit for initial state of buttons }
OldNextButtonOnClick := WizardForm.NextButton.OnClick;
WizardForm.NextButton.OnClick := #NextButtonOnClick;
end;
More general question on the topic: Inno Setup Placing image/control on custom page.

How to use Inno Setup to update a database using .sql script

I'd like to compile a setup that will connect to a remote database using the credentials provided by the user, then install few db components using .sql script.
Is that possible using Inno Setup?
More details:
I'd like to have a custom form, asking the user to enter the database address and credentials, then run a command that will execute an sql script that will update the remote database server.
If the update is successful - complete the installation with success.
This is rather general question - I have a lot of customized setups that should connect to different servers/run different scripts - the idea is to build a generic form that will provide this functionality.
I don't think you can have a completely generic form, as for different servers you may need either a single connection string, or a server name and an (optional) port; for some servers you will use system authentication, for others a user name password tuple.
Having said that I will give you a small demo Inno script that asks for server name and port, user name and password, then makes a few tests, then executes an application that is extracted (by code) to the temp directory and will be deleted by the installer. You can use this as a starting point for your scripts. Having a few of such snippets, and including them in your scripts as necessary will probably be all you need:
[Setup]
AppID=DBUpdateTest
AppName=Test
AppVerName=Test 0.1
AppPublisher=My Company, Inc.
DefaultDirName={pf}\Test
DefaultGroupName=Test
DisableDirPage=yes
DisableProgramGroupPage=yes
OutputBaseFilename=setup
PrivilegesRequired=none
[Files]
Source: "isql.exe"; DestDir: "{tmp}"; Flags: dontcopy
Source: "update_V42.sql"; DestDir: "{tmp}"; Flags: dontcopy
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Code]
var
DBPage: TInputQueryWizardPage;
procedure InitializeWizard;
begin
DBPage := CreateInputQueryPage(wpReady,
'Database Connection Information', 'Which database is to be updated?',
'Please specify the server and the connection credentials, then click Next.');
DBPage.Add('Server:', False);
DBPage.Add('Port:', False);
DBPage.Add('User name:', False);
DBPage.Add('Password:', True);
DBPage.Values[0] := GetPreviousData('Server', '');
DBPage.Values[1] := GetPreviousData('Port', '');
DBPage.Values[2] := GetPreviousData('UserName', '');
DBPage.Values[3] := GetPreviousData('Password', '');
end;
procedure RegisterPreviousData(PreviousDataKey: Integer);
begin
SetPreviousData(PreviousDataKey, 'Server', DBPage.Values[0]);
SetPreviousData(PreviousDataKey, 'Port', DBPage.Values[1]);
SetPreviousData(PreviousDataKey, 'UserName', DBPage.Values[2]);
SetPreviousData(PreviousDataKey, 'Password', DBPage.Values[3]);
end;
function NextButtonClick(CurPageID: Integer): Boolean;
var
ResultCode: Integer;
begin
Result := True;
if CurPageID = DBPage.ID then begin
if DBPage.Values[0] = '' then begin
MsgBox('You must enter the server name or address.', mbError, MB_OK);
Result := False;
end else if DBPage.Values[2] = '' then begin
MsgBox('You must enter the user name.', mbError, MB_OK);
Result := False;
end else if DBPage.Values[3] = '' then begin
MsgBox('You must enter the user password.', mbError, MB_OK);
Result := False;
end else begin
ExtractTemporaryFile('isql.exe');
ExtractTemporaryFile('update_V42.sql');
if Exec(ExpandConstant('{tmp}') + '\isql.exe', '--user ' + DBPage.Values[2]
+ ' --password ' + DBPage.Values[3] + ' --database ' + DBPage.Values[0]
+ ':foo --script update_V42.sql', '',
SW_HIDE, ewWaitUntilTerminated, ResultCode)
then begin
// check ResultCode and set Result accordingly
Result := ResultCode = 0;
end else begin
MsgBox('Database update failed:'#10#10 + SysErrorMessage(ResultCode),
mbError, MB_OK);
Result := False;
end;
end;
end;
end;
Beware: I haven't fully tested this, so there may be more code necessary to properly clean everything up. Error handling is definitely missing!

How to propertly use Bing Translate API?

I'm using the API of Bing, more precisely - the translation part, and it all works quite well except one thing - auto detection of language. How is that possible?
My code is working fine,incase someone needs to look at:
function HTTPEncode(const AStr: string): string;
const
NoConversion = ['A'..'Z', 'a'..'z', '*', '#', '.', '_', '-'];
var
i: integer;
begin
Result := '';
for i := 1 to Length(AStr) do
begin
if CharInSet(AStr[i],NoConversion) then
Result := Result + AStr[i]
else
Result := Result + Format('%%%.2x',[ord(AStr[i])]);
end;
end;
function GetTranslation(text, fromLang, toLang: string): string;
var
xmldoc: TXMLDocument;
inode,mnode,rnode,irnode: IXMLNode;
j: integer;
uri: string;
idhttp:TIdHttp;
begin
Result := '';
idhttp:=TIdHttp.Create(nil);
xmldoc := TXMLDocument.Create(application);
try
xmldoc.LoadFromXML(idhttp.Get('http://api.search.live.net/xml.aspx?Appid=' + AppID + '&query='+HTTPEncode(text)+
'&sources=translation'+
'&Translation.SourceLanguage=' + fromLang +
'&Translation.TargetLanguage=' + toLang));
finally
idhttp.Free;
end;
try
inode := xmldoc.ChildNodes.FindNode('SearchResponse');
if Assigned(inode) then
begin
uri := 'http://schemas.microsoft.com/LiveSearch/2008/04/XML/translation';
mnode := inode.ChildNodes.FindNode('Translation',uri);
if Assigned(mnode) then
begin
rnode := mnode.ChildNodes.FindNode('Results',uri);
if Assigned(rnode) then
begin
irnode := rnode.ChildNodes.FindNode('TranslationResult',uri);
if Assigned(irnode) then
Result := irnode.ChildNodes.FindNode('TranslatedTerm',uri).NodeValue;
end;
end;
end;
finally
xmldoc.Free;
end;
end;
begin
ShowMessage(GetTranslation('Hello!','en','de'));
end;
I followed the packets from http://www.microsofttranslator.com/ when using auto-detection feature, the result was 'from=;' whereas if source language is English it'd be 'from=en;'.I tried aswell sending '' as source language,but it didn't work out - no result.
How do I use auto-detection?
I did this using their Ajax API. If you build your query with a null "from" parameter, then the service auto-detects the language.
This is the query url I format to make requests to the service:
#"http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appId={0}&from=&to={1}&text={2}"
Key thing being "from=&to={1}".
Here is an example for API version 3:
no from parameter
English text
detectedLanguage results in en
I read score as 100% sure about this result
$ curl -X POST "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&textType=html&to=fr" \
-d "[{'Text':'Underbeds'}]"> -H "Ocp-Apim-Subscription-Key:YOUR_KEY_HERE" \
> -H "Ocp-Apim-Subscription-Region:global" \
> -H "Content-Type: application/json" \
> -d "[{'Text':'Underbeds'}]"
[{"detectedLanguage":{"language":"en","score":1.0},"translations":[{"text":"Sous-lits","to":"fr"}]}]