diff --git a/PlanGrid.Api.Tests/ProjectsTests.cs b/PlanGrid.Api.Tests/ProjectsTests.cs index 58e0513..06b93e5 100644 --- a/PlanGrid.Api.Tests/ProjectsTests.cs +++ b/PlanGrid.Api.Tests/ProjectsTests.cs @@ -73,4 +73,4 @@ public async Task CreateProject() } */ } -} \ No newline at end of file +} diff --git a/PlanGrid.Api/AutoGeneratedIPlanGridApi.cs b/PlanGrid.Api/AutoGeneratedIPlanGridApi.cs index 461873f..60b9886 100644 --- a/PlanGrid.Api/AutoGeneratedIPlanGridApi.cs +++ b/PlanGrid.Api/AutoGeneratedIPlanGridApi.cs @@ -16,13 +16,15 @@ public partial class AutoGeneratedIPlanGridApi public RefitSettings Settings { get; private set; } public string Version { get; private set; } public int? MaxRetries { get; private set; } + public TokenType KeyType { get; private set; } - public void Initialize(string apiKey, RefitSettings settings, string version, int? maxRetries) + public void Initialize(string apiKey, RefitSettings settings, string version, int? maxRetries, TokenType keyType) { ApiKey = apiKey; Settings = settings; Version = version; MaxRetries = maxRetries; + KeyType = keyType; foreach (KeyValuePair> methodImpl in methodImpls.ToArray()) { diff --git a/PlanGrid.Api/PlanGrid.Api.projitems b/PlanGrid.Api/PlanGrid.Api.projitems index 0cd3314..eb1f8f2 100644 --- a/PlanGrid.Api/PlanGrid.Api.projitems +++ b/PlanGrid.Api/PlanGrid.Api.projitems @@ -76,5 +76,6 @@ + - \ No newline at end of file + diff --git a/PlanGrid.Api/PlanGridClient.cs b/PlanGrid.Api/PlanGridClient.cs index 7134d61..01d183c 100644 --- a/PlanGrid.Api/PlanGridClient.cs +++ b/PlanGrid.Api/PlanGridClient.cs @@ -22,8 +22,9 @@ public class PlanGridClient /// The version of the API you want to use. /// The maximum time that may elapse when making a call before timing out. /// The maximum number of attempts to make contacting the server in the event of a 503 service unavailable repsonse. This defaults to unlimited retries, with a delay between each attempt that multiplies by two. + /// The type of API key provided by PlanGrid. /// An interface upon which you can invoke the various methods exposed via the Public PlanGrid API. - public static IPlanGridApi Create(string apiKey = null, string baseUrl = null, string version = "1", int timeout = 60, int? maxRetries = null) + public static IPlanGridApi Create(string apiKey = null, string baseUrl = null, string version = "1", int timeout = 60, int? maxRetries = null, TokenType keyType = TokenType.Unknown) { apiKey = apiKey ?? Settings.ApiKey ?? Environment.GetEnvironmentVariable("PLANGRIDAPIKEY"); if (apiKey == null) @@ -31,6 +32,10 @@ public static IPlanGridApi Create(string apiKey = null, string baseUrl = null, s throw new ArgumentException("An ApiKey is required. Either pass it in to this method, add it to your App.config file, or set the environment variable \"PLANGRIDAPIKEY\".", nameof(apiKey)); } baseUrl = baseUrl ?? Settings.ApiBaseUrl ?? Environment.GetEnvironmentVariable("PLANGRIDAPIURL") ?? "https://io.plangrid.com"; + if (keyType == TokenType.Unknown) + { + keyType = Settings.ApiKeyType ?? Environment.GetEnvironmentVariable("PLANGRIDAPIKEYTYPE") ?? TokenType.Basic; + } string url = baseUrl; var settings = new RefitSettings @@ -48,13 +53,13 @@ public static IPlanGridApi Create(string apiKey = null, string baseUrl = null, s } }; var api = (AutoGeneratedIPlanGridApi)RestService.For( - new HttpClient(new PlanGridHttpHandler(apiKey, settings, version, maxRetries)) + new HttpClient(new PlanGridHttpHandler(apiKey, settings, version, maxRetries, keyType)) { BaseAddress = new Uri(url), Timeout = TimeSpan.FromSeconds(timeout) }, settings); - api.Initialize(apiKey, settings, version, maxRetries); + api.Initialize(apiKey, settings, version, maxRetries, keyType); return api; } } -} \ No newline at end of file +} diff --git a/PlanGrid.Api/PlanGridHttpHandler.cs b/PlanGrid.Api/PlanGridHttpHandler.cs index 6df5840..4b37cd7 100644 --- a/PlanGrid.Api/PlanGridHttpHandler.cs +++ b/PlanGrid.Api/PlanGridHttpHandler.cs @@ -19,13 +19,15 @@ public class PlanGridHttpHandler : HttpClientHandler public const HttpStatusCode RateLimitExceeded = (HttpStatusCode)429; private string authenticationToken; + private TokenType tokenType; private RefitSettings settings; private string version; private int? maxRetries; - public PlanGridHttpHandler(string accessToken, RefitSettings settings, string version, int? maxRetries) + public PlanGridHttpHandler(string accessToken, RefitSettings settings, string version, int? maxRetries, TokenType tokenType = TokenType.Basic) { - authenticationToken = BuildAuthenticationToken(accessToken); + authenticationToken = BuildAuthenticationToken(accessToken, tokenType); + this.tokenType = tokenType; this.settings = settings; this.version = version; this.maxRetries = maxRetries; @@ -42,7 +44,7 @@ protected override async Task SendAsync(HttpRequestMessage request.Content = new StringContent("", Encoding.UTF8, "application/json"); } - request.Headers.Authorization = new AuthenticationHeaderValue("Basic", authenticationToken); + request.Headers.Authorization = new AuthenticationHeaderValue(this.tokenType.ToString(), authenticationToken); request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse($"application/vnd.plangrid+json; version={version}")); HttpResponseMessage response = await base.SendAsync(request, cancellationToken); @@ -79,12 +81,20 @@ protected override async Task SendAsync(HttpRequestMessage throw new FailedRequestException(HttpStatusCode.ServiceUnavailable, $"Service unavailable after retrying {maxRetries} times."); } - private string BuildAuthenticationToken(string accessToken) + private string BuildAuthenticationToken(string accessToken, TokenType tokenType) { - string unencoded = $"{accessToken}:"; - byte[] authParamBytes = Encoding.ASCII.GetBytes(unencoded); - string encodedAuthParams = Convert.ToBase64String(authParamBytes); - return encodedAuthParams; + switch (tokenType) + { + case TokenType.Basic: + string unencoded = $"{accessToken}:"; + byte[] authParamBytes = Encoding.ASCII.GetBytes(unencoded); + string encodedAuthParams = Convert.ToBase64String(authParamBytes); + return encodedAuthParams; + case TokenType.Bearer: + return accessToken; + default: + throw new InvalidEnumArgumentException(); + } } } -} \ No newline at end of file +} diff --git a/PlanGrid.Api/TokenType.cs b/PlanGrid.Api/TokenType.cs new file mode 100644 index 0000000..6fd68cf --- /dev/null +++ b/PlanGrid.Api/TokenType.cs @@ -0,0 +1,15 @@ +using System.Runtime.Serialization; + +namespace PlanGrid.Api +{ + public enum TokenType + { + Unknown, + + [EnumMember(Value = "Basic")] + Basic, + + [EnumMember(Value = "Bearer")] + Bearer + } +}