Skip to content

Commit ee61c59

Browse files
authored
Merge pull request #14 from IBM/feat/icp4d-support
feat(icp4d): refactor iam token manager and add icp4d support
2 parents 082b4ae + f68f00c commit ee61c59

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2970
-381
lines changed

Authentication/IamTokenManager.cs

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/**
2+
* Copyright 2019 IBM Corp. 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+
18+
using IBM.Cloud.SDK.Connection;
19+
using IBM.Cloud.SDK.Utilities;
20+
using System;
21+
using System.Collections.Generic;
22+
using UnityEngine.Networking;
23+
using Newtonsoft.Json;
24+
using System.Text;
25+
using Utility = IBM.Cloud.SDK.Utilities.Utility;
26+
27+
28+
namespace IBM.Cloud.SDK.Authentication
29+
{
30+
public class IamTokenManager : JwtTokenManager
31+
{
32+
private string iamApikey;
33+
private string iamClientId;
34+
private string iamClientSecret;
35+
private string iamDefaultUrl = "https://iam.cloud.ibm.com/identity/token";
36+
37+
private const string CLIENT_ID_SECRET_WARNING = "Warning: Client ID and Secret must BOTH be given, or the defaults will be used.";
38+
39+
public IamTokenManager(IamTokenOptions options) : base(options)
40+
{
41+
if (string.IsNullOrEmpty(url))
42+
{
43+
if (!string.IsNullOrEmpty(options.IamUrl))
44+
{
45+
url = options.IamUrl;
46+
}
47+
else
48+
{
49+
url = iamDefaultUrl;
50+
}
51+
}
52+
53+
if (!string.IsNullOrEmpty(options.IamApiKey))
54+
{
55+
iamApikey = options.IamApiKey;
56+
}
57+
58+
if (!string.IsNullOrEmpty(options.IamAccessToken))
59+
{
60+
userAccessToken = options.IamAccessToken;
61+
}
62+
63+
if (!string.IsNullOrEmpty(options.IamClientId))
64+
{
65+
iamClientId = options.IamClientId;
66+
}
67+
68+
if (!string.IsNullOrEmpty(options.IamClientSecret))
69+
{
70+
iamClientSecret = options.IamClientSecret;
71+
}
72+
73+
if (string.IsNullOrEmpty(options.IamClientSecret) || string.IsNullOrEmpty(options.IamClientId))
74+
{
75+
iamClientId = "bx";
76+
iamClientSecret = "bx";
77+
Log.Warning("IamTokenManager():", CLIENT_ID_SECRET_WARNING);
78+
}
79+
}
80+
81+
public void SetIamAuthorizationInfo(string IamClientId, string IamClientSecret)
82+
{
83+
iamClientId = IamClientId;
84+
iamClientSecret = IamClientSecret;
85+
if (string.IsNullOrEmpty(iamClientSecret) || string.IsNullOrEmpty(iamClientId))
86+
{
87+
Log.Warning("SetIamAuthorizationInfo():", CLIENT_ID_SECRET_WARNING);
88+
}
89+
}
90+
91+
#region Request Token
92+
/// <summary>
93+
/// Request an IAM token using an API key.
94+
/// </summary>
95+
/// <param name="callback">The request callback.</param>
96+
/// <param name="error"> The request error.</param>
97+
/// <returns></returns>
98+
override protected bool RequestToken(Callback<TokenData> callback)
99+
{
100+
if (callback == null)
101+
throw new ArgumentNullException("successCallback");
102+
103+
RESTConnector connector = new RESTConnector();
104+
connector.URL = url;
105+
if (connector == null)
106+
return false;
107+
108+
RequestIamTokenRequest req = new RequestIamTokenRequest();
109+
req.Callback = callback;
110+
req.HttpMethod = UnityWebRequest.kHttpVerbGET;
111+
req.Headers.Add("Content-type", "application/x-www-form-urlencoded");
112+
req.Headers.Add("Authorization", Utility.CreateAuthorization(iamClientId, iamClientSecret));
113+
req.OnResponse = OnRequestIamTokenResponse;
114+
req.DisableSslVerification = disableSslVerification;
115+
req.Forms = new Dictionary<string, RESTConnector.Form>();
116+
req.Forms["grant_type"] = new RESTConnector.Form("urn:ibm:params:oauth:grant-type:apikey");
117+
req.Forms["apikey"] = new RESTConnector.Form(iamApikey);
118+
req.Forms["response_type"] = new RESTConnector.Form("cloud_iam");
119+
120+
return connector.Send(req);
121+
}
122+
123+
private class RequestIamTokenRequest : RESTConnector.Request
124+
{
125+
public Callback<TokenData> Callback { get; set; }
126+
}
127+
128+
private void OnRequestIamTokenResponse(RESTConnector.Request req, RESTConnector.Response resp)
129+
{
130+
DetailedResponse<TokenData> response = new DetailedResponse<TokenData>();
131+
response.Result = new TokenData();
132+
foreach (KeyValuePair<string, string> kvp in resp.Headers)
133+
{
134+
response.Headers.Add(kvp.Key, kvp.Value);
135+
}
136+
response.StatusCode = resp.HttpResponseCode;
137+
138+
try
139+
{
140+
string json = Encoding.UTF8.GetString(resp.Data);
141+
response.Result = JsonConvert.DeserializeObject<TokenData>(json);
142+
response.Response = json;
143+
}
144+
catch (Exception e)
145+
{
146+
Log.Error("Credentials.OnRequestIamTokenResponse()", "Exception: {0}", e.ToString());
147+
resp.Success = false;
148+
}
149+
150+
if (((RequestIamTokenRequest)req).Callback != null)
151+
((RequestIamTokenRequest)req).Callback(response, resp.Error);
152+
}
153+
#endregion
154+
}
155+
156+
public class IamTokenOptions : JwtTokenOptions
157+
{
158+
private string iamApiKey;
159+
public string IamApiKey
160+
{
161+
get
162+
{
163+
return iamApiKey;
164+
}
165+
set
166+
{
167+
if (!Utility.HasBadFirstOrLastCharacter(value))
168+
{
169+
iamApiKey = value;
170+
}
171+
else
172+
{
173+
throw new IBMException("The credentials shouldn't start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your credentials");
174+
}
175+
}
176+
}
177+
public string IamAccessToken { get; set; }
178+
public string IamUrl { get; set; }
179+
public string IamClientId { get; set; }
180+
public string IamClientSecret { get; set; }
181+
}
182+
}

Authentication/Icp4dTokenManager.cs

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/**
2+
* Copyright 2019 IBM Corp. 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+
18+
using IBM.Cloud.SDK.Connection;
19+
using IBM.Cloud.SDK.Utilities;
20+
using System;
21+
using System.Net.Http;
22+
using System.Collections.Generic;
23+
using UnityEngine.Networking;
24+
using Newtonsoft.Json;
25+
using System.Text;
26+
using Utility = IBM.Cloud.SDK.Utilities.Utility;
27+
28+
29+
namespace IBM.Cloud.SDK.Authentication
30+
{
31+
public class Icp4dTokenManager : JwtTokenManager
32+
{
33+
private string username;
34+
private string password;
35+
36+
public Icp4dTokenManager(Icp4dTokenOptions options) : base(options)
37+
{
38+
39+
if (!string.IsNullOrEmpty(options.Url))
40+
{
41+
url = options.Url + "/v1/preauth/validateAuth";
42+
}
43+
else if (string.IsNullOrEmpty(userAccessToken))
44+
{
45+
// url is not needed if the user specifies their own access token
46+
throw new ArgumentNullException("`url` is a required parameter for Icp4dTokenManagerV1");
47+
}
48+
49+
// username and password are required too, unless there's access token
50+
if (!string.IsNullOrEmpty(options.Username))
51+
{
52+
username = options.Username;
53+
}
54+
if (!string.IsNullOrEmpty(options.Password))
55+
{
56+
password = options.Password;
57+
}
58+
if (!string.IsNullOrEmpty(options.AccessToken))
59+
{
60+
userAccessToken = options.AccessToken;
61+
}
62+
disableSslVerification = options.DisableSslVerification;
63+
}
64+
65+
override protected bool RequestToken(Callback<TokenData> callback)
66+
{
67+
if (callback == null)
68+
throw new ArgumentNullException("successCallback");
69+
70+
RESTConnector connector = new RESTConnector();
71+
connector.URL = url;
72+
if (connector == null)
73+
return false;
74+
75+
RequestIcp4dTokenRequest req = new RequestIcp4dTokenRequest();
76+
req.HttpMethod = UnityWebRequest.kHttpVerbGET;
77+
req.Callback = callback;
78+
req.Headers.Add("Content-type", "application/x-www-form-urlencoded");
79+
req.Headers.Add("Authorization", Utility.CreateAuthorization(username, password));
80+
req.OnResponse = OnRequestIcp4dTokenResponse;
81+
req.DisableSslVerification = disableSslVerification;
82+
return connector.Send(req);
83+
}
84+
85+
private class RequestIcp4dTokenRequest : RESTConnector.Request
86+
{
87+
public Callback<TokenData> Callback { get; set; }
88+
}
89+
90+
private void OnRequestIcp4dTokenResponse(RESTConnector.Request req, RESTConnector.Response resp)
91+
{
92+
DetailedResponse<TokenData> response = new DetailedResponse<TokenData>();
93+
response.Result = new TokenData();
94+
foreach (KeyValuePair<string, string> kvp in resp.Headers)
95+
{
96+
response.Headers.Add(kvp.Key, kvp.Value);
97+
}
98+
response.StatusCode = resp.HttpResponseCode;
99+
100+
try
101+
{
102+
string json = Encoding.UTF8.GetString(resp.Data);
103+
response.Result = JsonConvert.DeserializeObject<TokenData>(json);
104+
response.Response = json;
105+
}
106+
catch (Exception e)
107+
{
108+
Log.Error("Credentials.OnRequestIamTokenResponse()", "Exception: {0}", e.ToString());
109+
resp.Success = false;
110+
}
111+
if (((RequestIcp4dTokenRequest)req).Callback != null)
112+
((RequestIcp4dTokenRequest)req).Callback(response, resp.Error);
113+
}
114+
}
115+
116+
public class Icp4dTokenOptions : JwtTokenOptions
117+
{
118+
private string username;
119+
public string Username
120+
{
121+
get { return username; }
122+
set
123+
{
124+
if (!Utility.HasBadFirstOrLastCharacter(value))
125+
{
126+
username = value;
127+
}
128+
else
129+
{
130+
throw new ArgumentException("The username shouldn't start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your username");
131+
}
132+
}
133+
}
134+
135+
private string password;
136+
public string Password
137+
{
138+
get { return password; }
139+
set
140+
{
141+
if (!Utility.HasBadFirstOrLastCharacter(value))
142+
{
143+
password = value;
144+
}
145+
else
146+
{
147+
throw new ArgumentException("The password shouldn't start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your password");
148+
}
149+
}
150+
}
151+
152+
public bool DisableSslVerification { get; set; }
153+
}
154+
}

0 commit comments

Comments
 (0)