Exemplo n.º 1
0
        /// <summary>
        /// Makes a token request. This will make a token request now, even if the library already
        /// has a valid token. It would typically be used to issue tokens for use by other clients.
        /// </summary>
        /// <param name="requestData">The <see cref="TokenRequest"/> data used for the token</param>
        /// <param name="options">Extra <see cref="AuthOptions"/> used for creating a token </param>
        /// <returns>A valid ably token</returns>
        /// <exception cref="AblyException"></exception>
        public TokenDetails RequestToken(TokenRequest requestData, AuthOptions options)
        {
            var mergedOptions = options != null?options.Merge(_options) : _options;

            string keyId = "", keyValue = "";

            if (!string.IsNullOrEmpty(mergedOptions.Key))
            {
                var key = mergedOptions.ParseKey();
                keyId    = key.KeyName;
                keyValue = key.KeySecret;
            }

            var data = requestData ?? new TokenRequest
            {
                KeyName  = keyId,
                ClientId = _options.ClientId
            };

            if (requestData == null && options == null && _lastTokenRequest != null)
            {
                data = _lastTokenRequest;
            }

            data.KeyName = data.KeyName ?? keyId;

            _lastTokenRequest = data;

            var request = _rest.CreatePostRequest(String.Format("/keys/{0}/requestToken", data.KeyName));

            request.SkipAuthentication = true;
            TokenRequestPostData postData = null;

            if (mergedOptions.AuthCallback != null)
            {
                var token = mergedOptions.AuthCallback(data);
                if (token != null)
                {
                    return(token);
                }
                throw new AblyException("AuthCallback returned an invalid token");
            }

            if (mergedOptions.AuthUrl.IsNotEmpty())
            {
                var url         = mergedOptions.AuthUrl;
                var protocol    = _options.UseBinaryProtocol == false ? Protocol.Json : Protocol.MsgPack;
                var authRequest = new AblyRequest(url, mergedOptions.AuthMethod, protocol);
                if (mergedOptions.AuthMethod == HttpMethod.Get)
                {
                    authRequest.AddQueryParameters(mergedOptions.AuthParams);
                }
                else
                {
                    authRequest.PostParameters = mergedOptions.AuthParams;
                }
                authRequest.Headers.Merge(mergedOptions.AuthHeaders);
                authRequest.SkipAuthentication = true;
                var response = _rest.ExecuteRequest(authRequest);
                if (response.Type != ResponseType.Json)
                {
                    throw new AblyException(
                              new ErrorInfo(
                                  string.Format("Content Type {0} is not supported by this client library",
                                                response.ContentType), 500));
                }

                var signedData = response.TextResponse;
                var jData      = JObject.Parse(signedData);
                if (TokenDetails.IsToken(jData))
                {
                    return(jData.ToObject <TokenDetails>());
                }

                postData = JsonConvert.DeserializeObject <TokenRequestPostData>(signedData);
            }
            else
            {
                postData = data.GetPostData(keyValue);
            }

            if (mergedOptions.QueryTime)
            {
                postData.timestamp = _rest.Time().ToUnixTimeInMilliseconds().ToString();
            }

            request.PostData = postData;

            var result = _rest.ExecuteRequest <TokenDetails>(request);

            if (result == null)
            {
                throw new AblyException(new ErrorInfo("Invalid token response returned", 500));
            }

            return(result);
        }