[Tizen] Add BuildTools 2.1.0-rc1-02804-05
[platform/upstream/coreclr.git] / Tools / dotnetcli / sdk / NuGetFallbackFolder / microsoft.identitymodel.clients.activedirectory / 3.14.1 / src / src / ADAL.PCL.Android / BrokerHelper.cs
1 //------------------------------------------------------------------------------
2 //
3 // Copyright (c) Microsoft Corporation.
4 // All rights reserved.
5 //
6 // This code is licensed under the MIT License.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files(the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions :
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 // THE SOFTWARE.
25 //
26 //------------------------------------------------------------------------------
27
28 using System;
29 using System.Collections.Generic;
30 using System.Threading;
31 using System.Threading.Tasks;
32 using Android.Accounts;
33 using Android.App;
34 using Android.Content;
35 using Java.IO;
36
37 namespace Microsoft.IdentityModel.Clients.ActiveDirectory
38 {
39     [Android.Runtime.Preserve(AllMembers = true)]
40     class BrokerHelper : IBrokerHelper
41     {
42         private static SemaphoreSlim readyForResponse = null;
43         private static AuthenticationResultEx resultEx = null;
44
45         private BrokerProxy mBrokerProxy = new BrokerProxy(Application.Context);
46
47         public IPlatformParameters PlatformParameters { get; set; }
48
49         private bool WillUseBroker()
50         {
51             PlatformParameters pp = PlatformParameters as PlatformParameters;
52             if (pp != null)
53             {
54                 return pp.UseBroker;
55             }
56
57             return false;
58         }
59
60         public bool CanInvokeBroker { get { return WillUseBroker() && mBrokerProxy.CanSwitchToBroker(); } }
61
62
63         public async Task<AuthenticationResultEx> AcquireTokenUsingBroker(IDictionary<string, string> brokerPayload)
64         {
65             resultEx = null;
66             readyForResponse = new SemaphoreSlim(0);
67             try
68             {
69                 await Task.Run(() => AcquireToken(brokerPayload)).ConfigureAwait(false);
70             }
71             catch (Exception exc)
72             {
73                 PlatformPlugin.Logger.Error(null, exc);
74                 throw;
75             }
76             await readyForResponse.WaitAsync().ConfigureAwait(false);
77             return resultEx;
78         }
79         public void AcquireToken(IDictionary<string, string> brokerPayload)
80         {
81
82             if (brokerPayload.ContainsKey("broker_install_url"))
83             {
84                 string url = brokerPayload["broker_install_url"];
85                 Uri uri = new Uri(url);
86                 string query = uri.Query;
87                 if (query.StartsWith("?"))
88                 {
89                     query = query.Substring(1);
90                 }
91
92                 Dictionary<string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null);
93
94                 PlatformParameters pp = PlatformParameters as PlatformParameters;
95                 pp.CallerActivity.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse(keyPair["app_link"])));
96                 
97                 throw new AdalException(AdalErrorAndroidEx.BrokerApplicationRequired, AdalErrorMessageAndroidEx.BrokerApplicationRequired);
98             }
99
100             Context mContext = Application.Context;
101             AuthenticationRequest request = new AuthenticationRequest(brokerPayload);
102             PlatformParameters platformParams = PlatformParameters as PlatformParameters;
103
104             // BROKER flow intercepts here
105             // cache and refresh call happens through the authenticator service
106             if (mBrokerProxy.VerifyUser(request.LoginHint,
107                 request.UserId))
108             {
109                 PlatformPlugin.Logger.Verbose(null, "It switched to broker for context: " + mContext.PackageName);
110                 request.BrokerAccountName = request.LoginHint;
111
112                 // Don't send background request, if prompt flag is always or
113                 // refresh_session
114                 if (!string.IsNullOrEmpty(request.BrokerAccountName) || !string.IsNullOrEmpty(request.UserId))
115                 {
116                     PlatformPlugin.Logger.Verbose(null, "User is specified for background token request");
117                     resultEx = mBrokerProxy.GetAuthTokenInBackground(request, platformParams.CallerActivity);
118                 }
119                 else
120                 {
121                     PlatformPlugin.Logger.Verbose(null, "User is not specified for background token request");
122                 }
123
124                 if (resultEx != null && resultEx.Result != null && !string.IsNullOrEmpty(resultEx.Result.AccessToken))
125                 {
126                     PlatformPlugin.Logger.Verbose(null, "Token is returned from background call ");
127                     readyForResponse.Release();
128                     return;
129                 }
130
131                 // Launch broker activity
132                 // if cache and refresh request is not handled.
133                 // Initial request to authenticator needs to launch activity to
134                 // record calling uid for the account. This happens for Prompt auto
135                 // or always behavior.
136                 PlatformPlugin.Logger.Verbose(null, "Token is not returned from backgroud call");
137
138                 // Only happens with callback since silent call does not show UI
139                 PlatformPlugin.Logger.Verbose(null, "Launch activity for Authenticator");
140                 PlatformPlugin.Logger.Verbose(null, "Starting Authentication Activity");
141                 if (resultEx == null)
142                 {
143                     PlatformPlugin.Logger.Verbose(null, "Initial request to authenticator");
144                     // Log the initial request but not force a prompt
145                 }
146
147                 if (brokerPayload.ContainsKey("silent_broker_flow"))
148                 {
149                     throw new AdalSilentTokenAcquisitionException();
150                 }
151
152                 // onActivityResult will receive the response
153                 // Activity needs to launch to record calling app for this
154                 // account
155                 Intent brokerIntent = mBrokerProxy.GetIntentForBrokerActivity(request, platformParams.CallerActivity);
156                 if (brokerIntent != null)
157                 {
158                     try
159                     {
160                         PlatformPlugin.Logger.Verbose(null, "Calling activity pid:" + Android.OS.Process.MyPid()
161                                                             + " tid:" + Android.OS.Process.MyTid() + "uid:"
162                                                             + Android.OS.Process.MyUid());
163                         platformParams.CallerActivity.StartActivityForResult(brokerIntent, 1001);
164                     }
165                     catch (ActivityNotFoundException e)
166                     {
167                         PlatformPlugin.Logger.Error(null, e);
168                     }
169                 }
170             }
171             else
172             {
173                 throw new AdalException(AdalErrorAndroidEx.NoBrokerAccountFound, "Add requested account as a Workplace account via Settings->Accounts or set UseBroker=true.");
174             }
175         }
176         
177         internal static void SetBrokerResult(Intent data, int resultCode)
178         {
179             if (resultCode != BrokerResponseCode.ResponseReceived)
180             {
181                     resultEx = new AuthenticationResultEx
182                     {
183                         Exception =
184                             new AdalException(data.GetStringExtra(BrokerConstants.ResponseErrorCode),
185                                 data.GetStringExtra(BrokerConstants.ResponseErrorMessage))
186                     };
187             }
188             else
189             {
190                 string accessToken = data.GetStringExtra(BrokerConstants.AccountAccessToken);
191                 DateTimeOffset expiresOn = BrokerProxy.ConvertFromTimeT(data.GetLongExtra(BrokerConstants.AccountExpireDate, 0));
192                 UserInfo userInfo = BrokerProxy.GetUserInfoFromBrokerResult(data.Extras);
193                 resultEx = new AuthenticationResultEx
194                 {
195                     Result = new AuthenticationResult("Bearer", accessToken, expiresOn)
196                     {
197                         UserInfo = userInfo
198                     }
199                 };
200             }
201
202             readyForResponse.Release();
203         }
204     }
205
206     internal class CallBackHandler : Java.Lang.Object, IAccountManagerCallback
207     {
208         public void Run(IAccountManagerFuture future)
209         {
210         }
211     }
212 }