Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Account.OAuth2 / Tizen.Account.OAuth2 / ResourceOwnerPwdCredentialsAuthorizer.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.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using System.Threading.Tasks;
21
22 namespace Tizen.Account.OAuth2
23 {
24     /// <summary>
25     /// The ResourceOwnerPwdCredentialsAuthorizer is used to obtain access tokens using Resource Owner Password Credentials Grant flow as described at https://tools.ietf.org/html/rfc6749#section-4.3
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public class ResourceOwnerPwdCredentialsAuthorizer : Authorizer
29     {
30         /// <summary>
31         /// The constructor
32         /// </summary>
33         /// <since_tizen> 3 </since_tizen>
34         public ResourceOwnerPwdCredentialsAuthorizer()
35         {
36
37         }
38
39         /// <summary>
40         /// Authorization not supported through this API for this flow.
41         /// </summary>
42         /// <since_tizen> 3 </since_tizen>
43         /// <exception cref="InvalidOperationException">Thrown when the operation is not supported</exception>
44         public override Task<AuthorizationResponse> AuthorizeAsync(AuthorizationRequest request)
45         {
46             Log.Error(ErrorFactory.LogTag, "Authorization is not supported in this flow");
47             throw new InvalidOperationException();
48         }
49
50         /// <summary>
51         /// Retrieves access token by sending resource owner's password credentials.
52         /// The authroization request parameters should be as defined in https://tools.ietf.org/html/rfc6749#section-4.3.2
53         /// </summary>
54         /// <since_tizen> 3 </since_tizen>
55         /// <param name="request">The token request <see cref="ResourceOwnerPwdCredentialsTokenRequest"/></param>
56         /// <returns>The response containing access token.</returns>
57         /// <privilege>http://tizen.org/privilege/internet</privilege>
58         /// <exception cref="ArgumentException">Thrown when method failed due to invalid argumets</exception>
59         /// <exception cref="OAuth2Exception">Thrown when method fails due to server error</exception>
60         public override async Task<TokenResponse> GetAccessTokenAsync(TokenRequest request)
61         {
62             IntPtr requestHandle = GetRequestHandle(request as ResourceOwnerPwdCredentialsTokenRequest);
63             return await Task.Run(() => GetAccessToken(requestHandle));
64         }
65
66         // Fill device request handle for access token
67         private IntPtr GetRequestHandle(ResourceOwnerPwdCredentialsTokenRequest request)
68         {
69             if (request == null)
70             {
71                 Log.Error(ErrorFactory.LogTag, "Invalid request or request is null");
72                 throw ErrorFactory.GetException((int)OAuth2Error.InvalidParameter);
73             }
74
75             IntPtr requestHandle;
76             int ret = Interop.Request.Create(out requestHandle);
77             if (ret != (int)OAuth2Error.None)
78             {
79                 Log.Error(ErrorFactory.LogTag, "Interop failed");
80                 throw ErrorFactory.GetException(ret);
81             }
82
83             ret = Interop.Request.SetTokenEndPointUrl(requestHandle, request.TokenEndpoint.ToString());
84             if (ret != (int)OAuth2Error.None)
85             {
86                 Log.Error(ErrorFactory.LogTag, "Interop failed");
87                 throw ErrorFactory.GetException(ret);
88             }
89
90             ret = Interop.Request.SetRedirectionUrl(requestHandle, request.RedirectionEndPoint.ToString());
91             if (ret != (int)OAuth2Error.None)
92             {
93                 Log.Error(ErrorFactory.LogTag, "Interop failed");
94                 throw ErrorFactory.GetException(ret);
95             }
96
97             ret = Interop.Request.SetGrantType(requestHandle, Interop.GrantType.Password);
98             if (ret != (int)OAuth2Error.None)
99             {
100                 Log.Error(ErrorFactory.LogTag, "Interop failed");
101                 throw ErrorFactory.GetException(ret);
102             }
103
104             ret = Interop.Request.SetUserName(requestHandle, request.Username);
105             if (ret != (int)OAuth2Error.None)
106             {
107                 Log.Error(ErrorFactory.LogTag, "Interop failed");
108                 throw ErrorFactory.GetException(ret);
109             }
110
111             ret = Interop.Request.SetPassword(requestHandle, request.Password);
112             if (ret != (int)OAuth2Error.None)
113             {
114                 Log.Error(ErrorFactory.LogTag, "Interop failed");
115                 throw ErrorFactory.GetException(ret);
116             }
117
118             if (request.ClientSecrets.Id != null)
119             {
120                 ret = Interop.Request.SetClientId(requestHandle, request.ClientSecrets.Id);
121                 if (ret != (int)OAuth2Error.None)
122                 {
123                     Log.Error(ErrorFactory.LogTag, "Interop failed");
124                     throw ErrorFactory.GetException(ret);
125                 }
126             }
127
128             if (request.ClientSecrets.Secret != null)
129             {
130                 ret = Interop.Request.SetClientSecret(requestHandle, request.ClientSecrets.Secret);
131                 if (ret != (int)OAuth2Error.None)
132                 {
133                     Log.Error(ErrorFactory.LogTag, "Interop failed");
134                     throw ErrorFactory.GetException(ret);
135                 }
136             }
137
138             if (request.Scopes != null)
139             {
140                 string scope = string.Join(" ", request.Scopes);
141                 ret = Interop.Request.SetScope(requestHandle, scope);
142                 if (ret != (int)OAuth2Error.None)
143                 {
144                     Log.Error(ErrorFactory.LogTag, "Interop failed");
145                     throw ErrorFactory.GetException(ret);
146                 }
147             }
148
149             if (request.CustomData != null)
150             {
151                 foreach (var item in request.CustomData)
152                 {
153                     ret = Interop.Request.AddCustomData(requestHandle, item.Key, item.Value);
154                     if (ret != (int)OAuth2Error.None)
155                     {
156                         Log.Error(ErrorFactory.LogTag, "Interop failed");
157                         throw ErrorFactory.GetException(ret);
158                     }
159                 }
160             }
161
162             if (request.State != null)
163             {
164                 ret = Interop.Request.SetState(requestHandle, request.State);
165                 if (ret != (int)OAuth2Error.None)
166                 {
167                     Log.Error(ErrorFactory.LogTag, "Interop failed");
168                     throw ErrorFactory.GetException(ret);
169                 }
170             }
171
172             ret = Interop.Request.SetClientAuthenticationType(requestHandle, (int)request.AuthenticationScheme);
173             if (ret != (int)OAuth2Error.None)
174             {
175                 Log.Error(ErrorFactory.LogTag, "Interop failed");
176                 throw ErrorFactory.GetException(ret);
177             }
178
179             return requestHandle;
180         }
181     }
182 }