2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using System.Threading.Tasks;
22 namespace Tizen.Account.OAuth2
25 /// The ImplicitGrantAuthorizer is used to obtain access tokens using Implicit Grant flow as described at https://tools.ietf.org/html/rfc6749#section-4.2
27 /// <since_tizen> 3 </since_tizen>
28 public class ImplicitGrantAuthorizer : Authorizer
33 /// <since_tizen> 3 </since_tizen>
34 public ImplicitGrantAuthorizer()
40 /// Retrieves access token asynchronously. The authroization request parameters should be as defined in https://tools.ietf.org/html/rfc6749#section-4.2.1
42 /// <since_tizen> 3 </since_tizen>
43 /// <param name="request">The authorization request <see cref="ImplicitGrantAuthorizationRequest"/></param>
44 /// <returns>The response containing access token.</returns>
45 /// <privilege>http://tizen.org/privilege/internet</privilege>
46 /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
47 /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
48 public new virtual async Task<TokenResponse> AuthorizeAsync(AuthorizationRequest request)
50 IntPtr requestHandle = GetRequestHandle(request as ImplicitGrantAuthorizationRequest);
51 return await Task.Run(() => GetAuthorizationResponse(requestHandle));
55 /// Access token can be retreived implicitly using <see cref="AuthorizeAsync"/> in this flow.
57 /// <since_tizen> 3 </since_tizen>
58 /// <exception cref="InvalidOperationException">Thrown when the operation is not supported</exception>
59 public override Task<TokenResponse> GetAccessTokenAsync(TokenRequest request)
61 Log.Error(ErrorFactory.LogTag, "Obtain token directly from authorization grant ");
62 throw new InvalidOperationException();
66 /// Refreshing access token is not supported in this flow.
68 /// <since_tizen> 3 </since_tizen>
69 /// <exception cref="InvalidOperationException">Thrown when the operation is not supported</exception>
70 public override Task<TokenResponse> RefreshAccessTokenAsync(RefreshTokenRequest request)
72 Log.Error(ErrorFactory.LogTag, "Refesh token is not supported in Implicit Grant flow");
73 throw new InvalidOperationException();
76 private TokenResponse GetAuthorizationResponse(IntPtr requestHandle)
78 IntPtr error = IntPtr.Zero;
79 TokenResponse response = null;
80 int ret = (int)OAuth2Error.None;
81 Interop.Manager.Oauth2AuthGrantCallback authGrantCb = (IntPtr responseHandle, IntPtr usrData) =>
83 if (responseHandle == IntPtr.Zero)
85 Log.Error(ErrorFactory.LogTag, "Error occured");
86 throw (new ArgumentNullException());
89 Interop.Response.GetError(responseHandle, out error);
90 if (error != IntPtr.Zero)
92 Log.Error(ErrorFactory.LogTag, "Server Error occured");
97 ret = Interop.Response.GetAccessToken(responseHandle, out accessToken);
98 if (ret != (int)OAuth2Error.None)
100 Log.Error(ErrorFactory.LogTag, "Interop failed");
101 throw ErrorFactory.GetException(ret);
105 ret = Interop.Response.GetTokenType(responseHandle, out tokenType);
106 if (ret != (int)OAuth2Error.None)
108 Log.Error(ErrorFactory.LogTag, "Interop failed");
109 throw ErrorFactory.GetException(ret);
113 ret = Interop.Response.GetExpiresIn(responseHandle, out expiresIn);
114 if (ret != (int)OAuth2Error.None)
116 Log.Error(ErrorFactory.LogTag, "Interop failed");
117 throw ErrorFactory.GetException(ret);
121 ret = Interop.Response.GetScope(responseHandle, out scope);
122 if (ret != (int)OAuth2Error.None)
124 Log.Error(ErrorFactory.LogTag, "Interop failed");
125 throw ErrorFactory.GetException(ret);
129 ret = Interop.Response.GetState(responseHandle, out state);
130 if (ret != (int)OAuth2Error.None)
132 Log.Error(ErrorFactory.LogTag, "Interop failed");
133 throw ErrorFactory.GetException(ret);
136 IEnumerable<string> scopes = (scope == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(scope)?.Split(' ');
138 var token = new AccessToken() { Token = Marshal.PtrToStringAnsi(accessToken), ExpiresIn = expiresIn, Scope = scopes, TokenType = Marshal.PtrToStringAnsi(tokenType) };
139 response = new TokenResponse(responseHandle) { AccessToken = token, State = Marshal.PtrToStringAnsi(state), RefreshToken = null };
143 ret = Interop.Manager.RequestAuthorizationGrant(_managerHandle, requestHandle, authGrantCb, IntPtr.Zero);
144 Interop.Request.Destroy(requestHandle);
145 if (ret != (int)OAuth2Error.None || error != IntPtr.Zero)
147 if (error != IntPtr.Zero)
149 throw ErrorFactory.GetException(error);
153 Log.Error(ErrorFactory.LogTag, "Interop failed");
154 throw ErrorFactory.GetException(ret);
161 // Fill device request handle for Authorization code grant
162 private IntPtr GetRequestHandle(ImplicitGrantAuthorizationRequest request)
166 Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
167 throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
170 IntPtr requestHandle;
171 int ret = Interop.Request.Create(out requestHandle);
172 if (ret != (int)OAuth2Error.None)
174 Log.Error(ErrorFactory.LogTag, "Interop failed");
175 throw ErrorFactory.GetException(ret);
178 ret = Interop.Request.SetAuthEndPointUrl(requestHandle, request.AuthorizationEndpoint.ToString());
179 if (ret != (int)OAuth2Error.None)
181 Log.Error(ErrorFactory.LogTag, "Interop failed");
182 throw ErrorFactory.GetException(ret);
185 ret = Interop.Request.SetResponseType(requestHandle, Interop.ResponseType.Token);
186 if (ret != (int)OAuth2Error.None)
188 Log.Error(ErrorFactory.LogTag, "Interop failed");
189 throw ErrorFactory.GetException(ret);
192 ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
193 if (ret != (int)OAuth2Error.None)
195 Log.Error(ErrorFactory.LogTag, "Interop failed");
196 throw ErrorFactory.GetException(ret);
199 if (request.RedirectionEndPoint != null)
201 ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.ToString());
202 if (ret != (int)OAuth2Error.None)
204 Log.Error(ErrorFactory.LogTag, "Interop failed");
205 throw ErrorFactory.GetException(ret);
209 if (request.Scopes != null)
211 string scope = string.Join(" ", request.Scopes);
212 ret = Interop.Request.SetScope(requestHandle, scope);
213 if (ret != (int)OAuth2Error.None)
215 Log.Error(ErrorFactory.LogTag, "Interop failed");
216 throw ErrorFactory.GetException(ret);
220 if (request.State != null)
222 ret = Interop.Request.SetState(requestHandle, request.State);
223 if (ret != (int)OAuth2Error.None)
225 Log.Error(ErrorFactory.LogTag, "Interop failed");
226 throw ErrorFactory.GetException(ret);
230 if (request.CustomData != null)
232 foreach (var item in request.CustomData)
234 ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
235 if (ret != (int)OAuth2Error.None)
237 Log.Error(ErrorFactory.LogTag, "Interop failed");
238 throw ErrorFactory.GetException(ret);
243 return requestHandle;