/// <inheritdoc/> public virtual Task <ListTenantsApiCall> PrepareListTenantsAsync(CancellationToken cancellationToken) { UriTemplate template = new UriTemplate("v2.0/tenants"); Dictionary <string, string> parameters = new Dictionary <string, string>(); Func <HttpResponseMessage, CancellationToken, Task <ReadOnlyCollectionPage <Tenant> > > deserializeResult = (responseMessage, innerCancellationToken) => { Uri originalUri = responseMessage.RequestMessage.RequestUri; if (!HttpApiCall.IsAcceptable(responseMessage)) { throw new HttpWebException(responseMessage); } return(responseMessage.Content.ReadAsStringAsync() .Select( innerTask => { if (string.IsNullOrEmpty(innerTask.Result)) { return null; } JObject responseObject = JsonConvert.DeserializeObject <JObject>(innerTask.Result); JArray tenantsArray = responseObject["tenants"] as JArray; if (tenantsArray == null) { return null; } IList <Tenant> list = tenantsArray.ToObject <Tenant[]>(); // http://docs.openstack.org/api/openstack-identity-service/2.0/content/Paginated_Collections-d1e325.html Func <CancellationToken, Task <IHttpApiCall <ReadOnlyCollectionPage <Tenant> > > > prepareGetNextPageAsync = null; JArray tenantsLinksArray = responseObject["tenants_links"] as JArray; if (tenantsLinksArray != null) { IList <Link> tenantsLinks = tenantsLinksArray.ToObject <Link[]>(); Link nextLink = tenantsLinks.FirstOrDefault(i => string.Equals("next", i.Relation, StringComparison.OrdinalIgnoreCase)); if (nextLink != null) { prepareGetNextPageAsync = nextCancellationToken => { return PrepareListTenantsAsync(nextCancellationToken) .WithUri(nextLink.Target) .Select(_ => _.Result.AsHttpApiCall()); }; } } ReadOnlyCollectionPage <Tenant> results = new BasicReadOnlyCollectionPage <Tenant>(list, prepareGetNextPageAsync); return results; })); }; return(GetBaseUriAsync(cancellationToken) .Then(PrepareRequestAsyncFunc(HttpMethod.Get, template, parameters, cancellationToken)) .Select(task => new ListTenantsApiCall(CreateCustomApiCall(task.Result, HttpCompletionOption.ResponseContentRead, deserializeResult)))); }
/// <inheritdoc/> public virtual Task <ListApiVersionsApiCall> PrepareListApiVersionsAsync(CancellationToken cancellationToken) { UriTemplate template = new UriTemplate(string.Empty); IDictionary <string, string> parameters = ImmutableDictionary <string, string> .Empty; Func <HttpResponseMessage, CancellationToken, Task <ReadOnlyCollectionPage <ApiVersion> > > deserializeResult = (responseMessage, innerCancellationToken) => { Uri originalUri = responseMessage.RequestMessage.RequestUri; if (!HttpApiCall.IsAcceptable(responseMessage)) { throw new HttpWebException(responseMessage); } return(responseMessage.Content.ReadAsStringAsync() .Select( innerTask => { if (string.IsNullOrEmpty(innerTask.Result)) { return null; } JObject responseObject = JsonConvert.DeserializeObject <JObject>(innerTask.Result); JObject versionsObject = responseObject["versions"] as JObject; if (versionsObject == null) { return null; } JArray versionsArray = versionsObject["values"] as JArray; if (versionsArray == null) { return null; } IList <ApiVersion> list = versionsArray.ToObject <ApiVersion[]>(); // according to the available documentation, this call does not appear to be paginated Func <CancellationToken, Task <IHttpApiCall <ReadOnlyCollectionPage <ApiVersion> > > > prepareGetNextPageAsync = null; ReadOnlyCollectionPage <ApiVersion> results = new BasicReadOnlyCollectionPage <ApiVersion>(list, prepareGetNextPageAsync); return results; })); }; return(GetBaseUriAsync(cancellationToken) .Then(PrepareRequestAsyncFunc(HttpMethod.Get, template, parameters, cancellationToken)) .Select(task => new ListApiVersionsApiCall(CreateCustomApiCall(task.Result, HttpCompletionOption.ResponseContentRead, deserializeResult)))); }
internal virtual void ValidateRequest(HttpRequestMessage request) { if (request == null) { throw new ArgumentNullException("request"); } if (request.Headers.Accept != null && request.Headers.Accept.Count > 0) { MediaTypeHeaderValue[] acceptTypes = request.Headers.Accept.ToArray(); MediaTypeHeaderValue contentType = new MediaTypeHeaderValue("application/json"); if (!acceptTypes.Any(acceptType => HttpApiCall.IsAcceptable(acceptType, contentType))) { throw new NotSupportedException(); } } }
/// <inheritdoc/> /// <remarks> /// <para>Rackspace sends back the <c>media-types</c> property value wrapped in an additional JSON object, as /// opposed to the array OpenStack uses. This method overrides the behavior of the base OpenStack client to /// replace the unexpected structure with the correct layout prior to deserialization.</para> /// <note type="note"> /// <para>If required, the original response is available via the <see cref="HttpResponseMessage.Content"/> /// property of the response.</para> /// </note> /// </remarks> public override Task <GetApiVersionApiCall> PrepareGetApiVersionAsync(ApiVersionId apiVersionId, CancellationToken cancellationToken) { UriTemplate template = new UriTemplate("{version_id}"); Dictionary <string, string> parameters = new Dictionary <string, string> { { "version_id", apiVersionId.Value } }; Func <HttpResponseMessage, CancellationToken, Task <ApiVersionResponse> > deserializeResult = (responseMessage, innerCancellationToken) => { Uri originalUri = responseMessage.RequestMessage.RequestUri; if (!HttpApiCall.IsAcceptable(responseMessage)) { throw new HttpWebException(responseMessage); } return(responseMessage.Content.ReadAsStringAsync() .Select( innerTask => { if (string.IsNullOrEmpty(innerTask.Result)) { return null; } JObject responseObject = JsonConvert.DeserializeObject <JObject>(innerTask.Result); if (responseObject == null) { return null; } JObject versionObject = responseObject["version"] as JObject; if (versionObject == null) { return responseObject.ToObject <ApiVersionResponse>(); } JToken mediaTypesToken = versionObject["media-types"]; if (mediaTypesToken is JArray) { return responseObject.ToObject <ApiVersionResponse>(); } JArray mediaTypesArray = mediaTypesToken["values"] as JArray; if (mediaTypesArray == null) { versionObject.Remove("media-types"); } else { versionObject["media-types"] = mediaTypesArray; } return responseObject.ToObject <ApiVersionResponse>(); })); }; return(GetBaseUriAsync(cancellationToken) .Then(PrepareRequestAsyncFunc(HttpMethod.Get, template, parameters, cancellationToken)) .Select(task => new GetApiVersionApiCall(CreateCustomApiCall(task.Result, HttpCompletionOption.ResponseContentRead, deserializeResult)))); }
public HttpResponseMessage PostAuthenticate([FromBody] AuthenticationRequest authenticationRequest) { MediaTypeHeaderValue acceptedType = new MediaTypeHeaderValue("application/json"); MediaTypeHeaderValue contentType = Request.Content.Headers.ContentType; if (!HttpApiCall.IsAcceptable(acceptedType, contentType)) { return(new HttpResponseMessage(HttpStatusCode.BadRequest)); } ValidateRequest(Request); if (authenticationRequest == null) { return(new HttpResponseMessage(HttpStatusCode.BadRequest)); } AuthenticationData authenticationData = authenticationRequest.AuthenticationData; if (authenticationData == null) { return(new HttpResponseMessage(HttpStatusCode.BadRequest)); } if (authenticationData.TenantName != null && !string.Equals(authenticationData.TenantName, _tenantName, StringComparison.OrdinalIgnoreCase)) { return(new HttpResponseMessage(HttpStatusCode.Unauthorized)); } if (authenticationData.TenantId != null && authenticationData.TenantId != new ProjectId(_tenantId)) { return(new HttpResponseMessage(HttpStatusCode.Unauthorized)); } if (authenticationData.Token != null) { throw new NotImplementedException(); } PasswordCredentials passwordCredentials = authenticationData.PasswordCredentials; if (passwordCredentials == null) { return(new HttpResponseMessage(HttpStatusCode.BadRequest)); } if (!string.Equals(passwordCredentials.Username, _username, StringComparison.OrdinalIgnoreCase) || !string.Equals(passwordCredentials.Password, _password, StringComparison.Ordinal)) { return(new HttpResponseMessage(HttpStatusCode.Unauthorized)); } bool hasTenant = authenticationData.TenantId != null || authenticationData.TenantName != null; string responseBody; if (hasTenant) { responseBody = IdentityServiceResources.AuthenticateResponseTemplate; } else { responseBody = IdentityServiceResources.AuthenticateWithoutTenantResponseTemplate; } lock (_lock) { var parameters = new Dictionary <string, string>(); // expire the token 5 minutes early if (!_tokenExpires.HasValue || _tokenExpires < DateTimeOffset.Now - TimeSpan.FromMinutes(5)) { // generate a new token _tokenCreated = DateTimeOffset.Now; _tokenExpires = _tokenCreated + TimeSpan.FromHours(24); _tokenId = new TokenId(Guid.NewGuid().ToString()); } parameters["issued_at"] = JsonConvert.SerializeObject(_tokenCreated.Value); parameters["expires"] = JsonConvert.SerializeObject(_tokenExpires.Value); parameters["tokenId"] = JsonConvert.SerializeObject(_tokenId); parameters["tenantId"] = JsonConvert.SerializeObject(_tenantId); parameters["tenantName"] = JsonConvert.SerializeObject(_tenantName); parameters["username"] = JsonConvert.SerializeObject(_username); parameters["userId"] = JsonConvert.SerializeObject(_userId); parameters["userFullName"] = JsonConvert.SerializeObject(_userFullName); foreach (var pair in parameters) { responseBody = responseBody.Replace("{" + pair.Key + "}", JsonConvert.DeserializeObject <string>(pair.Value)); } } HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); result.Content = new StringContent(responseBody, Encoding.UTF8, "application/json"); return(result); }