UAppCentreCom.pas 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. unit UAppCentreCom;
  2. {$WARN SYMBOL_PLATFORM OFF}
  3. interface
  4. uses
  5. Windows, ActiveX, Classes, ComObj, AppCentreCom_TLB, StdVcl, SysUtils, IdURI;
  6. type
  7. TLXTAppCentreCom = class(TTypedComObject, ILXTAppCentreCom)
  8. private
  9. procedure OnRedirect(Sender: TObject; var dest: string;
  10. var NumRedirect: Integer; var Handled: boolean; var VMethod: string);
  11. function DecodeAdapter(AData, AKey: string): string;
  12. protected
  13. function RegisterInstallationDirectory(AAppKey, ADir: PChar): SYSINT; stdcall;
  14. function GetInstallationDirectory(AAppKey: PChar): PChar; stdcall;
  15. function Authenticate(AAuthURL, AAppSecret: PChar): PChar; stdcall;
  16. // function ILXTAppCentreCom_Authenticate(AAuthURL, AAppSecret: PChar): PChar;
  17. // stdcall;
  18. {Declare ILXTAppCentreCom methods here}
  19. end;
  20. implementation
  21. uses ComServ, Registry, IdHTTP, StrUtils, Forms, Dialogs, superobject, XXTEA;
  22. type
  23. TAuthIdHTTP = class(TIdHTTP)
  24. private
  25. FAccessToken: string;
  26. FClientKey: string;
  27. public
  28. property AccessToken: string read FAccessToken write FAccessToken;
  29. property ClientKey: string read FClientKey write FClientKey;
  30. end;
  31. const
  32. APPCENTRE_REGISTRY: string = 'SOFTWARE\Winsoft\AppCentre\Directory';
  33. function TLXTAppCentreCom.RegisterInstallationDirectory(AAppKey,
  34. ADir: PChar): SYSINT;
  35. var
  36. ARegistry: TRegistry;
  37. begin
  38. Result := 0;
  39. ARegistry := TRegistry.Create;
  40. try
  41. ARegistry.RootKey := HKEY_LOCAL_MACHINE;
  42. if ARegistry.OpenKey(APPCENTRE_REGISTRY, True) then
  43. begin
  44. ARegistry.WriteString(string(AAppKey), string(ADir));
  45. Result := 1;
  46. end;
  47. finally
  48. ARegistry.CloseKey;
  49. ARegistry.Free;
  50. end;
  51. end;
  52. function TLXTAppCentreCom.GetInstallationDirectory(AAppKey: PChar): PChar;
  53. var
  54. ARegistry: TRegistry;
  55. begin
  56. Result := nil;
  57. ARegistry := TRegistry.Create;
  58. try
  59. ARegistry.RootKey := HKEY_LOCAL_MACHINE;
  60. if ARegistry.OpenKey(APPCENTRE_REGISTRY, True) and ARegistry.ValueExists(string(AAppKey)) then
  61. begin
  62. Result := PChar(ARegistry.ReadString(AAppKey));
  63. end;
  64. finally
  65. ARegistry.CloseKey;
  66. ARegistry.Free;
  67. end;
  68. end;
  69. function SplitString(const Source,Ch:string):TStringList;
  70. var
  71. Temp: string;
  72. iLoop: Integer;
  73. begin
  74. Result := TStringList.Create;
  75. Temp := Source;
  76. iLoop := Pos(Ch, Source);
  77. while iLoop <> 0 do
  78. begin
  79. Result.Add(copy(temp, 0, iLoop-1));
  80. Delete(temp, 1, iLoop);
  81. iLoop := Pos(Ch, Temp);
  82. end;
  83. Result.Add(temp);
  84. end;
  85. procedure TLXTAppCentreCom.OnRedirect(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
  86. const
  87. TOKEN: string = 'access_token=';
  88. CLIENT_KEY: string = 'clientkey=';
  89. var
  90. AParamsStr: string;
  91. AParams: TStrings;
  92. iStart, iEnd, iCount, i: Integer;
  93. begin
  94. // ShowMessage(dest);
  95. if NumRedirect = 3 then
  96. begin
  97. AParamsStr := dest;
  98. // ShowMessage(AParamsStr);
  99. AParams := SplitString(AParamsStr, '&');
  100. try
  101. for i := 0 to AParams.Count - 1 do
  102. begin
  103. iStart := Pos(TOKEN, AParams[i]);
  104. if iStart > 0 then
  105. begin
  106. Inc(iStart, Length(TOKEN));
  107. (Sender as TAuthIdHTTP).FAccessToken := Copy(AParams[i], iStart);
  108. Break;
  109. end;
  110. end;
  111. for i := 0 to AParams.Count - 1 do
  112. begin
  113. iStart := Pos(CLIENT_KEY, AParams[i]);
  114. if iStart > 0 then
  115. begin
  116. Inc(iStart, Length(CLIENT_KEY));
  117. (Sender as TAuthIdHTTP).FClientKey := Copy(AParams[i], iStart);
  118. Break;
  119. end;
  120. end;
  121. finally
  122. AParams.Free;
  123. end;
  124. end;
  125. end;
  126. function TLXTAppCentreCom.DecodeAdapter(AData, AKey: string): string;
  127. const
  128. TICKET_TAG: string = 'ticket=';
  129. EXTEND_TAG: string = 'extend=';
  130. ID_TAG: string = 'id=';
  131. var
  132. AResults: TStrings;
  133. AResultStr, ATicket, AExtend, AID: string;
  134. iStart, iEnd, iCount, i: Integer;
  135. jo: ISuperObject;
  136. begin
  137. AResultStr := (DecryptNoHex(HexToStr(AData), AKey));
  138. if AResultStr = '' then
  139. begin
  140. ShowMessage('错误:解密失败.');
  141. Exit;
  142. end;
  143. AResults := SplitString(AResultStr, '&');
  144. try
  145. for i := 0 to AResults.Count - 1 do
  146. begin
  147. iStart := Pos(TICKET_TAG, AResults[i]);
  148. if iStart > 0 then
  149. begin
  150. Inc(iStart, Length(TICKET_TAG));
  151. ATicket := Copy(AResults[i], iStart);
  152. Break;
  153. end;
  154. end;
  155. for i := 0 to AResults.Count - 1 do
  156. begin
  157. iStart := Pos(EXTEND_TAG, AResults[i]);
  158. if iStart > 0 then
  159. begin
  160. Inc(iStart, Length(EXTEND_TAG));
  161. AExtend := Copy(AResults[i], iStart);
  162. Break;
  163. end;
  164. end;
  165. for i := 0 to AResults.Count - 1 do
  166. begin
  167. iStart := Pos(ID_TAG, AResults[i]);
  168. if iStart > 0 then
  169. begin
  170. Inc(iStart, Length(ID_TAG));
  171. AID := Copy(AResults[i], iStart);
  172. Break;
  173. end;
  174. end;
  175. if (AID = '') or (ATicket = '') then
  176. begin
  177. ShowMessage('错误:解密失败,找不到关键信息. \n\r信息:' + AResultStr);
  178. Exit;
  179. end;
  180. jo := SO('{}');
  181. jo.I['ticket'] := StrToInt64(ATicket);
  182. jo.S['id'] := AID;
  183. jo.S['extend'] := AExtend;
  184. Result := jo.AsJSon();
  185. finally
  186. AResults.Free;
  187. end;
  188. end;
  189. //
  190. function TLXTAppCentreCom.Authenticate(AAuthURL, AAppSecret: PChar): PChar;
  191. const
  192. GET_OPENKEY: string = 'http://%s:%s/api/oauth/me?access_token=%s';
  193. var
  194. AIdHttp: TAuthIdHTTP;
  195. AURL, AToken, AClientKey,
  196. ASecret,
  197. AOpenKey: string;
  198. AHost: string;
  199. joStr: string;
  200. jo: ISuperObject;
  201. AIDURL: TIdURI;
  202. begin
  203. // ShowMessage(AURL);
  204. AURL := string(AAuthURL);
  205. ASecret := string(AAppSecret);
  206. // ShowMessage(AURL);
  207. AIdHttp := TAuthIdHTTP.Create(nil);
  208. AIDURL := TIdURI.Create(AURL);
  209. try
  210. AIdHttp.RedirectMaximum := 5;
  211. AIdHttp.HandleRedirects := True;
  212. AIdHttp.OnRedirect := OnRedirect;
  213. try
  214. AIdHttp.Get(AURL);
  215. except
  216. end;
  217. if (Length(AIdHttp.FAccessToken) = 0) or (Length(AIdHttp.FAccessToken) <> 32) then
  218. begin
  219. ShowMessage('错误:没有获取到通行证或不是有效的通行证,可能是因为认证链接已经过期.');
  220. Exit;
  221. end;
  222. if (Length(AIdHttp.FClientKey) = 0) then
  223. begin
  224. ShowMessage('错误:您还没有绑定该应用的账号,请联系管理员绑定.');
  225. Exit;
  226. end;
  227. AClientKey := AIdHttp.FClientKey;
  228. AToken := AIdHttp.FAccessToken;
  229. AURL := Format(GET_OPENKEY, [AIDURL.Host, AIDURL.Port, AToken]);
  230. joStr := Utf8ToAnsi(AIdHttp.Get(AURL));
  231. if joStr = '' then
  232. begin
  233. ShowMessage('错误:不能获取OpenKey.');
  234. Exit;
  235. end;
  236. jo := SO(joStr);
  237. if jo = nil then
  238. begin
  239. ShowMessage('错误:OpenKey格式错误.');
  240. Exit;
  241. end;
  242. AOpenKey := jo.S['openkey'];
  243. if AOpenKey = '' then
  244. begin
  245. ShowMessage('错误:OpenKey为null.');
  246. Exit;
  247. end;
  248. try
  249. Result := PChar(DecodeAdapter(AClientKey, (string(ASecret) + AOpenKey)));
  250. // ShowMessage(string(Result));
  251. except
  252. on Ex: Exception do
  253. begin
  254. ShowMessage('错误:解密异常,' + Ex.Message + '.');
  255. Result := nil;
  256. end;
  257. end;
  258. except
  259. on Ex: Exception do
  260. begin
  261. ShowMessage('错误:解密异常,' + Ex.Message + '.');
  262. AIdHttp.Free;
  263. AIDURL.Free;
  264. end;
  265. end;
  266. AIdHttp.Free;
  267. AIDURL.Free;
  268. end;
  269. initialization
  270. TTypedComObjectFactory.Create(ComServer, TLXTAppCentreCom, Class_LXTAppCentreCom,
  271. ciSingleInstance, tmApartment);
  272. end.