Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add apikey authenticator #46

Merged
merged 17 commits into from
Oct 22, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d92e59b
feat(cpd-authentication): add apikey for authentication step and upda…
nan2iz Oct 12, 2021
8a851ae
test(cpd-tests): add testsing for CloudPakAuthentication
nan2iz Oct 12, 2021
d49dcfd
fix(detect-secrets): update detect-secrets for false positive
nan2iz Oct 12, 2021
60fb13f
fix(node-version): update appveyor.yml to use node version 15.6.0
nan2iz Oct 15, 2021
4c1c026
fix(renaming): rename function and vararaiables
nan2iz Oct 18, 2021
f4399a4
chore(detect-secrets): ran audit for detect-secrets
nan2iz Oct 18, 2021
d3291fe
fix(cp4d): fixed setter method with the correct naming
nan2iz Oct 18, 2021
5e61544
test(unit-test): remove unused tests
nan2iz Oct 19, 2021
055eef4
test(unit-testing): fix unit testing and remove unused testing function
nan2iz Oct 20, 2021
55e88e9
Merge branch 'main' of github.com:IBM/dotnet-sdk-core into add-apikey…
nan2iz Oct 20, 2021
b955890
fix(cpd-constuctor): revert the code for ConstructionDictionary
nan2iz Oct 21, 2021
65502b0
fix(cpd-authenticator): update apikey for CloudPakForDataAuthenticato…
nan2iz Oct 21, 2021
11f3c02
fix(semantic-release): update semantic-release version
nan2iz Oct 21, 2021
0ca8e45
fix(cpd-authenticator): renaming builder pattern functions and update…
nan2iz Oct 22, 2021
14691dd
fix(cpd-authenticate): remove unused condition
nan2iz Oct 22, 2021
18b32e4
fix(cpd-authentication): fix init function for initalize with password
nan2iz Oct 22, 2021
cb67218
fix(cpd-authenticator): add default value for password and apikey as …
nan2iz Oct 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 60 additions & 3 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "package-lock.json|^.secrets.baseline$",
"lines": null
},
"generated_at": "2021-03-04T18:54:10Z",
"generated_at": "2021-10-18T06:25:05Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand All @@ -25,6 +25,7 @@
"name": "CloudantDetector"
},
{
"ghe_instance": "github.ibm.com",
"name": "GheDetector"
},
{
Expand Down Expand Up @@ -101,11 +102,43 @@
}
],
"src/IBM.Cloud.SDK.Core/Authentication/CloudPakForData/CloudPakForDataAuthenticator.cs": [
{
"hashed_secret": "d7e417696b0fb23cfbb8c58cf748673382cbbc45",
"is_secret": false,
"is_verified": false,
"line_number": 113,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "0358c67856fb6a21c4767daf02fcb8fe4dc0a318",
"is_secret": false,
"is_verified": false,
"line_number": 119,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "69620d88f55564556dd0df45c97a051829c7b03e",
"is_secret": false,
"is_verified": false,
"line_number": 76,
"line_number": 154,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "f5cbae85fb47446511da4c9974e2da448caee7e1",
"is_secret": false,
"is_verified": false,
"line_number": 159,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "c2a6b03f190dfb2b4aa91f8af8d477a9bc3401dc",
"is_secret": false,
"is_verified": false,
"line_number": 248,
"type": "Secret Keyword",
"verified_result": null
}
Expand Down Expand Up @@ -216,6 +249,30 @@
"line_number": 38,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "500f6cbf87342a42e38738068db4785ab01cf4b6",
"is_secret": false,
"is_verified": false,
"line_number": 58,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "f75b33f87ffeacb3a4f793a09693e672e07449ff",
"is_secret": false,
"is_verified": false,
"line_number": 132,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "d4c3d66fd0c38547a3c7a4c6bdc29c36911bc030",
"is_secret": false,
"is_verified": false,
"line_number": 246,
"type": "Secret Keyword",
"verified_result": null
}
],
"test/IBM.Cloud.SDK.Core.Tests/ConfigBasedAuthenticatorFactoryTests.cs": [
Expand Down Expand Up @@ -401,7 +458,7 @@
}
]
},
"version": "0.13.1+ibm.31.dss",
"version": "0.13.1+ibm.46.dss",
"word_list": {
"file": null,
"hash": null
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ test_script:
{
Write-Output "branchName is main and not a pull request - running semantic release"

npx semantic-release@15.11.0
npx semantic-release@15.14.0

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@

using IBM.Cloud.SDK.Core.Http;
using IBM.Cloud.SDK.Core.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

using System.Net.Http;
using System.Text;

namespace IBM.Cloud.SDK.Core.Authentication.Cp4d
{
/// <summary>
Expand All @@ -30,22 +34,33 @@ public class CloudPakForDataAuthenticator : Authenticator
public IClient Client { get; set; }

// This is the suffix we'll need to add to the user-supplied URL to retrieve an access token.
private static string UrlSuffix = "/v1/preauth/validateAuth";
private static string UrlSuffix = "/v1/authorize";

// These are keys for body request for cpd authorization token
private const string KeyUsername = "username";
private const string KeyPassword = "password";
private const string KeyApikey = "api_key";

// Configuration properties for this authenticator.
public string Url { get; private set; }
public string Username { get; private set; }
public string Password { get; private set; }
public string Apikey { get; private set; }
public bool? DisableSslVerification { get; set; }
public Dictionary<string, string> Headers { get; set; }

// This field holds an access token and its expiration time.
private CloudPakForDataToken tokenData;

// this empty constructor will be used by builder
public CloudPakForDataAuthenticator()
{
}

/// <summary>
/// Constructs a CloudPakForDataAuthenticator with all properties.
/// </summary>
/// <param name="url">The base URL associated with the token server. The path "/v1/preauth/validateAuth" will be appended to this value automatically.</param>
/// <param name="url">The base URL associated with the token server. The path "/v1/authorize" will be appended to this value automatically.</param>
/// <param name="username">The username to be used when retrieving the access token</param>
/// <param name="password">The password to be used when retrieving the access token</param>
/// <param name="disableSslVerification">A flag indicating whether SSL hostname verification should be disabled</param>
Expand All @@ -64,17 +79,60 @@ public CloudPakForDataAuthenticator(Dictionary<string, string> config)
config.TryGetValue(PropNameUrl, out string url);
config.TryGetValue(PropNameUsername, out string username);
config.TryGetValue(PropNamePassword, out string password);
config.TryGetValue(PropNameApikey, out string apikey);
config.TryGetValue(PropNameDisableSslVerification, out string disableSslVerficiationString);
bool.TryParse(disableSslVerficiationString, out bool disableSslVerification);
Init(url, username, password, disableSslVerification);
Init(url, username, password, apikey, disableSslVerification);
}

public CloudPakForDataAuthenticator WithUrl(string url)
{
Url = url;
return this;
}

public CloudPakForDataAuthenticator WithUserName(string username)
{
Username = username;
return this;
}

public CloudPakForDataAuthenticator WithPassword(string password)
{
Password = password;
return this;
}

public CloudPakForDataAuthenticator WithApikey(string apikey)
{
Apikey = apikey;
return this;
}

public CloudPakForDataAuthenticator WithDisableSslVerification(bool disableSslVerification)
{
DisableSslVerification = disableSslVerification;
return this;
}

public CloudPakForDataAuthenticator WithHeaders(Dictionary<string, string> headers)
{
Headers = headers;
return this;
}

public CloudPakForDataAuthenticator Build()
{
Init();

return this;
}

private void Init(string url, string username, string password, bool? disableSslVerification = null, Dictionary<string, string> headers = null)
{
Url = url;
Username = username;
Password = password;


if (disableSslVerification != null)
{
DisableSslVerification = disableSslVerification;
Expand All @@ -85,12 +143,45 @@ private void Init(string url, string username, string password, bool? disableSsl
Headers = headers;
}

Validate();
Init();
}

private void Init(string url, string username, string password, string apikey, bool? disableSslVerification = null, Dictionary<string, string> headers = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need default values for password and apikey here? I dont think its guaranteed the values will come back from the config

Suggested change
private void Init(string url, string username, string password, string apikey, bool? disableSslVerification = null, Dictionary<string, string> headers = null)
private void Init(string url, string username, string password = null, string apikey = null, bool? disableSslVerification = null, Dictionary<string, string> headers = null)

{
Url = url;
Username = username;

if (password != null)
{
Password = password;
}

if (apikey != null)
{
Apikey = apikey;
}

if (disableSslVerification != null)
{
DisableSslVerification = disableSslVerification;
}

Client = new IBMHttpClient()
if (headers != null)
{
ServiceUrl = Url + UrlSuffix
};
Headers = headers;
}

Init();
}

public void Init()
{
Validate();

Client = new IBMHttpClient()
{
ServiceUrl = Url + UrlSuffix
};
}

public override string AuthenticationType
Expand Down Expand Up @@ -133,8 +224,9 @@ protected DetailedResponse<CloudPakForDataTokenResponse> RequestToken()

try
{
IClient client = Client.WithAuthentication(Username, Password);
var request = Client.GetAsync(Url + UrlSuffix);
var request = Client.PostAsync(Url + UrlSuffix);
request.WithHeader("Content-type", "Content-Type: application/json");

if (DisableSslVerification != null)
{
Client.DisableSslVerification((bool)DisableSslVerification);
Expand All @@ -145,6 +237,21 @@ protected DetailedResponse<CloudPakForDataTokenResponse> RequestToken()
request.WithHeaders(Headers);
}

JObject bodyObject = new JObject();
bodyObject[KeyUsername] = Username;

if (string.IsNullOrEmpty(Password))
{
bodyObject[KeyApikey] = Apikey;
}
else
{
bodyObject[KeyPassword] = Password;
}

var httpContent = new StringContent(JsonConvert.SerializeObject(bodyObject), Encoding.UTF8, HttpMediaType.APPLICATION_JSON);
request.WithBodyContent(httpContent);

result = request.As<CloudPakForDataTokenResponse>().Result;
if (result == null)
{
Expand All @@ -171,9 +278,9 @@ public override void Validate()
throw new ArgumentNullException(string.Format(ErrorMessagePropMissing, "Username"));
}

if (string.IsNullOrEmpty(Password))
if (string.IsNullOrEmpty(Password) && string.IsNullOrEmpty(Apikey))
{
throw new ArgumentNullException(string.Format(ErrorMessagePropMissing, "Password"));
throw new ArgumentNullException(string.Format(ErrorMessagePropMissing, "Password or Apikey"));
}

if (CredentialUtils.HasBadStartOrEndChar(Url))
Expand All @@ -186,10 +293,15 @@ public override void Validate()
throw new ArgumentException(string.Format(ErrorMessagePropInvalid, "Username"));
}

if (CredentialUtils.HasBadStartOrEndChar(Password))
if (!string.IsNullOrEmpty(Password) && CredentialUtils.HasBadStartOrEndChar(Password))
{
throw new ArgumentException(string.Format(ErrorMessagePropInvalid, "Password"));
}

if (!string.IsNullOrEmpty(Apikey) && CredentialUtils.HasBadStartOrEndChar(Apikey))
{
throw new ArgumentException(string.Format(ErrorMessagePropInvalid, "Apikey"));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public CloudPakForDataToken(string accessToken)

public CloudPakForDataToken(CloudPakForDataTokenResponse response)
{
AccessToken = response.AccessToken;
AccessToken = response.Token;
long? iat = null;
long? exp = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,8 @@ namespace IBM.Cloud.SDK.Core.Authentication.Cp4d
/// </summary>
public class CloudPakForDataTokenResponse
{
[JsonProperty("username", NullValueHandling = NullValueHandling.Ignore)]
public string Username { get; set; }
[JsonProperty("role", NullValueHandling = NullValueHandling.Ignore)]
public string Role { get; set; }
[JsonProperty("permissions", NullValueHandling = NullValueHandling.Ignore)]
public List<string> Permissions { get; set; }
[JsonProperty("sub", NullValueHandling = NullValueHandling.Ignore)]
public string Sub { get; set; }
[JsonProperty("iss", NullValueHandling = NullValueHandling.Ignore)]
public string Iss { get; set; }
[JsonProperty("aud", NullValueHandling = NullValueHandling.Ignore)]
public string Aud { get; set; }
[JsonProperty("uid", NullValueHandling = NullValueHandling.Ignore)]
public string Uid { get; set; }
[JsonProperty("accessToken", NullValueHandling = NullValueHandling.Ignore)]
public string AccessToken { get; set; }
mediumTaj marked this conversation as resolved.
Show resolved Hide resolved
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
public string Token { get; set; }
[JsonProperty("_messageCode_", NullValueHandling = NullValueHandling.Ignore)]
public string MessageCode { get; set; }
[JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
Expand Down
Loading