14f0f31410d855e550c7a987b8464277aa7b8370
[platform/core/csapi/tizenfx.git] / src / Tizen.Account.OAuth2 / Tizen.Account.OAuth2 / CodeGrantAuthorizer.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Threading.Tasks;
19 using System.Runtime.InteropServices;
20 using System.Collections.Generic;
21
22 namespace Tizen.Account.OAuth2
23 {
24     /// <summary>
25     /// The CodeGrantAuthorizer is used to obtain access tokens and refresh tokens using Authorization Code Grant flow as described at https://tools.ietf.org/html/rfc6749#section-4.1
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public class CodeGrantAuthorizer : Authorizer
29     {
30         /// <summary>
31         /// The constructor
32         /// </summary>
33         /// <since_tizen> 3 </since_tizen>
34         public CodeGrantAuthorizer()
35         {
36
37         }
38
39
40
41         /// <summary>
42         /// Retrieves access token by exchanging authorization code received using <see cref="ClientCredentialsAuthorizer.AuthorizeAsync(AuthorizationRequest)"/>.
43         /// The authroization request parameters should be as defined in https://tools.ietf.org/html/rfc6749#section-4.1.3
44         /// </summary>
45         /// <since_tizen> 3 </since_tizen>
46         /// <param name="request">The token request <see cref="CodeGrantTokenRequest"/></param>
47         /// <returns>The response containing access token.</returns>
48         /// <privilege>http://tizen.org/privilege/internet</privilege>
49         /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
50         /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
51         public  async Task<TokenResponse> GetAccessTokenAsync(TokenRequest request)
52         {
53             IntPtr requestHandle = GetRequestHandle(request as CodeGrantTokenRequest);
54             return await Task.Run(() => GetAccessTokenByCode(requestHandle) );
55         }
56
57
58         // Fill device request handle for Authorization code grant
59         private IntPtr GetRequestHandle(CodeGrantAuthorizationRequest request)
60         {
61             if (request == null)
62             {
63                 Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
64                 throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
65             }
66
67             IntPtr requestHandle;
68             int ret = Interop.Request.Create(out requestHandle);
69             if (ret != (int)OAuth2Error.None)
70             {
71                 Log.Error(ErrorFactory.LogTag, "Interop failed");
72                 throw ErrorFactory.GetException(ret);
73             }
74
75             ret = Interop.Request.SetAuthEndPointUrl(requestHandle, request.AuthorizationEndpoint.ToString());
76             if (ret != (int)OAuth2Error.None)
77             {
78                 Log.Error(ErrorFactory.LogTag, "Interop failed");
79                 throw ErrorFactory.GetException(ret);
80             }
81
82             ret = Interop.Request.SetResponseType(requestHandle, Interop.ResponseType.Code);
83             if (ret != (int)OAuth2Error.None)
84             {
85                 Log.Error(ErrorFactory.LogTag, "Interop failed");
86                 throw ErrorFactory.GetException(ret);
87             }
88
89             if (request.ClientSecrets.Id != null)
90             {
91                 ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
92                 if (ret != (int)OAuth2Error.None)
93                 {
94                     Log.Error(ErrorFactory.LogTag, "Interop failed");
95                     throw ErrorFactory.GetException(ret);
96                 }
97             }
98
99             if (request.ClientSecrets.Secret != null)
100             {
101                 ret = Interop.Request.SetClientSecret(requestHandle, request.ClientSecrets.Secret);
102                 if (ret != (int)OAuth2Error.None)
103                 {
104                     Log.Error(ErrorFactory.LogTag, "Interop failed");
105                     throw ErrorFactory.GetException(ret);
106                 }
107             }
108
109             if (request.RedirectionEndPoint != null)
110             {
111                 ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.OriginalString);
112                 if (ret != (int)OAuth2Error.None)
113                 {
114                     Log.Error(ErrorFactory.LogTag, "Interop failed");
115                     throw ErrorFactory.GetException(ret);
116                 }
117             }
118
119             if (request.Scopes != null)
120             {
121                 string scope = string.Join(" ", request.Scopes);
122                 ret = Interop.Request.SetScope(requestHandle, scope);
123                 if (ret != (int)OAuth2Error.None)
124                 {
125                     Log.Error(ErrorFactory.LogTag, "Interop failed");
126                     throw ErrorFactory.GetException(ret);
127                 }
128             }
129
130             if (request.State != null)
131             {
132                 ret = Interop.Request.SetState(requestHandle, request.State);
133                 if (ret != (int)OAuth2Error.None)
134                 {
135                     Log.Error(ErrorFactory.LogTag, "Interop failed");
136                     throw ErrorFactory.GetException(ret);
137                 }
138             }
139
140             if (request.CustomData != null)
141             {
142                 foreach( var item in request.CustomData)
143                 {
144                     ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
145                     if (ret != (int)OAuth2Error.None)
146                     {
147                         Log.Error(ErrorFactory.LogTag, "Interop failed");
148                         throw ErrorFactory.GetException(ret);
149                     }
150                 }
151             }
152
153             return requestHandle;
154         }
155
156         // Fill device request handle for access token
157         private IntPtr GetRequestHandle(CodeGrantTokenRequest request)
158         {
159             if (request == null)
160             {
161                 Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
162                 throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
163             }
164
165             IntPtr requestHandle;
166             int ret = Interop.Request.Create(out requestHandle);
167             if (ret != (int)OAuth2Error.None)
168             {
169                 Log.Error(ErrorFactory.LogTag, "Interop failed");
170                 throw ErrorFactory.GetException(ret);
171             }
172
173             ret = Interop.Request.SetGrantType(requestHandle, Interop.GrantType.AuthCode);
174             if (ret != (int)OAuth2Error.None)
175             {
176                 Log.Error(ErrorFactory.LogTag, "Interop failed");
177                 throw ErrorFactory.GetException(ret);
178             }
179
180             ret = Interop.Request.SetAuthorizationCode(requestHandle, request.Code);
181             if (ret != (int)OAuth2Error.None)
182             {
183                 Log.Error(ErrorFactory.LogTag, "Interop failed");
184                 throw ErrorFactory.GetException(ret);
185             }
186
187             ret = Interop.Request.SetTokenEndPointUrl(requestHandle, request.TokenEndpoint.ToString());
188             if (ret != (int)OAuth2Error.None)
189             {
190                 Log.Error(ErrorFactory.LogTag, "Interop failed");
191                 throw ErrorFactory.GetException(ret);
192             }
193
194             ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.ToString());
195             if (ret != (int)OAuth2Error.None)
196             {
197                 Log.Error(ErrorFactory.LogTag, "Interop failed");
198                 throw ErrorFactory.GetException(ret);
199             }
200
201             ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
202             if (ret != (int)OAuth2Error.None)
203             {
204                 Log.Error(ErrorFactory.LogTag, "Interop failed");
205                 throw ErrorFactory.GetException(ret);
206             }
207
208             if (request.ClientSecrets.Secret != null)
209             {
210                 ret = Interop.Request.SetClientSecret(requestHandle, request.ClientSecrets.Secret);
211                 if (ret != (int)OAuth2Error.None)
212                 {
213                     Log.Error(ErrorFactory.LogTag, "Interop failed");
214                     throw ErrorFactory.GetException(ret);
215                 }
216             }
217
218             if (request.CustomData != null)
219             {
220                 foreach (var item in request.CustomData)
221                 {
222                     ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
223                     if (ret != (int)OAuth2Error.None)
224                     {
225                         Log.Error(ErrorFactory.LogTag, "Interop failed");
226                         throw ErrorFactory.GetException(ret);
227                     }
228                 }
229             }
230
231             ret = Interop.Request.SetClientAuthenticationType(requestHandle, (int)request.AuthenticationScheme);
232             if (ret != (int)OAuth2Error.None)
233             {
234                 Log.Error(ErrorFactory.LogTag, "Interop failed");
235                 throw ErrorFactory.GetException(ret);
236             }
237
238             return requestHandle;
239         }
240
241     }
242 }