i have a https soap and i want ignore the certificate validation. I have done that with OnBeforePost event into THTTPRIO.HTTPWebNode:
procedure TMySOAP.OnBeforePost(const HTTPReqResp: THTTPReqResp; Data: Pointer);
var
aFlagsSize: DWord;
aFlags: DWord;
begin
aFlagsSize := SizeOf(aFlags);
// get security flags
if InternetQueryOption(Data, INTERNET_OPTION_SECURITY_FLAGS, #aFlags, aFlagsSize) then
begin
// add all flag for ignore validation
aFlags := aFlags or
SECURITY_FLAG_IGNORE_UNKNOWN_CA or
SECURITY_FLAG_IGNORE_REVOCATION or
SECURITY_FLAG_IGNORE_CERT_CN_INVALID or
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID or
SECURITY_FLAG_IGNORE_WRONG_USAGE;
// set the new flags
InternetSetOption(Data, INTERNET_OPTION_SECURITY_FLAGS, #aFlags, aFlagsSize)
end;
end;
it works.. but i have a second problem. My clients are behind a company firewall without internet and each request to the soap loses 15 seconds because Windows try to validate the certificate path throug internet and this operation has a default timeout of 15 seconds (see https://technet.microsoft.com/en-us/library/cc771429(v=ws.11).aspx).
There is any flag or snippet for set at runtime, a custom retrieval timeout settings?
THTTPRIO.HTTPWebNode has:
property ConnectTimeout: Integer;
property SendTimeout: Integer;
property ReceiveTimeout: Integer;
All of them are in milliseconds.
RIO := THTTPRIO.Create(nil);
RIO.HTTPWebNode.ReceiveTimeout := 20000; //Wait just 20 secs
Related
I've learned in this SO question that there currently is no simple way to turn cookie-based CSRF tokens into HTTP request headers in Elm. Thus, to write a single page application (SPA) that works nicely with a Django Rest Framework backend, I need to manually retrieve the CSRF-Token from the corresponding cookie value.
How do I retrieve a cookie value in Elm? Does Elm provide runtime support for this via some Command? Or do I need to retrieve the cookie using plain JavaScript and provide it to the ELM SPA via a port?
As of Elm 0.9, you need to use Ports to read the cookie from JavaScript and pass it back to the Elm application.
In my application, I do the following. I define a fetchCsrfToken port that I use from Elm to call a JavaScript function that reads the cookie. That function then triggers a callback to Elm via a csrfTokenReciever port. My Elm application subscribes to that event via subscriptions.
-- Ports.elm
port fetchCsrfToken : () -> Cmd msg
port csrfTokenReciever : (String -> msg) -> Sub msg
-- Main.elm
init : Flags -> Url -> Key -> ( Model, Cmd Msg )
init flags url key =
-- ...
(model, Ports.fetchCsrfToken ())
subscriptions : Model -> Sub Msg
subscriptions model =
Ports.csrfTokenReciever GotCsrfToken
// index.js
app.ports.fetchCsrfToken.subscribe(function (str) {
const value = getCookie('csrftoken')
if (value === null) {
app.ports.csrfTokenReciever.send('')
} else {
app.ports.csrfTokenReciever.send(value)
}
})
Using Elm 0.19.1
First solution:
Use of 2 ports, a subscription and some JS/TS code like #viam0Zah mentioned.
Second solution:
Pass the CSRF into your flags at init
const app = Elm.Main.init({
node: document.querySelector("main"),
flags: {
csrfToken: getCookie('csrftoken')
}
});
add csrfToken to Flags
type alias Flags =
{ ---
, csrfToken : String
}
And don't forget to add a decoder for the csrfToken:
import Json.Decode as D
flagsDecoder : D.Decoder Flags
flagsDecoder =
D.succeed Flags
|> ---
|> D.required "csrfToken" D.string
If you want to be more robust and extend type safety for both solutions - flags and ports, you should check out https://elm-ts-interop.com/, it's just amazing!
I am using Parse Server from the market place of AWS and is able to access the database without a problem. But, I am not able to send email verification to newly signed up users.
After did some research, I know that I have to add Mail Adapter and enable a few parameters for the Parse Server but I don't know how to add Adapter from the dashboard
https://github.com/parse-community/parse-server#email-verification-and-password-reset
It's not possible to add a mail adapter using the dashboard. You should have the Mailgun adapter installed by default.
To add the configuration you need to access your server and add the following to your index.js file:
var server = ParseServer({
...otherOptions,
// Enable email verification
verifyUserEmails: true,
// if `verifyUserEmails` is `true` and
// if `emailVerifyTokenValidityDuration` is `undefined` then
// email verify token never expires
// else
// email verify token expires after `emailVerifyTokenValidityDuration`
//
// `emailVerifyTokenValidityDuration` defaults to `undefined`
//
// email verify token below expires in 2 hours (= 2 * 60 * 60 == 7200 seconds)
emailVerifyTokenValidityDuration: 2 * 60 * 60, // in seconds (2 hours = 7200 seconds)
// set preventLoginWithUnverifiedEmail to false to allow user to login without verifying their email
// set preventLoginWithUnverifiedEmail to true to prevent user from login if their email is not verified
preventLoginWithUnverifiedEmail: false, // defaults to false
// The public URL of your app.
// This will appear in the link that is used to verify email addresses and reset passwords.
// Set the mount path as it is in serverURL
publicServerURL: 'https://example.com/parse',
// Your apps name. This will appear in the subject and body of the emails that are sent.
appName: 'Parse App',
// The email adapter
emailAdapter: {
module: '#parse/simple-mailgun-adapter',
options: {
// The address that your emails come from
fromAddress: 'parse#example.com',
// Your domain from mailgun.com
domain: 'example.com',
// Your API key from mailgun.com
apiKey: 'key-mykey',
}
},
// account lockout policy setting (OPTIONAL) - defaults to undefined
// if the account lockout policy is set and there are more than `threshold` number of failed login attempts then the `login` api call returns error code `Parse.Error.OBJECT_NOT_FOUND` with error message `Your account is locked due to multiple failed login attempts. Please try again after <duration> minute(s)`. After `duration` minutes of no login attempts, the application will allow the user to try login again.
accountLockout: {
duration: 5, // duration policy setting determines the number of minutes that a locked-out account remains locked out before automatically becoming unlocked. Set it to a value greater than 0 and less than 100000.
threshold: 3, // threshold policy setting determines the number of failed sign-in attempts that will cause a user account to be locked. Set it to an integer value greater than 0 and less than 1000.
},
// optional settings to enforce password policies
passwordPolicy: {
// Two optional settings to enforce strong passwords. Either one or both can be specified.
// If both are specified, both checks must pass to accept the password
// 1. a RegExp object or a regex string representing the pattern to enforce
validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/, // enforce password with at least 8 char with at least 1 lower case, 1 upper case and 1 digit
// 2. a callback function to be invoked to validate the password
validatorCallback: (password) => { return validatePassword(password) },
validationError: 'Password must contain at least 1 digit.' // optional error message to be sent instead of the default "Password does not meet the Password Policy requirements." message.
doNotAllowUsername: true, // optional setting to disallow username in passwords
maxPasswordAge: 90, // optional setting in days for password expiry. Login fails if user does not reset the password within this period after signup/last reset.
maxPasswordHistory: 5, // optional setting to prevent reuse of previous n passwords. Maximum value that can be specified is 20. Not specifying it or specifying 0 will not enforce history.
//optional setting to set a validity duration for password reset links (in seconds)
resetTokenValidityDuration: 24*60*60, // expire after 24 hours
}
});
You will need to replace some of the values with your own. See here for more details.
I am trying to receive ebay api transaction notifications into an ASP hosted on a web server. The notifications are sent as SOAP messages and can be sent to a URL with a query string. Notifications must be responded to with HTTP 200 OK. I would like the notification to land inside a variable so that I can parse it and send it on to the next part of the system.
http://developer.ebay.com/DevZone/guides/ebayfeatures/Notifications/Notifications.html#ReceivingPlatformNotifications
In the documentation they mention that this is possible, but the sample they give goes the route of subscribing to an email server. This ASP would not necessarily need to make SOAP requests, just accept SOAP messages from the ebay servers.
I am studying ASP, SOAP, and query strings, but a little guidance would be truly appreciated. Thanks!
This should be pretty straight forward, your Classic ASP page becomes the endpoint for the eBay Notification API (as long as you have configured it to send notifications and what URL to send them to).
You should be able to test this with a simple Classic ASP page
<%
Dim isPost: isPost = (UCase(Request.ServerVariables("REQUEST_METHOD") & "") = "POST")
Dim hasSoapAction
'Is it a HTTP POST?
If isPost Then
'Do we have a SOAPACTION header (check both because
'it can be either HTTP_ or HEADER_ depending on IIS version)?
hasSoapAction = ( _
Len(Request.ServerVariables("HEADER_SOAPACTION") & "") > 0 Or _
Len(Request.ServerVariables("HTTP_SOAPACTION") & "") > 0 _
)
If hasSoapAction Then
'Process the notification here.
'Use Request.BinaryRead to read the SOAP
End If
'Let eBay know we have received and processing the message.
Response.Status = "200 OK"
Else
'Return method not allowed
Response.Status = "405 Method Not Allowed"
End If
Response.End
%>
You might also want to check REMOTE_HOST to make sure that you are only getting sent messages for the expected source (this isn't bulletproof though as the information can be spoofed).
Useful Links
Accessing a request's body (great existing answer that explains how to use Request.BinaryRead() to read the content and convert it to a string which you can then use in a variable or for parsing with XMLDocument.LoadXML()).
How to generate MD5 using VBScript in classic ASP? (If you want to look at a way of verifying the MD5 signature)
This is what i have so far in my notifications.asp. When I try to send it a basic SOAP post through Postman nothing is happening. Does this look like it should work?
I tested this without the If statements checking for SOAP headers, and I posted just regular string data and it works. So the binary to string conversion and output to file is all good. Now I just need to test it with actual ebay api notifications. ;-)
<%
Function BytesToStr(bytes)
Dim Stream
Set Stream = Server.CreateObject("Adodb.Stream")
Stream.Type = 1 'adTypeBinary
Stream.Open
Stream.Write bytes
Stream.Position = 0
Stream.Type = 2 'adTypeText
Stream.Charset = "iso-8859-1"
BytesToStr = Stream.ReadText
Stream.Close
Set Stream = Nothing
End Function
Dim isPost: isPost = (UCase(Request.ServerVariables("REQUEST_METHOD") & "") = "POST")
Dim hasSoapAction
'Is it a HTTP POST?
If isPost Then
'Do we have a SOAPACTION header?
hasSoapAction = (Len(Request.ServerVariables("HEADER_SOAPACTION") & "") > 0)
If hasSoapAction Then
'Process the notification here.
'Use Request.BinaryRead to read the SOAP
If Request.TotalBytes > 0 Then
Dim lngBytesCount, text
lngBytesCount = Request.TotalBytes
text = BytesToStr(Request.BinaryRead(lngBytesCount))
dim fs, tfile
set fs=Server.CreateObject("Scripting.FileSystemObject")
set tfile=fs.CreateTextFile("C:\inetpub\wwwroot\ASPtest\notifications.txt")
tfile.WriteLine(text)
tfile.Close
set tfile=nothing
set fs=nothing
End If
End If
'Let eBay know we have received and processing the message.
Response.Status = "200 OK"
Else
'Return method not allowed
Response.Status = "405 Method Not Allowed"
End If
Response.End
%>
I'm posting the login-data from delphi on a django-created-form which runs on my localhost. Like this:
procedure TForm1.btnPostClick(Sender: TObject);
var
IdHTTP: TidHTTP;
auth: TStringList;
test,token:string;
begin
IdHTTP := TidHTTP.Create(nil);
IdHTTP.Request.Accept :='text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
IdHTTP.Request.AcceptCharSet :='iso-8859-1, utf-8, utf-16, *;q=0.1';
IdHTTP.Request.AcceptEncoding :='deflate, gzip, identity, *;q=0';
IdHTTP.Request.Connection :='Keep-Alive';
IdHTTP.Request.ContentType :='application/x-www-form-urlencoded';
token := IdHTTP.Get('http://localhost:8000/accounts/signup/');
token := copy(token, AnsiPos('csrfmiddlewaretoken', token) + 28, 32);
IdHTTP.Request.CustomHeaders.Clear;
with IdHTTP.Request.CustomHeaders do
begin
AddValue('X-CSRFToken',token);
Values['COOKIE']:='';
//if IdHTTP2.CookieManager.CookieCollection.count > 0 then
// Add('COOKIE: '+token);
end;
try
auth := TStringList.Create;
auth.Add('csrfmiddlewaretoken='+ token);
auth.Add('first_name=' + edtVorname.Text);
auth.Add('last_name=' + edtName.Text);
auth.Add('function=' + edtFunction.Text);
auth.Add('company=' + edtCompany.Text);
auth.Add('country=' + edtCountry.Text);
auth.Add('email=' + edtEmail.Text);
auth.Add('password1=' + edtPassword.Text);
auth.Add('password2=' + edtPasswordAgain.Text);
//IdHTTP.Request.CustomHeaders.AddValue('Accept-Language', 'en-EN');
//IdHTTP.Request.CustomHeaders.AddValue('Referer',
IdHTTP.post('http://127.0.0.1:8000/accounts/signup/', auth);
except
end;
end;
Whenever it gets until the Line with the post
IdHTTP.post('http://127.0.0.1:8000/accounts/signup/', auth);
Im getting the 403 error "Forbidden". My guess is im sending the CSRF-Token wrong
because from the python debugger I see being caught in
if csrf_token is None:
# No CSRF cookie. For POST requests, we insist on a CSRF cookie,
# and in this way we can avoid all CSRF attacks, including login
# CSRF.
return self._reject(request, REASON_NO_CSRF_COOKIE)
But HOW is it supposed to be? How do I need to send this csrf-token?
P.S Well I think the problem was that per default HandleRedirects is set to True and it gave me the 403. The cookievalue in the latest Django versions is usually called csrftoken and not X-CSRFToken how I did here.
You shouldn't set cookie by yourself. When Django response with a form and django.middleware.csrf.CsrfViewMiddleware is in your list of middleware classes (more on https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/), it should already set csrftoken cookie. So you only have to read value of this cookie and set it to csrfmiddlewaretoken form field.
Also don't forget to set UserAgent in your request. Without UserAgent Indy (Delphi 2010) and Django 1.8 won't cooperate with each other.
I don't know how to add csrfmiddlewaretoken field on redirects so I did it without redirects!
Here is my code:
uses
IdURI, IdCookie;
...
procedure TForm1.btnLoginClick(Sender: TObject);
var
idHTTP: TIdHTTP;
token: AnsiString;
stream: TStringStream;
params: TStringList;
cookie: TidCookieRFC2109;
begin
idHTTP := TIdHTTP.Create(nil);
stream := TStringStream.Create;
params := TStringList.Create;
try
idHTTP.AllowCookies := True;
idHTTP.HandleRedirects := False;
//even if HandleRedirects := False, you must have OnRedirect event (don't know why)
idHTTP.OnRedirect := IdHttpOnRedirect;
IdHTTP.Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
IdHTTP.Request.AcceptCharSet := 'iso-8859-1, utf-8, utf-16, *;q=0.1';
IdHTTP.Request.AcceptEncoding := 'gzip, deflate, sdch';
IdHTTP.Request.Connection := 'Keep-Alive';
IdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
idHTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36';
idHTTP.Request.CharSet := 'utf-8';
idHTTP.Get('http://www.ttaksa.si/login/');
cookie := idHTTP.CookieManager.CookieCollection.Cookie['csrftoken', '.www.ttaksa.si'];
token := cookie.Value;
params.Values['csrfmiddlewaretoken'] := token;
params.Values['username'] := txtUporabniskoIme.Text;
params.Values['password'] := txtGeslo.Text;
idHTTP.Post('http://www.ttaksa.si/login/', params, stream);
idHTTP.Get('http://www.ttaksa.si/objekti/export/?zacetni_datum=23.7.2015-12:00:00&format=xml&indent=2', stream);
stream.SaveToFile(txtFilename.Text);
wbUvoz.Navigate('File://' + txtFilename.Text);
finally
idHTTP.Free;
stream.Free;
params.Free;
end;
end;
procedure TForm1.IdHTTPOnRedirect(Sender: TObject; var dest: string;
var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
begin
Handled := True;
end;
Delphi 2009 imported the UPS WSDL without any errors, and I managed to invoke the web service with my account information and an example parcel ID. The response from the server is:
<detail>
<err:Errors xmlns:err="http://www.ups.com/XMLSchema/XOLTWS/Error/v1.1">
<err:ErrorDetail>
<err:Severity>Hard</err:Severity>
<err:PrimaryErrorCode>
<err:Code>9150002</err:Code>
<err:Description>Invalid or missing inquiry number - TrackingNumber, ShipmentIdentificationNumber, or ReferenceNumber</err:Description>
</err:PrimaryErrorCode>
</err:ErrorDetail>
</err:Errors>
</detail>
Has somebody already sucessfully used the UPS Parcel Tracking web service with a Delphi client, and knows what is wrong?
Here is the client code:
var
Service: TrackPortType;
MyRequest: TrackRequest;
Security: UPSSecurity;
MyResponse: TrackResponse;
ReqOpt: Array_Of_string;
begin
Service := (HTTPRIO1 as TrackPortType);
Security := UPSSecurity.Create;
Security.UsernameToken := UsernameToken.Create;
Security.UsernameToken.Username := 'username';
Security.UsernameToken.Password := 'password';
Security.ServiceAccessToken := ServiceAccessToken.Create;
Security.ServiceAccessToken.AccessLicenseNumber := 'licensenumber';
MyRequest := TrackRequest.Create;
SetLength(ReqOpt, 1);
ReqOpt[0] := '0';
MyRequest.Request := Request.Create;
MyRequest.Request.RequestOption := ReqOpt;
MyRequest.TrackingOption := '02';
MyRequest.InquiryNumber := '1Z...';
try
(Service as ISoapHeaders).Send(Security);
MyResponse := Service.ProcessTrack(MyRequest, nil);
except
on E:ERemotableException do
begin
Memo1.Lines.Text := FormatXmlData(E.FaultDetail);
end;
end;
Solved it with the Java API for XML Web Services (JAX-WS).
To integrate with Delphi, I proxy it as an Intranet Servlet. The Delphi GUI application then can use a simple HTTP request to query the tracking status.
Update: in a second attempt to get it working in Delphi, I hardcoded the SOAP XML request body, and used Indy and XMLDocument instead of the Delphi SOAP library.