<commit_before>package dispatch.oauth
import dispatch._

import collection.Map
import collection.immutable.{TreeMap, Map=>IMap}

import javax.crypto
import java.net.URI

import org.apache.http.protocol.HTTP.UTF_8
import org.apache.commons.codec.binary.Base64.encodeBase64
import org.apache.http.client.methods.HttpRequestBase

case class Consumer(key: String, secret: String)
case class Token(value: String, secret: String)
object Token {
  def apply[T <: Any](m: Map[String, T]): Option[Token] = List("oauth_token", "oauth_token_secret").flatMap(m.get) match {
    case value :: secret :: Nil => Some(Token(value.toString, secret.toString))
    case _ => None
  }
}

/** Import this object's methods to add signing operators to dispatch.Request */
object OAuth {
  /** @return oauth parameter map including signature */
  def sign(method: String, url: String, user_params: Map[String, Any], consumer: Consumer, 
      token: Option[Token], verifier: Option[String]) = {
    val oauth_params = IMap(
      "oauth_consumer_key" -> consumer.key,
      "oauth_signature_method" -> "HMAC-SHA1",
      "oauth_timestamp" -> (System.currentTimeMillis / 1000).toString,
      "oauth_nonce" -> System.nanoTime.toString,
      "oauth_version" -> "1.0"
    ) ++ token.map { "oauth_token" -> _.value } ++ 
      verifier.map { "oauth_verifier" -> _ }
    
    val encoded_ordered_params = (
      new TreeMap[String, String] ++ (user_params ++ oauth_params map %%)
    ) map { case (k, v) => k + "=" + v } mkString "&"
    
    val message = %%(method :: url :: encoded_ordered_params :: Nil)
    
    val SHA1 = "HmacSHA1";
    val key_str = %%(consumer.secret :: (token map { _.secret } getOrElse "") :: Nil)
    val key = new crypto.spec.SecretKeySpec(bytes(key_str), SHA1)
    val sig = {
      val mac = crypto.Mac.getInstance(SHA1)
      mac.init(key)
      new String(encodeBase64(mac.doFinal(bytes(message))))
    }
    oauth_params + ("oauth_signature" -> sig)
  }
  
  /** Out-of-band callback code */
  val oob = "oob"
  
  /** Map with oauth_callback set to the given url */
  def callback(url: String) = IMap("oauth_callback" -> url)
  
  //normalize to OAuth percent encoding
  private def %% (str: String): String = (Http % str) replace ("+", "%20") replace ("%7E", "~") replace ("*", "%2A")
  private def %% (s: Seq[String]): String = s map %% mkString "&"
  private def %% (t: (String, Any)): (String, String) = (%%(t._1), %%(t._2.toString))
  
  private def bytes(str: String) = str.getBytes(UTF_8)
  
  /** Add OAuth operators to dispatch.Request */
  implicit def Request2RequestSigner(r: Request) = new RequestSigner(r)
  /** Add String conversion since Http#str2req implicit will not chain. */
  implicit def Request2RequestSigner(r: String) = new RequestSigner(new Request(r))
  
  class RequestSigner(r: Request) {
    
    // sign requests with an Authorization header
    def <@ (consumer: Consumer): Request = sign(consumer, None, None)
    def <@ (consumer: Consumer, token: Token): Request = sign(consumer, Some(token), None)
    def <@ (consumer: Consumer, token: Token, verifier: String): Request = 
      sign(consumer, Some(token), Some(verifier))
    
    /** add token value as a query string parameter, for user authorization redirects */
    def <<? (token: Token) = r <<? IMap("oauth_token" -> token.value)

    /** Sign request by reading Post (<<) and query string parameters */
    private def sign(consumer: Consumer, token: Option[Token], verifier: Option[String]) = r next { req =>
      val oauth_url = Http.to_uri(r.host, req).toString.split('?')(0)
      val query_params = split_decode(req.getURI.getRawQuery)
      val oauth_params = OAuth.sign(req.getMethod, oauth_url, query_params ++ (req match {
        case before: Post[_] => before.oauth_values
        case _ => IMap()
      }), consumer, token, verifier )
      req.addHeader("Authorization", "OAuth " + oauth_params.map { 
        case (k, v) => (Http % k) + "=\"%s\"".format(Http % v)
      }.mkString(",") )
      req
    }

    def >% [T] (block: IMap[String, String] => T) = r >- ( split_decode andThen block )
    def as_token = r >% { Token(_).getOrElse { error("Token parameters not found in given map") } }
    
    val split_decode: (String => IMap[String, String]) = {
      case null => IMap.empty
      case query => IMap.empty ++ query.trim.split('&').map { nvp =>
        ( nvp split "=" map Http.-% ) match { 
          case Array(name) => name -> ""
          case Array(name, value) => name -> value
        }
      }
    }
  }
  
}<commit_msg>make oauth_callback a required param in the first step of the dance (default to oob) http://tools.ietf.org/html/rfc5849#section-2.1<commit_after>package dispatch.oauth
import dispatch._

import collection.Map
import collection.immutable.{TreeMap, Map=>IMap}

import javax.crypto
import java.net.URI

import org.apache.http.protocol.HTTP.UTF_8
import org.apache.commons.codec.binary.Base64.encodeBase64
import org.apache.http.client.methods.HttpRequestBase

