· 4 years ago · Mar 12, 2021, 12:42 PM
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Web;
5using Chilkat;
6
7//Class to communicate with odoo oAuth
8
9namespace WebApplication6.Helpers
10{
11 public class oAuth1ManagerOdoo
12 {
13
14 //Variables + Fetch/Set
15 public string scp_OdooEmail { get; set; }
16 public string scp_OdooPassword { get; set; }
17 public string scp_consumerKey { get; set; }
18 public string scp_consumerSecret { get; set; }
19
20
21 //oAuth Varialbes
22 public string oauth_baseURL { get; set; }
23 public string oauth_requestTokenURL { get; set; }
24 public string oauth_authorizeURL { get; set; }
25 public string oauth_tokenURL { get; set; }
26 public string oauth_callbackURL { get; set; }
27 public int oauth_callbackPort { get; set; }
28 public string oauth_token { get; set; }
29 public string oauth_tokenSecret { get; set; }
30
31 public string oauth_verifierCode { get; set; }
32
33 public oAuth1ManagerOdoo()
34 {
35
36 //Setup email and password as fixed data
37 scp_OdooEmail = "helpdesk@maximcomputer.co.uk";
38 scp_OdooPassword = "GJj3EH3WVxCjx3j";
39
40 //Setup API Credentials
41 scp_consumerKey = "eXcCsagekvmhaRnI4YKQ9u9nPNPPw5";
42 scp_consumerSecret = "m9XG3JbHOD8KEmLXaNA84csvzFH1ha";
43
44 //Setup oAuth URI
45 oauth_baseURL = "https://odoo.maximcomputer.co.uk/api";
46 oauth_requestTokenURL = oauth_baseURL + "/authentication/oauth1/initiate";
47 oauth_authorizeURL = oauth_baseURL + "/authentication/oauth1/authorize";
48 oauth_tokenURL = oauth_baseURL + "/authentication/oauth1/token";
49 oauth_callbackURL = "http://localhost:2815/";
50 oauth_callbackPort = 2815;
51
52 }
53
54 //Fetch Temporary Token for Authorization
55 public Boolean GetRequestToken()
56 {
57 //Start new HTTP Session
58 Chilkat.Http http = new Chilkat.Http();
59 bool success;
60
61 //Setup Enviroment
62 http.OAuth1 = true;
63 http.OAuthConsumerKey = scp_consumerKey;
64 http.OAuthConsumerSecret = scp_consumerSecret;
65 http.OAuthCallback = oauth_callbackURL;
66
67 Chilkat.HttpRequest req = new Chilkat.HttpRequest();
68 Chilkat.HttpResponse resp = http.PostUrlEncoded(oauth_requestTokenURL, req);
69 if (http.LastMethodSuccess != true)
70 {
71 Console.WriteLine(http.LastErrorText);
72 success = false;
73 return success;
74 }
75 else
76 {
77 success = true;
78 }
79
80 // If successful, the resp.BodyStr contains something like this:
81 // oauth_token=-Wa_KwAAAAAAxfEPAAABV8Qar4Q&oauth_token_secret=OfHY4tZBX2HK4f7yIw76WYdvnl99MVGB&oauth_callback_confirmed=true
82 Console.WriteLine(resp.BodyStr);
83
84 Chilkat.Hashtable hashTab = new Chilkat.Hashtable();
85 hashTab.AddQueryParams(resp.BodyStr);
86
87 string requestToken = hashTab.LookupStr("oauth_token");
88 string requestTokenSecret = hashTab.LookupStr("oauth_token_secret");
89 http.OAuthTokenSecret = requestTokenSecret;
90
91 Console.WriteLine("oauth_token = " + requestToken);
92 Console.WriteLine("oauth_token_secret = " + requestTokenSecret);
93 oauth_token = requestToken;
94 oauth_tokenSecret = requestTokenSecret;
95
96 Chilkat.StringBuilder sbUrlForBrowser = new Chilkat.StringBuilder();
97 sbUrlForBrowser.Append(oauth_authorizeURL);
98 sbUrlForBrowser.Append("?oauth_token=");
99 sbUrlForBrowser.Append(oauth_token);
100 string urlForBrowser = sbUrlForBrowser.GetAsString();
101
102 // When the urlForBrowser is loaded into a browser, the response from Odoo will redirect back to localhost:3017
103 // We'll need to start a socket that is listening on port 3017 for the callback from the browser.
104 Chilkat.Socket listenSock = new Chilkat.Socket();
105
106 int backLog = 5;
107 success = listenSock.BindAndListen(oauth_callbackPort, backLog);
108 if (success != true)
109 {
110 Console.WriteLine(listenSock.LastErrorText);
111 return false;
112 }
113
114 // Wait for the browser's connection in a background thread.
115 // (We'll send load the URL into the browser following this..)
116 // Wait a max of 60 seconds before giving up.
117 int maxWaitMs = 60000;
118 Chilkat.Task task = listenSock.AcceptNextConnectionAsync(maxWaitMs);
119 task.Run();
120
121 // At this point, your application should load the URL in a browser.
122 System.Diagnostics.Process.Start(urlForBrowser);
123
124 // Wait for the listenSock's task to complete.
125 success = task.Wait(maxWaitMs);
126 if (!success || (task.StatusInt != 7) || (task.TaskSuccess != true))
127 {
128 if (!success)
129 {
130 // The task.LastErrorText applies to the Wait method call.
131 Console.WriteLine(task.LastErrorText);
132 }
133 else
134 {
135 // The ResultErrorText applies to the underlying task method call (i.e. the AcceptNextConnection)
136 Console.WriteLine(task.Status);
137 Console.WriteLine(task.ResultErrorText);
138 }
139
140 return false;
141 }
142
143 // If we get to this point, the connection from the browser arrived and was accepted.
144
145 // We no longer need the listen socket...
146 // Stop listening on port 3017.
147 listenSock.Close(10);
148
149 // First get the connected socket.
150 Chilkat.Socket sock = new Chilkat.Socket();
151 sock.LoadTaskResult(task);
152
153 // Read the start line of the request..
154 string startLine = sock.ReceiveUntilMatch("\r\n");
155 if (sock.LastMethodSuccess != true)
156 {
157 Console.WriteLine(sock.LastErrorText);
158 return false;
159 }
160
161 // Read the request header.
162 string requestHeader = sock.ReceiveUntilMatch("\r\n\r\n");
163 if (sock.LastMethodSuccess != true)
164 {
165 Console.WriteLine(sock.LastErrorText);
166 return false;
167 }
168
169 // The browser SHOULD be sending us a GET request, and therefore there is no body to the request.
170 // Once the request header is received, we have all of it.
171 // We can now send our HTTP response.
172 Chilkat.StringBuilder sbResponseHtml = new Chilkat.StringBuilder();
173 sbResponseHtml.Append("<html><body><p>Chilkat thanks you!</b></body</html>");
174
175 Chilkat.StringBuilder sbResponse = new Chilkat.StringBuilder();
176 sbResponse.Append("HTTP/1.1 200 OK\r\n");
177 sbResponse.Append("Content-Length: ");
178 sbResponse.AppendInt(sbResponseHtml.Length);
179 sbResponse.Append("\r\n");
180 sbResponse.Append("Content-Type: text/html\r\n");
181 sbResponse.Append("\r\n");
182 sbResponse.AppendSb(sbResponseHtml);
183
184 sock.SendString(sbResponse.GetAsString());
185 sock.Close(50);
186
187 // The information we need is in the startLine.
188 // For example, the startLine will look something like this:
189 // GET /?oauth_token=abcdRQAAZZAAxfBBAAABVabcd_k&oauth_verifier=9rdOq5abcdCe6cn8M3jabcdj3Eabcd&org=mUkIZabcdKEababcd189t0 HTTP/1.1
190 Chilkat.StringBuilder sbStartLine = new Chilkat.StringBuilder();
191 sbStartLine.Append(startLine);
192 int numReplacements = sbStartLine.Replace("GET /?", "");
193 numReplacements = sbStartLine.Replace(" HTTP/1.1", "");
194 sbStartLine.Trim();
195
196 // oauth_token=abcdRQAAZZAAxfBBAAABVabcd_k&oauth_verifier=9rdOq5abcdCe6cn8M3jabcdj3Eabcd&org=mUkIZabcdKEababcd189t0
197 Console.WriteLine("startline: " + sbStartLine.GetAsString());
198
199 hashTab.Clear();
200 hashTab.AddQueryParams(sbStartLine.GetAsString());
201
202 oauth_token = hashTab.LookupStr("oauth_token");
203 oauth_verifierCode = hashTab.LookupStr("oauth_verifier");
204
205 http.OAuthToken = requestToken;
206 http.OAuthVerifier = oauth_verifierCode;
207 resp = http.PostUrlEncoded(oauth_tokenURL, req);
208 if (http.LastMethodSuccess != true)
209 {
210 Console.WriteLine(http.LastErrorText);
211 return false;
212 }
213
214 // Make sure a successful response was received.
215 if (resp.StatusCode != 200)
216 {
217 Console.WriteLine(resp.StatusLine);
218 Console.WriteLine(resp.Header);
219 Console.WriteLine(resp.BodyStr);
220 return false;
221 }
222
223 // If successful, the resp.BodyStr contains something like this:
224 // oauth_token=85123455-fF41296Bi3daM8eCo9Y5vZabcdxXpRv864plYPOjr&oauth_token_secret=afiYJOgabcdSfGae7BDvJVVTwys8fUGpra5guZxbmFBZo&oauth_expires_in=1800&xero_org_muid=abcdecNhPKabcdNjz189t0
225 Console.WriteLine(resp.BodyStr);
226
227 hashTab.Clear();
228 hashTab.AddQueryParams(resp.BodyStr);
229
230 oauth_token = hashTab.LookupStr("oauth_token");
231 oauth_tokenSecret = hashTab.LookupStr("oauth_token_secret");
232
233 // The access token + secret is what should be saved and used for
234 // subsequent REST API calls.
235 Console.WriteLine("Access Token = " + oauth_token);
236 Console.WriteLine("Access Token Secret = " + oauth_tokenSecret);
237
238 Console.WriteLine("Done!");
239 return true;
240 }
241
242
243
244
245 }
246}