procedure TGCalendars.GetTokens;
function EncodeURL(url: string): string;
var
x: integer;
sBuff: string;
const
SafeMask = ['A'..'Z', '0'..'9', 'a'..'z', '*', '@', '.', '_', '-'];
begin
//Init
sBuff := '';
for x := 1 to Length(url) do
begin
//Check if we have a safe char
if url[x] in SafeMask then
begin
//Append all other chars
sBuff := sBuff + url[x];
end
else if url[x] = ' ' then
begin
//Append space
sBuff := sBuff + '+';
end
else
begin
//Convert to hex
sBuff := sBuff + '%' + IntToHex(Ord(url[x]), 2);
end;
end;
Result := sBuff;
end;
var
URLString: String;
OkResult: Boolean;
InputResult: string;
JSon: ISuperObject;
FCode: String;
Req, Resp: TStringStream;
begin
FAccessToken := '';
if FRefreshToken <> '' then
begin
{ Lets get access token using previous refresh token}
URLString := 'client_id=' + FClientID;
URLString := URLString + '&client_secret=' + FClientSecret;
URLString := URLString + '&refresh_token=' + FRefreshToken;
URLString := URLString + '&grant_type=refresh_token';
Req := TStringStream.Create(URLString);
Resp := TStringStream.Create('');
try
try
FHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
FHTTP.DoRequest('POST', 'https://accounts.google.com/o/oauth2/token', Req, Resp, []);
{ When not working response was:
Recv 31.12.2017. 14:12:59: HTTP/1.1 400 Bad Request
"error" : "invalid_grant" }
except
end;
if FHTTP.ResponseCode = 200 then
begin
JSon := SO(UTF8Decode(Resp.DataString));
FAccessToken := JSon['access_token'].AsString;
if JSon['refresh_token'] <> nil then
FRefreshToken := JSon['refresh_token'].AsString;
Exit;
end;
finally
Req.Free;
Resp.Free;
end;
end;
{ Ja kods augstāk bijis veiksmīgs, tas iziet ar Exit, un šis tālāk neizpildās.
Šeit tiek apstrādāts, ja refresh_token ir neveiksmīgs. Atveram browseri lai iegūtu "user consent" }
URLString := 'https://accounts.google.com/o/oauth2/auth';
URLString := URLString + '?client_id=' + FClientID;
URLString := URLString + '&redirect_uri=urn:ietf:wg:oauth:2.0:oob';
URLString := URLString + '&scope=https://www.googleapis.com/auth/calendar https://www.google.com/m8/feeds';
URLString := URLString + '&response_type=code';
OpenURL(UrlString); { Lazarus equivalent of Delphi ShellExecute((Form.Handle), nil, PChar(URLString), nil, nil, 0); }
repeat
OkResult := false;
InputResult := '';
if Assigned(FOnAuthorizationContinueQuery) then
FOnAuthorizationContinueQuery(Self, OkResult, InputResult)
else
OkResult := InputQuery(Application.Title, 'Enter your code here:', InputResult);
if OkResult then
FCode := InputResult { that code I copy/pasted from browser }
else
Exit;
URLString := 'client_id=' + FClientID;
URLString := URLString + '&client_secret=' + FClientSecret;
URLString := URLString + '&code=' + FCode;
URLString := URLString + '&redirect_uri=urn:ietf:wg:oauth:2.0:oob';
URLString := URLString + '&grant_type=authorization_code';
Req := TStringStream.Create(URLString);
Resp := TStringStream.Create('');
try
try
FHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
FHTTP.DoRequest('POST', 'https://accounts.google.com/o/oauth2/token', Req, Resp, []);
except
end;
if FHTTP.ResponseCode <> 200 then
begin
if Assigned(FOnWrongVerifier) then
FOnWrongVerifier(Self)
else
MessageDlg('Wrong code! Try again.', mtError, [mbOK], -1);
end
else
begin
{ iegūstam gan access_token, gan refresh_token }
JSon := SO(UTF8Decode(Resp.DataString));
FAccessToken := JSon['access_token'].AsString;
if JSon['refresh_token'] <> nil then
FRefreshToken := JSon['refresh_token'].AsString;
end;
finally
Req.Free;
Resp.Free;
end;
until FHTTP.ResponseCode = 200;
end;