case class Consumer(key: String, secret: String)
case class Token(value: String, secret: String)
object Token {
  def apply[T <: Any](m: Map[String, T]): Option[Token] = List("oauth_token", "oauth_token_secret").flatMap(m.get) match {
    case value :: secret :: Nil => Some(Token(value.toString, secret.toString))
    case _ => None
  }
}

/** Import this object's methods to add signing operators to dispatch.Request */
object OAuth {
  /** @return oauth parameter map including signature */
  def sign(method: String, url: String, user_params: Map[String, Any], consumer: Consumer, 
      token: Option[Token], verifier: Option[String], callback: Option[String]) = {
    val oauth_params = IMap(
      "oauth_consumer_key" -> consumer.key,
      "oauth_signature_method" -> "HMAC-SHA1",
      "oauth_timestamp" -> (System.currentTimeMillis / 1000).toString,
      "oauth_nonce" -> System.nanoTime.toString,
      "oauth_version" -> "1.0"
    ) ++ token.map { "oauth_token" -> _.value } ++ 
      verifier.map { "oauth_verifier" -> _ } ++
      callback.map { "oauth_callback" -> _ }
    
    val encoded_ordered_params = (
      new TreeMap[String, String] ++ (user_params ++ oauth_params map %%)
    ) map { case (k, v) => k + "=" + v } mkString "&"
    
    val message = %%(method :: url :: encoded_ordered_params :: Nil)
    
    val SHA1 = "HmacSHA1"
    val key_str = %%(consumer.secret :: (token map { _.secret } getOrElse "") :: Nil)
    val key = new crypto.spec.SecretKeySpec(bytes(key_str), SHA1)
    val sig = {
      val mac = crypto.Mac.getInstance(SHA1)
      mac.init(key)
      new String(encodeBase64(mac.doFinal(bytes(message))))
    }
    oauth_params + ("oauth_signature" -> sig)
  }
  
  /** Out-of-band callback code */
  val oob = "oob"
  
  /** Map with oauth_callback set to the given url */
  def callback(url: String) = IMap("oauth_callback" -> url)
  
  //normalize to OAuth percent encoding
  private def %% (str: String): String = (Http % str) replace ("+", "%20") replace ("%7E", "~") replace ("*", "%2A")
  private def %% (s: Seq[String]): String = s map %% mkString "&"
  private def %% (t: (String, Any)): (String, String) = (%%(t._1), %%(t._2.toString))
  
  private def bytes(str: String) = str.getBytes(UTF_8)
  
  /** Add OAuth operators to dispatch.Request */
  implicit def Request2RequestSigner(r: Request) = new RequestSigner(r)
  /** Add String conversion since Http#str2req implicit will not chain. */
  implicit def Request2RequestSigner(r: String) = new RequestSigner(new Request(r))
  
  class RequestSigner(r: Request) {
    
    // sign requests with an Authorization header
    /** sign an out-of-band request for an unauthorized token */
    def <@ (consumer: Consumer): Request = sign(consumer, None, None, Some(oob))
    /** sign a request for an unauthorized token with a callback */
    def <@ (consumer: Consumer, callback: String): Request = sign(consumer, None, None, Some(callback))
    /** sign a request for authorizing an unauthorized token */
    def <@ (consumer: Consumer, token: Token): Request = sign(consumer, Some(token), None, None)
    /** sign a request for an authorized token */
    def <@ (consumer: Consumer, token: Token, verifier: String): Request = 
      sign(consumer, Some(token), Some(verifier), None)
    
    /** add token value as a query string parameter, for user authorization redirects */
    def <<? (token: Token) = r <<? IMap("oauth_token" -> token.value)

    /** Sign request by reading Post (<<) and query string parameters */
    private def sign(consumer: Consumer, token: Option[Token], verifier: Option[String], callback: Option[String]) = r next { req =>
      val oauth_url = Http.to_uri(r.host, req).toString.split('?')(0)
      val query_params = split_decode(req.getURI.getRawQuery)
      val oauth_params = OAuth.sign(req.getMethod, oauth_url, query_params ++ (req match {
        case before: Post[_] => before.oauth_values
        case _ => IMap()
      }), consumer, token, verifier, callback)
      req.addHeader("Authorization", "OAuth " + oauth_params.map { 
        case (k, v) => (Http % k) + "=\"%s\"".format(Http % v)
      }.mkString(",") )
      req
    }

    def >% [T] (block: IMap[String, String] => T) = r >- ( split_decode andThen block )
    def as_token = r >% { Token(_).getOrElse { error("Token parameters not found in given map") } }
    
    val split_decode: (String => IMap[String, String]) = {
      case null => IMap.empty
      case query => IMap.empty ++ query.trim.split('&').map { nvp =>
        ( nvp split "=" map Http.-% ) match { 
          case Array(name) => name -> ""
          case Array(name, value) => name -> value
        }
      }
    }
  }
  
}
{'fraction_non_alphanumeric': 0.14965006175380816, 'fraction_numerical': 0.006587072869493619, 'mean_word_length': 3.290066225165563, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 64, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '120078', 'n_tokens_mistral': 3169, 'n_tokens_neox': 3070, 'n_words': 850}