pike.git / lib / modules / Web.pmod / Auth.pmod / module.pmod

version» Context lines:

pike.git/lib/modules/Web.pmod/Auth.pmod/module.pmod:1: + //! Various authentication modules and classes.    -  + // Checks if A is an instance of B (either directly or by inheritance) + #define INSTANCE_OF(A,B) (object_program((A)) == object_program((B)) || \ +  Program.inherits(object_program((A)), \ +  object_program(B))) +  + //! Parameter collection class + //! + //! @seealso + //! @[Param] + class Params + { +  //! The parameters. +  protected array(Param) params; +  +  //! Creates a new instance of @[Params] +  //! +  //! @param args +  protected void create(Param ... args) +  { +  params = args||({}); +  } +  +  //! Sign the parameters +  //! +  //! @param secret +  //! The API secret +  string sign(string secret) +  { +  return md5(sort(params)->name_value()*"" + secret); +  } +  +  //! Parameter keys +  array(string) _indices() +  { +  return params->get_name(); +  } +  +  //! Parameter values +  array(string) _values() +  { +  return params->get_value(); +  } +  +  //! Returns the array of @[Param]eters +  array(Param) get_params() +  { +  return params; +  } +  +  string to_unencoded_query() +  { +  return params->name_value()*"&"; +  } +  +  //! Turns the parameters into a query string +  string to_query() +  { +  array o = ({}); +  foreach (params, Param p) +  o += ({ urlencode(p->get_name()) + "=" + urlencode(p->get_value()) }); +  +  return o*"&"; +  } +  +  //! Turns the parameters into a mapping +  mapping(string:mixed) to_mapping() +  { +  return mkmapping(params->get_name(), params->get_value()); +  } +  +  //! Add a mapping of key/value pairs to the current instance +  //! +  //! @param value +  //! +  //! @returns +  //! The object being called +  this_program add_mapping(mapping value) +  { +  foreach (value; string k; mixed v) +  params += ({ Param(k, (string)v) }); +  +  return this; +  } +  +  //! Add @[p] to the array of @[Param]eters +  //! +  //! @param p +  //! +  //! @returns +  //! A new @[Params] object +  this_program `+(Param|this_program p) +  { +  if (mappingp(p)) { +  foreach (p; string k; string v) { +  params += ({ Param(k, v) }); +  } +  +  return this; +  } +  +  if (INSTANCE_OF(p, this)) +  params += p->get_params(); +  else +  params += ({ p }); +  +  return this; +  } +  +  //! Remove @[p] from the @[Param]eters array of the current object. +  //! +  //! @param p +  this_program `-(Param|this_program p) +  { +  if (!p) return this; +  +  array(Param) the_params; +  if (INSTANCE_OF(p, this)) +  the_params = p->get_params(); +  else +  the_params = ({ p }); +  +  return object_program(this)(@(params-the_params)); +  } +  +  //! Index lookup +  //! +  //! @param key +  //! The name of a @[Param]erter to find. +  Param `[](string key) +  { +  foreach (params, Param p) +  if (p->get_name() == key) +  return p; +  +  return 0; +  } +  +  //! Clone the current instance +  this_program clone() +  { +  return object_program(this)(@params); +  } +  +  //! String format method +  //! +  //! @param t +  string _sprintf(int t) +  { +  return t == 'O' && sprintf("%O(%O)", object_program(this), params); +  } +  +  //! Casting method +  //! +  //! @param how +  mixed cast(string how) +  { +  switch (how) { +  case "mapping": return to_mapping(); +  case "string": return to_query(); +  } +  } + } +  + //! Representation of a parameter. + //! + //! Many Social web services use a RESTful communication and have similiar + //! API's. This class is suitable for many RESTful web services and if this + //! class doesn't suite a particular service, just inherit this class and + //! rewrite the behaviour where needed. + //! + //! @seealso + //! @[Params] + class Param + { +  //! The name of the parameter +  protected string name; +  +  //! The value of the parameter +  protected string value; +  +  //! Creates a new instance of @[Param] +  //! +  //! @param _name +  //! @param _value +  protected void create(string _name, mixed _value) +  { +  name = _name; +  low_set_value((string)_value); +  } +  +  //! Getter for the parameter name +  string get_name() +  { +  return name; +  } +  +  //! Setter for the parameter name +  //! +  //! @param _name +  void set_name(string _name) +  { +  name = _name; +  } +  +  //! Getter for the parameter value +  string get_value() +  { +  return value; +  } +  +  //! Setter for the parameter value +  //! +  //! @param _value +  void set_value(mixed _value) +  { +  low_set_value((string)_value); +  } +  +  //! Returns the name and value as querystring key/value pair +  string name_value() +  { +  return name + "=" + value; +  } +  +  //! Same as @[name_value()] except this URL encodes the value. +  string name_value_encoded() +  { +  return urlencode(name) + "=" + urlencode(value); +  } +  +  //! Comparer method. Checks if @[other] equals this object +  //! +  //! @param other +  int(0..1) `==(mixed other) +  { +  if (!INSTANCE_OF(this, other)) return 0; +  if (name == other->get_name()) +  return value == other->get_value(); +  +  return 0; +  } +  +  //! Checks if this object is greater than @[other] +  //! +  //! @param other +  int(0..1) `>(mixed other) +  { +  if (!INSTANCE_OF(this, other)) return 0; +  if (name == other->get_name()) +  return value > other->get_value(); +  +  return name > other->get_name(); +  } +  +  //! Checks if this object is less than @[other] +  //! +  //! @param other +  int(0..1) `<(mixed other) +  { +  if (!INSTANCE_OF(this, other)) return 0; +  if (name == other->get_name()) +  return value < other->get_value(); +  +  return name < other->get_name(); +  } +  +  //! String format method +  //! +  //! @param t +  string _sprintf(int t) +  { +  return t == 'O' && sprintf("%O(%O,%O)", object_program(this), name, value); +  } +  +  mixed cast(string how) +  { +  switch (how) +  { +  case "string": return name_value_encoded(); +  } +  +  error("Cant cast %O() to %O\n", this_program, how); +  } +  +  //! Makes sure @[v] to set as @[value] is in UTF-8 encoding +  //! +  //! @param v +  private void low_set_value(string v) +  { +  value = v; +  +  if (String.width(value) < 8) { +  if (mixed e = catch(value = string_to_utf8(value))) { +  werror("Warning: Auth.low_set_value(%O): string_to_utf8() failed. " +  "Already encoded?\n%s\n", value, describe_error(e)); +  } +  } +  } + } +  + //! Same as @[Protocols.HTTP.uri_encode()] except this turns spaces into + //! @tt{+@} instead of @tt{%20@}. + //! + //! @param s + string urlencode(string s) + { + #if constant(Protocols.HTTP.uri_encode) +  return Protocols.HTTP.uri_encode(s); + #elif constant(Protocols.HTTP.http_encode_string) +  return Protocols.HTTP.http_encode_string(s); + #endif + } +  + //! Same as @[Protocols.HTTP.uri_decode()] except this turns spaces into + //! @tt{+@} instead of @tt{%20@}. + //! + //! @param s + string urldecode(string s) + { + #if constant(Protocols.HTTP.uri_decode) +  return Protocols.HTTP.uri_decode(s); + #elif constant(Protocols.HTTP.http_decode_string) +  return Protocols.HTTP.http_decode_string(s); + #else +  return s; + #endif + } +  + //! Turns a query string into a mapping + //! + //! @param query + mapping query_to_mapping(string query) + { +  mapping m = ([]); +  if (!query || !sizeof(query)) +  return m; +  +  if (query[0] == '?') +  query = query[1..]; +  +  foreach (query/"&", string p) { +  sscanf (p, "%s=%s", string k, string v); +  m[k] = urldecode(v); +  } +  +  return m; + } +  + //! MD5 routine + //! + //! @param s + string md5(string s) + { + #if constant(Crypto.MD5) +  return String.string2hex(Crypto.MD5.hash(s)); + #else +  return Crypto.string_to_hex(Crypto.md5()->update(s)->digest()); + #endif + }   Newline at end of file added.