/// <summary>
        /// Called just before issuing request to third-party service when everything is ready.
        /// Allows to add extra parameters to request or do any other needed preparations.
        /// </summary>
        protected override void BeforeGetUserInfo(BeforeAfterRequestArgs args)
        {
            // Source document
            // http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=12878032

            args.Request.AddParameter("application_key", _configuration.ClientPublic);
            args.Request.AddParameter("method", "users.getCurrentUser");

            // workaround for current design, oauth_token is always present in URL, so we need emulate it for correct request signing 
            var fakeParam = new Parameter() { Name = "oauth_token", Value = AccessToken };
            args.Request.AddParameter(fakeParam);

            // Signing.
            // Call API methods using access_token instead of session_key parameter
            // Calculate every request signature parameter sig using a little bit different way described in
            // http://dev.odnoklassniki.ru/wiki/display/ok/Authentication+and+Authorization
            // sig = md5( request_params_composed_string+ md5(access_token + application_secret_key)  )
            // Don't include access_token into request_params_composed_string
            string signature = string.Concat(args.Request.Parameters.OrderBy(x => x.Name).Select(x => string.Format("{0}={1}", x.Name, x.Value)).ToList());
            signature = (signature + (AccessToken + _configuration.ClientSecret).GetMd5Hash()).GetMd5Hash();

            // Removing fake param to prevent dups
            args.Request.Parameters.Remove(fakeParam);

            args.Request.AddParameter("access_token", AccessToken);
            args.Request.AddParameter("sig", signature);
        }
 /// <summary>
 /// Add a default parameter to a REST client
 /// </summary>
 /// <param name="client">REST client to add the new parameter to</param>
 /// <param name="parameter">The parameter to add</param>
 /// <returns>The REST client to allow call chains</returns>
 public static IRestClient AddDefaultParameter(this IRestClient client, Parameter parameter)
 {
     if (parameter.Type == ParameterType.RequestBody)
         throw new NotSupportedException("Cannot set request body from default headers. Use Request.AddBody() instead.");
     client.DefaultParameters.Add(parameter);
     return client;
 }
 /// <inheritdoc/>
 public void CopyTo(Parameter[] array, int arrayIndex)
 {
     foreach (var dictItem in _dictionary)
     {
         foreach (var item in dictItem.Value)
         {
             array[arrayIndex++] = item.Parameter;
         }
     }
 }
 /// <inheritdoc/>
 public void AddOrUpdate(Parameter parameter)
 {
     ulong order;
     var key = new ParameterKey(parameter);
     IReadOnlyCollection<ParameterEntry> oldEntries;
     if (_dictionary.TryGetValue(key, out oldEntries))
     {
         order = oldEntries.First().Order;
         _dictionary.Remove(key);
     }
     else
     {
         order = _order++;
     }
     _dictionary.Add(key, new ParameterEntry(order, parameter));
 }
        private static string UrlEncode(Parameter parameter, Encoding encoding, bool spaceAsPlus)
        {
            var flags = spaceAsPlus ? UrlEscapeFlags.EscapeSpaceAsPlus : UrlEscapeFlags.Default;

            if (parameter.Value == null)
                return string.Empty;

            var s = parameter.Value as string;
            if (s != null)
                return UrlUtility.Escape(s, encoding, flags);

            var bytes = parameter.Value as byte[];
            if (bytes != null)
                return UrlUtility.Escape(bytes, flags);

            return UrlUtility.Escape(parameter.ToRequestString(), encoding, flags);
        }
 /// <summary>
 /// Generic add parameters function
 /// </summary>
 /// <param name="request">The REST request to add this parameter to</param>
 /// <param name="parameter">Parameter to add</param>
 /// <returns>The request object to allow call chains</returns>
 public static IRestRequest AddParameter(this IRestRequest request, Parameter parameter)
 {
     request.Parameters.Add(parameter);
     return request;
 }
        /// <summary>
        /// Returns the HttpContent for the body parameter
        /// </summary>
        /// <param name="request">The request the body parameter belongs to</param>
        /// <param name="body">The body parameter</param>
        /// <returns>The resulting HttpContent</returns>
        private static HttpContent GetBodyContent(this IRestRequest request, Parameter body)
        {
            if (body == null)
                return null;

            MediaTypeHeaderValue contentType;
            byte[] buffer;
            if (body.Value is byte[])
            {
                buffer = (byte[])body.Value;
                contentType = body.ContentType;
            }
            else
            {
                buffer = request.Serializer.Serialize(body.Value);
                contentType = request.Serializer.ContentType;
            }
            var content = new ByteArrayContent(buffer);
            content.Headers.ContentType = contentType;
            content.Headers.ContentLength = buffer.Length;
            return content;
        }
        /// <summary>
        /// Called just before issuing request to third-party service when everything is ready.
        /// Allows to add extra parameters to request or do any other needed preparations.
        /// </summary>
        protected override void BeforeGetUserInfo(BeforeAfterRequestArgs args)
        {
            // Source documents
            // http://api.mail.ru/docs/guides/restapi/
            // http://api.mail.ru/docs/reference/rest/users.getInfo/

            args.Request.AddOrUpdateParameter("app_id", _configuration.ClientId);
            args.Request.AddOrUpdateParameter("method", "users.getInfo");
            args.Request.AddOrUpdateParameter("secure", "1");            
            args.Request.AddOrUpdateParameter("session_key", AccessToken);

            // workaround for current design, oauth_token is always present in URL, so we need emulate it for correct request signing 
            var fakeParam = new Parameter { Name = "oauth_token", Value = AccessToken };
            args.Request.AddParameter(fakeParam);

            //sign=hex_md5('app_id={client_id}method=users.getInfosecure=1session_key={access_token}{secret_key}')
            string signature = string.Concat(args.Request.Parameters.OrderBy(x => x.Name).Select(x => string.Format("{0}={1}", x.Name, x.Value)).ToList());            
            signature = (signature+_configuration.ClientSecret).GetMd5Hash();

            args.Request.Parameters.Remove(fakeParam);

            args.Request.AddOrUpdateParameter("sig", signature);            
        }
 public EncodedParameter(Parameter parameter)
 {
     Name = UrlUtility.Escape(parameter.Name);
     _parameter = parameter;
 }
 /// <summary>
 /// Generic add parameters function
 /// </summary>
 /// <param name="request">The REST request to add this parameter to</param>
 /// <param name="parameter">Parameter to add</param>
 /// <returns>The request object to allow call chains</returns>
 public static IRestRequest AddParameter(this IRestRequest request, Parameter parameter)
 {
     if (parameter.Type == ParameterType.UrlSegment || parameter.Type == ParameterType.RequestBody || parameter is FileParameter)
     {
         request.Parameters.AddOrUpdate(parameter);
     }
     else
     {
         request.Parameters.Add(parameter);
     }
     return request;
 }
 /// <inheritdoc/>
 public bool Remove(Parameter item)
 {
     var key = new ParameterKey(item);
     IReadOnlyCollection<ParameterEntry> entries;
     if (!_dictionary.TryGetValue(key, out entries))
         return false;
     var entry = entries.FirstOrDefault(x => ReferenceEquals(x.Parameter, item));
     if (entry == null)
         return false;
     return _dictionary.Remove(key, entry);
 }
 /// <inheritdoc/>
 public bool Contains(Parameter item)
 {
     return _dictionary.ContainsKey(new ParameterKey(item));
 }
 /// <inheritdoc/>
 public void Add(Parameter item)
 {
     _dictionary.Add(new ParameterKey(item), new ParameterEntry(_order++, item));
 }
 public ParameterEntry(ulong order, Parameter param)
 {
     Order = order;
     Parameter = param;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ParameterKey"/> class.
 /// </summary>
 /// <param name="parameter">The parameter to create the key from</param>
 public ParameterKey(Parameter parameter)
     : this(parameter.Type, parameter.Name)
 {
 }
 public EncodedParameter(Parameter parameter)
 {
     Name       = UrlUtility.Escape(parameter.Name);
     _parameter = parameter;
 }