Commit 99e56573796a9566f50902d679b4ff075c79db2e

Authored by Edmar Moretti
1 parent 538ca12b

Implementação de comentários do usuário em uma camada

Showing 90 changed files with 8682 additions and 109 deletions   Show diff stats
admin/admin.db
No preview for this file type
admin/index.html
... ... @@ -181,6 +181,7 @@ essa criação podem ser obtidos no item "Outras opções".</p>
181 181 <table class=lista1 >
182 182 <tr onclick="abre('html/incluimap.html')"><td><div class=aplicar ></div></td><td>Ajusta mapfiles</td></tr>
183 183 <tr onclick="abre('php/estatisticas.php')"><td><div class=aplicar ></div></td><td>Estat&iacute;sticas</td></tr>
  184 +<tr onclick="abre('php/upgradebanco44_45.php')"><td><div class=aplicar ></div></td><td>Adiciona as tabelas necessárias à versão 4.5 do i3Geo e que não existiam nas vesões anteriores</td></tr>
184 185  
185 186 <tr onclick="abre('php/sqlite.php')"><td><div class=aplicar ></div></td><td>Descri&ccedil;&atilde;o do banco padr&atilde;o (SQLITE)</td></tr>
186 187 <tr onclick="abre('php/criabanco.php')"><td><div class=aplicar ></div></td><td>Criar banco de dados</td></tr>
... ... @@ -191,6 +192,8 @@ essa cria&amp;ccedil;&amp;atilde;o podem ser obtidos no item &quot;Outras op&amp;ccedil;ões&quot;.&lt;/p&gt;
191 192 <tr onclick="abre('xmlservicosws.php')"><td><div class=aplicar ></div></td><td>Ver xml com a lista de servi&ccedil;os WS (webservices convencionais)</td></tr>
192 193 <tr onclick="abre('xmlsistemas.php')"><td><div class=aplicar ></div></td><td>Ver xml com a lista de sistemas que adicionam temas especiais</td></tr>
193 194 <tr onclick="abre('rssgrupos.php')"><td><div class=aplicar ></div></td><td>Ver RSS com os grupos, subgrupos e temas</td></tr>
  195 +<tr onclick="abre('rsscomentariostemas.php')"><td><div class=aplicar ></div></td><td>Ver RSS com os comentários sobre os temas</td></tr>
  196 +
194 197 <tr onclick="abre('hiperbolica.php')"><td><div class=aplicar ></div></td><td>Ver XML para &aacute;rvorehiperb&oacute;lica</td></tr>
195 198 </table>
196 199 </div>
... ...
admin/js/editormapfile.js
... ... @@ -1123,6 +1123,8 @@ function montaEditorMetadados(dados)
1123 1123 titulo:"Aplica extensao (APLICAEXTENSAO)",id:"",value:dados.aplicaextensao,tipo:"text",div:"<div id=cAplicaextensao ></div>"},
1124 1124 {ajuda:"Indica se o usuário pode abrir o editor de SQL para poder alterar o elemento DATA do Mapfile.",
1125 1125 titulo:"Permite editar SQL (EDITORSQL)",id:"",value:dados.editorsql,tipo:"text",div:"<div id=cEditorsql ></div>"},
  1126 + {ajuda:"Indica se o usuário pode fazer comentários no tema",
  1127 + titulo:"Permite comentar (PERMITECOMENTARIO)",id:"",value:dados.permitecomentario,tipo:"text",div:"<div id=cPermitecomentario ></div>"},
1126 1128 {ajuda:"Indica se o usuário pode fazer download do tema",
1127 1129 titulo:"Download (DOWNLOAD)",id:"",value:dados.download,tipo:"text",div:"<div id=cDownload ></div>"},
1128 1130 {ajuda:"Endereço de um arquivo para download dos dados (caminho completo no servidor). Se definido, o sistema irá usar esse arquivo ao invés de gerar os dados, quando o usuário clicar nas opções de download. Se não for definido, o arquivo de download é gerado diretamente do original, convertendo do banco ou copiando o arquivo definido em DATA.",
... ... @@ -1203,6 +1205,10 @@ function montaEditorMetadados(dados)
1203 1205 temp += core_combosimnao(dados.editorsql)
1204 1206 temp += "</select>"
1205 1207 $i("cEditorsql").innerHTML = temp
  1208 + temp = "<select id='permitecomentario' >"
  1209 + temp += core_combosimnao(dados.permitecomentario)
  1210 + temp += "</select>"
  1211 + $i("cPermitecomentario").innerHTML = temp
1206 1212 temp = "<select id='download' >"
1207 1213 temp += core_combosimnao(dados.download)
1208 1214 temp += "</select>"
... ... @@ -1563,7 +1569,7 @@ function salvarDadosEditor(tipo,codigoMap,codigoLayer,indiceClasse,indiceEstilo,
1563 1569 else
1564 1570 {alert("Valor de escala incorreto");return;}
1565 1571 }
1566   - var campos = new Array("cache","iconetema","ltempoformatodata","ltempoiteminicio","ltempoitemfim","ltempoitemtitulo","ltempoitemdescricao","ltempoitemtip","ltempoitemimagem","ltempoitemicone","ltempoitemlink","editorsql","description_template","palletefile","palletestep","arquivodownload","aplicaextensao","classestamanho","classessimbolo","classescor","classesnome","classesitem","mensagem","identifica","extensao","escondido","download","escala","tema","classe","tip","itenslink","itens","itensdesc")
  1572 + var campos = new Array("permitecomentario","cache","iconetema","ltempoformatodata","ltempoiteminicio","ltempoitemfim","ltempoitemtitulo","ltempoitemdescricao","ltempoitemtip","ltempoitemimagem","ltempoitemicone","ltempoitemlink","editorsql","description_template","palletefile","palletestep","arquivodownload","aplicaextensao","classestamanho","classessimbolo","classescor","classesnome","classesitem","mensagem","identifica","extensao","escondido","download","escala","tema","classe","tip","itenslink","itens","itensdesc")
1567 1573 var par = "&codigoMap="+codigoMap+"&codigoLayer="+codigoLayer
1568 1574 var prog = "../php/editormapfile.php?funcao=alterarMetadados"
1569 1575 }
... ...
admin/php/classe_arvore.php
... ... @@ -658,7 +658,6 @@ Verifica se uma string ocorre em um array
658 658 $texto = mb_convert_encoding($texto,mb_detect_encoding($texto),"UTF-8");
659 659 else
660 660 $texto = mb_convert_encoding($texto,mb_detect_encoding($texto),"ISO-8859-1");
661   -
662 661 return $texto;
663 662 }
664 663 }
... ...
admin/php/conexao.php
... ... @@ -74,7 +74,7 @@ if($conexaoadmin == &quot;&quot;)
74 74 $arquivosqlite = $locaplic."/admin/admin.db";
75 75 if(!file_exists($arquivosqlite))
76 76 {
77   - echo "O arquivo menutemas/admin.db não existe. Utilize i3geo/admin/criabanco.php para criar o banco de dados SQLITE.";
  77 + echo "O arquivo admin.db não existe. Utilize i3geo/admin/criabanco.php para criar o banco de dados SQLITE.";
78 78 exit;
79 79 }
80 80 $conAdmin = "sqlite:$arquivosqlite";
... ...
admin/php/criabanco.php
... ... @@ -5,7 +5,7 @@ Title: criabanco.php
5 5 Cria um novo banco de dados de administração.
6 6  
7 7 Se vc quiser recriar o banco de dados default, apague o arquivo
8   -i3geo/menutemas/admin.db ou faça uma cópia. Depois é só executar esse programa.
  8 +i3geo/admin/admin.db ou faça uma cópia. Depois é só executar esse programa.
9 9  
10 10 Se a configuração do arquivo de conexão foi alterada (veja ms_configura.php), o novo
11 11 banco irá ser criado conforme a nova string de conexão.
... ... @@ -60,15 +60,17 @@ $tabelas = array(
60 60 "CREATE TABLE i3geoadmin_raiz (ordem NUMERIC, id_tema NUMERIC, id_menu NUMERIC, id_nivel NUMERIC, id_raiz INTEGER PRIMARY KEY, nivel NUMERIC, perfil TEXT)",
61 61 "CREATE TABLE i3geoadmin_n1 (publicado TEXT, ordem NUMERIC, id_menu NUMERIC, id_grupo NUMERIC, id_n1 INTEGER PRIMARY KEY, n1_perfil TEXT)",
62 62 "CREATE TABLE i3geoadmin_n2 (publicado TEXT, ordem NUMERIC, id_n1 NUMERIC, id_n2 INTEGER PRIMARY KEY, id_subgrupo NUMERIC, n2_perfil TEXT)",
63   -"CREATE TABLE i3geoadmin_n3 (publicado TEXT, ordem NUMERIC, id_n2 NUMERIC, id_n3 INTEGER PRIMARY KEY, id_tema NUMERIC, n3_perfil TEXT)"
  63 +"CREATE TABLE i3geoadmin_n3 (publicado TEXT, ordem NUMERIC, id_n2 NUMERIC, id_n3 INTEGER PRIMARY KEY, id_tema NUMERIC, n3_perfil TEXT)",
  64 +"CREATE TABLE i3geoadmin_comentarios (comentario TEXT, data TEXT, openidnome TEXT, openidimagem TEXT, openidservico TEXT, openidusuario TEXT, openidurl TEXT, id_tema NUMERIC)"
  65 +
64 66 );
65 67 if($conexaoadmin == "")
66 68 {
67   - if(file_exists("../../menutemas/admin.db"))
68   - {echo "Arquivo menutemas/admin.db ja existe";exit;}
69   - $banco = sqlite_open("../../menutemas/admin.db",0666);
  69 + if(file_exists("../../admin/admin.db"))
  70 + {echo "Arquivo admin/admin.db ja existe";exit;}
  71 + $banco = sqlite_open("../../admin/admin.db",0666);
70 72 $banco = null;
71   - $dbhw = new PDO('sqlite:../../menutemas/admin.db');
  73 + $dbhw = new PDO('sqlite:../../admin/admin.db');
72 74 }
73 75 else
74 76 {
... ...
admin/php/editormapfile.php
... ... @@ -692,6 +692,8 @@ switch (strtoupper($funcao))
692 692  
693 693 cache
694 694  
  695 + permitecomentario
  696 +
695 697 Retorno:
696 698  
697 699 {JSON}
... ... @@ -1331,11 +1333,12 @@ function pegaMetadados()
1331 1333 $dados["ltempoitemicone"] = $layer->getmetadata("ltempoitemicone");
1332 1334 $dados["ltempoitemlink"] = $layer->getmetadata("ltempoitemlink");
1333 1335 $dados["iconetema"] = $layer->getmetadata("iconetema");
  1336 + $dados["permitecomentario"] = $layer->getmetadata("permitecomentario");
1334 1337 return $dados;
1335 1338 }
1336 1339 function alterarMetadados()
1337 1340 {
1338   - global $iconetema,$ltempoformatodata,$ltempoiteminicio,$ltempoitemfim,$ltempoitemtitulo,$ltempoitemdescricao,$ltempoitemtip,$ltempoitemimagem,$ltempoitemicone,$ltempoitemlink,$description_template,$palletestep,$palletefile,$arquivodownload,$codigoMap,$codigoLayer,$locaplic,$aplicaextensao,$classestamanho,$classessimbolo,$classescor,$classesnome,$classesitem,$mensagem,$identifica,$extensao,$escondido,$download,$escala,$tema,$classe,$tip,$itenslink,$itens,$itensdesc,$editorsql,$cache;
  1341 + global $permitecomentario,$iconetema,$ltempoformatodata,$ltempoiteminicio,$ltempoitemfim,$ltempoitemtitulo,$ltempoitemdescricao,$ltempoitemtip,$ltempoitemimagem,$ltempoitemicone,$ltempoitemlink,$description_template,$palletestep,$palletefile,$arquivodownload,$codigoMap,$codigoLayer,$locaplic,$aplicaextensao,$classestamanho,$classessimbolo,$classescor,$classesnome,$classesitem,$mensagem,$identifica,$extensao,$escondido,$download,$escala,$tema,$classe,$tip,$itenslink,$itens,$itensdesc,$editorsql,$cache;
1339 1342 $dados = array();
1340 1343 $mapfile = $locaplic."/temas/".$codigoMap.".map";
1341 1344 $mapa = ms_newMapObj($mapfile);
... ... @@ -1375,6 +1378,7 @@ function alterarMetadados()
1375 1378 $layer->setmetadata("ltempoitemicone",$ltempoitemicone);
1376 1379 $layer->setmetadata("ltempoitemlink",$ltempoitemlink);
1377 1380 $layer->setmetadata("iconetema",$iconetema);
  1381 + $layer->setmetadata("permitecomentario",$permitecomentario);
1378 1382 $mapa->save($mapfile);
1379 1383 removeCabecalho($mapfile);
1380 1384 return "ok";
... ...
admin/php/sqlite.php
... ... @@ -32,13 +32,13 @@ Arquivo:
32 32  
33 33 i3geo/admin/php/sqlite.php
34 34 */
35   -if(!file_exists("../../menutemas/admin.db"))
  35 +if(!file_exists("../admin.db"))
36 36 {
37 37 echo "O arquivo menutemas/admin.db não existe. Utilize i3geo/admin/criasqlite.php para criar o banco de dados SQLITE.";
38 38 exit;
39 39 }
40 40 echo "<pre>";
41   -$dbh = new PDO('sqlite:../../menutemas/admin.db');
  41 +$dbh = new PDO('sqlite:../admin.db');
42 42 echo "<br><br><span style=color:red >Lista de tabelas</span><br><br>";
43 43 $q = $dbh->query("SELECT name FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type='table' ORDER BY name",PDO::FETCH_ASSOC);
44 44 $resultado = $q->fetchAll();
... ...
admin/php/upgradebanco44_45.php 0 → 100644
... ... @@ -0,0 +1,68 @@
  1 +<?php
  2 +/*
  3 +Title: upgradebanco44_45.php
  4 +
  5 +Adiciona as novas tabelas utilizadas na versão 4.5
  6 +
  7 +Se vc quiser recriar o banco de dados default, apague o arquivo
  8 +i3geo/admin/admin.db ou faça uma cópia. Depois é só executar esse programa.
  9 +
  10 +Se a configuração do arquivo de conexão foi alterada (veja ms_configura.php), o novo
  11 +banco irá ser criado conforme a nova string de conexão.
  12 +
  13 +Licenca:
  14 +
  15 +GPL2
  16 +
  17 +i3Geo Interface Integrada de Ferramentas de Geoprocessamento para Internet
  18 +
  19 +Direitos Autorais Reservados (c) 2006 Ministério do Meio Ambiente Brasil
  20 +Desenvolvedor: Edmar Moretti edmar.moretti@mma.gov.br
  21 +
  22 +Este programa é software livre; você pode redistribuí-lo
  23 +e/ou modificá-lo sob os termos da Licença Pública Geral
  24 +GNU conforme publicada pela Free Software Foundation;
  25 +
  26 +Este programa é distribuído na expectativa de que seja útil,
  27 +porém, SEM NENHUMA GARANTIA; nem mesmo a garantia implícita
  28 +de COMERCIABILIDADE OU ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA.
  29 +Consulte a Licença Pública Geral do GNU para mais detalhes.
  30 +Você deve ter recebido uma cópia da Licença Pública Geral do
  31 +GNU junto com este programa; se não, escreva para a
  32 +Free Software Foundation, Inc., no endereço
  33 +59 Temple Street, Suite 330, Boston, MA 02111-1307 USA.
  34 +
  35 +Arquivo:
  36 +
  37 +i3geo/admin/php/criabanco.php
  38 +*/
  39 +$funcao = "";
  40 +include_once("admin.php");
  41 +error_reporting(0);
  42 +if(verificaEditores($editores) == "nao")
  43 +{echo "Vc nao e um editor cadastrado. Apenas os editores definidos em i3geo/ms_configura.php podem acessar o sistema de administracao.";exit;}
  44 +
  45 +$tabelas = array(
  46 +"CREATE TABLE i3geoadmin_comentarios (comentario TEXT, data TEXT, openidnome TEXT, openidimagem TEXT, openidservico TEXT, openidusuario TEXT, openidurl TEXT, id_tema NUMERIC)"
  47 +);
  48 +if($conexaoadmin == "")
  49 +{
  50 + $banco = sqlite_open("../admin.db",0666);
  51 + $banco = null;
  52 + $dbhw = new PDO('sqlite:../admin.db');
  53 +}
  54 +else
  55 +{
  56 + include($conexaoadmin);
  57 +}
  58 +foreach($tabelas as $tabela)
  59 +{
  60 + if($dbhw->getAttribute(PDO::ATTR_DRIVER_NAME) == "pgsql")
  61 + {
  62 + $tabela = str_replace("INTEGER PRIMARY KEY","SERIAL PRIMARY KEY NOT NULL",$tabela);
  63 + }
  64 + $q = $dbhw->query($tabela);
  65 +}
  66 +$banco = null;
  67 +echo "Feito!!!";
  68 +?>
0 69 \ No newline at end of file
... ...
admin/php/xml.php
... ... @@ -92,6 +92,28 @@ function geraXmlSistemas($perfil,$locaplic,$editores)
92 92 return $xml;
93 93 }
94 94 /*
  95 +Function: geraRSScomentariosTemas
  96 +
  97 +RSS com os comentarios sobre um ou todos os temas
  98 +
  99 +Parametros:
  100 +
  101 +locaplic {string} - localização do i3Geo no sistema de arquivos
  102 +
  103 +id_tema {numeric} - (opcional) id do tema para mostrar apenas os comentários de um tema
  104 +
  105 +Retorno:
  106 +
  107 +RSS
  108 +*/
  109 +function geraRSScomentariosTemas($locaplic,$id_tema="")
  110 +{
  111 + $sql = "select b.nome_tema||' '||a.data as nome_ws,a.openidnome||' '||a.openidurl||' &amp;lt;br&amp;gt;'||a.comentario as desc_ws, a.openidnome as autor_ws, b.link_tema as link_ws from i3geoadmin_comentarios as a,i3geoadmin_temas as b where a.id_tema = b.id_tema ";
  112 + if($id_tema != "")
  113 + {$sql .= " and a.id_tema = $id_tema ";}
  114 + return geraXmlRSS($locaplic,$sql,"Lista de comentarios");
  115 +}
  116 +/*
95 117 Function: geraRSStemas
96 118  
97 119 RSS com os temas cadastrados
... ...
admin/rsscomentariostemas.php 0 → 100644
... ... @@ -0,0 +1,66 @@
  1 +<?php
  2 +/*
  3 +Title: rsscomentariostemas
  4 +
  5 +Monta um arquivo XML no padrão RSS contendo os comentários postados para os temas cadastrados.
  6 +
  7 +<http://localhost/i3geo/admin/rsscomentariostemas.php>
  8 +
  9 +Parametros:
  10 +
  11 +id_tema {numeric} - (opcional) id do tema para mostrar apenas os comentários de um tema
  12 +
  13 +Licenca:
  14 +
  15 +GPL2
  16 +
  17 +i3Geo Interface Integrada de Ferramentas de Geoprocessamento para Internet
  18 +
  19 +Direitos Autorais Reservados (c) 2006 Ministério do Meio Ambiente Brasil
  20 +Desenvolvedor: Edmar Moretti edmar.moretti@mma.gov.br
  21 +
  22 +Este programa é software livre; você pode redistribuí-lo
  23 +e/ou modificá-lo sob os termos da Licença Pública Geral
  24 +GNU conforme publicada pela Free Software Foundation;
  25 +
  26 +Este programa é distribuído na expectativa de que seja útil,
  27 +porém, SEM NENHUMA GARANTIA; nem mesmo a garantia implícita
  28 +de COMERCIABILIDADE OU ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA.
  29 +Consulte a Licença Pública Geral do GNU para mais detalhes.
  30 +Você deve ter recebido uma cópia da Licença Pública Geral do
  31 +GNU junto com este programa; se não, escreva para a
  32 +Free Software Foundation, Inc., no endereço
  33 +59 Temple Street, Suite 330, Boston, MA 02111-1307 USA.
  34 +
  35 +Arquivo:
  36 +
  37 +i3geo/admin/rsscomentariostemas.php
  38 +*/
  39 +
  40 +error_reporting(0);
  41 +if(!isset($locaplic))
  42 +{
  43 + $locaplic = "";
  44 + if(file_exists("../../../ms_configura.php"))
  45 + {include_once("../../../ms_configura.php");}
  46 + else
  47 + {
  48 + if(file_exists("../../ms_configura.php"))
  49 + {include_once("../../ms_configura.php");}
  50 + else
  51 + {
  52 + if(file_exists("../ms_configura.php"))
  53 + {include_once("../ms_configura.php");}
  54 + else
  55 + include_once("ms_configura.php");
  56 + }
  57 + }
  58 +}
  59 +include_once($locaplic."/classesphp/pega_variaveis.php");
  60 +include_once($locaplic."/admin/php/xml.php");
  61 +$parametros = array_merge($_POST,$_GET);
  62 +if(empty($parametros["id_tema"]))
  63 +{$parametros["id_tema"] = "";}
  64 +echo header("Content-type: application/xml");
  65 +echo geraRSScomentariosTemas($locaplic,$parametros["id_tema"]);
  66 +?>
... ...
admin/rsstemas.php
... ... @@ -38,7 +38,6 @@ Arquivo:
38 38  
39 39 i3geo/admin/rsstemas.php
40 40 */
41   -
42 41 error_reporting(0);
43 42 if(!isset($locaplic))
44 43 {
... ...
classesjs/classe_arvoredecamadas.js
... ... @@ -246,8 +246,7 @@ i3GEO.arvoreDeCamadas = {
246 246  
247 247 "editorsql":"sim",
248 248  
249   - "iconetema":""
250   -
  249 + "iconetema":""
251 250 }
252 251 ]
253 252  
... ... @@ -779,6 +778,9 @@ i3GEO.arvoreDeCamadas = {
779 778 //i3GEO.arvoreDeCamadas.adicionaOpcaoTema($trad("t43"),$trad("t43"),'i3GEO.tema.dialogo.aplicarsld(\"'+ltema.name+'\")',node);
780 779 if(ltema.editorsql == "sim" || ltema.editorsql == "SIM")
781 780 {i3GEO.arvoreDeCamadas.adicionaOpcaoTema($trad("t40"),$trad("t41"),'i3GEO.tema.dialogo.editorsql(\"'+ltema.name+'\")',node);}
  781 + if(ltema.permitecomentario.toLowerCase() !== "nao")
  782 + {i3GEO.arvoreDeCamadas.adicionaOpcaoTema($trad("t45"),$trad("t45"),'i3GEO.tema.dialogo.comentario(\"'+ltema.name+'\")',node);}
  783 +
782 784 if(i3GEO.arvoreDeTemas.OPCOESADICIONAIS.navegacaoDir == true)
783 785 {i3GEO.arvoreDeCamadas.adicionaOpcaoTema($trad("t44"),"<span style=color:red >"+$trad("t44")+"</span>",'i3GEO.tema.dialogo.salvaMapfile(\"'+ltema.name+'\")',node);}
784 786 node.loadComplete();
... ...
classesjs/classe_arvoredetemas.js
... ... @@ -83,7 +83,9 @@ i3GEO.arvoreDeTemas = {
83 83  
84 84 carousel: true,
85 85  
86   - uploadgpx: true
  86 + uploadgpx: true,
  87 +
  88 + comentarios: true
87 89 }
88 90  
89 91 Tipo:
... ... @@ -108,7 +110,8 @@ i3GEO.arvoreDeTemas = {
108 110 estrelas: true,
109 111 refresh: true,
110 112 carousel: true,
111   - uploadgpx: true
  113 + uploadgpx: true,
  114 + comentarios: true
112 115 },
113 116 /*
114 117 Propriedade: FATORESTRELA
... ... @@ -976,7 +979,8 @@ i3GEO.arvoreDeTemas = {
976 979 idtema:raiz[i].tid,
977 980 fonte:raiz[i].link,
978 981 ogc:raiz[i].ogc,
979   - kmz:raiz[i].kmz
  982 + kmz:raiz[i].kmz,
  983 + permitecomentario:raiz[i].permitecomentario
980 984 },
981 985 node,
982 986 false,
... ... @@ -1209,6 +1213,17 @@ i3GEO.arvoreDeTemas = {
1209 1213 tempNode.enableHighlight = false;
1210 1214 tempNode.isLeaf = true;
1211 1215 }
  1216 + if (node.data.permitecomentario != "nao" && i3GEO.arvoreDeTemas.OPCOESADICIONAIS.comentarios === true){
  1217 + html = "<a href='#' title='' onclick='i3GEO.tema.dialogo.comentario(\""+node.data.idtema+"\",\"comentario\")' >Comentário</a>";
  1218 + tempNode = new YAHOO.widget.HTMLNode(
  1219 + {html:html},
  1220 + node,
  1221 + false,
  1222 + true
  1223 + );
  1224 + tempNode.enableHighlight = false;
  1225 + tempNode.isLeaf = true;
  1226 + }
1212 1227 if(i3GEO.arvoreDeTemas.OPCOESADICIONAIS.qrcode === true){
1213 1228 lkgrcode = i3GEO.arvoreDeTemas.LOCAPLIC+"/pacotes/qrcode/php/qr_html.php?d="+i3GEO.arvoreDeTemas.LOCAPLIC+"/mobile/index.php?temasa="+node.data.idtema;
1214 1229 lkgrcode1 = i3GEO.arvoreDeTemas.LOCAPLIC+"/pacotes/qrcode/php/qr_img.php?d="+i3GEO.arvoreDeTemas.LOCAPLIC+"/mobile/index.php?temasa="+node.data.idtema;
... ...
classesjs/classe_barradebotoes.js
... ... @@ -510,6 +510,8 @@ i3GEO.barraDeBotoes = {
510 510 */
511 511 inicializaBarra:function(idconteudo,idconteudonovo,barraZoom,x,y,onde){
512 512 if(typeof(console) !== 'undefined'){console.info("i3GEO.barraDeBotoes.inicializaBarra()");}
  513 + if(i3GEO.util.pegaCookie("botoesAjuda") == "nao")
  514 + {i3GEO.barraDeBotoes.AJUDA = false;}
513 515 if(i3GEO.barraDeBotoes.TEMPLATEBOTAO === "")
514 516 {i3GEO.barraDeBotoes.TEMPLATEBOTAO = "<div style='display:inline;background-color:rgb(250,250,250);'><p style='font-size:2px;'>&nbsp;</p><img style='border:0px solid white;' src='"+i3GEO.configura.locaplic+"/imagens/branco.gif' id='$$'/></div>";}
515 517 var tipo,mostra,numerobotoes = 0,i,temp,elementos,nelementos = 0,e,wj,recuo,novoel,alturadisponivel,n,chaves,re,estilo;
... ... @@ -908,10 +910,9 @@ i3GEO.barraDeBotoes = {
908 910 else
909 911 {document.body.appendChild(divmensagem);}
910 912 if(i3GEO.barraDeBotoes.TIPOAJUDA == "horizontal")
911   - {divmensagem.innerHTML = "<table style='z-index:20000' ><tr><td id='imgMensagemBarraDeBotoes' style='background:none;padding-top:2px;padding-right:3px;vertical-align:top'><img src='"+$im("left.png")+"' ></td><td style='text-align:left;border-left:1px solid rgb(210,210,210)'><span style='text-align:right;cursor:pointer;color:blue;' onclick='javascript:i3GEO.barraDeBotoes.AJUDA = false;'>fecha</span><br><div style='vertical-align:middle;text-align:left;width:250px;border: 0px solid black;border-left:1px;' id='divMensagemBarraDeBotoesCorpo'></div></td></tr></table>";}
  913 + {divmensagem.innerHTML = "<table style='z-index:20000' ><tr><td id='imgMensagemBarraDeBotoes' style='background:none;padding-top:2px;padding-right:3px;vertical-align:top'><img src='"+$im("left.png")+"' ></td><td style='text-align:left;border-left:1px solid rgb(210,210,210)'><span style='text-align:right;cursor:pointer;color:blue;' onclick='javascript:i3GEO.util.insereCookie(\"botoesAjuda\",\"nao\");i3GEO.barraDeBotoes.AJUDA = false;'>fecha</span><br><div style='vertical-align:middle;text-align:left;width:250px;border: 0px solid black;border-left:1px;' id='divMensagemBarraDeBotoesCorpo'></div></td></tr></table>";}
912 914 if(i3GEO.barraDeBotoes.TIPOAJUDA == "vertical")
913   - {divmensagem.innerHTML = "<table style='z-index:20000' ><tr><td id='imgMensagemBarraDeBotoes' style='background:none;padding-top:2px;padding-right:3px;vertical-align:top'><img src='"+$im("top.png")+"' ></td><td style='text-align:left;border-left:1px solid rgb(210,210,210)'><span style='text-align:right;cursor:pointer;color:blue;' onclick='javascript:i3GEO.barraDeBotoes.AJUDA = false;'>fecha</span><br><div style='vertical-align:middle;text-align:left;width:250px;border: 0px solid black;border-left:1px;' id='divMensagemBarraDeBotoesCorpo'></div></td></tr></table>";}
914   -
  915 + {divmensagem.innerHTML = "<table style='z-index:20000' ><tr><td id='imgMensagemBarraDeBotoes' style='background:none;padding-top:2px;padding-right:3px;vertical-align:top'><img src='"+$im("top.png")+"' ></td><td style='text-align:left;border-left:1px solid rgb(210,210,210)'><span style='text-align:right;cursor:pointer;color:blue;' onclick='javascript:i3GEO.util.insereCookie(\"botoesAjuda\",\"nao\");i3GEO.barraDeBotoes.AJUDA = false;'>fecha</span><br><div style='vertical-align:middle;text-align:left;width:250px;border: 0px solid black;border-left:1px;' id='divMensagemBarraDeBotoesCorpo'></div></td></tr></table>";}
915 916 }
916 917 if(mensagem != ""){
917 918 if(i3GEO.barraDeBotoes.TIPOAJUDA == "horizontal"){
... ...
classesjs/classe_i3geo.js
... ... @@ -114,6 +114,8 @@ i3GEO = {
114 114 embedLegenda {String} - sim|nao indica se na inicialização a legenda foi inserida no conteúdo do mapa ou não
115 115  
116 116 celularef {Numeric} - tamanho da célula do mapa de referência
  117 +
  118 + autenticadoopenid {sim|nao} - indica se o usuário foi autenticado em alguma rede social
117 119 */
118 120 parametros: {
119 121 mapexten: "",
... ... @@ -141,7 +143,8 @@ i3GEO = {
141 143 mensageminicia:"",
142 144 interfacePadrao:"geral.htm",
143 145 embedLegenda:"nao",
144   - celularef:""
  146 + celularef:"",
  147 + autenticadoopenid:"nao"
145 148 },
146 149 /*
147 150 Propriedade: finaliza
... ... @@ -224,37 +227,6 @@ i3GEO = {
224 227 //
225 228 tamanho = i3GEO.calculaTamanho();
226 229 i3GEO.Interface.cria(tamanho[0],tamanho[1]);
227   -
228   - /*
229   - i3GEO.parametros = {
230   - mapexten: "",
231   - mapscale: "",
232   - mapres: "",
233   - pixelsize: "",
234   - mapfile: "",
235   - cgi: "",
236   - extentTotal: "",
237   - mapimagem: "",
238   - geoip: "",
239   - listavisual: "",
240   - utilizacgi:"",
241   - versaoms:"",
242   - versaomscompleta:"",
243   - mensagens:"",
244   - w: tamanho[0],
245   - h: tamanho[1],
246   - locsistemas:"",
247   - locidentifica:"",
248   - r:"",
249   - locmapas:"",
250   - extentref:"",
251   - kmlurl:"",
252   - mensageminicia:"",
253   - interfacePadrao:"geral.htm",
254   - embedLegenda:"nao",
255   - celularef: ""
256   - };
257   - */
258 230 if(tamanho[0] < 550){
259 231 i = $i(i3GEO.gadgets.PARAMETROS.mostraQuadros.idhtml);
260 232 if(i){i.style.display = "none";}
... ... @@ -295,57 +267,12 @@ i3GEO = {
295 267 }
296 268 else{
297 269 if(retorno.data.variaveis){
298   - //
299   - //executa com eval a string que é retornada pelo servidor (função inicia do mapa_controle.php
300   - //
301   -
302   - /*
303   - tempo = "";
304   - titulo = "";
305   - eval(retorno.data.variaveis);
306   - try{
307   - if (titulo !== "")
308   - {top.document.title = titulo;}
309   - }
310   - catch(e){}
311   - i3GEO.ajuda.mostraJanela("Tempo de desenho em segundos: "+tempo,"");
312   -
313   - try{
314   - i3GEO.parametros.mapexten= mapexten;
315   - i3GEO.parametros.mapscale= parseInt(mapscale,10);
316   - i3GEO.parametros.mapres= mapres;
317   - i3GEO.parametros.pixelsize= g_celula;
318   - i3GEO.parametros.mapfile= mapfile;
319   - i3GEO.parametros.cgi= cgi;
320   - i3GEO.parametros.extentTotal=mapexten;
321   - i3GEO.parametros.mapimagem= mapimagem;
322   - i3GEO.parametros.geoip= geoip;
323   - i3GEO.parametros.listavisual= listavisual;
324   - i3GEO.parametros.utilizacgi= utilizacgi;
325   - i3GEO.parametros.versaoms= versaoms;
326   - i3GEO.parametros.mensagens= mensagens;
327   - i3GEO.parametros.locsistemas = locsistemas;
328   - i3GEO.parametros.locidentifica = locidentifica;
329   - i3GEO.parametros.r = r;
330   - i3GEO.parametros.locmapas = locmapas;
331   - i3GEO.parametros.extentref = extentref;
332   - i3GEO.parametros.versaoms = versaoms;
333   - i3GEO.parametros.versaomscompleta = versaomscompleta;
334   - i3GEO.parametros.kmlurl = kmlurl;
335   - i3GEO.parametros.mensageminicia = mensagemInicia;
336   - i3GEO.parametros.interfacePadrao = interfacePadrao;
337   - i3GEO.parametros.embedLegenda = embedLegenda;
338   - }
339   - catch(e){alert("Erro durante a definicao de i3GEO.parametros "+e);}
340   - */
341 270 i3GEO.parametros = retorno.data.variaveis;
342   -
343 271 i3GEO.parametros.mapscale = i3GEO.parametros.mapscale*1;
344 272 i3GEO.parametros.mapres = i3GEO.parametros.mapres*1;
345 273 i3GEO.parametros.pixelsize = i3GEO.parametros.pixelsize*1;
346 274 i3GEO.parametros.w = i3GEO.parametros.w*1;
347 275 i3GEO.parametros.h = i3GEO.parametros.h*1;
348   -
349 276 i3GEO.arvoreDeCamadas.CAMADAS = retorno.data.temas;
350 277 if(retorno.data.variaveis.navegacaoDir == "sim")
351 278 {i3GEO.arvoreDeTemas.OPCOESADICIONAIS.navegacaoDir = true;}
... ... @@ -389,8 +316,6 @@ i3GEO = {
389 316 if (!$i("i3geo"))
390 317 {document.body.id = "i3geo";}
391 318 $i("i3geo").className = "yui-skin-sam";
392   - //if($i("mst"))
393   - //{$i("mst").style.visibility ="hidden";}
394 319 //
395 320 //se i3GEO.configura.sid = "", o html foi aberto diretamente
396 321 //então, é necessário criar os arquivos temporários do mapa
... ...
classesjs/classe_tema.js
... ... @@ -350,6 +350,18 @@ i3GEO.tema = {
350 350 */
351 351 dialogo:{
352 352 /*
  353 + Function: comentario
  354 +
  355 + Abre a janela de diálogo para o usuário ver e inserir comentarios em um tema
  356 +
  357 + Parametros:
  358 +
  359 + tema - código do tema escolhido
  360 + */
  361 + comentario: function(tema){
  362 + i3GEO.janela.cria("530px","330px",i3GEO.configura.locaplic+"/ferramentas/comentarios/index.php?tema="+tema+"&g_sid="+i3GEO.configura.sid+"&locaplic="+i3GEO.configura.locaplic,"","","<img src='"+i3GEO.configura.locaplic+"/imagens/player_volta.png' style=cursor:pointer onclick='javascript:history.go(-1)'><span style=position:relative;top:-2px; > Comentários de "+tema+" </span><a class=ajuda_usuario target=_blank href='"+i3GEO.configura.locaplic+"/ajuda_usuario.php?idcategoria=7&idajuda=68' >&nbsp;&nbsp;&nbsp;</a>","comentario"+Math.random());
  363 + },
  364 + /*
353 365 Function: cortina
354 366  
355 367 Abre a janela de diálogo da ferramenta cortina
... ...
classesjs/dicionario.js
... ... @@ -761,6 +761,13 @@ en:&quot;Save mapfile&quot;,
761 761 es:"Guardar mapfile",
762 762 it:"Salva mapfile"
763 763 }],
  764 +"t45": [
  765 +{
  766 +pt: "Comentar",
  767 +en:"Comentar",
  768 +es:"Comentar",
  769 +it:"Comentar"
  770 +}],
764 771 //guia adiciona
765 772 "a1":[
766 773 {
... ...
classesjs/dicionario_ajuda.js
... ... @@ -786,6 +786,14 @@ g_traducao_ajuda = {
786 786 pt:"Salva as definições da camada no arquivo mapfile de origem",
787 787 complemento:"Essa opção só é ativada para usuários que são administradores. Permite que a camada seja alterada, por exemplo, modificando-se a legenda, e que o resultado seja salvo nas definições originais da camada.",
788 788 apijs:"i3GEO.tema.dialogo.salvaMapfile()"
  789 + },
  790 + "93": {
  791 + titulo: "Comentários",
  792 + diretorio:"i3geo/ferramentas/comentarios",
  793 + categoria:"5",
  794 + pt:"Mostra os comentários existentes sobre o tema e permite ao usuário inserir novos",
  795 + complemento:"Para entar com um comentário, o usuário precisa ser autenticado em alguma das redes sociais compatíveis com a rotina de login disponível no i3Geo",
  796 + apijs:"i3GEO.tema.dialogo.comentario()"
789 797 }
790 798 }
791 799 };
... ...
classesphp/classe_mapa.php
... ... @@ -221,6 +221,9 @@ string - javascript com os parametros
221 221 $ltempo = "nao";
222 222 if($oLayer->getmetadata("ltempoformatodata") !== "")
223 223 {$ltempo = "sim";}
  224 + $permitecomentario = "nao";
  225 + if($oLayer->getmetadata("nomeoriginal") != "" && strtoupper($oLayer->getmetadata("pemitecomentario")) != "NAO")
  226 + {$permitecomentario = "sim";}
224 227 $temas[] = array(
225 228 "name"=>($oLayer->name),
226 229 "status"=>($oLayer->status),
... ... @@ -240,7 +243,8 @@ string - javascript com os parametros
240 243 "linhadotempo"=>$ltempo,
241 244 "escondido"=>strtolower($escondido),
242 245 "iconetema"=>($oLayer->getmetadata("iconetema")),
243   - "classe"=>($oLayer->getmetadata("classe"))
  246 + "classe"=>($oLayer->getmetadata("classe")),
  247 + "permitecomentario"=>$permitecomentario
244 248 );
245 249 }
246 250 }
... ...
classesphp/mapa_controle.php
... ... @@ -124,11 +124,11 @@ if ($funcao != &quot;criaMapa&quot;)
124 124 eval("\$".$k."='".$_SESSION[$k]."';");
125 125 }
126 126 $postgis_mapa = $_SESSION["postgis_mapa"];
127   - if(isset($fingerprint))
128   - {
  127 + //if(isset($fingerprint))
  128 + //{
129 129 if (md5('I3GEOSEC' . $_SERVER['HTTP_USER_AGENT'] . session_id()) != $fingerprint)
130 130 {exit;}
131   - }
  131 + //}
132 132 }
133 133 //
134 134 //verifica se deve ativar o debug
... ... @@ -2929,7 +2929,7 @@ function redesenhaMapa()
2929 2929 $m->salva();
2930 2930 }
2931 2931 include_once("classe_mapa.php");
2932   - $m = New Mapa($map_file);
  2932 + $m = New Mapa($map_file,$locaplic);
2933 2933 $par = $m->parametrosTemas();
2934 2934 //
2935 2935 //na interface googlemaps não é necessário gerar a imagem
... ...
classesphp/mapa_inicia.php
... ... @@ -42,6 +42,8 @@ Inicia um mapa e obtém os parâmetros necessários para o funcionamento da interfa
42 42  
43 43 Globais:
44 44  
  45 +$openid - indica se o usuário foi ou não autenticado em alguma rede social (veja i3geo/pacotes/openid)
  46 +
45 47 $interfacePadrao - interface definida em ms_configura.php
46 48  
47 49 $navegadoresLocais - array que indica quais usuários podem navegar no servidor
... ... @@ -96,7 +98,7 @@ Retorno:
96 98 */
97 99 function iniciaMapa()
98 100 {
99   - global $interfacePadrao,$mensagemInicia,$kmlurl,$tituloInstituicao,$tempo,$navegadoresLocais,$locaplic,$embedLegenda,$map_file,$mapext,$w,$h,$R_path,$locmapserv,$utilizacgi,$expoeMapfile,$interface;
  101 + global $openid,$interfacePadrao,$mensagemInicia,$kmlurl,$tituloInstituicao,$tempo,$navegadoresLocais,$locaplic,$embedLegenda,$map_file,$mapext,$w,$h,$R_path,$locmapserv,$utilizacgi,$expoeMapfile,$interface;
100 102 if(!isset($kmlurl))
101 103 {$kmlurl = "";}
102 104 error_reporting(E_ALL);
... ... @@ -195,7 +197,7 @@ function iniciaMapa()
195 197 //
196 198 $qyfile = str_replace(".map",".qy",$map_file);
197 199 $arqsel = (file_exists($qyfile)) ? true : false;
198   - $m = New Mapa($map_file);
  200 + $m = New Mapa($map_file,$locaplic);
199 201 $temas = $m->parametrosTemas();
200 202 //$m->ligaDesligaTemas("",implode(",",$m->nomes),"nao");
201 203 //
... ... @@ -264,6 +266,10 @@ function iniciaMapa()
264 266 $res["mappath"] = $imgo->imagepath;
265 267 $res["mapurl"] = $imgo->imageurl;
266 268 $res["navegacaoDir"] = $navegadoresLocais;
  269 + if($openid == true)
  270 + {$res["autenticadoopenid"] = "sim";}
  271 + else
  272 + {$res["autenticadoopenid"] = "nao";}
267 273  
268 274 copy($map_file,(str_replace(".map","reinc.map",$map_file)));
269 275 copy($map_file,(str_replace(".map","seguranca.map",$map_file)));
... ...
ferramentas/comentarios/index.php 0 → 100644
... ... @@ -0,0 +1,112 @@
  1 +<html>
  2 +<head>
  3 +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
  4 +<link rel="stylesheet" type="text/css" href="../../admin/html/admin.css">
  5 +</head>
  6 +<body>
  7 +<?php
  8 +/*
  9 +Parametros:
  10 +
  11 +g_sid
  12 +
  13 +tema - tema que será comentado
  14 +*/
  15 +$parametrosURL = array_merge($_GET,$_POST);
  16 +
  17 +session_name("openid");
  18 +session_start();
  19 +if(!empty($parametrosURL["limpalogin"]))
  20 +{
  21 + session_destroy();
  22 + session_name("openid");
  23 + session_start();
  24 + $_SESSION["g_sid"] = $parametrosURL["g_sid"];
  25 +}
  26 +if(!empty($parametrosURL["tema"]))
  27 +{$_SESSION["tema"] = $parametrosURL["tema"];}
  28 +if(!empty($parametrosURL["locaplic"]))
  29 +{$_SESSION["locaplic"] = $parametrosURL["locaplic"];}
  30 +$_SESSION["urlVolta"] = $_SESSION["locaplic"]."/ferramentas/comentarios/index.php";
  31 +
  32 +
  33 +if($_SESSION["openid"] == true && $_POST["novocomentario"] != "")
  34 +{gravaComentario();}
  35 +
  36 +listaComentarios($_SESSION["tema"]);
  37 +
  38 +if($_SESSION["openid"] == true)
  39 +{formularioInsere();}
  40 +else
  41 +{linkOpenid();}
  42 +
  43 +function linkOpenId()
  44 +{
  45 + $urlVolta = $_SESSION["locaplic"]."/ferramentas/comentarios/index.php?";
  46 + $urlVolta .= "tema=".$_SESSION["tema"];
  47 + $url = $_SESSION["locaplic"]."/pacotes/openid/login.php?";
  48 + echo "<p><a href='".$url."' target=_self ><img style='border:0px solid white' src='../../imagens/plus.png' >Inserir comentário</a>";
  49 +}
  50 +function formularioInsere()
  51 +{
  52 + echo "<p>Adicione um comentário:</p>";
  53 + $url = $_SESSION["locaplic"]."/ferramentas/comentarios/index.php?g_sid=".$_SESSION["g_sid"]."&tema=".$_SESSION["tema"];
  54 + echo "<form action='".$url."' method='post'>";
  55 + echo " <textarea name=novocomentario value='' type='text' style='height:150px;width:98%' ></textarea><br>";
  56 + echo " <input type=submit value='Salvar' />";
  57 + echo "</form>";
  58 + echo "<p>Para alterar o seu login e escolher uma outra rede, <a href='".$url."&limpalogin=sim' >clique aqui</a>";
  59 +}
  60 +function listaComentarios()
  61 +{
  62 + $locaplic = "../..";
  63 + include("../../admin/php/conexao.php");
  64 + $data = gmdate("d-m-Y\TH:i:s\Z");
  65 + $id_tema = $dbh->query("select * from i3geoadmin_temas where codigo_tema = '".$_SESSION["tema"]."' ",PDO::FETCH_ASSOC);
  66 + $id_tema = $id_tema->fetchAll();
  67 + $id_tema = $id_tema[0]["id_tema"];
  68 + $lista = $dbh->query("select * from i3geoadmin_comentarios where id_tema = $id_tema ",PDO::FETCH_ASSOC);
  69 + $lista = $lista->fetchAll();
  70 + echo "<p><a href='../../admin/rsscomentariostemas.php'><img src='../../imagens/rss.gif' style='border:0px solid gray;' > todos os comentários</a>";
  71 + echo " <a href='../../admin/rsscomentariostemas.php?id_tema=".$id_tema."'><img src='../../imagens/rss.gif' style='border:0px solid gray;' > comentários para o tema</a></p>";
  72 +
  73 + echo "<table>";
  74 + foreach ($lista as $reg)
  75 + {
  76 + //echo "<tr><td>&nbsp;</td><td></td></tr><tr>";
  77 + echo "<td style='vertical-align:top;border-top:2px solid white;' >";
  78 + if($reg["openidimagem"] != "")
  79 + {echo "<img src='".$reg["openidimagem"]."'/>&nbsp;";}
  80 + echo "<p><a href='".$reg["openidurl"]."'>".$reg["openidnome"]."</a></td>";
  81 + echo "<td style='vertical-align:top;border-top:2px solid white;' ><p style=line-height:15px ><span style=color:gray >".$reg["data"]."</span><br>".mb_convert_encoding($reg["comentario"],"ISO-8859-1",mb_detect_encoding($reg["comentario"]))."<br></td>";
  82 + echo "</tr>";
  83 + }
  84 + echo "</table><hr>";
  85 + $dbhw = null;
  86 + $dbh = null;
  87 +}
  88 +function gravaComentario()
  89 +{
  90 + //necessário para os includes do admin.php
  91 + include_once("../../admin/php/conexao.php");
  92 + $data = gmdate("d-m-Y\TH:i:s\Z");
  93 + $id_tema = $dbh->query("select * from i3geoadmin_temas where codigo_tema = '".$_SESSION["tema"]."' ",PDO::FETCH_ASSOC);
  94 + $id_tema = $id_tema->fetchAll();
  95 + $id_tema = $id_tema[0]["id_tema"];
  96 + $q = "INSERT INTO i3geoadmin_comentarios (comentario,data,openidnome,openidimagem,openidservico,openidusuario,openidurl,id_tema) VALUES ('".converte($_POST["novocomentario"])."','".$data."','".$_SESSION["openidnome"]."','".$_SESSION["openidimagem"]."','".$_SESSION["openidservico"]."','".$_SESSION["openidusuario"]."','".$_SESSION["openidurl"]."','".$id_tema."')";
  97 + $dbhw->query($q);
  98 + $dbhw = null;
  99 + $dbh = null;
  100 +}
  101 +function converte($texto){
  102 + global $convUTF;
  103 + if($convUTF == true)
  104 + $texto = mb_convert_encoding($texto,mb_detect_encoding($texto),"UTF-8");
  105 + else
  106 + $texto = mb_convert_encoding($texto,mb_detect_encoding($texto),"ISO-8859-1");
  107 + return $texto;
  108 +}
  109 +?>
  110 +<script>
  111 +
  112 +</script>
0 113 \ No newline at end of file
... ...
guia_de_migracao.txt
... ... @@ -18,7 +18,13 @@ Para a versão 4.5
18 18  
19 19 A pasta "images" foi removida e as imagens movidas para a pasta "imagens\depreciado"
20 20  
21   -
  21 + Opção de comentários em temas
  22 + Foram acrescentadas novas variáveis em ms_configura.php. Veja esse arquivo para editar as variáveis e registrar
  23 + as APIs das redes sociais como Twitter e Facebook
  24 + Por default, todos os temas podem receber comentários. Para bloquear comentários em temas específicos,
  25 + utilize o editor de mapfiles do sistema de admnistração
  26 + Os comentários são armazenados em uma tabela no banco de dados de administração. Essa tabela precisa ser criada no banco.
  27 + Para criar a tabela veja o item "Outras opções" em http://localhost/i3geo/admin
22 28  
23 29 -------------------------------------------------------------------------------------------------
24 30 Para a versão 4.4
... ...
imagens/redes_blogger.png 0 → 100644

2.3 KB

imagens/redes_facebook.png 0 → 100644

2.66 KB

imagens/redes_google.png 0 → 100644

5.99 KB

imagens/redes_linkedin.png 0 → 100644

3.65 KB

imagens/redes_myspace.png 0 → 100644

5.59 KB

imagens/redes_oauth.png 0 → 100644

1.42 KB

imagens/redes_openid.png 0 → 100644

1.11 KB

imagens/redes_twitter.png 0 → 100644

4.76 KB

imagens/redes_windowslive.png 0 → 100644

3.99 KB

imagens/redes_wordpress.png 0 → 100644

3.77 KB

interface/googlemaps.phtml
... ... @@ -141,6 +141,8 @@ i3GEO.idioma.IDSELETOR = &quot;seletorIdiomas&quot;;
141 141 i3GEO.Interface.ATIVAMENUCONTEXTO = true;
142 142 i3GEO.arvoreDeTemas.TIPOBOTAO = "radio";
143 143 i3GEO.arvoreDeTemas.ATIVATEMAIMEDIATO = true;
  144 +//para evitar a entrada de comentários na árvore de camadas, modifique a opção de cada tema individualmente no sistema de administração
  145 +i3GEO.arvoreDeTemas.OPCOESADICIONAIS.comentario = true;
144 146  
145 147 i3GEO.inicia();
146 148 </script>
... ...
ms_configura.php
... ... @@ -43,6 +43,96 @@ Arquivo: ms_configura.php
43 43  
44 44 */
45 45 /*
  46 + Variavel: linkedinoauth (ainda não implementado)
  47 +
  48 + Parâmetros registrados no Linkedin para permitir que o i3Geo faça autenticação com base na conta do usuário
  49 +
  50 + O Linkedin exige que cada site seja registrado para permitir que a API de autenticação funcione
  51 +
  52 + Veja o site para maiores informações: http://developer.linkedin.com/docs/DOC-1008
  53 +
  54 + Caso vc não queira permitir essa opção, deixe essa variável vazia, e.x
  55 +
  56 + Ao registrar utilize o valor http://meuservidor/i3geo/pacotes/openid/login.php?login
  57 +
  58 + Exemplo:
  59 +
  60 + $linkedinoauth = array(
  61 + "consumerkey" => "0oQ30ge-ggKarx4HGaXVK118n8mekMBbFYTrC-agGV9hvxUXfeWwS1q7ZMvD-8LL",
  62 + "consumersecret" => "nRGXfHp1XNMt0eCG7tWJpoCcXX1uoZseDtgiU-CRy1ajqipo4KpjjZdDUXmqZGQA"
  63 + );
  64 +
  65 + Tipo:
  66 + {array}
  67 +*/
  68 +$linkedinoauth = "";
  69 +/*
  70 + Variavel: facebookoauth
  71 +
  72 + Parâmetros registrados no Facebook para permitir que o i3Geo faça autenticação com base na conta do usuário
  73 +
  74 + O Facebook exige que cada site seja registrado para permitir que a API de autenticação funcione
  75 +
  76 + Veja o site para maiores informações: http://developers.facebook.com/setup/
  77 +
  78 + Caso vc não queira permitir essa opção, deixe essa variável vazia, e.x
  79 +
  80 + Ao registrar utilize o valor http://meuservidor/i3geo/pacotes/openid/login.php?login
  81 +
  82 + Exemplo:
  83 +
  84 + $facebookoauth = array(
  85 + "consumerkey" => "136279263094148",
  86 + "consumersecret" => "679fc4a007b1d289377fa8af8f7086b6"
  87 + );
  88 +
  89 + Tipo:
  90 + {array}
  91 +*/
  92 +$facebookoauth = array(
  93 + "consumerkey" => "136279263094148",
  94 + "consumersecret" => "679fc4a007b1d289377fa8af8f7086b6"
  95 + );
  96 +/*
  97 + Variavel: twitteroauth
  98 +
  99 + Parâmetros registrados no Twitter para permitir que o i3Geo faça autenticação com base na conta do usuário
  100 +
  101 + O Twitter exige que cada site seja registrado para permitir que a API de autenticação funcione
  102 +
  103 + Veja o site para maiores informações: http://www.snipe.net/2009/07/writing-your-first-twitter-application-with-oauth/
  104 +
  105 + Lista de aplicações cadastradas: https://twitter.com/oauth_clients/
  106 +
  107 + Caso vc não queira permitir essa opção, deixe essa variável vazia, e.x
  108 +
  109 + $twitteroauth = "";
  110 +
  111 + Ao registrar a aplicação, utilize o endereço do i3geo em Application Website, por exemplo http://meuservidor/i3geo
  112 +
  113 + Ao registrar utilize como "Callback URL" o valor http://meuservidor/i3geo/pacotes/openid/login.php?login
  114 +
  115 + Exemplo:
  116 +
  117 + $twitteroauth = array(
  118 + "consumerkey" => "vUvBcsOULjS0ewxuSvbS6w",
  119 + "consumersecret" => "0Hj6uCyycDCeNOgzTUF1bBSel75KtfbnCS4bxWVqaxk",
  120 + "requesttokenurl" => "https://twitter.com/oauth/request_token",
  121 + "accesstokenurl" => "https://twitter.com/oauth/access_token",
  122 + "authorizeurl" => "https://twitter.com/oauth/authorize"
  123 + );
  124 +
  125 + Tipo:
  126 + {array}
  127 +*/
  128 +$twitteroauth = array(
  129 + "consumerkey" => "vUvBcsOULjS0ewxuSvbS6w",
  130 + "consumersecret" => "0Hj6uCyycDCeNOgzTUF1bBSel75KtfbnCS4bxWVqaxk",
  131 + "requesttokenurl" => "https://twitter.com/oauth/request_token",
  132 + "accesstokenurl" => "https://twitter.com/oauth/access_token",
  133 + "authorizeurl" => "https://twitter.com/oauth/authorize"
  134 + );
  135 +/*
46 136 Variavel: mensagemInicia
47 137  
48 138 Mensagem de inicialização mostrada pelo programa ms_criamapa.php
... ...
pacotes/facebookoauth/callback.php 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +<?php
  2 +/**
  3 + * @file
  4 + * Take the user when they return from Twitter. Get access tokens.
  5 + * Verify credentials and redirect to based on response from Twitter.
  6 + */
  7 +
  8 +/* Start session and load lib */
  9 +$par = array_merge($_GET,$_POST);
  10 +session_name("openid");
  11 +session_start();
  12 +$_SESSION["openid"] = true;
  13 +$_SESSION["openid_identifier"] = $par["openid_identifier"];
  14 +$_SESSION["openidusuario"] = basename($_SESSION["openid_identifier"]);
  15 +$_SESSION["openidservico"] = "facebook";
  16 +$_SESSION["openidimagem"] = "http://graph.facebook.com/".$_SESSION["openidusuario"]."/picture";
  17 +$_SESSION["openidnome"] = $par["openidnome"];
  18 +header('Location: '.$_SESSION["urlVolta"]);
  19 +?>
... ...
pacotes/facebookoauth/clearsessions.php 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<?php
  2 +/**
  3 + * @file
  4 + * Clears PHP sessions and redirects to the connect page.
  5 + */
  6 +
  7 +/* Load and clear sessions */
  8 +session_start("openid");
  9 +session_destroy();
  10 +
  11 +/* Redirect to page with the connect to Twitter option. */
  12 +header('Location: ../openid/login.php?login&erro=ok');
  13 +?>
0 14 \ No newline at end of file
... ...
pacotes/facebookoauth/config.php 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +<?php
  2 +include_once("../../ms_configura.php");
  3 +define('FACEBOOK_APP_ID', $facebookoauth["consumerkey"]);
  4 +define('FACEBOOK_SECRET', $facebookoauth["consumersecret"]);
  5 +?>
0 6 \ No newline at end of file
... ...
pacotes/facebookoauth/index.php 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +<?php
  2 +session_name("openid");
  3 +session_start();
  4 +require_once('config.php');
  5 +?>
  6 +<html>
  7 +<div id="fb-root"></div>
  8 +<script src="http://connect.facebook.net/en_US/all.js"></script>
  9 +<body onload="inicia()">
  10 +<script>
  11 + function inicia(){
  12 + FB.init({appId: '<?php echo FACEBOOK_APP_ID;?>', status: true, cookie: true, xfbml: true});
  13 +
  14 + FB.login(function(response) {
  15 + if (response.session) {
  16 + FB.api('/me',
  17 + function(response) {
  18 + window.location.href = "callback.php?openid_identifier="+response.link+"&openidnome="+response.name;
  19 + }
  20 + );
  21 + } else {
  22 + window.location.href = "clearsessions.php";
  23 + }
  24 + });
  25 + }
  26 +</script>
  27 +</body>
  28 +</html>
0 29 \ No newline at end of file
... ...
pacotes/linkedinoauth/CHANGELOG.txt 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +== 2008.08.04 ==
  2 +* Added LICENSE.txt file with MIT license, copyright owner is perhaps
  3 + dubious however.
  4 +== 2008.07.22 ==
  5 +* Change to encoding to fix last change to encoding of spaces
  6 +== 2008.07.15 ==
  7 +* Another change to encoding per
  8 + http://groups.google.com/group/oauth/browse_thread/thread/d39931d39b4af4bd
  9 +* A change to port handling to better deal with https and the like per
  10 + http://groups.google.com/group/oauth/browse_thread/thread/1b203a51d9590226
  11 +* Fixed a small bug per
  12 + http://code.google.com/p/oauth/issues/detail?id=26
  13 +* Added missing base_string debug info when using RSA-SHA1
  14 +* Increased size of example endpoint input field and added note about
  15 + query strings
... ...
pacotes/linkedinoauth/LICENSE.txt 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +The MIT License
  2 +
  3 +Copyright (c) 2007 Andy Smith
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in
  13 +all copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21 +THE SOFTWARE.
  22 +
... ...
pacotes/linkedinoauth/OAuth.php 0 → 100644
... ... @@ -0,0 +1,866 @@
  1 +<?php
  2 +// vim: foldmethod=marker
  3 +
  4 +/* Generic exception class
  5 + */
  6 +class OAuthException extends Exception {
  7 + // pass
  8 +}
  9 +
  10 +class OAuthConsumer {
  11 + public $key;
  12 + public $secret;
  13 +
  14 + function __construct($key, $secret, $callback_url=NULL) {
  15 + $this->key = $key;
  16 + $this->secret = $secret;
  17 + $this->callback_url = $callback_url;
  18 + }
  19 +
  20 + function __toString() {
  21 + return "OAuthConsumer[key=$this->key,secret=$this->secret]";
  22 + }
  23 +}
  24 +
  25 +class OAuthToken {
  26 + // access tokens and request tokens
  27 + public $key;
  28 + public $secret;
  29 +
  30 + /**
  31 + * key = the token
  32 + * secret = the token secret
  33 + */
  34 + function __construct($key, $secret) {
  35 + $this->key = $key;
  36 + $this->secret = $secret;
  37 + }
  38 +
  39 + /**
  40 + * generates the basic string serialization of a token that a server
  41 + * would respond to request_token and access_token calls with
  42 + */
  43 + function to_string() {
  44 + return "oauth_token=" .
  45 + OAuthUtil::urlencode_rfc3986($this->key) .
  46 + "&oauth_token_secret=" .
  47 + OAuthUtil::urlencode_rfc3986($this->secret);
  48 + }
  49 +
  50 + function __toString() {
  51 + return $this->to_string();
  52 + }
  53 +}
  54 +
  55 +/**
  56 + * A class for implementing a Signature Method
  57 + * See section 9 ("Signing Requests") in the spec
  58 + */
  59 +abstract class OAuthSignatureMethod {
  60 + /**
  61 + * Needs to return the name of the Signature Method (ie HMAC-SHA1)
  62 + * @return string
  63 + */
  64 + abstract public function get_name();
  65 +
  66 + /**
  67 + * Build up the signature
  68 + * NOTE: The output of this function MUST NOT be urlencoded.
  69 + * the encoding is handled in OAuthRequest when the final
  70 + * request is serialized
  71 + * @param OAuthRequest $request
  72 + * @param OAuthConsumer $consumer
  73 + * @param OAuthToken $token
  74 + * @return string
  75 + */
  76 + abstract public function build_signature($request, $consumer, $token);
  77 +
  78 + /**
  79 + * Verifies that a given signature is correct
  80 + * @param OAuthRequest $request
  81 + * @param OAuthConsumer $consumer
  82 + * @param OAuthToken $token
  83 + * @param string $signature
  84 + * @return bool
  85 + */
  86 + public function check_signature($request, $consumer, $token, $signature) {
  87 + $built = $this->build_signature($request, $consumer, $token);
  88 + return $built == $signature;
  89 + }
  90 +}
  91 +
  92 +/**
  93 + * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
  94 + * where the Signature Base String is the text and the key is the concatenated values (each first
  95 + * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
  96 + * character (ASCII code 38) even if empty.
  97 + * - Chapter 9.2 ("HMAC-SHA1")
  98 + */
  99 +class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
  100 + function get_name() {
  101 + return "HMAC-SHA1";
  102 + }
  103 +
  104 + public function build_signature($request, $consumer, $token) {
  105 + $base_string = $request->get_signature_base_string();
  106 + $request->base_string = $base_string;
  107 +
  108 + $key_parts = array(
  109 + $consumer->secret,
  110 + ($token) ? $token->secret : ""
  111 + );
  112 +
  113 + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
  114 + $key = implode('&', $key_parts);
  115 +
  116 + return base64_encode(hash_hmac('sha1', $base_string, $key, true));
  117 + }
  118 +}
  119 +
  120 +/**
  121 + * The PLAINTEXT method does not provide any security protection and SHOULD only be used
  122 + * over a secure channel such as HTTPS. It does not use the Signature Base String.
  123 + * - Chapter 9.4 ("PLAINTEXT")
  124 + */
  125 +class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
  126 + public function get_name() {
  127 + return "PLAINTEXT";
  128 + }
  129 +
  130 + /**
  131 + * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
  132 + * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
  133 + * empty. The result MUST be encoded again.
  134 + * - Chapter 9.4.1 ("Generating Signatures")
  135 + *
  136 + * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
  137 + * OAuthRequest handles this!
  138 + */
  139 + public function build_signature($request, $consumer, $token) {
  140 + $key_parts = array(
  141 + $consumer->secret,
  142 + ($token) ? $token->secret : ""
  143 + );
  144 +
  145 + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
  146 + $key = implode('&', $key_parts);
  147 + $request->base_string = $key;
  148 +
  149 + return $key;
  150 + }
  151 +}
  152 +
  153 +/**
  154 + * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
  155 + * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
  156 + * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
  157 + * verified way to the Service Provider, in a manner which is beyond the scope of this
  158 + * specification.
  159 + * - Chapter 9.3 ("RSA-SHA1")
  160 + */
  161 +abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
  162 + public function get_name() {
  163 + return "RSA-SHA1";
  164 + }
  165 +
  166 + // Up to the SP to implement this lookup of keys. Possible ideas are:
  167 + // (1) do a lookup in a table of trusted certs keyed off of consumer
  168 + // (2) fetch via http using a url provided by the requester
  169 + // (3) some sort of specific discovery code based on request
  170 + //
  171 + // Either way should return a string representation of the certificate
  172 + protected abstract function fetch_public_cert(&$request);
  173 +
  174 + // Up to the SP to implement this lookup of keys. Possible ideas are:
  175 + // (1) do a lookup in a table of trusted certs keyed off of consumer
  176 + //
  177 + // Either way should return a string representation of the certificate
  178 + protected abstract function fetch_private_cert(&$request);
  179 +
  180 + public function build_signature($request, $consumer, $token) {
  181 + $base_string = $request->get_signature_base_string();
  182 + $request->base_string = $base_string;
  183 +
  184 + // Fetch the private key cert based on the request
  185 + $cert = $this->fetch_private_cert($request);
  186 +
  187 + // Pull the private key ID from the certificate
  188 + $privatekeyid = openssl_get_privatekey($cert);
  189 +
  190 + // Sign using the key
  191 + $ok = openssl_sign($base_string, $signature, $privatekeyid);
  192 +
  193 + // Release the key resource
  194 + openssl_free_key($privatekeyid);
  195 +
  196 + return base64_encode($signature);
  197 + }
  198 +
  199 + public function check_signature($request, $consumer, $token, $signature) {
  200 + $decoded_sig = base64_decode($signature);
  201 +
  202 + $base_string = $request->get_signature_base_string();
  203 +
  204 + // Fetch the public key cert based on the request
  205 + $cert = $this->fetch_public_cert($request);
  206 +
  207 + // Pull the public key ID from the certificate
  208 + $publickeyid = openssl_get_publickey($cert);
  209 +
  210 + // Check the computed signature against the one passed in the query
  211 + $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
  212 +
  213 + // Release the key resource
  214 + openssl_free_key($publickeyid);
  215 +
  216 + return $ok == 1;
  217 + }
  218 +}
  219 +
  220 +class OAuthRequest {
  221 + private $parameters;
  222 + private $http_method;
  223 + private $http_url;
  224 + // for debug purposes
  225 + public $base_string;
  226 + public static $version = '1.0';
  227 + public static $POST_INPUT = 'php://input';
  228 +
  229 + function __construct($http_method, $http_url, $parameters=NULL) {
  230 + @$parameters or $parameters = array();
  231 + $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
  232 + $this->parameters = $parameters;
  233 + $this->http_method = $http_method;
  234 + $this->http_url = $http_url;
  235 + }
  236 +
  237 +
  238 + /**
  239 + * attempt to build up a request from what was passed to the server
  240 + */
  241 + public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
  242 + $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
  243 + ? 'http'
  244 + : 'https';
  245 + @$http_url or $http_url = $scheme .
  246 + '://' . $_SERVER['HTTP_HOST'] .
  247 + ':' .
  248 + $_SERVER['SERVER_PORT'] .
  249 + $_SERVER['REQUEST_URI'];
  250 + @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
  251 +
  252 + // We weren't handed any parameters, so let's find the ones relevant to
  253 + // this request.
  254 + // If you run XML-RPC or similar you should use this to provide your own
  255 + // parsed parameter-list
  256 + if (!$parameters) {
  257 + // Find request headers
  258 + $request_headers = OAuthUtil::get_headers();
  259 +
  260 + // Parse the query-string to find GET parameters
  261 + $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
  262 +
  263 + // It's a POST request of the proper content-type, so parse POST
  264 + // parameters and add those overriding any duplicates from GET
  265 + if ($http_method == "POST"
  266 + && @strstr($request_headers["Content-Type"],
  267 + "application/x-www-form-urlencoded")
  268 + ) {
  269 + $post_data = OAuthUtil::parse_parameters(
  270 + file_get_contents(self::$POST_INPUT)
  271 + );
  272 + $parameters = array_merge($parameters, $post_data);
  273 + }
  274 +
  275 + // We have a Authorization-header with OAuth data. Parse the header
  276 + // and add those overriding any duplicates from GET or POST
  277 + if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
  278 + $header_parameters = OAuthUtil::split_header(
  279 + $request_headers['Authorization']
  280 + );
  281 + $parameters = array_merge($parameters, $header_parameters);
  282 + }
  283 +
  284 + }
  285 +
  286 + return new OAuthRequest($http_method, $http_url, $parameters);
  287 + }
  288 +
  289 + /**
  290 + * pretty much a helper function to set up the request
  291 + */
  292 + public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
  293 + @$parameters or $parameters = array();
  294 + $defaults = array("oauth_version" => OAuthRequest::$version,
  295 + "oauth_nonce" => OAuthRequest::generate_nonce(),
  296 + "oauth_timestamp" => OAuthRequest::generate_timestamp(),
  297 + "oauth_consumer_key" => $consumer->key);
  298 + if ($token)
  299 + $defaults['oauth_token'] = $token->key;
  300 +
  301 + $parameters = array_merge($defaults, $parameters);
  302 +
  303 + return new OAuthRequest($http_method, $http_url, $parameters);
  304 + }
  305 +
  306 + public function set_parameter($name, $value, $allow_duplicates = true) {
  307 + if ($allow_duplicates && isset($this->parameters[$name])) {
  308 + // We have already added parameter(s) with this name, so add to the list
  309 + if (is_scalar($this->parameters[$name])) {
  310 + // This is the first duplicate, so transform scalar (string)
  311 + // into an array so we can add the duplicates
  312 + $this->parameters[$name] = array($this->parameters[$name]);
  313 + }
  314 +
  315 + $this->parameters[$name][] = $value;
  316 + } else {
  317 + $this->parameters[$name] = $value;
  318 + }
  319 + }
  320 +
  321 + public function get_parameter($name) {
  322 + return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
  323 + }
  324 +
  325 + public function get_parameters() {
  326 + return $this->parameters;
  327 + }
  328 +
  329 + public function unset_parameter($name) {
  330 + unset($this->parameters[$name]);
  331 + }
  332 +
  333 + /**
  334 + * The request parameters, sorted and concatenated into a normalized string.
  335 + * @return string
  336 + */
  337 + public function get_signable_parameters() {
  338 + // Grab all parameters
  339 + $params = $this->parameters;
  340 +
  341 + // Remove oauth_signature if present
  342 + // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
  343 + if (isset($params['oauth_signature'])) {
  344 + unset($params['oauth_signature']);
  345 + }
  346 +
  347 + return OAuthUtil::build_http_query($params);
  348 + }
  349 +
  350 + /**
  351 + * Returns the base string of this request
  352 + *
  353 + * The base string defined as the method, the url
  354 + * and the parameters (normalized), each urlencoded
  355 + * and the concated with &.
  356 + */
  357 + public function get_signature_base_string() {
  358 + $parts = array(
  359 + $this->get_normalized_http_method(),
  360 + $this->get_normalized_http_url(),
  361 + $this->get_signable_parameters()
  362 + );
  363 +
  364 + $parts = OAuthUtil::urlencode_rfc3986($parts);
  365 +
  366 + return implode('&', $parts);
  367 + }
  368 +
  369 + /**
  370 + * just uppercases the http method
  371 + */
  372 + public function get_normalized_http_method() {
  373 + return strtoupper($this->http_method);
  374 + }
  375 +
  376 + /**
  377 + * parses the url and rebuilds it to be
  378 + * scheme://host/path
  379 + */
  380 + public function get_normalized_http_url() {
  381 + $parts = parse_url($this->http_url);
  382 +
  383 + $port = @$parts['port'];
  384 + $scheme = $parts['scheme'];
  385 + $host = $parts['host'];
  386 + $path = @$parts['path'];
  387 +
  388 + $port or $port = ($scheme == 'https') ? '443' : '80';
  389 +
  390 + if (($scheme == 'https' && $port != '443')
  391 + || ($scheme == 'http' && $port != '80')) {
  392 + $host = "$host:$port";
  393 + }
  394 + return "$scheme://$host$path";
  395 + }
  396 +
  397 + /**
  398 + * builds a url usable for a GET request
  399 + */
  400 + public function to_url() {
  401 + $post_data = $this->to_postdata();
  402 + $out = $this->get_normalized_http_url();
  403 + if ($post_data) {
  404 + $out .= '?'.$post_data;
  405 + }
  406 + return $out;
  407 + }
  408 +
  409 + /**
  410 + * builds the data one would send in a POST request
  411 + */
  412 + public function to_postdata() {
  413 + return OAuthUtil::build_http_query($this->parameters);
  414 + }
  415 +
  416 + /**
  417 + * builds the Authorization: header
  418 + */
  419 + public function to_header($realm=null) {
  420 + if($realm)
  421 + $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
  422 + else
  423 + $out = 'Authorization: OAuth';
  424 +
  425 + $total = array();
  426 + foreach ($this->parameters as $k => $v) {
  427 + if (substr($k, 0, 5) != "oauth") continue;
  428 + if (is_array($v)) {
  429 + throw new OAuthException('Arrays not supported in headers');
  430 + }
  431 + $out .= ',' .
  432 + OAuthUtil::urlencode_rfc3986($k) .
  433 + '="' .
  434 + OAuthUtil::urlencode_rfc3986($v) .
  435 + '"';
  436 + }
  437 + return $out;
  438 + }
  439 +
  440 + public function __toString() {
  441 + return $this->to_url();
  442 + }
  443 +
  444 +
  445 + public function sign_request($signature_method, $consumer, $token) {
  446 + $this->set_parameter(
  447 + "oauth_signature_method",
  448 + $signature_method->get_name(),
  449 + false
  450 + );
  451 + $signature = $this->build_signature($signature_method, $consumer, $token);
  452 + $this->set_parameter("oauth_signature", $signature, false);
  453 + }
  454 +
  455 + public function build_signature($signature_method, $consumer, $token) {
  456 + $signature = $signature_method->build_signature($this, $consumer, $token);
  457 + return $signature;
  458 + }
  459 +
  460 + /**
  461 + * util function: current timestamp
  462 + */
  463 + private static function generate_timestamp() {
  464 + return time();
  465 + }
  466 +
  467 + /**
  468 + * util function: current nonce
  469 + */
  470 + private static function generate_nonce() {
  471 + $mt = microtime();
  472 + $rand = mt_rand();
  473 +
  474 + return md5($mt . $rand); // md5s look nicer than numbers
  475 + }
  476 +}
  477 +
  478 +class OAuthServer {
  479 + protected $timestamp_threshold = 300; // in seconds, five minutes
  480 + protected $version = '1.0'; // hi blaine
  481 + protected $signature_methods = array();
  482 +
  483 + protected $data_store;
  484 +
  485 + function __construct($data_store) {
  486 + $this->data_store = $data_store;
  487 + }
  488 +
  489 + public function add_signature_method($signature_method) {
  490 + $this->signature_methods[$signature_method->get_name()] =
  491 + $signature_method;
  492 + }
  493 +
  494 + // high level functions
  495 +
  496 + /**
  497 + * process a request_token request
  498 + * returns the request token on success
  499 + */
  500 + public function fetch_request_token(&$request) {
  501 + $this->get_version($request);
  502 +
  503 + $consumer = $this->get_consumer($request);
  504 +
  505 + // no token required for the initial token request
  506 + $token = NULL;
  507 +
  508 + $this->check_signature($request, $consumer, $token);
  509 +
  510 + // Rev A change
  511 + $callback = $request->get_parameter('oauth_callback');
  512 + $new_token = $this->data_store->new_request_token($consumer, $callback);
  513 +
  514 + return $new_token;
  515 + }
  516 +
  517 + /**
  518 + * process an access_token request
  519 + * returns the access token on success
  520 + */
  521 + public function fetch_access_token(&$request) {
  522 + $this->get_version($request);
  523 +
  524 + $consumer = $this->get_consumer($request);
  525 +
  526 + // requires authorized request token
  527 + $token = $this->get_token($request, $consumer, "request");
  528 +
  529 + $this->check_signature($request, $consumer, $token);
  530 +
  531 + // Rev A change
  532 + $verifier = $request->get_parameter('oauth_verifier');
  533 + $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
  534 +
  535 + return $new_token;
  536 + }
  537 +
  538 + /**
  539 + * verify an api call, checks all the parameters
  540 + */
  541 + public function verify_request(&$request) {
  542 + $this->get_version($request);
  543 + $consumer = $this->get_consumer($request);
  544 + $token = $this->get_token($request, $consumer, "access");
  545 + $this->check_signature($request, $consumer, $token);
  546 + return array($consumer, $token);
  547 + }
  548 +
  549 + // Internals from here
  550 + /**
  551 + * version 1
  552 + */
  553 + private function get_version(&$request) {
  554 + $version = $request->get_parameter("oauth_version");
  555 + if (!$version) {
  556 + // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
  557 + // Chapter 7.0 ("Accessing Protected Ressources")
  558 + $version = '1.0';
  559 + }
  560 + if ($version !== $this->version) {
  561 + throw new OAuthException("OAuth version '$version' not supported");
  562 + }
  563 + return $version;
  564 + }
  565 +
  566 + /**
  567 + * figure out the signature with some defaults
  568 + */
  569 + private function get_signature_method(&$request) {
  570 + $signature_method =
  571 + @$request->get_parameter("oauth_signature_method");
  572 +
  573 + if (!$signature_method) {
  574 + // According to chapter 7 ("Accessing Protected Ressources") the signature-method
  575 + // parameter is required, and we can't just fallback to PLAINTEXT
  576 + throw new OAuthException('No signature method parameter. This parameter is required');
  577 + }
  578 +
  579 + if (!in_array($signature_method,
  580 + array_keys($this->signature_methods))) {
  581 + throw new OAuthException(
  582 + "Signature method '$signature_method' not supported " .
  583 + "try one of the following: " .
  584 + implode(", ", array_keys($this->signature_methods))
  585 + );
  586 + }
  587 + return $this->signature_methods[$signature_method];
  588 + }
  589 +
  590 + /**
  591 + * try to find the consumer for the provided request's consumer key
  592 + */
  593 + private function get_consumer(&$request) {
  594 + $consumer_key = @$request->get_parameter("oauth_consumer_key");
  595 + if (!$consumer_key) {
  596 + throw new OAuthException("Invalid consumer key");
  597 + }
  598 +
  599 + $consumer = $this->data_store->lookup_consumer($consumer_key);
  600 + if (!$consumer) {
  601 + throw new OAuthException("Invalid consumer");
  602 + }
  603 +
  604 + return $consumer;
  605 + }
  606 +
  607 + /**
  608 + * try to find the token for the provided request's token key
  609 + */
  610 + private function get_token(&$request, $consumer, $token_type="access") {
  611 + $token_field = @$request->get_parameter('oauth_token');
  612 + $token = $this->data_store->lookup_token(
  613 + $consumer, $token_type, $token_field
  614 + );
  615 + if (!$token) {
  616 + throw new OAuthException("Invalid $token_type token: $token_field");
  617 + }
  618 + return $token;
  619 + }
  620 +
  621 + /**
  622 + * all-in-one function to check the signature on a request
  623 + * should guess the signature method appropriately
  624 + */
  625 + private function check_signature(&$request, $consumer, $token) {
  626 + // this should probably be in a different method
  627 + $timestamp = @$request->get_parameter('oauth_timestamp');
  628 + $nonce = @$request->get_parameter('oauth_nonce');
  629 +
  630 + $this->check_timestamp($timestamp);
  631 + $this->check_nonce($consumer, $token, $nonce, $timestamp);
  632 +
  633 + $signature_method = $this->get_signature_method($request);
  634 +
  635 + $signature = $request->get_parameter('oauth_signature');
  636 + $valid_sig = $signature_method->check_signature(
  637 + $request,
  638 + $consumer,
  639 + $token,
  640 + $signature
  641 + );
  642 +
  643 + if (!$valid_sig) {
  644 + throw new OAuthException("Invalid signature");
  645 + }
  646 + }
  647 +
  648 + /**
  649 + * check that the timestamp is new enough
  650 + */
  651 + private function check_timestamp($timestamp) {
  652 + if( ! $timestamp )
  653 + throw new OAuthException(
  654 + 'Missing timestamp parameter. The parameter is required'
  655 + );
  656 +
  657 + // verify that timestamp is recentish
  658 + $now = time();
  659 + if (abs($now - $timestamp) > $this->timestamp_threshold) {
  660 + throw new OAuthException(
  661 + "Expired timestamp, yours $timestamp, ours $now"
  662 + );
  663 + }
  664 + }
  665 +
  666 + /**
  667 + * check that the nonce is not repeated
  668 + */
  669 + private function check_nonce($consumer, $token, $nonce, $timestamp) {
  670 + if( ! $nonce )
  671 + throw new OAuthException(
  672 + 'Missing nonce parameter. The parameter is required'
  673 + );
  674 +
  675 + // verify that the nonce is uniqueish
  676 + $found = $this->data_store->lookup_nonce(
  677 + $consumer,
  678 + $token,
  679 + $nonce,
  680 + $timestamp
  681 + );
  682 + if ($found) {
  683 + throw new OAuthException("Nonce already used: $nonce");
  684 + }
  685 + }
  686 +
  687 +}
  688 +
  689 +class OAuthDataStore {
  690 + function lookup_consumer($consumer_key) {
  691 + // implement me
  692 + }
  693 +
  694 + function lookup_token($consumer, $token_type, $token) {
  695 + // implement me
  696 + }
  697 +
  698 + function lookup_nonce($consumer, $token, $nonce, $timestamp) {
  699 + // implement me
  700 + }
  701 +
  702 + function new_request_token($consumer, $callback = null) {
  703 + // return a new token attached to this consumer
  704 + }
  705 +
  706 + function new_access_token($token, $consumer, $verifier = null) {
  707 + // return a new access token attached to this consumer
  708 + // for the user associated with this token if the request token
  709 + // is authorized
  710 + // should also invalidate the request token
  711 + }
  712 +
  713 +}
  714 +
  715 +class OAuthUtil {
  716 + public static function urlencode_rfc3986($input) {
  717 + if (is_array($input)) {
  718 + return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
  719 + } else if (is_scalar($input)) {
  720 + return str_replace(
  721 + '+',
  722 + ' ',
  723 + str_replace('%7E', '~', rawurlencode($input))
  724 + );
  725 + } else {
  726 + return '';
  727 + }
  728 +}
  729 +
  730 +
  731 + // This decode function isn't taking into consideration the above
  732 + // modifications to the encoding process. However, this method doesn't
  733 + // seem to be used anywhere so leaving it as is.
  734 + public static function urldecode_rfc3986($string) {
  735 + return urldecode($string);
  736 + }
  737 +
  738 + // Utility function for turning the Authorization: header into
  739 + // parameters, has to do some unescaping
  740 + // Can filter out any non-oauth parameters if needed (default behaviour)
  741 + public static function split_header($header, $only_allow_oauth_parameters = true) {
  742 + $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
  743 + $offset = 0;
  744 + $params = array();
  745 + while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
  746 + $match = $matches[0];
  747 + $header_name = $matches[2][0];
  748 + $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
  749 + if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
  750 + $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content);
  751 + }
  752 + $offset = $match[1] + strlen($match[0]);
  753 + }
  754 +
  755 + if (isset($params['realm'])) {
  756 + unset($params['realm']);
  757 + }
  758 +
  759 + return $params;
  760 + }
  761 +
  762 + // helper to try to sort out headers for people who aren't running apache
  763 + public static function get_headers() {
  764 + if (function_exists('apache_request_headers')) {
  765 + // we need this to get the actual Authorization: header
  766 + // because apache tends to tell us it doesn't exist
  767 + $headers = apache_request_headers();
  768 +
  769 + // sanitize the output of apache_request_headers because
  770 + // we always want the keys to be Cased-Like-This and arh()
  771 + // returns the headers in the same case as they are in the
  772 + // request
  773 + $out = array();
  774 + foreach( $headers AS $key => $value ) {
  775 + $key = str_replace(
  776 + " ",
  777 + "-",
  778 + ucwords(strtolower(str_replace("-", " ", $key)))
  779 + );
  780 + $out[$key] = $value;
  781 + }
  782 + } else {
  783 + // otherwise we don't have apache and are just going to have to hope
  784 + // that $_SERVER actually contains what we need
  785 + $out = array();
  786 + foreach ($_SERVER as $key => $value) {
  787 + if (substr($key, 0, 5) == "HTTP_") {
  788 + // this is chaos, basically it is just there to capitalize the first
  789 + // letter of every word that is not an initial HTTP and strip HTTP
  790 + // code from przemek
  791 + $key = str_replace(
  792 + " ",
  793 + "-",
  794 + ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
  795 + );
  796 + $out[$key] = $value;
  797 + }
  798 + }
  799 + }
  800 + return $out;
  801 + }
  802 +
  803 + // This function takes a input like a=b&a=c&d=e and returns the parsed
  804 + // parameters like this
  805 + // array('a' => array('b','c'), 'd' => 'e')
  806 + public static function parse_parameters( $input ) {
  807 + if (!isset($input) || !$input) return array();
  808 +
  809 + $pairs = explode('&', $input);
  810 +
  811 + $parsed_parameters = array();
  812 + foreach ($pairs as $pair) {
  813 + $split = explode('=', $pair, 2);
  814 + $parameter = OAuthUtil::urldecode_rfc3986($split[0]);
  815 + $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
  816 +
  817 + if (isset($parsed_parameters[$parameter])) {
  818 + // We have already recieved parameter(s) with this name, so add to the list
  819 + // of parameters with this name
  820 +
  821 + if (is_scalar($parsed_parameters[$parameter])) {
  822 + // This is the first duplicate, so transform scalar (string) into an array
  823 + // so we can add the duplicates
  824 + $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
  825 + }
  826 +
  827 + $parsed_parameters[$parameter][] = $value;
  828 + } else {
  829 + $parsed_parameters[$parameter] = $value;
  830 + }
  831 + }
  832 + return $parsed_parameters;
  833 + }
  834 +
  835 + public static function build_http_query($params) {
  836 + if (!$params) return '';
  837 +
  838 + // Urlencode both keys and values
  839 + $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
  840 + $values = OAuthUtil::urlencode_rfc3986(array_values($params));
  841 + $params = array_combine($keys, $values);
  842 +
  843 + // Parameters are sorted by name, using lexicographical byte value ordering.
  844 + // Ref: Spec: 9.1.1 (1)
  845 + uksort($params, 'strcmp');
  846 +
  847 + $pairs = array();
  848 + foreach ($params as $parameter => $value) {
  849 + if (is_array($value)) {
  850 + // If two or more parameters share the same name, they are sorted by their value
  851 + // Ref: Spec: 9.1.1 (1)
  852 + natsort($value);
  853 + foreach ($value as $duplicate_value) {
  854 + $pairs[] = $parameter . '=' . $duplicate_value;
  855 + }
  856 + } else {
  857 + $pairs[] = $parameter . '=' . $value;
  858 + }
  859 + }
  860 + // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
  861 + // Each name-value pair is separated by an '&' character (ASCII code 38)
  862 + return implode('&', $pairs);
  863 + }
  864 +}
  865 +
  866 +?>
... ...
pacotes/linkedinoauth/OAuthTests.xml 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<phpunit colors="true">
  2 + <testsuite name="OAuth">
  3 + <directory>tests</directory>
  4 + </testsuite>
  5 + <filter>
  6 + <blacklist>
  7 + <directory>tests</directory>
  8 + </blacklist>
  9 + </filter>
  10 + <logging>
  11 + <log type="coverage-html" target="./report" charset="UTF-8" yui="true" highlight="false" lowUpperBound="35" highLowerBound="70"/>
  12 + </logging>
  13 +</phpunit>
0 14 \ No newline at end of file
... ...
pacotes/linkedinoauth/OAuth_TestServer.php 0 → 100644
... ... @@ -0,0 +1,106 @@
  1 +<?php //vim: foldmethod=marker
  2 +//require_once("OAuth.php");
  3 +
  4 +class TestOAuthServer extends OAuthServer {
  5 + public function get_signature_methods() {
  6 + return $this->signature_methods;
  7 + }
  8 +}
  9 +
  10 +class TestOAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod_RSA_SHA1 {
  11 + public function fetch_private_cert(&$request) {
  12 + $cert = <<<EOD
  13 +-----BEGIN PRIVATE KEY-----
  14 +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
  15 +A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
  16 +7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
  17 +hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
  18 +X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
  19 +uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
  20 +rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
  21 +zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
  22 +qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
  23 +WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
  24 +cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
  25 +3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
  26 +AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
  27 +Lw03eHTNQghS0A==
  28 +-----END PRIVATE KEY-----
  29 +EOD;
  30 + return $cert;
  31 + }
  32 +
  33 + public function fetch_public_cert(&$request) {
  34 + $cert = <<<EOD
  35 +-----BEGIN CERTIFICATE-----
  36 +MIIBpjCCAQ+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAZMRcwFQYDVQQDDA5UZXN0
  37 +IFByaW5jaXBhbDAeFw03MDAxMDEwODAwMDBaFw0zODEyMzEwODAwMDBaMBkxFzAV
  38 +BgNVBAMMDlRlc3QgUHJpbmNpcGFsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
  39 +gQC0YjCwIfYoprq/FQO6lb3asXrxLlJFuCvtinTF5p0GxvQGu5O3gYytUvtC2JlY
  40 +zypSRjVxwxrsuRcP3e641SdASwfrmzyvIgP08N4S0IFzEURkV1wp/IpH7kH41Etb
  41 +mUmrXSwfNZsnQRE5SYSOhh+LcK2wyQkdgcMv11l4KoBkcwIDAQABMA0GCSqGSIb3
  42 +DQEBBQUAA4GBAGZLPEuJ5SiJ2ryq+CmEGOXfvlTtEL2nuGtr9PewxkgnOjZpUy+d
  43 +4TvuXJbNQc8f4AMWL/tO9w0Fk80rWKp9ea8/df4qMq5qlFWlx6yOLQxumNOmECKb
  44 +WpkUQDIDJEoFUzKMVuJf4KO/FJ345+BNLGgbJ6WujreoM1X/gYfdnJ/J
  45 +-----END CERTIFICATE-----
  46 +EOD;
  47 + return $cert;
  48 + }
  49 +}
  50 +
  51 +/**
  52 + * A mock store for testing
  53 + */
  54 +class MockOAuthDataStore extends OAuthDataStore {/*{{{*/
  55 + private $consumer;
  56 + private $request_token;
  57 + private $access_token;
  58 + private $nonce;
  59 +
  60 + function __construct() {/*{{{*/
  61 + $this->consumer = new OAuthConsumer("key", "secret", NULL);
  62 + $this->request_token = new OAuthToken("requestkey", "requestsecret", 1);
  63 + $this->access_token = new OAuthToken("accesskey", "accesssecret", 1);
  64 + $this->nonce = "nonce";
  65 + }/*}}}*/
  66 +
  67 + function lookup_consumer($consumer_key) {/*{{{*/
  68 + if ($consumer_key == $this->consumer->key) return $this->consumer;
  69 + return NULL;
  70 + }/*}}}*/
  71 +
  72 + function lookup_token($consumer, $token_type, $token) {/*{{{*/
  73 + $token_attrib = $token_type . "_token";
  74 + if ($consumer->key == $this->consumer->key
  75 + && $token == $this->$token_attrib->key) {
  76 + return $this->$token_attrib;
  77 + }
  78 + return NULL;
  79 + }/*}}}*/
  80 +
  81 + function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
  82 + if ($consumer->key == $this->consumer->key
  83 + && (($token && $token->key == $this->request_token->key)
  84 + || ($token && $token->key == $this->access_token->key))
  85 + && $nonce == $this->nonce) {
  86 + return $this->nonce;
  87 + }
  88 + return NULL;
  89 + }/*}}}*/
  90 +
  91 + function new_request_token($consumer) {/*{{{*/
  92 + if ($consumer->key == $this->consumer->key) {
  93 + return $this->request_token;
  94 + }
  95 + return NULL;
  96 + }/*}}}*/
  97 +
  98 + function new_access_token($token, $consumer) {/*{{{*/
  99 + if ($consumer->key == $this->consumer->key
  100 + && $token->key == $this->request_token->key) {
  101 + return $this->access_token;
  102 + }
  103 + return NULL;
  104 + }/*}}}*/
  105 +}/*}}}*/
  106 +?>
... ...
pacotes/linkedinoauth/doc/design.txt 0 → 100644
... ... @@ -0,0 +1,68 @@
  1 +Interfaces:
  2 +
  3 +# OAuthConsumer is a data type that represents the identity of the Consumer
  4 +# via its shared secret with the Service Provider.
  5 +OAuthConsumer
  6 + - key : str
  7 + - secret : str
  8 +
  9 +# OAuthToken is a data type that represents an End User via either an access
  10 +# or request token
  11 +OAuthToken
  12 + - token : str
  13 + - secret : str
  14 + - to_string() -> str
  15 + - (static) from_string() -> OAuthToken
  16 +
  17 +# OAuthSignatureMethod is a strategy class that implements a signature method
  18 +OAuthSignatureMethod
  19 + - get_name() -> str
  20 + - build_signature (OAuthRequest, OAuthConsumer, OAuthToken) -> str
  21 +
  22 +# OAuthRequest represents the request and can be seriali
  23 +OAuthRequest:
  24 + - OAuthRequest(str http_method, str http_url, [dict parameters]) -> constructor
  25 + - set_parameter(str parameter, str value) -> void
  26 + - example parameters: oauth_consumer_key, foo
  27 + - get_parameter(str parameter) -> str
  28 + - get_parameters() -> dict
  29 +
  30 + - get_normalized_http_method() -> str
  31 + - get_normalized_http_url() -> str
  32 + - get_signable_params() -> dict
  33 +
  34 + - to_header () -> str # serialize as a header for an HTTPAuth request
  35 + - to_postdata () -> str # serialize as post data for a POST request
  36 + - to_url () -> str # serialize as a url for a GET request
  37 + - sign_request(OAuthSignatureMethod, OAuthConsumer, OAuthToken) -> void
  38 + - build_signature(OAuthSignatureMethod, OAuthConsumer, OAuthToken) -> str
  39 + - (static) from_request([str http_method, str http_url, dict parameters])
  40 + - (static) from_consumer_and_token(OAuthConsumer, OAuthToken, str http_method, str http_url, [dict parameters]) -> OAuthRequest
  41 +
  42 +
  43 +# OAuthServer is a worker to check a requests validity against a data store
  44 +OAuthServer:
  45 + - OAuthServer(OAuthDataStore) -> constructor
  46 + - set_data_store(OAuthDataStore) -> void
  47 + - get_data_store() -> OAuthDataStore
  48 +
  49 + - fetch_request_token (OAuthRequest) -> OAuthToken
  50 + - fetch_access_token (OAuthRequest) -> OAuthToken
  51 + - verify_request (OAuthRequest) -> OAuthToken
  52 +
  53 +# OAuthClient is a worker to attempt to execute a request
  54 +OAuthClient:
  55 + - OAuthClient(OAuthConsumer, OAuthToken) -> constructor
  56 + - get_consumer() -> OAuthConsumer
  57 + - get_token() -> OAuthToken
  58 +
  59 + - fetch_request_token (OAuthRequest) -> OAuthToken
  60 + - fetch_access_token (OAuthRequest) -> OAuthToken
  61 +
  62 +# OAuthDataStore is a database abstraction used to lookup consumers and tokens
  63 +OAuthDataStore:
  64 + - lookup_consumer(str key) -> OAuthConsumer
  65 + - lookup_token(OAuthConsumer, str token_type, str token_token) -> OAuthToken
  66 + - lookup_nonce(OAuthConsumer, OAuthToken, str nonce, int timestamp) -> OAuthToken
  67 + - fetch_request_token(OAuthConsumer) -> OAuthToken
  68 + - fetch_access_token(OAuthConsumer, OAuthToken) -> OAuthToken
... ...
pacotes/linkedinoauth/example/SimpleOAuthDataStore.php 0 → 100644
... ... @@ -0,0 +1,74 @@
  1 +<?php
  2 +
  3 +/* A very naive dbm-based oauth storage
  4 + *
  5 + * NOTE: This is for reference ONLY,
  6 + * and contains, amongst others, a hole
  7 + * where you can get the token secret
  8 + * easily..
  9 + */
  10 +class SimpleOAuthDataStore extends OAuthDataStore {/*{{{*/
  11 + private $dbh;
  12 +
  13 + function __construct($path = "oauth.gdbm") {/*{{{*/
  14 + $this->dbh = dba_popen($path, 'c', 'gdbm');
  15 + }/*}}}*/
  16 +
  17 + function __destruct() {/*{{{*/
  18 + dba_close($this->dbh);
  19 + }/*}}}*/
  20 +
  21 + function lookup_consumer($consumer_key) {/*{{{*/
  22 + $rv = dba_fetch("consumer_$consumer_key", $this->dbh);
  23 + if ($rv === FALSE) {
  24 + return NULL;
  25 + }
  26 + $obj = unserialize($rv);
  27 + if (!($obj instanceof OAuthConsumer)) {
  28 + return NULL;
  29 + }
  30 + return $obj;
  31 + }/*}}}*/
  32 +
  33 + function lookup_token($consumer, $token_type, $token) {/*{{{*/
  34 + $rv = dba_fetch("${token_type}_${token}", $this->dbh);
  35 + if ($rv === FALSE) {
  36 + return NULL;
  37 + }
  38 + $obj = unserialize($rv);
  39 + if (!($obj instanceof OAuthToken)) {
  40 + return NULL;
  41 + }
  42 + return $obj;
  43 + }/*}}}*/
  44 +
  45 + function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
  46 + if (dba_exists("nonce_$nonce", $this->dbh)) {
  47 + return TRUE;
  48 + } else {
  49 + dba_insert("nonce_$nonce", "1", $this->dbh);
  50 + return FALSE;
  51 + }
  52 + }/*}}}*/
  53 +
  54 + function new_token($consumer, $type="request") {/*{{{*/
  55 + $key = md5(time());
  56 + $secret = time() + time();
  57 + $token = new OAuthToken($key, md5(md5($secret)));
  58 + if (!dba_insert("${type}_$key", serialize($token), $this->dbh)) {
  59 + throw new OAuthException("doooom!");
  60 + }
  61 + return $token;
  62 + }/*}}}*/
  63 +
  64 + function new_request_token($consumer) {/*{{{*/
  65 + return $this->new_token($consumer, "request");
  66 + }/*}}}*/
  67 +
  68 + function new_access_token($token, $consumer) {/*{{{*/
  69 +
  70 + $token = $this->new_token($consumer, 'access');
  71 + dba_delete("request_" . $token->key, $this->dbh);
  72 + return $token;
  73 + }/*}}}*/
  74 +}/*}}}*/
0 75 \ No newline at end of file
... ...
pacotes/linkedinoauth/example/access_token.php 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +<?php
  2 +require_once("common.inc.php");
  3 +
  4 +try {
  5 + $req = OAuthRequest::from_request();
  6 + $token = $test_server->fetch_access_token($req);
  7 + print $token;
  8 +} catch (OAuthException $e) {
  9 + print($e->getMessage() . "\n<hr />\n");
  10 + print_r($req);
  11 + die();
  12 +}
  13 +
  14 +?>
... ...
pacotes/linkedinoauth/example/client.php 0 → 100644
... ... @@ -0,0 +1,133 @@
  1 +<?php
  2 +require_once("common.inc.php");
  3 +
  4 +$key = @$_REQUEST['key'];
  5 +$secret = @$_REQUEST['secret'];
  6 +$token = @$_REQUEST['token'];
  7 +$token_secret = @$_REQUEST['token_secret'];
  8 +$endpoint = @$_REQUEST['endpoint'];
  9 +$action = @$_REQUEST['action'];
  10 +$dump_request = @$_REQUEST['dump_request'];
  11 +$user_sig_method = @$_REQUEST['sig_method'];
  12 +$sig_method = $hmac_method;
  13 +if ($user_sig_method) {
  14 + $sig_method = $sig_methods[$user_sig_method];
  15 +}
  16 +
  17 +$test_consumer = new OAuthConsumer($key, $secret, NULL);
  18 +
  19 +$test_token = NULL;
  20 +if ($token) {
  21 + $test_token = new OAuthConsumer($token, $token_secret);
  22 +}
  23 +
  24 +
  25 +if ($action == "request_token") {
  26 + $parsed = parse_url($endpoint);
  27 + $params = array();
  28 + parse_str($parsed['query'], $params);
  29 +
  30 + $req_req = OAuthRequest::from_consumer_and_token($test_consumer, NULL, "GET", $endpoint, $params);
  31 + $req_req->sign_request($sig_method, $test_consumer, NULL);
  32 + if ($dump_request) {
  33 + Header('Content-type: text/plain');
  34 + print "request url: " . $req_req->to_url(). "\n";
  35 + print_r($req_req);
  36 + exit;
  37 + }
  38 + Header("Location: $req_req");
  39 +}
  40 +else if ($action == "authorize") {
  41 + $callback_url = "$base_url/client.php?key=$key&secret=$secret&token=$token&token_secret=$token_secret&endpoint=" . urlencode($endpoint);
  42 + $auth_url = $endpoint . "?oauth_token=$token&oauth_callback=".urlencode($callback_url);
  43 + if ($dump_request) {
  44 + Header('Content-type: text/plain');
  45 + print("auth_url: " . $auth_url);
  46 + exit;
  47 + }
  48 + Header("Location: $auth_url");
  49 +}
  50 +else if ($action == "access_token") {
  51 + $parsed = parse_url($endpoint);
  52 + $params = array();
  53 + parse_str($parsed['query'], $params);
  54 +
  55 + $acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, "GET", $endpoint, $params);
  56 + $acc_req->sign_request($sig_method, $test_consumer, $test_token);
  57 + if ($dump_request) {
  58 + Header('Content-type: text/plain');
  59 + print "request url: " . $acc_req->to_url() . "\n";
  60 + print_r($acc_req);
  61 + exit;
  62 + }
  63 + Header("Location: $acc_req");
  64 +}
  65 +
  66 +?>
  67 +<html>
  68 +<head>
  69 +<title>OAuth Test Client</title>
  70 +</head>
  71 +<body>
  72 +<div><a href="index.php">server</a> | <a href="client.php">client</a></div>
  73 +<h1>OAuth Test Client</h1>
  74 +<h2>Instructions for Use</h2>
  75 +<p>This is a test client that will let you test your OAuth server code. Enter the appropriate information below to test.</p>
  76 +<p>Note: we don't store any of the information you type in.</p>
  77 +
  78 +<form method="POST" name="oauth_client">
  79 +<h3>Choose a Signature Method</h3>
  80 +<select name="sig_method">
  81 +<?php
  82 +foreach ($sig_methods as $name=> $method) {
  83 + $selected = "";
  84 + if ($name == $sig_method->get_name()) {
  85 + $selected = " selected='selected'";
  86 + }
  87 + print "<option value='$name'$selected>$name</option>\n";
  88 +}
  89 +?>
  90 +</select>
  91 +<h3>Enter The Endpoint to Test</h3>
  92 +endpoint: <input type="text" name="endpoint" value="<?php echo $endpoint; ?>" size="100"/><br />
  93 +<small style="color: green">Note: You can include query parameters in there to have them parsed in and signed too</small>
  94 +<h3>Enter Your Consumer Key / Secret</h3>
  95 +consumer key: <input type="text" name="key" value="<?php echo $key; ?>" /><br />
  96 +consumer secret: <input type="text" name="secret" value="<?php echo $secret;?>" /><br />
  97 +dump request, don't redirect: <input type="checkbox" name="dump_request" value="1" <?php if ($dump_request) echo 'checked="checked"'; ?>/><br />
  98 +make a token request (don't forget to copy down the values you get)
  99 +<input type="submit" name="action" value="request_token" />
  100 +<h3>Enter Your Request Token / Secret</h3>
  101 +token: <input type="text" name="token" value="<?php echo $token; ?>" /><br />
  102 +token secret: <input type="text" name="token_secret" value="<?php echo $token_secret; ?>" /><br />
  103 +<p><strong>Don't forget to update your endpoint to point at the auth or access token url</strong></p>
  104 +try to authorize this token: <input type="submit" name="action" value="authorize" /><br />
  105 +try to get an access token: <input type="submit" name="action" value="access_token" /><br />
  106 +
  107 +<h3>Currently Supported Signature Methods</h3>
  108 +<p>Current signing method is: <?php echo $sig_method->get_name() ?></p>
  109 +<ul>
  110 +<?php
  111 +foreach ($sig_methods as $key => $method) {
  112 +
  113 + print "<li>$key";
  114 + if ($key != $sig_method->get_name()) {
  115 + print "(<a href='?sig_method=$key'>switch</a>)";
  116 + }
  117 + print "</li>\n";
  118 +}
  119 +?>
  120 +</ul>
  121 +
  122 +<?php
  123 +if ("RSA-SHA1" == $sig_method->get_name()) {
  124 + // passing test_server as a dummy referecne
  125 + print "<pre>" . $sig_method->fetch_private_cert($test_server). "</pre>\n";
  126 + print "<pre>" . $sig_method->fetch_public_cert($test_server) . "</pre>\n";
  127 +}
  128 +?>
  129 +
  130 +<h3>Further Resources</h3>
  131 +<p>There is also a <a href="index.php">test server</a> implementation in here.</p>
  132 +<p>The code running this example can be downloaded from the PHP section of the OAuth google code project: <a href="http://code.google.com/p/oauth/">http://code.google.com/p/oauth/</a>
  133 +</body>
... ...
pacotes/linkedinoauth/example/common.inc.php 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +<?php
  2 +require_once("../OAuth.php");
  3 +require_once("../OAuth_TestServer.php");
  4 +
  5 +/*
  6 + * Config Section
  7 + */
  8 +$domain = $_SERVER['HTTP_HOST'];
  9 +$base = "/i3geo/pacotes/linkedinoauth/example";
  10 +
  11 +$base_url = "http://$domain$base";
  12 +
  13 +/**
  14 + * Some default objects
  15 + */
  16 +
  17 +$test_server = new TestOAuthServer(new MockOAuthDataStore());
  18 +$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
  19 +$plaintext_method = new OAuthSignatureMethod_PLAINTEXT();
  20 +$rsa_method = new TestOAuthSignatureMethod_RSA_SHA1();
  21 +
  22 +$test_server->add_signature_method($hmac_method);
  23 +$test_server->add_signature_method($plaintext_method);
  24 +$test_server->add_signature_method($rsa_method);
  25 +
  26 +$sig_methods = $test_server->get_signature_methods();
  27 +?>
... ...
pacotes/linkedinoauth/example/echo_api.php 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +<?php
  2 +require_once("common.inc.php");
  3 +
  4 +try {
  5 + $req = OAuthRequest::from_request();
  6 + list($consumer, $token) = $test_server->verify_request($req);
  7 +
  8 + // lsit back the non-OAuth params
  9 + $total = array();
  10 + foreach($req->get_parameters() as $k => $v) {
  11 + if (substr($k, 0, 5) == "oauth") continue;
  12 + $total[] = urlencode($k) . "=" . urlencode($v);
  13 + }
  14 + print implode("&", $total);
  15 +} catch (OAuthException $e) {
  16 + print($e->getMessage() . "\n<hr />\n");
  17 + print_r($req);
  18 + die();
  19 +}
  20 +
  21 +?>
... ...
pacotes/linkedinoauth/example/index.php 0 → 100644
... ... @@ -0,0 +1,108 @@
  1 +<?php
  2 +require_once("common.inc.php");
  3 +include_once("../../../ms_configura.php");
  4 +
  5 +$test_consumer = new OAuthConsumer($linkedinoauth["consumerkey"], $linkedinoauth["consumersecret"], NULL);
  6 +$req_token = new OAuthConsumer($linkedinoauth["consumerkey"], $linkedinoauth["consumersecret"], 1);
  7 +$acc_token = new OAuthConsumer($linkedinoauth["consumerkey"], $linkedinoauth["consumersecret"], 1);
  8 +
  9 +$sig_method = $hmac_method;
  10 +$user_sig_method = @$_GET['sig_method'];
  11 +if ($user_sig_method) {
  12 + $sig_method = $sig_methods[$user_sig_method];
  13 +}
  14 +
  15 +$req_req = OAuthRequest::from_consumer_and_token($test_consumer, NULL, "GET", $base_url . "/request_token.php");
  16 +$req_req->sign_request($sig_method, $test_consumer, NULL);
  17 +
  18 +$acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $req_token, "GET", $base_url . "/access_token.php");
  19 +$acc_req->sign_request($sig_method, $test_consumer, $req_token);
  20 +
  21 +$echo_req = OAuthRequest::from_consumer_and_token($test_consumer, $acc_token, "GET", $base_url . "/echo_api.php", array("method"=> "foo%20bar", "bar" => "baz"));
  22 +$echo_req->sign_request($sig_method, $test_consumer, $acc_token);
  23 +
  24 +?>
  25 +<html>
  26 +<head>
  27 +<title>OAuth Test Server</title>
  28 +</head>
  29 +<body>
  30 +<div><a href="index.php">server</a> | <a href="client.php">client</a></div>
  31 +<h1>OAuth Test Server</h1>
  32 +<h2>Instructions for Use</h2>
  33 +<p>This is a test server with a predefined static set of keys and tokens, you can make your requests using them to test your code (and mine ;)).</p>
  34 +<h3>Your Consumer Key / Secret</h3>
  35 +<ul>
  36 +<li>consumer key: <code><strong>key</strong></code></li>
  37 +<li>consumer secret: <code><strong>secret</strong></code></li>
  38 +</ul>
  39 +<p>Use this key and secret for all your requests.</p>
  40 +<h3>Getting a Request Token</h3>
  41 +
  42 +<ul>
  43 +<li>request token endpoint: <code><strong><?php echo $base_url . "/request_token.php"; ?></strong></code></li>
  44 +</ul>
  45 +
  46 +<p>A successful request will return the following:</p>
  47 +<p><code>oauth_token=requestkey&amp;oauth_token_secret=requestsecret</code></p>
  48 +
  49 +<p>An unsuccessful request will attempt to describe what went wrong.</p>
  50 +
  51 +<h4>Example</h4>
  52 +<a href="<?php echo $req_req; ?>"><?php echo $req_req; ?></a>
  53 +
  54 +<h3>Getting an Access Token</h3>
  55 +<p>The Request Token provided above is already authorized, you may use it to request an Access Token right away.</p>
  56 +
  57 +<ul>
  58 +<li>access token endpoint: <code><strong><?php echo $base_url . "/access_token.php"; ?></strong></code></li>
  59 +</ul>
  60 +
  61 +<p>A successful request will return the following:</p>
  62 +<p><code>oauth_token=accesskey&amp;oauth_token_secret=accesssecret</code></p>
  63 +
  64 +<p>An unsuccessful request will attempt to describe what went wrong.</p>
  65 +
  66 +<h4>Example</h4>
  67 +<a href="<?php echo $acc_req; ?>"><?php echo $acc_req; ?></a>
  68 +
  69 +<h3>Making Authenticated Calls</h3>
  70 +<p>Using your Access Token you can make authenticated calls.</p>
  71 +
  72 +<ul>
  73 +<li>api endpoint: <code><strong><?php echo $base_url . "/echo_api.php"; ?></strong></code></li>
  74 +</ul>
  75 +<p>
  76 +A successful request will echo the non-OAuth parameters sent to it, for example:</p>
  77 +<p><code>method=foo&amp;bar=baz</code></p>
  78 +<p>An unsuccessful request will attempt to describe what went wrong.</p>
  79 +
  80 +<h4>Example</h4>
  81 +<a href="<?php echo $echo_req; ?>"><?php echo $echo_req; ?></a>
  82 +
  83 +<h3>Currently Supported Signature Methods</h3>
  84 +<p>Current signing method is: <?php echo $user_sig_method ?></p>
  85 +<ul>
  86 +<?php
  87 +$sig_methods = $test_server->get_signature_methods();
  88 +foreach ($sig_methods as $key => $method) {
  89 + print "<li>$key";
  90 + if ($key != $sig_method->get_name()) {
  91 + print "(<a href='?sig_method=$key'>switch</a>)";
  92 + }
  93 + print "</li>\n";
  94 +}
  95 +?>
  96 +</ul>
  97 +
  98 +<?php
  99 +if ("RSA-SHA1" == $sig_method->get_name()) {
  100 + print "<pre>" . $sig_method->fetch_private_cert($req_req) . "</pre>\n";
  101 + print "<pre>" . $sig_method->fetch_public_cert($req_req) . "</pre>\n";
  102 +}
  103 +?>
  104 +
  105 +<h3>Further Resources</h3>
  106 +<p>There is also a <a href="client.php">test client</a> implementation in here.</p>
  107 +<p>The code running this example can be downloaded from the PHP section of the OAuth google code project: <a href="http://code.google.com/p/oauth/">http://code.google.com/p/oauth/</a>
  108 +</body>
... ...
pacotes/linkedinoauth/example/request_token.php 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +<?php
  2 +require_once("common.inc.php");
  3 +
  4 +try {
  5 + $req = OAuthRequest::from_request();
  6 + $token = $test_server->fetch_request_token($req);
  7 + print $token;
  8 +} catch (OAuthException $e) {
  9 + print($e->getMessage() . "\n<hr />\n");
  10 + print_r($req);
  11 + die();
  12 +}
  13 +
  14 +?>
... ...
pacotes/linkedinoauth/linkedin.php 0 → 100644
... ... @@ -0,0 +1,139 @@
  1 +<?php
  2 +require_once("OAuth.php");
  3 +
  4 +class LinkedIn {
  5 + public $base_url = "http://api.linkedin.com";
  6 + public $secure_base_url = "https://api.linkedin.com";
  7 + public $oauth_callback = "oob";
  8 + public $consumer;
  9 + public $request_token;
  10 + public $access_token;
  11 + public $oauth_verifier;
  12 + public $signature_method;
  13 + public $request_token_path;
  14 + public $access_token_path;
  15 + public $authorize_path;
  16 + public $debug = false;
  17 +
  18 + function __construct($consumer_key, $consumer_secret, $oauth_callback = NULL) {
  19 +
  20 + if($oauth_callback) {
  21 + $this->oauth_callback = $oauth_callback;
  22 + }
  23 +
  24 + $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret, $this->oauth_callback);
  25 + $this->signature_method = new OAuthSignatureMethod_HMAC_SHA1();
  26 + $this->request_token_path = $this->secure_base_url . "/uas/oauth/requestToken";
  27 + $this->access_token_path = $this->secure_base_url . "/uas/oauth/accessToken";
  28 + $this->authorize_path = $this->secure_base_url . "/uas/oauth/authorize";
  29 +
  30 + }
  31 +
  32 + function getRequestToken() {
  33 + $consumer = $this->consumer;
  34 + $request = OAuthRequest::from_consumer_and_token($consumer, NULL, "GET", $this->request_token_path);
  35 + $request->set_parameter("oauth_callback", $this->oauth_callback);
  36 + $request->sign_request($this->signature_method, $consumer, NULL);
  37 + $headers = Array();
  38 + $url = $request->to_url();
  39 + $response = $this->httpRequest($url, $headers, "GET");
  40 + parse_str($response, $response_params);
  41 + $this->request_token = new OAuthConsumer($response_params['oauth_token'], $response_params['oauth_token_secret'], 1);
  42 + }
  43 +
  44 + function generateAuthorizeUrl() {
  45 + $consumer = $this->consumer;
  46 + $request_token = $this->request_token;
  47 + return $this->authorize_path . "?oauth_token=" . $request_token->key;
  48 + }
  49 +
  50 + function getAccessToken($oauth_verifier) {
  51 + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->request_token, "GET", $this->access_token_path);
  52 + $request->set_parameter("oauth_verifier", $oauth_verifier);
  53 + $request->sign_request($this->signature_method, $this->consumer, $this->request_token);
  54 + $headers = Array();
  55 + $url = $request->to_url();
  56 + $response = $this->httpRequest($url, $headers, "GET");
  57 + parse_str($response, $response_params);
  58 + if($debug) {
  59 + echo $response . "\n";
  60 + }
  61 + $this->access_token = new OAuthConsumer($response_params['oauth_token'], $response_params['oauth_token_secret'], 1);
  62 + }
  63 +
  64 + function getProfile($resource = "~") {
  65 + $profile_url = $this->base_url . "/v1/people/" . $resource;
  66 + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->access_token, "GET", $profile_url);
  67 + $request->sign_request($this->signature_method, $this->consumer, $this->access_token);
  68 + $auth_header = $request->to_header("https://api.linkedin.com"); # this is the realm
  69 + # This PHP library doesn't generate the header correctly when a realm is not specified.
  70 + # Make sure there is a space and not a comma after OAuth
  71 + // $auth_header = preg_replace("/Authorization\: OAuth\,/", "Authorization: OAuth ", $auth_header);
  72 + // # Make sure there is a space between OAuth attribute
  73 + // $auth_header = preg_replace('/\"\,/', '", ', $auth_header);
  74 + if ($debug) {
  75 + echo $auth_header;
  76 + }
  77 + // $response will now hold the XML document
  78 + $response = $this->httpRequest($profile_url, $auth_header, "GET");
  79 + return $response;
  80 + }
  81 +
  82 + function setStatus($status) {
  83 + $status_url = $this->base_url . "/v1/people/~/current-status";
  84 + echo "Setting status...\n";
  85 + $xml = "<current-status>" . htmlspecialchars($status, ENT_NOQUOTES, "UTF-8") . "</current-status>";
  86 + echo $xml . "\n";
  87 + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->access_token, "PUT", $status_url);
  88 + $request->sign_request($this->signature_method, $this->consumer, $this->access_token);
  89 + $auth_header = $request->to_header("https://api.linkedin.com");
  90 + if ($debug) {
  91 + echo $auth_header . "\n";
  92 + }
  93 + $response = $this->httpRequest($profile_url, $auth_header, "GET");
  94 + return $response;
  95 + }
  96 +
  97 + # Parameters should be a query string starting with "?"
  98 + # Example search("?count=10&start=10&company=LinkedIn");
  99 + function search($parameters) {
  100 + $search_url = $this->base_url . "/v1/people/" . $parameters;
  101 + echo "Performing search for: " . $parameters . "\n";
  102 + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->access_token, "GET", $search_url);
  103 + $request->sign_request($this->signature_method, $this->consumer, $this->access_token);
  104 + $auth_header = $request->to_header("https://api.linkedin.com");
  105 + if ($debug) {
  106 + echo $request->get_signature_base_string() . "\n";
  107 + echo $auth_header . "\n";
  108 + }
  109 + $response = $this->httpRequest($search_url, $auth_header, "GET");
  110 + return $response;
  111 + }
  112 +
  113 + function httpRequest($url, $auth_header, $method, $body = NULL) {
  114 + if (!$method) {
  115 + $method = "GET";
  116 + };
  117 +
  118 + $curl = curl_init();
  119 + curl_setopt($curl, CURLOPT_URL, $url);
  120 + curl_setopt($curl, CURLOPT_HEADER, 0);
  121 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  122 + curl_setopt($curl, CURLOPT_HTTPHEADER, array($auth_header)); // Set the headers.
  123 +
  124 + if ($body) {
  125 + curl_setopt($curl, CURLOPT_POST, 1);
  126 + curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
  127 + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
  128 + curl_setopt($curl, CURLOPT_HTTPHEADER, array($auth_header, "Content-Type: text/xml;charset=utf-8"));
  129 + }
  130 +
  131 + $data = curl_exec($curl);
  132 + if ($this->debug) {
  133 + echo $data . "\n";
  134 + }
  135 + curl_close($curl);
  136 + return $data;
  137 + }
  138 +
  139 +}
... ...
pacotes/linkedinoauth/testLinkedinOauth.php 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +<?php
  2 +require_once 'linkedin.php';
  3 +include_once("../../ms_configura.php");
  4 +$consumer_key = $linkedinoauth["consumerkey"];
  5 +$consumer_secret = $linkedinoauth["consumersecret"];
  6 +echo "<pre>";
  7 +# First step is to initialize with your consumer key and secret. We'll use an out-of-band oauth_callback
  8 +$linkedin = new LinkedIn($consumer_key, $consumer_secret, "oob");
  9 +$linkedin->debug = true;
  10 +
  11 +# Now we retrieve a request token. It will be set as $linkedin->request_token
  12 +$linkedin->getRequestToken();
  13 +
  14 +# With a request token in hand, we can generate an authorization URL, which we'll direct the user to
  15 +echo "Authorization URL: " . $linkedin->generateAuthorizeUrl() . "\n\n";
  16 +
  17 +# After logging in, the user will be presented with an OAuth Verifier, which you would then ask the member to enter in a UI you present. Once you have the OAuth verifier, set it here:
  18 +
  19 +echo "Enter OAuth Verifier:\n";
  20 +$handle = fopen("php://stdin", "r");
  21 +$oauth_verifier = trim(fgets($handle));
  22 +
  23 +$linkedin->getAccessToken($oauth_verifier);
  24 +
  25 +# You now have a $linkedin->access_token and can make calls on behalf of the current member
  26 +$xml_response = $linkedin->getProfile("~:(id,first-name,last-name,headline,picture-url)");
  27 +
  28 +echo $xml_response;
  29 +
  30 +# Let's set our status
  31 +
  32 +$xml_response2 = $linkedin->setStatus("setting my status using the LinkedIn API.");
  33 +echo $xml_response2;
  34 +
  35 +# Let's do a search!
  36 +$search_response = $linkedin->search("?company=Google&count=10");
  37 +echo $search_response;
  38 +
  39 +?>
... ...
pacotes/linkedinoauth/testWithAcessToken.php 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +<?php
  2 +require_once 'linkedin.php';
  3 +
  4 +# Use this to used already retrieved access token credentials for testing.
  5 +
  6 +$consumer_key = "";
  7 +$consumer_secret = "";
  8 +$access_token = "";
  9 +$access_token_secret = "";
  10 +
  11 +# First step is to initialize with your consumer key and secret. We'll use an out-of-band oauth_callback
  12 +$linkedin = new LinkedIn($consumer_key, $consumer_secret, "oob");
  13 +$linkedin->debug = true;
  14 +
  15 +$linkedin->access_token = new OAuthConsumer($access_token, $access_token_secret, 1);
  16 +
  17 +# Let's do a search!
  18 +$search_response = $linkedin->search("?company=Google&count=10");
  19 +
  20 +echo $search_response;
  21 +
  22 +?>
... ...
pacotes/linkedinoauth/tests/Mock_OAuthBaseStringRequest.php 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<?php
  2 +
  3 +/**
  4 + * A very simple class that you can pass a base-string, and then have it returned again.
  5 + * Used for testing the signature-methods
  6 + */
  7 +class Mock_OAuthBaseStringRequest {
  8 + private $provided_base_string;
  9 + public $base_string; // legacy
  10 + public function __construct($bs) { $this->provided_base_string = $bs; }
  11 + public function get_signature_base_string() { return $this->provided_base_string; }
  12 +}
... ...
pacotes/linkedinoauth/tests/Mock_OAuthDataStore.php 0 → 100644
... ... @@ -0,0 +1,57 @@
  1 +<?php
  2 +
  3 +/**
  4 + * A mock store for testing
  5 + */
  6 +class Mock_OAuthDataStore extends OAuthDataStore {
  7 + private $consumer;
  8 + private $request_token;
  9 + private $access_token;
  10 + private $nonce;
  11 +
  12 + function __construct() {
  13 + $this->consumer = new OAuthConsumer("key", "secret", NULL);
  14 + $this->request_token = new OAuthToken("requestkey", "requestsecret", 1);
  15 + $this->access_token = new OAuthToken("accesskey", "accesssecret", 1);
  16 + $this->nonce = "nonce";
  17 + }
  18 +
  19 + function lookup_consumer($consumer_key) {
  20 + if ($consumer_key == $this->consumer->key) return $this->consumer;
  21 + return NULL;
  22 + }
  23 +
  24 + function lookup_token($consumer, $token_type, $token) {
  25 + $token_attrib = $token_type . "_token";
  26 + if ($consumer->key == $this->consumer->key
  27 + && $token == $this->$token_attrib->key) {
  28 + return $this->$token_attrib;
  29 + }
  30 + return NULL;
  31 + }
  32 +
  33 + function lookup_nonce($consumer, $token, $nonce, $timestamp) {
  34 + if ($consumer->key == $this->consumer->key
  35 + && (($token && $token->key == $this->request_token->key)
  36 + || ($token && $token->key == $this->access_token->key))
  37 + && $nonce == $this->nonce) {
  38 + return $this->nonce;
  39 + }
  40 + return NULL;
  41 + }
  42 +
  43 + function new_request_token($consumer) {
  44 + if ($consumer->key == $this->consumer->key) {
  45 + return $this->request_token;
  46 + }
  47 + return NULL;
  48 + }
  49 +
  50 + function new_access_token($token, $consumer) {
  51 + if ($consumer->key == $this->consumer->key
  52 + && $token->key == $this->request_token->key) {
  53 + return $this->access_token;
  54 + }
  55 + return NULL;
  56 + }
  57 +}
0 58 \ No newline at end of file
... ...
pacotes/linkedinoauth/tests/Mock_OAuthSignatureMethod_RSA_SHA1.php 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +<?php
  2 +
  3 +/**
  4 + * A mock implementation of OAuthSignatureMethod_RSA_SHA1
  5 + * Always returns the signatures described in
  6 + * http://wiki.oauth.net/TestCases section 9.3 ("RSA-SHA1")
  7 + */
  8 +class Mock_OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod_RSA_SHA1 {
  9 + public function fetch_private_cert(&$request) {
  10 + $cert = <<<EOD
  11 +-----BEGIN PRIVATE KEY-----
  12 +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
  13 +A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
  14 +7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
  15 +hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
  16 +X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
  17 +uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
  18 +rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
  19 +zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
  20 +qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
  21 +WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
  22 +cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
  23 +3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
  24 +AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
  25 +Lw03eHTNQghS0A==
  26 +-----END PRIVATE KEY-----
  27 +EOD;
  28 + return $cert;
  29 + }
  30 +
  31 + public function fetch_public_cert(&$request) {
  32 + $cert = <<<EOD
  33 +-----BEGIN CERTIFICATE-----
  34 +MIIBpjCCAQ+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAZMRcwFQYDVQQDDA5UZXN0
  35 +IFByaW5jaXBhbDAeFw03MDAxMDEwODAwMDBaFw0zODEyMzEwODAwMDBaMBkxFzAV
  36 +BgNVBAMMDlRlc3QgUHJpbmNpcGFsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
  37 +gQC0YjCwIfYoprq/FQO6lb3asXrxLlJFuCvtinTF5p0GxvQGu5O3gYytUvtC2JlY
  38 +zypSRjVxwxrsuRcP3e641SdASwfrmzyvIgP08N4S0IFzEURkV1wp/IpH7kH41Etb
  39 +mUmrXSwfNZsnQRE5SYSOhh+LcK2wyQkdgcMv11l4KoBkcwIDAQABMA0GCSqGSIb3
  40 +DQEBBQUAA4GBAGZLPEuJ5SiJ2ryq+CmEGOXfvlTtEL2nuGtr9PewxkgnOjZpUy+d
  41 +4TvuXJbNQc8f4AMWL/tO9w0Fk80rWKp9ea8/df4qMq5qlFWlx6yOLQxumNOmECKb
  42 +WpkUQDIDJEoFUzKMVuJf4KO/FJ345+BNLGgbJ6WujreoM1X/gYfdnJ/J
  43 +-----END CERTIFICATE-----
  44 +EOD;
  45 + return $cert;
  46 + }
  47 +}
0 48 \ No newline at end of file
... ...
pacotes/linkedinoauth/tests/OAuthConsumerTest.php 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +<?php
  2 +
  3 +require 'common.php';
  4 +
  5 +class OAuthConsumerTest extends PHPUnit_Framework_TestCase {
  6 + public function testConvertToString() {
  7 + $consumer = new OAuthConsumer('key', 'secret');
  8 + $this->assertEquals('OAuthConsumer[key=key,secret=secret]', (string) $consumer);
  9 + }
  10 +}
0 11 \ No newline at end of file
... ...
pacotes/linkedinoauth/tests/OAuthRequestTest.php 0 → 100644
... ... @@ -0,0 +1,317 @@
  1 +<?php
  2 +
  3 +/*
  4 + * Tests of OAuthRequest
  5 + *
  6 + * The tests works by using OAuthTestUtils::build_request
  7 + * to populare $_SERVER, $_GET & $_POST.
  8 + *
  9 + * Most of the base string and signature tests
  10 + * are either very simple or based upon
  11 + * http://wiki.oauth.net/TestCases
  12 + */
  13 +
  14 +require_once dirname(__FILE__) . '/common.php';
  15 +
  16 +class OAuthRequestTest extends PHPUnit_Framework_TestCase {
  17 + public function testCanGetSingleParameter() {
  18 + // Yes, a awesomely boring test.. But if this doesn't work, the other tests is unreliable
  19 + $request = new OAuthRequest('', '', array('test'=>'foo'));
  20 + $this->assertEquals( 'foo', $request->get_parameter('test'), 'Failed to read back parameter');
  21 +
  22 + $request = new OAuthRequest('', '', array('test'=>array('foo', 'bar')));
  23 + $this->assertEquals( array('foo', 'bar'), $request->get_parameter('test'), 'Failed to read back parameter');
  24 +
  25 +
  26 + $request = new OAuthRequest('', '', array('test'=>'foo', 'bar'=>'baz'));
  27 + $this->assertEquals( 'foo', $request->get_parameter('test'), 'Failed to read back parameter');
  28 + $this->assertEquals( 'baz', $request->get_parameter('bar'), 'Failed to read back parameter');
  29 + }
  30 +
  31 + public function testGetAllParameters() {
  32 + // Yes, a awesomely boring test.. But if this doesn't work, the other tests is unreliable
  33 + $request = new OAuthRequest('', '', array('test'=>'foo'));
  34 + $this->assertEquals( array('test'=>'foo'), $request->get_parameters(), 'Failed to read back parameters');
  35 +
  36 + $request = new OAuthRequest('', '', array('test'=>'foo', 'bar'=>'baz'));
  37 + $this->assertEquals( array('test'=>'foo', 'bar'=>'baz'), $request->get_parameters(), 'Failed to read back parameters');
  38 +
  39 + $request = new OAuthRequest('', '', array('test'=>array('foo', 'bar')));
  40 + $this->assertEquals( array('test'=>array('foo', 'bar')), $request->get_parameters(), 'Failed to read back parameters');
  41 + }
  42 +
  43 + public function testSetParameters() {
  44 + $request = new OAuthRequest('', '');
  45 + $this->assertEquals( NULL, $request->get_parameter('test'), 'Failed to assert that non-existing parameter is NULL');
  46 +
  47 + $request->set_parameter('test', 'foo');
  48 + $this->assertEquals( 'foo', $request->get_parameter('test'), 'Failed to set single-entry parameter');
  49 +
  50 + $request->set_parameter('test', 'bar');
  51 + $this->assertEquals( array('foo', 'bar'), $request->get_parameter('test'), 'Failed to set single-entry parameter');
  52 +
  53 + $request->set_parameter('test', 'bar', false);
  54 + $this->assertEquals( 'bar', $request->get_parameter('test'), 'Failed to set single-entry parameter');
  55 + }
  56 +
  57 + public function testUnsetParameter() {
  58 + $request = new OAuthRequest('', '');
  59 + $this->assertEquals( NULL, $request->get_parameter('test'));
  60 +
  61 + $request->set_parameter('test', 'foo');
  62 + $this->assertEquals( 'foo', $request->get_parameter('test'));
  63 +
  64 + $request->unset_parameter('test');
  65 + $this->assertEquals( NULL, $request->get_parameter('test'), 'Failed to unset parameter');
  66 + }
  67 +
  68 + public function testCreateRequestFromConsumerAndToken() {
  69 + $cons = new OAuthConsumer('key', 'kd94hf93k423kf44');
  70 + $token = new OAuthToken('token', 'pfkkdhi9sl3r4s00');
  71 +
  72 + $request = OAuthRequest::from_consumer_and_token($cons, $token, 'POST', 'http://example.com');
  73 + $this->assertEquals('POST', $request->get_normalized_http_method());
  74 + $this->assertEquals('http://example.com', $request->get_normalized_http_url());
  75 + $this->assertEquals('1.0', $request->get_parameter('oauth_version'));
  76 + $this->assertEquals($cons->key, $request->get_parameter('oauth_consumer_key'));
  77 + $this->assertEquals($token->key, $request->get_parameter('oauth_token'));
  78 + $this->assertEquals(time(), $request->get_parameter('oauth_timestamp'));
  79 + $this->assertRegExp('/[0-9a-f]{32}/', $request->get_parameter('oauth_nonce'));
  80 + // We don't know what the nonce will be, except it'll be md5 and hence 32 hexa digits
  81 +
  82 + $request = OAuthRequest::from_consumer_and_token($cons, $token, 'POST', 'http://example.com', array('oauth_nonce'=>'foo'));
  83 + $this->assertEquals('foo', $request->get_parameter('oauth_nonce'));
  84 +
  85 + $request = OAuthRequest::from_consumer_and_token($cons, NULL, 'POST', 'http://example.com', array('oauth_nonce'=>'foo'));
  86 + $this->assertNull($request->get_parameter('oauth_token'));
  87 +
  88 + // Test that parameters given in the $http_url instead of in the $parameters-parameter
  89 + // will still be picked up
  90 + $request = OAuthRequest::from_consumer_and_token($cons, $token, 'POST', 'http://example.com/?foo=bar');
  91 + $this->assertEquals('http://example.com/', $request->get_normalized_http_url());
  92 + $this->assertEquals('bar', $request->get_parameter('foo'));
  93 + }
  94 +
  95 + public function testBuildRequestFromPost() {
  96 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'foo=bar&baz=blargh');
  97 + $this->assertEquals(array('foo'=>'bar','baz'=>'blargh'), OAuthRequest::from_request()->get_parameters(), 'Failed to parse POST parameters');
  98 + }
  99 +
  100 + public function testBuildRequestFromGet() {
  101 + OAuthTestUtils::build_request('GET', 'http://testbed/test?foo=bar&baz=blargh');
  102 + $this->assertEquals(array('foo'=>'bar','baz'=>'blargh'), OAuthRequest::from_request()->get_parameters(), 'Failed to parse GET parameters');
  103 + }
  104 +
  105 + public function testBuildRequestFromHeader() {
  106 + $test_header = 'OAuth realm="",oauth_foo=bar,oauth_baz="bla,rgh"';
  107 + OAuthTestUtils::build_request('POST', 'http://testbed/test', '', $test_header);
  108 + $this->assertEquals(array('oauth_foo'=>'bar','oauth_baz'=>'bla,rgh'), OAuthRequest::from_request()->get_parameters(), 'Failed to split auth-header correctly');
  109 + }
  110 +
  111 + public function testHasProperParameterPriority() {
  112 + $test_header = 'OAuth realm="",oauth_foo=header';
  113 + OAuthTestUtils::build_request('POST', 'http://testbed/test?oauth_foo=get', 'oauth_foo=post', $test_header);
  114 + $this->assertEquals('header', OAuthRequest::from_request()->get_parameter('oauth_foo'), 'Loaded parameters in with the wrong priorities');
  115 +
  116 + OAuthTestUtils::build_request('POST', 'http://testbed/test?oauth_foo=get', 'oauth_foo=post');
  117 + $this->assertEquals('post', OAuthRequest::from_request()->get_parameter('oauth_foo'), 'Loaded parameters in with the wrong priorities');
  118 +
  119 + OAuthTestUtils::build_request('POST', 'http://testbed/test?oauth_foo=get');
  120 + $this->assertEquals('get', OAuthRequest::from_request()->get_parameter('oauth_foo'), 'Loaded parameters in with the wrong priorities');
  121 + }
  122 +
  123 + public function testNormalizeHttpMethod() {
  124 + OAuthTestUtils::build_request('POST', 'http://testbed/test');
  125 + $this->assertEquals('POST', OAuthRequest::from_request()->get_normalized_http_method(), 'Failed to normalize HTTP method: POST');
  126 +
  127 + OAuthTestUtils::build_request('post', 'http://testbed/test');
  128 + $this->assertEquals('POST', OAuthRequest::from_request()->get_normalized_http_method(), 'Failed to normalize HTTP method: post');
  129 +
  130 + OAuthTestUtils::build_request('GET', 'http://testbed/test');
  131 + $this->assertEquals('GET', OAuthRequest::from_request()->get_normalized_http_method(), 'Failed to normalize HTTP method: GET');
  132 +
  133 + OAuthTestUtils::build_request('PUT', 'http://testbed/test');
  134 + $this->assertEquals('PUT', OAuthRequest::from_request()->get_normalized_http_method(), 'Failed to normalize HTTP method: PUT');
  135 + }
  136 +
  137 + public function testNormalizeParameters() {
  138 + // This is mostly repeats of OAuthUtilTest::testParseParameters & OAuthUtilTest::TestBuildHttpQuery
  139 +
  140 + // Tests taken from
  141 + // http://wiki.oauth.net/TestCases ("Normalize Request Parameters")
  142 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'name');
  143 + $this->assertEquals( 'name=', OAuthRequest::from_request()->get_signable_parameters());
  144 +
  145 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'a=b');
  146 + $this->assertEquals( 'a=b', OAuthRequest::from_request()->get_signable_parameters());
  147 +
  148 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'a=b&c=d');
  149 + $this->assertEquals( 'a=b&c=d', OAuthRequest::from_request()->get_signable_parameters());
  150 +
  151 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'a=x%21y&a=x+y');
  152 + $this->assertEquals( 'a=x%20y&a=x%21y', OAuthRequest::from_request()->get_signable_parameters());
  153 +
  154 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'x%21y=a&x=a');
  155 + $this->assertEquals( 'x=a&x%21y=a', OAuthRequest::from_request()->get_signable_parameters());
  156 +
  157 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'a=1&c=hi there&f=25&f=50&f=a&z=p&z=t');
  158 + $this->assertEquals( 'a=1&c=hi%20there&f=25&f=50&f=a&z=p&z=t', OAuthRequest::from_request()->get_signable_parameters());
  159 + }
  160 +
  161 + public function testNormalizeHttpUrl() {
  162 + OAuthTestUtils::build_request('POST', 'http://example.com');
  163 + $this->assertEquals('http://example.com', OAuthRequest::from_request()->get_normalized_http_url());
  164 +
  165 + OAuthTestUtils::build_request('POST', 'https://example.com');
  166 + $this->assertEquals('https://example.com', OAuthRequest::from_request()->get_normalized_http_url());
  167 +
  168 + // Tests that http on !80 and https on !443 keeps the port
  169 + OAuthTestUtils::build_request('POST', 'http://example.com:8080');
  170 + $this->assertEquals('http://example.com:8080', OAuthRequest::from_request()->get_normalized_http_url());
  171 +
  172 + OAuthTestUtils::build_request('POST', 'https://example.com:80');
  173 + $this->assertEquals('https://example.com:80', OAuthRequest::from_request()->get_normalized_http_url());
  174 +
  175 + OAuthTestUtils::build_request('POST', 'http://example.com:443');
  176 + $this->assertEquals('http://example.com:443', OAuthRequest::from_request()->get_normalized_http_url());
  177 + }
  178 +
  179 + public function testBuildPostData() {
  180 + OAuthTestUtils::build_request('POST', 'http://example.com');
  181 + $this->assertEquals('', OAuthRequest::from_request()->to_postdata());
  182 +
  183 + OAuthTestUtils::build_request('POST', 'http://example.com', 'foo=bar');
  184 + $this->assertEquals('foo=bar', OAuthRequest::from_request()->to_postdata());
  185 +
  186 + OAuthTestUtils::build_request('GET', 'http://example.com?foo=bar');
  187 + $this->assertEquals('foo=bar', OAuthRequest::from_request()->to_postdata());
  188 + }
  189 +
  190 + public function testBuildUrl() {
  191 + OAuthTestUtils::build_request('POST', 'http://example.com');
  192 + $this->assertEquals('http://example.com', OAuthRequest::from_request()->to_url());
  193 +
  194 + OAuthTestUtils::build_request('POST', 'http://example.com', 'foo=bar');
  195 + $this->assertEquals('http://example.com?foo=bar', OAuthRequest::from_request()->to_url());
  196 +
  197 + OAuthTestUtils::build_request('GET', 'http://example.com?foo=bar');
  198 + $this->assertEquals('http://example.com?foo=bar', OAuthRequest::from_request()->to_url());
  199 + }
  200 +
  201 + public function testConvertToString() {
  202 + OAuthTestUtils::build_request('POST', 'http://example.com');
  203 + $this->assertEquals('http://example.com', (string) OAuthRequest::from_request());
  204 +
  205 + OAuthTestUtils::build_request('POST', 'http://example.com', 'foo=bar');
  206 + $this->assertEquals('http://example.com?foo=bar', (string) OAuthRequest::from_request());
  207 +
  208 + OAuthTestUtils::build_request('GET', 'http://example.com?foo=bar');
  209 + $this->assertEquals('http://example.com?foo=bar', (string) OAuthRequest::from_request());
  210 + }
  211 +
  212 + public function testBuildHeader() {
  213 + OAuthTestUtils::build_request('POST', 'http://example.com');
  214 + $this->assertEquals('Authorization: OAuth', OAuthRequest::from_request()->to_header());
  215 + $this->assertEquals('Authorization: OAuth realm="test"', OAuthRequest::from_request()->to_header('test'));
  216 +
  217 + OAuthTestUtils::build_request('POST', 'http://example.com', 'foo=bar');
  218 + $this->assertEquals('Authorization: OAuth', OAuthRequest::from_request()->to_header());
  219 + $this->assertEquals('Authorization: OAuth realm="test"', OAuthRequest::from_request()->to_header('test'));
  220 +
  221 + // Is headers supposted to be Urlencoded. More to the point:
  222 + // Should it be baz = bla,rgh or baz = bla%2Crgh ??
  223 + // - morten.fangel
  224 + OAuthTestUtils::build_request('POST', 'http://example.com', '', 'OAuth realm="",oauth_foo=bar,oauth_baz="bla,rgh"');
  225 + $this->assertEquals('Authorization: OAuth,oauth_foo="bar",oauth_baz="bla%2Crgh"', OAuthRequest::from_request()->to_header());
  226 + $this->assertEquals('Authorization: OAuth realm="test",oauth_foo="bar",oauth_baz="bla%2Crgh"', OAuthRequest::from_request()->to_header('test'));
  227 + }
  228 +
  229 + public function testWontBuildHeaderWithArrayInput() {
  230 + $this->setExpectedException('OAuthException');
  231 + OAuthTestUtils::build_request('POST', 'http://example.com', 'oauth_foo=bar&oauth_foo=baz');
  232 + OAuthRequest::from_request()->to_header();
  233 + }
  234 +
  235 + public function testBuildBaseString() {
  236 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'n=v');
  237 + $this->assertEquals('POST&http%3A%2F%2Ftestbed%2Ftest&n%3Dv', OAuthRequest::from_request()->get_signature_base_string());
  238 +
  239 + OAuthTestUtils::build_request('POST', 'http://testbed/test', 'n=v&n=v2');
  240 + $this->assertEquals('POST&http%3A%2F%2Ftestbed%2Ftest&n%3Dv%26n%3Dv2', OAuthRequest::from_request()->get_signature_base_string());
  241 +
  242 + OAuthTestUtils::build_request('GET', 'http://example.com?n=v');
  243 + $this->assertEquals('GET&http%3A%2F%2Fexample.com&n%3Dv', OAuthRequest::from_request()->get_signature_base_string());
  244 +
  245 + $params = 'oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_timestamp=1191242090';
  246 + $params .= '&oauth_nonce=hsu94j3884jdopsl&oauth_signature_method=PLAINTEXT&oauth_signature=ignored';
  247 + OAuthTestUtils::build_request('POST', 'https://photos.example.net/request_token', $params);
  248 + $this->assertEquals('POST&https%3A%2F%2Fphotos.example.net%2Frequest_token&oauth_'
  249 + .'consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dhsu94j3884j'
  250 + .'dopsl%26oauth_signature_method%3DPLAINTEXT%26oauth_timestam'
  251 + .'p%3D1191242090%26oauth_version%3D1.0',
  252 + OAuthRequest::from_request()->get_signature_base_string());
  253 +
  254 + $params = 'file=vacation.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03';
  255 + $params .= '&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1191242096&oauth_nonce=kllo9940pd9333jh';
  256 + $params .= '&oauth_signature=ignored&oauth_signature_method=HMAC-SHA1';
  257 + OAuthTestUtils::build_request('GET', 'http://photos.example.net/photos?'.$params);
  258 + $this->assertEquals('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation'
  259 + .'.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%'
  260 + .'3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26o'
  261 + .'auth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jd'
  262 + .'k%26oauth_version%3D1.0%26size%3Doriginal',
  263 + OAuthRequest::from_request()->get_signature_base_string());
  264 + }
  265 +
  266 + public function testBuildSignature() {
  267 + $params = 'file=vacation.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03';
  268 + $params .= '&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1191242096&oauth_nonce=kllo9940pd9333jh';
  269 + $params .= '&oauth_signature=ignored&oauth_signature_method=HMAC-SHA1';
  270 + OAuthTestUtils::build_request('GET', 'http://photos.example.net/photos?'.$params);
  271 + $r = OAuthRequest::from_request();
  272 +
  273 + $cons = new OAuthConsumer('key', 'kd94hf93k423kf44');
  274 + $token = new OAuthToken('token', 'pfkkdhi9sl3r4s00');
  275 +
  276 + $hmac = new OAuthSignatureMethod_HMAC_SHA1();
  277 + $plaintext = new OAuthSignatureMethod_PLAINTEXT();
  278 +
  279 + $this->assertEquals('tR3+Ty81lMeYAr/Fid0kMTYa/WM=', $r->build_signature($hmac, $cons, $token));
  280 + $this->assertEquals('kd94hf93k423kf44&pfkkdhi9sl3r4s00', $r->build_signature($plaintext, $cons, $token));
  281 + }
  282 +
  283 + public function testSign() {
  284 + $params = 'file=vacation.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03';
  285 + $params .= '&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1191242096&oauth_nonce=kllo9940pd9333jh';
  286 + $params .= '&oauth_signature=__ignored__&oauth_signature_method=HMAC-SHA1';
  287 + OAuthTestUtils::build_request('GET', 'http://photos.example.net/photos?'.$params);
  288 + $r = OAuthRequest::from_request();
  289 +
  290 + $cons = new OAuthConsumer('key', 'kd94hf93k423kf44');
  291 + $token = new OAuthToken('token', 'pfkkdhi9sl3r4s00');
  292 +
  293 + $hmac = new OAuthSignatureMethod_HMAC_SHA1();
  294 + $plaintext = new OAuthSignatureMethod_PLAINTEXT();
  295 +
  296 + // We need to test both what the parameter is, and how the serialized request is..
  297 +
  298 + $r->sign_request($hmac, $cons, $token);
  299 + $this->assertEquals('HMAC-SHA1', $r->get_parameter('oauth_signature_method'));
  300 + $this->assertEquals('tR3+Ty81lMeYAr/Fid0kMTYa/WM=', $r->get_parameter('oauth_signature'));
  301 + $expectedPostdata = 'file=vacation.jpg&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=kllo9940pd9333jh&'
  302 + . 'oauth_signature=tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D&oauth_signature_method=HMAC-SHA1&'
  303 + . 'oauth_timestamp=1191242096&oauth_token=nnch734d00sl2jdk&oauth_version=1.0&size=original';
  304 + $this->assertEquals( $expectedPostdata, $r->to_postdata());
  305 +
  306 + $r->sign_request($plaintext, $cons, $token);
  307 + $this->assertEquals('PLAINTEXT', $r->get_parameter('oauth_signature_method'));
  308 + $this->assertEquals('kd94hf93k423kf44&pfkkdhi9sl3r4s00', $r->get_parameter('oauth_signature'));
  309 + $expectedPostdata = 'file=vacation.jpg&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=kllo9940pd9333jh&'
  310 + . 'oauth_signature=kd94hf93k423kf44%26pfkkdhi9sl3r4s00&oauth_signature_method=PLAINTEXT&'
  311 + . 'oauth_timestamp=1191242096&oauth_token=nnch734d00sl2jdk&oauth_version=1.0&size=original';
  312 + $this->assertEquals( $expectedPostdata, $r->to_postdata());
  313 +
  314 + }
  315 +}
  316 +
  317 +?>
0 318 \ No newline at end of file
... ...
pacotes/linkedinoauth/tests/OAuthServerTest.php 0 → 100644
... ... @@ -0,0 +1,225 @@
  1 +<?php
  2 +
  3 +require_once dirname(__FILE__) . '/common.php';
  4 +require_once dirname(__FILE__) . '/Mock_OAuthDataStore.php';
  5 +
  6 +/**
  7 + * Tests of OAuthUtil
  8 + */
  9 +class OAuthServerTest extends PHPUnit_Framework_TestCase {
  10 + private $consumer;
  11 + private $request_token;
  12 + private $access_token;
  13 + private $hmac_sha1;
  14 + private $plaintext;
  15 + private $server;
  16 +
  17 + public function setUp() {
  18 + $this->consumer = new OAuthConsumer('key', 'secret');
  19 + $this->request_token = new OAuthToken('requestkey', 'requestsecret');
  20 + $this->access_token = new OAuthToken('accesskey', 'accesssecret');
  21 +
  22 + $this->hmac_sha1 = new OAuthSignatureMethod_HMAC_SHA1();
  23 + $this->plaintext = new OAuthSignatureMethod_PLAINTEXT();
  24 +
  25 + $this->server = new OAuthServer( new Mock_OAuthDataStore() );
  26 + $this->server->add_signature_method( $this->hmac_sha1 );
  27 + $this->server->add_signature_method( $this->plaintext );
  28 + }
  29 +
  30 + public function testAcceptValidRequest() {
  31 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  32 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  33 + list($consumer, $token) = $this->server->verify_request( $request );
  34 + $this->assertEquals( $this->consumer, $consumer );
  35 + $this->assertEquals( $this->access_token, $token );
  36 +
  37 + $request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token );
  38 + list($consumer, $token) = $this->server->verify_request( $request );
  39 + $this->assertEquals( $this->consumer, $consumer );
  40 + $this->assertEquals( $this->access_token, $token );
  41 + }
  42 +
  43 + public function testAcceptRequestWithoutVersion() {
  44 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  45 + $request->unset_parameter('oauth_version');
  46 + $request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token );
  47 +
  48 + $this->server->verify_request( $request );
  49 + }
  50 +
  51 + public function testRejectRequestSignedWithRequestToken() {
  52 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
  53 + $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
  54 +
  55 + $this->setExpectedException('OAuthException');
  56 + $this->server->verify_request( $request );
  57 + }
  58 +
  59 + public function testRejectRequestWithMissingParameters() {
  60 + // The list of required parameters is taken from
  61 + // Chapter 7 ("Accessing Protected Resources")
  62 +
  63 + $required_parameters = array(
  64 + 'oauth_consumer_key',
  65 + 'oauth_token',
  66 + 'oauth_signature_method',
  67 + 'oauth_signature',
  68 + 'oauth_timestamp',
  69 + 'oauth_nonce'
  70 + );
  71 +
  72 + foreach( $required_parameters AS $required ) {
  73 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  74 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  75 + try {
  76 + $request->unset_parameter( $required );
  77 + $this->server->verify_request($request);
  78 + $this->fail('Allowed a request without `' . $required . '`');
  79 + } catch( OAuthException $e ) { /* expected */ }
  80 + }
  81 + }
  82 +
  83 + public function testRejectPastTimestamp() {
  84 + // We change the timestamp to be 10 hours ago, it should throw an exception
  85 +
  86 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  87 + $request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') - 10*60*60, false);
  88 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  89 +
  90 + $this->setExpectedException('OAuthException');
  91 + $this->server->verify_request($request);
  92 + }
  93 +
  94 + public function testRejectFutureTimestamp() {
  95 + // We change the timestamp to be 10 hours in the future, it should throw an exception
  96 +
  97 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  98 + $request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') + 10*60*60, false);
  99 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  100 +
  101 + $this->setExpectedException('OAuthException');
  102 + $this->server->verify_request($request);
  103 + }
  104 +
  105 + public function testRejectUsedNonce() {
  106 + // We give a known nonce and should see an exception
  107 +
  108 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  109 + // The Mock datastore is set to say that the `nonce` nonce is known
  110 + $request->set_parameter( 'oauth_nonce', 'nonce', false);
  111 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  112 +
  113 + $this->setExpectedException('OAuthException');
  114 + $this->server->verify_request($request);
  115 + }
  116 +
  117 + public function testRejectInvalidSignature() {
  118 + // We change the signature post-signing to be something invalid
  119 +
  120 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  121 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  122 + $request->set_parameter( 'oauth_signature', '__whatever__', false);
  123 +
  124 + $this->setExpectedException('OAuthException');
  125 + $this->server->verify_request($request);
  126 + }
  127 +
  128 + public function testRejectInvalidConsumer() {
  129 + // We use the consumer-key "unknown", which isn't known by the datastore.
  130 +
  131 + $unknown_consumer = new OAuthConsumer('unknown', '__unused__');
  132 +
  133 + $request = OAuthRequest::from_consumer_and_token( $unknown_consumer, $this->access_token, 'POST', 'http://example.com');
  134 + $request->sign_request( $this->plaintext, $unknown_consumer, $this->access_token );
  135 +
  136 + $this->setExpectedException('OAuthException');
  137 + $this->server->verify_request( $request );
  138 + }
  139 +
  140 + public function testRejectInvalidToken() {
  141 + // We use the access-token "unknown" which isn't known by the datastore
  142 +
  143 + $unknown_token = new OAuthToken('unknown', '__unused__');
  144 +
  145 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $unknown_token, 'POST', 'http://example.com');
  146 + $request->sign_request( $this->plaintext, $this->consumer, $unknown_token );
  147 +
  148 + $this->setExpectedException('OAuthException');
  149 + $this->server->verify_request( $request );
  150 + }
  151 +
  152 + public function testRejectUnknownSignatureMethod() {
  153 + // We use a server that only supports HMAC-SHA1, but requests with PLAINTEXT signature
  154 +
  155 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  156 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  157 +
  158 + $server = new OAuthServer( new Mock_OAuthDataStore() );
  159 + $server->add_signature_method( $this->hmac_sha1 );
  160 +
  161 + $this->setExpectedException('OAuthException');
  162 + $server->verify_request( $request );
  163 + }
  164 +
  165 + public function testRejectUnknownVersion() {
  166 + // We use the version "1.0a" which isn't "1.0", so reject the request
  167 +
  168 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  169 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  170 + $request->set_parameter('oauth_version', '1.0a', false);
  171 +
  172 + $this->setExpectedException('OAuthException');
  173 + $this->server->verify_request( $request );
  174 + }
  175 +
  176 + public function testCreateRequestToken() {
  177 + // We request a new Request Token
  178 +
  179 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com');
  180 + $request->sign_request( $this->plaintext, $this->consumer, NULL );
  181 +
  182 + $token = $this->server->fetch_request_token($request);
  183 + $this->assertEquals($this->request_token, $token);
  184 + }
  185 +
  186 + public function testRejectSignedRequestTokenRequest() {
  187 + // We request a new Request Token, but the request is signed with a token which should fail
  188 +
  189 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
  190 + $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
  191 +
  192 + $this->setExpectedException('OAuthException');
  193 + $token = $this->server->fetch_request_token($request);
  194 + }
  195 +
  196 + public function testCreateAccessToken() {
  197 + // We request a new Access Token
  198 +
  199 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
  200 + $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
  201 +
  202 + $token = $this->server->fetch_access_token($request);
  203 + $this->assertEquals($this->access_token, $token);
  204 + }
  205 +
  206 + public function testRejectUnsignedAccessTokenRequest() {
  207 + // We request a new Access Token, but we didn't sign the request with a Access Token
  208 +
  209 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com');
  210 + $request->sign_request( $this->plaintext, $this->consumer, NULL );
  211 +
  212 + $this->setExpectedException('OAuthException');
  213 + $token = $this->server->fetch_access_token($request);
  214 + }
  215 +
  216 + public function testRejectAccessTokenSignedAccessTokenRequest() {
  217 + // We request a new Access Token, but the request is signed with an access token, so fail!
  218 +
  219 + $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  220 + $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  221 +
  222 + $this->setExpectedException('OAuthException');
  223 + $token = $this->server->fetch_access_token($request);
  224 + }
  225 +}
... ...
pacotes/linkedinoauth/tests/OAuthSignatureMethodHmacSha1Test.php 0 → 100644
... ... @@ -0,0 +1,60 @@
  1 +<?php
  2 +
  3 +require_once 'common.php';
  4 +require_once 'Mock_OAuthBaseStringRequest.php';
  5 +
  6 +class OAuthSignatureMethodHmacSha1Test extends PHPUnit_Framework_TestCase {
  7 + private $method;
  8 +
  9 + public function setUp() {
  10 + $this->method = new OAuthSignatureMethod_HMAC_SHA1();
  11 + }
  12 +
  13 + public function testIdentifyAsHmacSha1() {
  14 + $this->assertEquals('HMAC-SHA1', $this->method->get_name());
  15 + }
  16 +
  17 + public function testBuildSignature() {
  18 + // Tests taken from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1")
  19 + $request = new Mock_OAuthBaseStringRequest('bs');
  20 + $consumer = new OAuthConsumer('__unused__', 'cs');
  21 + $token = NULL;
  22 + $this->assertEquals('egQqG5AJep5sJ7anhXju1unge2I=', $this->method->build_signature( $request, $consumer, $token) );
  23 +
  24 + $request = new Mock_OAuthBaseStringRequest('bs');
  25 + $consumer = new OAuthConsumer('__unused__', 'cs');
  26 + $token = new OAuthToken('__unused__', 'ts');
  27 + $this->assertEquals('VZVjXceV7JgPq/dOTnNmEfO0Fv8=', $this->method->build_signature( $request, $consumer, $token) );
  28 +
  29 + $request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26'
  30 + . 'oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26'
  31 + . 'oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal');
  32 + $consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44');
  33 + $token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00');
  34 + $this->assertEquals('tR3+Ty81lMeYAr/Fid0kMTYa/WM=', $this->method->build_signature( $request, $consumer, $token) );
  35 + }
  36 +
  37 + public function testVerifySignature() {
  38 + // Tests taken from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1")
  39 + $request = new Mock_OAuthBaseStringRequest('bs');
  40 + $consumer = new OAuthConsumer('__unused__', 'cs');
  41 + $token = NULL;
  42 + $signature = 'egQqG5AJep5sJ7anhXju1unge2I=';
  43 + $this->assertTrue( $this->method->check_signature( $request, $consumer, $token, $signature) );
  44 +
  45 + $request = new Mock_OAuthBaseStringRequest('bs');
  46 + $consumer = new OAuthConsumer('__unused__', 'cs');
  47 + $token = new OAuthToken('__unused__', 'ts');
  48 + $signature = 'VZVjXceV7JgPq/dOTnNmEfO0Fv8=';
  49 + $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) );
  50 +
  51 + $request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26'
  52 + . 'oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26'
  53 + . 'oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal');
  54 + $consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44');
  55 + $token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00');
  56 + $signature = 'tR3+Ty81lMeYAr/Fid0kMTYa/WM=';
  57 + $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) );
  58 +
  59 + }
  60 +}
0 61 \ No newline at end of file
... ...
pacotes/linkedinoauth/tests/OAuthSignatureMethodPlaintextTest.php 0 → 100644
... ... @@ -0,0 +1,79 @@
  1 +<?php
  2 +
  3 +require_once 'common.php';
  4 +require_once 'Mock_OAuthBaseStringRequest.php';
  5 +
  6 +class OAuthSignatureMethodPlaintextTest extends PHPUnit_Framework_TestCase {
  7 + private $method;
  8 +
  9 + public function setUp() {
  10 + $this->method = new OAuthSignatureMethod_PLAINTEXT();
  11 + }
  12 +
  13 + public function testIdentifyAsPlaintext() {
  14 + $this->assertEquals('PLAINTEXT', $this->method->get_name());
  15 + }
  16 +
  17 + public function testBuildSignature() {
  18 + // Tests based on from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1")
  19 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  20 + $consumer = new OAuthConsumer('__unused__', 'cs');
  21 + $token = NULL;
  22 + $this->assertEquals('cs&', $this->method->build_signature( $request, $consumer, $token) );
  23 +
  24 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  25 + $consumer = new OAuthConsumer('__unused__', 'cs');
  26 + $token = new OAuthToken('__unused__', 'ts');
  27 + $this->assertEquals('cs&ts', $this->method->build_signature( $request, $consumer, $token) );
  28 +
  29 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  30 + $consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44');
  31 + $token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00');
  32 + $this->assertEquals('kd94hf93k423kf44&pfkkdhi9sl3r4s00', $this->method->build_signature( $request, $consumer, $token) );
  33 +
  34 + // Tests taken from Chapter 9.4.1 ("Generating Signature") from the spec
  35 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  36 + $consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88');
  37 + $token = new OAuthToken('__unused__', 'jjd999tj88uiths3');
  38 + $this->assertEquals('djr9rjt0jd78jf88&jjd999tj88uiths3', $this->method->build_signature( $request, $consumer, $token) );
  39 +
  40 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  41 + $consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88');
  42 + $token = new OAuthToken('__unused__', 'jjd99$tj88uiths3');
  43 + $this->assertEquals('djr9rjt0jd78jf88&jjd99%24tj88uiths3', $this->method->build_signature( $request, $consumer, $token) );
  44 + }
  45 +
  46 + public function testVerifySignature() {
  47 + // Tests based on from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1")
  48 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  49 + $consumer = new OAuthConsumer('__unused__', 'cs');
  50 + $token = NULL;
  51 + $signature = 'cs&';
  52 + $this->assertTrue( $this->method->check_signature( $request, $consumer, $token, $signature) );
  53 +
  54 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  55 + $consumer = new OAuthConsumer('__unused__', 'cs');
  56 + $token = new OAuthToken('__unused__', 'ts');
  57 + $signature = 'cs&ts';
  58 + $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) );
  59 +
  60 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  61 + $consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44');
  62 + $token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00');
  63 + $signature = 'kd94hf93k423kf44&pfkkdhi9sl3r4s00';
  64 + $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) );
  65 +
  66 + // Tests taken from Chapter 9.4.1 ("Generating Signature") from the spec
  67 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  68 + $consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88');
  69 + $token = new OAuthToken('__unused__', 'jjd999tj88uiths3');
  70 + $signature = 'djr9rjt0jd78jf88&jjd999tj88uiths3';
  71 + $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) );
  72 +
  73 + $request = new Mock_OAuthBaseStringRequest('__unused__');
  74 + $consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88');
  75 + $token = new OAuthToken('__unused__', 'jjd99$tj88uiths3');
  76 + $signature = 'djr9rjt0jd78jf88&jjd99%24tj88uiths3';
  77 + $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) );
  78 + }
  79 +}
0 80 \ No newline at end of file
... ...
pacotes/linkedinoauth/tests/OAuthSignatureMethodRsaSha1Test.php 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +<?php
  2 +
  3 +require_once 'common.php';
  4 +require_once 'Mock_OAuthBaseStringRequest.php';
  5 +require_once 'Mock_OAuthSignatureMethod_RSA_SHA1.php';
  6 +
  7 +class OAuthSignatureMethodRsaSha1Test extends PHPUnit_Framework_TestCase {
  8 + private $method;
  9 +
  10 + public function setUp() {
  11 + $this->method = new Mock_OAuthSignatureMethod_RSA_SHA1();
  12 + }
  13 +
  14 + public function testIdentifyAsRsaSha1() {
  15 + $this->assertEquals('RSA-SHA1', $this->method->get_name());
  16 + }
  17 +
  18 + public function testBuildSignature() {
  19 + if( ! function_exists('openssl_get_privatekey') ) {
  20 + $this->markTestSkipped('OpenSSL not available, can\'t test RSA-SHA1 functionality');
  21 + }
  22 +
  23 + // Tests taken from http://wiki.oauth.net/TestCases section 9.3 ("RSA-SHA1")
  24 + $request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacaction.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3D13917289812797014437%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1196666512%26oauth_version%3D1.0%26size%3Doriginal');
  25 + $consumer = new OAuthConsumer('dpf43f3p2l4k3l03', '__unused__');
  26 + $token = NULL;
  27 + $signature = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=';
  28 + $this->assertEquals($signature, $this->method->build_signature( $request, $consumer, $token) );
  29 + }
  30 +
  31 + public function testVerifySignature() {
  32 + if( ! function_exists('openssl_get_privatekey') ) {
  33 + $this->markTestSkipped('OpenSSL not available, can\'t test RSA-SHA1 functionality');
  34 + }
  35 +
  36 + // Tests taken from http://wiki.oauth.net/TestCases section 9.3 ("RSA-SHA1")
  37 + $request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacaction.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3D13917289812797014437%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1196666512%26oauth_version%3D1.0%26size%3Doriginal');
  38 + $consumer = new OAuthConsumer('dpf43f3p2l4k3l03', '__unused__');
  39 + $token = NULL;
  40 + $signature = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=';
  41 + $this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) );
  42 + }
  43 +}
0 44 \ No newline at end of file
... ...
pacotes/linkedinoauth/tests/OAuthTokenTest.php 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +<?php
  2 +
  3 +require_once 'common.php';
  4 +
  5 +class OAuthTokenTest extends PHPUnit_Framework_TestCase {
  6 + public function testSerialize() {
  7 + $token = new OAuthToken('token', 'secret');
  8 + $this->assertEquals('oauth_token=token&oauth_token_secret=secret', $token->to_string());
  9 +
  10 + $token = new OAuthToken('token&', 'secret%');
  11 + $this->assertEquals('oauth_token=token%26&oauth_token_secret=secret%25', $token->to_string());
  12 + }
  13 + public function testConvertToString() {
  14 + $token = new OAuthToken('token', 'secret');
  15 + $this->assertEquals('oauth_token=token&oauth_token_secret=secret', (string) $token);
  16 +
  17 + $token = new OAuthToken('token&', 'secret%');
  18 + $this->assertEquals('oauth_token=token%26&oauth_token_secret=secret%25', (string) $token);
  19 + }
  20 +}
0 21 \ No newline at end of file
... ...
pacotes/linkedinoauth/tests/OAuthUtilTest.php 0 → 100644
... ... @@ -0,0 +1,133 @@
  1 +<?php
  2 +
  3 +require_once dirname(__FILE__) . '/common.php';
  4 +
  5 +/**
  6 + * Tests of OAuthUtil
  7 + */
  8 +class OAuthUtilTest extends PHPUnit_Framework_TestCase {
  9 + public function testUrlencode() {
  10 + // Tests taken from
  11 + // http://wiki.oauth.net/TestCases ("Parameter Encoding")
  12 + $this->assertEquals('abcABC123', OAuthUtil::urlencode_rfc3986('abcABC123'));
  13 + $this->assertEquals('-._~', OAuthUtil::urlencode_rfc3986('-._~'));
  14 + $this->assertEquals('%25', OAuthUtil::urlencode_rfc3986('%'));
  15 + $this->assertEquals('%2B', OAuthUtil::urlencode_rfc3986('+'));
  16 + $this->assertEquals('%0A', OAuthUtil::urlencode_rfc3986("\n"));
  17 + $this->assertEquals('%20', OAuthUtil::urlencode_rfc3986(' '));
  18 + $this->assertEquals('%7F', OAuthUtil::urlencode_rfc3986("\x7F"));
  19 + //$this->assertEquals('%C2%80', OAuthUtil::urlencode_rfc3986("\x00\x80"));
  20 + //$this->assertEquals('%E3%80%81', OAuthUtil::urlencode_rfc3986("\x30\x01"));
  21 +
  22 + // Last two checks disabled because of lack of UTF-8 support, or lack
  23 + // of knowledge from me (morten.fangel) on how to use it properly..
  24 +
  25 + // A few tests to ensure code-coverage
  26 + $this->assertEquals( '', OAuthUtil::urlencode_rfc3986(NULL));
  27 + $this->assertEquals( '', OAuthUtil::urlencode_rfc3986(new stdClass()));
  28 + }
  29 +
  30 + public function testUrldecode() {
  31 + // Tests taken from
  32 + // http://wiki.oauth.net/TestCases ("Parameter Encoding")
  33 + $this->assertEquals('abcABC123', OAuthUtil::urldecode_rfc3986('abcABC123'));
  34 + $this->assertEquals('-._~', OAuthUtil::urldecode_rfc3986('-._~'));
  35 + $this->assertEquals('%', OAuthUtil::urldecode_rfc3986('%25'));
  36 + $this->assertEquals('+', OAuthUtil::urldecode_rfc3986('%2B'));
  37 + $this->assertEquals("\n", OAuthUtil::urldecode_rfc3986('%0A'));
  38 + $this->assertEquals(' ', OAuthUtil::urldecode_rfc3986('%20'));
  39 + $this->assertEquals("\x7F", OAuthUtil::urldecode_rfc3986('%7F'));
  40 + //$this->assertEquals("\x00\x80", OAuthUtil::urldecode_rfc3986('%C2%80'));
  41 + //$this->assertEquals("\x30\x01", OAuthUtil::urldecode_rfc3986('%E3%80%81'));
  42 +
  43 + // Last two checks disabled because of lack of UTF-8 support, or lack
  44 + // of knowledge from me (morten.fangel) on how to use it properly..
  45 + }
  46 +
  47 + public function testParseParameter() {
  48 + // Tests taken from
  49 + // http://wiki.oauth.net/TestCases ("Normalize Request Parameters")
  50 +
  51 + $this->assertEquals(
  52 + array('name'=>''),
  53 + OAuthUtil::parse_parameters('name')
  54 + );
  55 + $this->assertEquals(
  56 + array('a'=>'b'),
  57 + OAuthUtil::parse_parameters('a=b')
  58 + );
  59 + $this->assertEquals(
  60 + array('a'=>'b','c'=>'d'),
  61 + OAuthUtil::parse_parameters('a=b&c=d')
  62 + );
  63 + $this->assertEquals(
  64 + array('a'=>array('x!y','x y')),
  65 + OAuthUtil::parse_parameters('a=x!y&a=x+y')
  66 + );
  67 + $this->assertEquals(
  68 + array('x!y'=>'a', 'x' =>'a'),
  69 + OAuthUtil::parse_parameters('x!y=a&x=a')
  70 + );
  71 + }
  72 +
  73 + public function testBuildHttpQuery() {
  74 + // Tests taken from
  75 + // http://wiki.oauth.net/TestCases ("Normalize Request Parameters")
  76 + $this->assertEquals(
  77 + 'name=',
  78 + OAuthUtil::build_http_query(array('name'=>''))
  79 + );
  80 + $this->assertEquals(
  81 + 'a=b',
  82 + OAuthUtil::build_http_query(array('a'=>'b'))
  83 + );
  84 + $this->assertEquals(
  85 + 'a=b&c=d',
  86 + OAuthUtil::build_http_query(array('a'=>'b','c'=>'d'))
  87 + );
  88 + $this->assertEquals(
  89 + 'a=x%20y&a=x%21y',
  90 + OAuthUtil::build_http_query(array('a'=>array('x!y','x y')))
  91 + );
  92 + $this->assertEquals(
  93 + 'x=a&x%21y=a',
  94 + OAuthUtil::build_http_query(array('x!y'=>'a', 'x' =>'a'))
  95 + );
  96 +
  97 + // Test taken from the Spec 9.1.1
  98 + $this->assertEquals(
  99 + 'a=1&c=hi%20there&f=25&f=50&f=a&z=p&z=t',
  100 + OAuthUtil::build_http_query(array('a'=>'1', 'c' =>'hi there', 'f'=>array(25, 50, 'a'), 'z'=>array('p','t')))
  101 + );
  102 + }
  103 +
  104 + public function testSplitHeader() {
  105 + $this->assertEquals(
  106 + array('oauth_foo'=>'bar','oauth_baz'=>'bla,rgh'),
  107 + OAuthUtil::split_header('OAuth realm="",oauth_foo=bar,oauth_baz="bla,rgh"')
  108 + );
  109 + $this->assertEquals(
  110 + array(),
  111 + OAuthUtil::split_header('OAuth realm="",foo=bar,baz="bla,rgh"')
  112 + );
  113 + $this->assertEquals(
  114 + array('foo'=>'bar', 'baz'=>'bla,rgh'),
  115 + OAuthUtil::split_header('OAuth realm="",foo=bar,baz="bla,rgh"', false)
  116 + );
  117 + $this->assertEquals(
  118 + array('oauth_foo' => 'hi there'),
  119 + OAuthUtil::split_header('OAuth realm="",oauth_foo=hi+there,foo=bar,baz="bla,rgh"')
  120 + );
  121 +
  122 + }
  123 +
  124 + public function testGetHeaders() {
  125 + if (function_exists('apache_request_headers')) {
  126 + $this->markTestSkipped('We assume the apache module is well tested. Since this module is present, no need testing our suplement');
  127 + }
  128 +
  129 + $_SERVER['HTTP_HOST'] = 'foo';
  130 + $_SERVER['HTTP_X_WHATEVER'] = 'bar';
  131 + $this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar'), OAuthUtil::get_headers() );
  132 + }
  133 +}
... ...
pacotes/linkedinoauth/tests/common.php 0 → 100644
... ... @@ -0,0 +1,62 @@
  1 +<?php
  2 +
  3 +require dirname(__FILE__).'/../OAuth.php';
  4 +require_once 'PHPUnit/Framework.php';
  5 +
  6 +/**
  7 + * A simple utils class for methods needed
  8 + * during some of the tests
  9 + */
  10 +class OAuthTestUtils {
  11 + private static function reset_request_vars() {
  12 + $_SERVER = array();
  13 + $_POST = array();
  14 + $_GET = array();
  15 + }
  16 +
  17 + /**
  18 + * Populates $_{SERVER,GET,POST} and whatever environment-variables needed to test everything..
  19 + *
  20 + * @param string $method GET or POST
  21 + * @param string $uri What URI is the request to (eg http://example.com/foo?bar=baz)
  22 + * @param string $post_data What should the post-data be
  23 + * @param string $auth_header What to set the Authorization header to
  24 + */
  25 + public static function build_request( $method, $uri, $post_data = '', $auth_header = '' ) {
  26 + self::reset_request_vars();
  27 +
  28 + $method = strtoupper($method);
  29 +
  30 + $parts = parse_url($uri);
  31 +
  32 + $port = @$parts['port'];
  33 + $scheme = $parts['scheme'];
  34 + $host = $parts['host'];
  35 + $path = @$parts['path'];
  36 + $query = @$parts['query'];
  37 +
  38 + $port or $port = ($scheme == 'https') ? '443' : '80';
  39 +
  40 + if( $scheme == 'https') {
  41 + $_SERVER['HTTPS'] = 'on';
  42 + }
  43 +
  44 + $_SERVER['REQUEST_METHOD'] = $method;
  45 + $_SERVER['HTTP_HOST'] = $host;
  46 + $_SERVER['SERVER_PORT'] = $port;
  47 + $_SERVER['SCRIPT_NAME'] = $path;
  48 + $_SERVER['REQUEST_URI'] = $path . '?' . $query;
  49 + $_SERVER['QUERY_STRING'] = $query.'';
  50 + parse_str($query, $_GET);
  51 +
  52 + if( $method == 'POST' ) {
  53 + $_SERVER['HTTP_CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
  54 + $_POST = parse_str($post_data);
  55 + OAuthRequest::$POST_INPUT = 'data:application/x-www-form-urlencoded,'.$post_data;
  56 + }
  57 +
  58 + if( $auth_header != '' ) {
  59 + $_SERVER['HTTP_AUTHORIZATION'] = $auth_header;
  60 + }
  61 + }
  62 +}
... ...
pacotes/openid/example-google.php 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +<?php
  2 +# Logging in with Google accounts requires setting special identity, so this example shows how to do it.
  3 +require 'openid.php';
  4 +try {
  5 + $openid = new LightOpenID;
  6 + if(!$openid->mode) {
  7 + if(isset($_GET['login'])) {
  8 + $openid->identity = 'https://www.google.com/accounts/o8/id';
  9 + header('Location: ' . $openid->authUrl());
  10 + }
  11 +?>
  12 +<form action="?login" method="post">
  13 + <button>Login with Google</button>
  14 +</form>
  15 +<?php
  16 + } elseif($openid->mode == 'cancel') {
  17 + echo 'User has canceled authentication!';
  18 + } else {
  19 + echo 'User ' . ($openid->validate() ? $openid->identity . ' has ' : 'has not ') . 'logged in.';
  20 + }
  21 +} catch(ErrorException $e) {
  22 + echo $e->getMessage();
  23 +}
... ...
pacotes/openid/login.php 0 → 100644
... ... @@ -0,0 +1,132 @@
  1 +<html>
  2 +<style>
  3 +body
  4 +{background-color:white;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 12px;margin: 10px}
  5 +img
  6 +{cursor:pointer;border:1px solid gray;}
  7 +</style>
  8 +<?php
  9 +//http://localhost/i3geo/pacotes/openid/login.php?g_sid=dqpk71kh6ei121s4u5g1qb9vi1
  10 +session_name("openid");
  11 +session_start();
  12 +include_once("../../ms_configura.php");
  13 +if($_SESSION["openid"] == false)
  14 +{
  15 + $dadosurl = array_merge($_GET,$_POST);
  16 + if(!empty($dadosurl["erro"])){
  17 + echo "<span style=color:red >Ocorreu algum erro</span><br><br>";
  18 + }
  19 +
  20 +}
  21 +require 'openid.php';
  22 +try {
  23 + $openid = new LightOpenID;
  24 + if(!$openid->mode && $_SESSION["openid"] == false) {
  25 + if(isset($dadosurl['openid_identifier']) && empty($dadosurl["erro"])) {
  26 + $openid->identity = $dadosurl['openid_identifier'];
  27 + header('Location: ' . $openid->authUrl());
  28 + }
  29 +?>
  30 +
  31 +<body>
  32 +<div id=corpo >
  33 +<a href="http://openid.net/" target=_blank ><img style="border:0px solid gray;" src="../../imagens/redes_openid.png"/></a>&nbsp;
  34 +<a href="http://oauth.net/" target=_blank ><img width=135px style="border:0px solid gray;" src="../../imagens/redes_oauth.png"/></a><br>
  35 +
  36 +Utilize uma das redes abaixo para confirmar sua identidade<br><br>
  37 +<img src="../../imagens/redes_google.png" onclick="submete('google')"/>&nbsp;
  38 +<?php
  39 +if(is_array($facebookoauth))
  40 +{echo '<img src="../../imagens/redes_facebook.png" onclick="submete(\'facebook\')"/>&nbsp;';}
  41 +?>
  42 +<img src="../../imagens/redes_myspace.png" onclick="submete('myspace')"/>&nbsp;
  43 +<?php
  44 +if(is_array($twitteroauth))
  45 +{echo '<img src="../../imagens/redes_twitter.png" onclick="submete(\'twitter\')"/>&nbsp;';}
  46 +?>
  47 +<?php
  48 +if(is_array($linkedinoauth))
  49 +{echo '<img src="../../imagens/redes_linkedin.png" onclick="submete(\'linkedin\')"/>&nbsp;';}
  50 +?>
  51 +<img src="../../imagens/redes_windowslive.png"/>&nbsp;
  52 +<img src="../../imagens/redes_wordpress.png" onclick="submete('wordpress')"/>&nbsp;
  53 +<img src="../../imagens/redes_blogger.png" onclick="submete('blogger')"/>&nbsp;
  54 +</div>
  55 +
  56 +<script>
  57 +function submete(quem){
  58 + if(quem == "linkedin")
  59 + {
  60 + var url = "<?php echo $_SESSION["locaplic"]; ?>/pacotes/linkedinoauth/index.php";
  61 + }
  62 + if(quem == "google")
  63 + {
  64 + var u = window.prompt("Usuário","");
  65 + if(!u){return;}
  66 + var url = 'http://www.google.com/profiles/'+u;
  67 + }
  68 + if(quem == "myspace")
  69 + {
  70 + var u = window.prompt("Usuário","");
  71 + if(!u){return;}
  72 + var url = 'http://myspace.com/'+u;
  73 + }
  74 + if(quem == "twitter")
  75 + {
  76 + var url = "<?php echo $_SESSION["locaplic"]; ?>/pacotes/twitteroauth/redirect.php";
  77 + }
  78 + if(quem == "wordpress")
  79 + {
  80 + var u = window.prompt("Usuário","");
  81 + if(!u){return;}
  82 + var url = 'http://'+u+'wordpress.com';
  83 + }
  84 + if(quem == "blogger")
  85 + {
  86 + var u = window.prompt("Usuário","");
  87 + if(!u){return;}
  88 + var url = 'http://'+u+'.blogspot.com';
  89 + }
  90 + if(quem == "facebook")
  91 + {
  92 + var url = "<?php echo $_SESSION["locaplic"]; ?>/pacotes/facebookoauth/index.php";
  93 + }
  94 + if(quem == "google" || quem == "myspace" || quem == "wordpress" || quem == "blogger"){
  95 + url = "login.php?&usuario="+u+"&openid_identifier="+url+"&servico="+quem+"&imagem=&nome="+u;
  96 + }
  97 + document.getElementById("corpo").style.display = "none";
  98 + document.body.innerHTML += "Aguarde...";
  99 + window.location.href = url;
  100 +}
  101 +</script>
  102 +<?php
  103 + } elseif($openid->mode == 'cancel') {
  104 + echo 'User has canceled authentication!';
  105 + } else {
  106 + if($_SESSION["openidservico"] != "twitter" && $_SESSION["openidservico"] != "facebook" && $_SESSION["openidservico"] != "linkedin"){
  107 + $valido = $openid->validate();
  108 + $_SESSION["openid"] = false;
  109 + if($valido){
  110 + $_SESSION["openid"] = true;
  111 + $_SESSION["openidurl"] = $dadosurl["openid_identifier"];
  112 + $_SESSION["openidusuario"] = $dadosurl["usuario"];
  113 + $_SESSION["openidservico"] = $dadosurl["servico"];
  114 + $_SESSION["openidimagem"] = $dadosurl["imagem"];
  115 + $_SESSION["openidnome"] = $dadosurl["nome"];
  116 + }
  117 + }
  118 + else{
  119 + $valido = $_SESSION["openid"];
  120 + }
  121 + if($valido){
  122 + header('Location: ' . $_SESSION["urlVolta"]);
  123 + }
  124 + if(!$valido){
  125 + $url = "login.php?login&erro=ok";
  126 + header('Location: ' . $url);
  127 + }
  128 + }
  129 +} catch(ErrorException $e) {
  130 + echo $e->getMessage();
  131 +}
  132 +?>
0 133 \ No newline at end of file
... ...
pacotes/openid/openid.php 0 → 100644
... ... @@ -0,0 +1,743 @@
  1 +<?php
  2 +/**
  3 + * This class provides a simple interface for OpenID (1.1 and 2.0) authentication.
  4 + * Supports Yadis discovery.
  5 + * The authentication process is stateless/dumb.
  6 + *
  7 + * Usage:
  8 + * Sign-on with OpenID is a two step process:
  9 + * Step one is authentication with the provider:
  10 + * <code>
  11 + * $openid = new LightOpenID;
  12 + * $openid->identity = 'ID supplied by user';
  13 + * header('Location: ' . $openid->authUrl());
  14 + * </code>
  15 + * The provider then sends various parameters via GET, one of them is openid_mode.
  16 + * Step two is verification:
  17 + * <code>
  18 + * if ($this->data['openid_mode']) {
  19 + * $openid = new LightOpenID;
  20 + * echo $openid->validate() ? 'Logged in.' : 'Failed';
  21 + * }
  22 + * </code>
  23 + *
  24 + * Optionally, you can set $returnUrl and $realm (or $trustRoot, which is an alias).
  25 + * The default values for those are:
  26 + * $openid->realm = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
  27 + * $openid->returnUrl = $openid->realm . $_SERVER['REQUEST_URI'];
  28 + * If you don't know their meaning, refer to any openid tutorial, or specification. Or just guess.
  29 + *
  30 + * AX and SREG extensions are supported.
  31 + * To use them, specify $openid->required and/or $openid->optional before calling $openid->authUrl().
  32 + * These are arrays, with values being AX schema paths (the 'path' part of the URL).
  33 + * For example:
  34 + * $openid->required = array('namePerson/friendly', 'contact/email');
  35 + * $openid->optional = array('namePerson/first');
  36 + * If the server supports only SREG or OpenID 1.1, these are automaticaly
  37 + * mapped to SREG names, so that user doesn't have to know anything about the server.
  38 + *
  39 + * To get the values, use $openid->getAttributes().
  40 + *
  41 + *
  42 + * The library requires PHP >= 5.1.2 with curl or http/https stream wrappers enabled..
  43 + * @author Mewp
  44 + * @copyright Copyright (c) 2010, Mewp
  45 + * @license http://www.opensource.org/licenses/mit-license.php MIT
  46 + */
  47 +class LightOpenID
  48 +{
  49 + public $returnUrl
  50 + , $g_sid
  51 + , $required = array()
  52 + , $optional = array()
  53 + , $verify_peer = null
  54 + , $capath = null
  55 + , $cainfo = null;
  56 + private $identity, $claimed_id;
  57 + protected $server, $version, $trustRoot, $aliases, $identifier_select = false
  58 + , $ax = false, $sreg = false, $data;
  59 + static protected $ax_to_sreg = array(
  60 + 'namePerson/friendly' => 'nickname',
  61 + 'contact/email' => 'email',
  62 + 'namePerson' => 'fullname',
  63 + 'birthDate' => 'dob',
  64 + 'person/gender' => 'gender',
  65 + 'contact/postalCode/home' => 'postcode',
  66 + 'contact/country/home' => 'country',
  67 + 'pref/language' => 'language',
  68 + 'pref/timezone' => 'timezone',
  69 + );
  70 +
  71 + function __construct()
  72 + {
  73 + $this->trustRoot = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
  74 + $uri = rtrim(preg_replace('#((?<=\?)|&)openid\.[^&]+#', '', $_SERVER['REQUEST_URI']), '?');
  75 + $this->returnUrl = $this->trustRoot . $uri;
  76 +
  77 + $this->data = $_POST + $_GET; # OPs may send data as POST or GET.
  78 + }
  79 +
  80 + function __set($name, $value)
  81 + {
  82 + switch ($name) {
  83 + case 'identity':
  84 + if (strlen($value = trim((String) $value))) {
  85 + if (preg_match('#^xri:/*#i', $value, $m)) {
  86 + $value = substr($value, strlen($m[0]));
  87 + } elseif (!preg_match('/^(?:[=@+\$!\(]|https?:)/i', $value)) {
  88 + $value = "http://$value";
  89 + }
  90 + if (preg_match('#^https?://[^/]+$#i', $value, $m)) {
  91 + $value .= '/';
  92 + }
  93 + }
  94 + $this->$name = $this->claimed_id = $value;
  95 + break;
  96 + case 'trustRoot':
  97 + case 'realm':
  98 + $this->trustRoot = trim($value);
  99 + }
  100 + }
  101 +
  102 + function __get($name)
  103 + {
  104 + switch ($name) {
  105 + case 'identity':
  106 + # We return claimed_id instead of identity,
  107 + # because the developer should see the claimed identifier,
  108 + # i.e. what he set as identity, not the op-local identifier (which is what we verify)
  109 + return $this->claimed_id;
  110 + case 'trustRoot':
  111 + case 'realm':
  112 + return $this->trustRoot;
  113 + case 'mode':
  114 + return empty($this->data['openid_mode']) ? null : $this->data['openid_mode'];
  115 + }
  116 + }
  117 +
  118 + /**
  119 + * Checks if the server specified in the url exists.
  120 + *
  121 + * @param $url url to check
  122 + * @return true, if the server exists; false otherwise
  123 + */
  124 + function hostExists($url)
  125 + {
  126 + if (strpos($url, '/') === false) {
  127 + $server = $url;
  128 + } else {
  129 + $server = @parse_url($url, PHP_URL_HOST);
  130 + }
  131 +
  132 + if (!$server) {
  133 + return false;
  134 + }
  135 +
  136 + return !!gethostbynamel($server);
  137 + }
  138 +
  139 + protected function request_curl($url, $method='GET', $params=array())
  140 + {
  141 + $s = PHP_SHLIB_SUFFIX;
  142 + if(!function_exists('curl_init'))
  143 + {@dl( 'php_curl'.'.'.$s );}
  144 + if(!function_exists('curl_init'))
  145 + {echo "curl não instalado";}
  146 + $params = http_build_query($params, '', '&');
  147 + $curl = curl_init($url . ($method == 'GET' && $params ? '?' . $params : ''));
  148 + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  149 + curl_setopt($curl, CURLOPT_HEADER, false);
  150 + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  151 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  152 + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/xrds+xml, */*'));
  153 +
  154 + if($this->verify_peer !== null) {
  155 + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
  156 + if($this->capath) {
  157 + curl_setopt($curl, CURLOPT_CAPATH, $this->capath);
  158 + }
  159 +
  160 + if($this->cainfo) {
  161 + curl_setopt($curl, CURLOPT_CAINFO, $this->cainfo);
  162 + }
  163 + }
  164 +
  165 + if ($method == 'POST') {
  166 + curl_setopt($curl, CURLOPT_POST, true);
  167 + curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
  168 + } elseif ($method == 'HEAD') {
  169 + curl_setopt($curl, CURLOPT_HEADER, true);
  170 + curl_setopt($curl, CURLOPT_NOBODY, true);
  171 + } else {
  172 + curl_setopt($curl, CURLOPT_HTTPGET, true);
  173 + }
  174 + $response = curl_exec($curl);
  175 + if($method == 'HEAD') {
  176 + $headers = array();
  177 + foreach(explode("\n", $response) as $header) {
  178 + $pos = strpos($header,':');
  179 + $name = strtolower(trim(substr($header, 0, $pos)));
  180 + $headers[$name] = trim(substr($header, $pos+1));
  181 + }
  182 +
  183 + # Updating claimed_id in case of redirections.
  184 + $effective_url = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
  185 + if($effective_url != $url) {
  186 + $this->identity = $this->claimed_id = $effective_url;
  187 + }
  188 +
  189 + return $headers;
  190 + }
  191 +
  192 + if (curl_errno($curl)) {
  193 + throw new ErrorException(curl_error($curl), curl_errno($curl));
  194 + }
  195 + return $response;
  196 + }
  197 +
  198 + protected function request_streams($url, $method='GET', $params=array())
  199 + {
  200 + if(!$this->hostExists($url)) {
  201 + throw new ErrorException('Invalid request.');
  202 + }
  203 +
  204 + $params = http_build_query($params, '', '&');
  205 + switch($method) {
  206 + case 'GET':
  207 + $opts = array(
  208 + 'http' => array(
  209 + 'method' => 'GET',
  210 + 'header' => 'Accept: application/xrds+xml, */*',
  211 + 'ignore_errors' => true,
  212 + )
  213 + );
  214 + $url = $url . ($params ? '?' . $params : '');
  215 + break;
  216 + case 'POST':
  217 + $opts = array(
  218 + 'http' => array(
  219 + 'method' => 'POST',
  220 + 'header' => 'Content-type: application/x-www-form-urlencoded',
  221 + 'content' => $params,
  222 + 'ignore_errors' => true,
  223 + )
  224 + );
  225 + break;
  226 + case 'HEAD':
  227 + # We want to send a HEAD request,
  228 + # but since get_headers doesn't accept $context parameter,
  229 + # we have to change the defaults.
  230 + $default = stream_context_get_options(stream_context_get_default());
  231 + stream_context_get_default(
  232 + array('http' => array(
  233 + 'method' => 'HEAD',
  234 + 'header' => 'Accept: application/xrds+xml, */*',
  235 + 'ignore_errors' => true,
  236 + ))
  237 + );
  238 +
  239 + $url = $url . ($params ? '?' . $params : '');
  240 + $headers_tmp = get_headers ($url);
  241 + if(!$headers_tmp) {
  242 + return array();
  243 + }
  244 +
  245 + # Parsing headers.
  246 + $headers = array();
  247 + foreach($headers_tmp as $header) {
  248 + $pos = strpos($header,':');
  249 + $name = strtolower(trim(substr($header, 0, $pos)));
  250 + $headers[$name] = trim(substr($header, $pos+1));
  251 +
  252 + # Following possible redirections. The point is just to have
  253 + # claimed_id change with them, because get_headers() will
  254 + # follow redirections automatically.
  255 + # We ignore redirections with relative paths.
  256 + # If any known provider uses them, file a bug report.
  257 + if($name == 'location') {
  258 + if(strpos($headers[$name], 'http') === 0) {
  259 + $this->identity = $this->claimed_id = $headers[$name];
  260 + } elseif($headers[$name][0] == '/') {
  261 + $parsed_url = parse_url($this->claimed_id);
  262 + $this->identity =
  263 + $this->claimed_id = $parsed_url['scheme'] . '://'
  264 + . $parsed_url['host']
  265 + . $headers[$name];
  266 + }
  267 + }
  268 + }
  269 +
  270 + # And restore them.
  271 + stream_context_get_default($default);
  272 + //var_dump($headers);exit;
  273 + return $headers;
  274 + }
  275 +
  276 + if($this->verify_peer) {
  277 + $opts += array('ssl' => array(
  278 + 'verify_peer' => true,
  279 + 'capath' => $this->capath,
  280 + 'cafile' => $this->cainfo,
  281 + ));
  282 + }
  283 +
  284 + $context = stream_context_create ($opts);
  285 +
  286 + return file_get_contents($url, false, $context);
  287 + }
  288 +
  289 + protected function request($url, $method='GET', $params=array())
  290 + {
  291 + if(function_exists('curl_init') && !ini_get('safe_mode')) {
  292 + return $this->request_curl($url, $method, $params);
  293 + }
  294 + return $this->request_streams($url, $method, $params);
  295 + }
  296 +
  297 + protected function build_url($url, $parts)
  298 + {
  299 + if (isset($url['query'], $parts['query'])) {
  300 + $parts['query'] = $url['query'] . '&' . $parts['query'];
  301 + }
  302 +
  303 + $url = $parts + $url;
  304 + $url = $url['scheme'] . '://'
  305 + . (empty($url['username'])?''
  306 + :(empty($url['password'])? "{$url['username']}@"
  307 + :"{$url['username']}:{$url['password']}@"))
  308 + . $url['host']
  309 + . (empty($url['port'])?'':":{$url['port']}")
  310 + . (empty($url['path'])?'':$url['path'])
  311 + . (empty($url['query'])?'':"?{$url['query']}")
  312 + . (empty($url['fragment'])?'':"#{$url['fragment']}");
  313 + return $url;
  314 + }
  315 +
  316 + /**
  317 + * Helper function used to scan for <meta>/<link> tags and extract information
  318 + * from them
  319 + */
  320 + protected function htmlTag($content, $tag, $attrName, $attrValue, $valueName)
  321 + {
  322 + preg_match_all("#<{$tag}[^>]*$attrName=['\"].*?$attrValue.*?['\"][^>]*$valueName=['\"](.+?)['\"][^>]*/?>#i", $content, $matches1);
  323 + preg_match_all("#<{$tag}[^>]*$valueName=['\"](.+?)['\"][^>]*$attrName=['\"].*?$attrValue.*?['\"][^>]*/?>#i", $content, $matches2);
  324 +
  325 + $result = array_merge($matches1[1], $matches2[1]);
  326 + return empty($result)?false:$result[0];
  327 + }
  328 +
  329 + /**
  330 + * Performs Yadis and HTML discovery. Normally not used.
  331 + * @param $url Identity URL.
  332 + * @return String OP Endpoint (i.e. OpenID provider address).
  333 + * @throws ErrorException
  334 + */
  335 + function discover($url)
  336 + {
  337 + if (!$url) throw new ErrorException('No identity supplied.');
  338 + # Use xri.net proxy to resolve i-name identities
  339 + if (!preg_match('#^https?:#', $url)) {
  340 + $url = "https://xri.net/$url";
  341 + }
  342 +
  343 + # We save the original url in case of Yadis discovery failure.
  344 + # It can happen when we'll be lead to an XRDS document
  345 + # which does not have any OpenID2 services.
  346 + $originalUrl = $url;
  347 +
  348 + # A flag to disable yadis discovery in case of failure in headers.
  349 + $yadis = true;
  350 +
  351 + # We'll jump a maximum of 5 times, to avoid endless redirections.
  352 + for ($i = 0; $i < 5; $i ++) {
  353 + if ($yadis) {
  354 + $headers = $this->request($url, 'HEAD');
  355 +
  356 + $next = false;
  357 + if (isset($headers['x-xrds-location'])) {
  358 + $url = $this->build_url(parse_url($url), parse_url(trim($headers['x-xrds-location'])));
  359 + $next = true;
  360 + }
  361 +
  362 + if (isset($headers['content-type'])
  363 + && (strpos($headers['content-type'], 'application/xrds+xml') !== false
  364 + || strpos($headers['content-type'], 'text/xml') !== false)
  365 + ) {
  366 + # Apparently, some providers return XRDS documents as text/html.
  367 + # While it is against the spec, allowing this here shouldn't break
  368 + # compatibility with anything.
  369 + # ---
  370 + # Found an XRDS document, now let's find the server, and optionally delegate.
  371 + $content = $this->request($url, 'GET');
  372 +
  373 + preg_match_all('#<Service.*?>(.*?)</Service>#s', $content, $m);
  374 + foreach($m[1] as $content) {
  375 + $content = ' ' . $content; # The space is added, so that strpos doesn't return 0.
  376 +
  377 + # OpenID 2
  378 + $ns = preg_quote('http://specs.openid.net/auth/2.0/');
  379 + if(preg_match('#<Type>\s*'.$ns.'(server|signon)\s*</Type>#s', $content, $type)) {
  380 + if ($type[1] == 'server') $this->identifier_select = true;
  381 +
  382 + preg_match('#<URI.*?>(.*)</URI>#', $content, $server);
  383 + preg_match('#<(Local|Canonical)ID>(.*)</\1ID>#', $content, $delegate);
  384 + if (empty($server)) {
  385 + return false;
  386 + }
  387 + # Does the server advertise support for either AX or SREG?
  388 + $this->ax = (bool) strpos($content, '<Type>http://openid.net/srv/ax/1.0</Type>');
  389 + $this->sreg = strpos($content, '<Type>http://openid.net/sreg/1.0</Type>')
  390 + || strpos($content, '<Type>http://openid.net/extensions/sreg/1.1</Type>');
  391 +
  392 + $server = $server[1];
  393 + if (isset($delegate[2])) $this->identity = trim($delegate[2]);
  394 + $this->version = 2;
  395 +
  396 + $this->server = $server;
  397 + return $server;
  398 + }
  399 +
  400 + # OpenID 1.1
  401 + $ns = preg_quote('http://openid.net/signon/1.1');
  402 + if (preg_match('#<Type>\s*'.$ns.'\s*</Type>#s', $content)) {
  403 +
  404 + preg_match('#<URI.*?>(.*)</URI>#', $content, $server);
  405 + preg_match('#<.*?Delegate>(.*)</.*?Delegate>#', $content, $delegate);
  406 + if (empty($server)) {
  407 + return false;
  408 + }
  409 + # AX can be used only with OpenID 2.0, so checking only SREG
  410 + $this->sreg = strpos($content, '<Type>http://openid.net/sreg/1.0</Type>')
  411 + || strpos($content, '<Type>http://openid.net/extensions/sreg/1.1</Type>');
  412 +
  413 + $server = $server[1];
  414 + if (isset($delegate[1])) $this->identity = $delegate[1];
  415 + $this->version = 1;
  416 +
  417 + $this->server = $server;
  418 + return $server;
  419 + }
  420 + }
  421 +
  422 + $next = true;
  423 + $yadis = false;
  424 + $url = $originalUrl;
  425 + $content = null;
  426 + break;
  427 + }
  428 + if ($next) continue;
  429 +
  430 + # There are no relevant information in headers, so we search the body.
  431 + $content = $this->request($url, 'GET');
  432 + $location = $this->htmlTag($content, 'meta', 'http-equiv', 'X-XRDS-Location', 'content');
  433 + if ($location) {
  434 + $url = $this->build_url(parse_url($url), parse_url($location));
  435 + continue;
  436 + }
  437 + }
  438 +
  439 + if (!$content) $content = $this->request($url, 'GET');
  440 +
  441 + # At this point, the YADIS Discovery has failed, so we'll switch
  442 + # to openid2 HTML discovery, then fallback to openid 1.1 discovery.
  443 + $server = $this->htmlTag($content, 'link', 'rel', 'openid2.provider', 'href');
  444 + $delegate = $this->htmlTag($content, 'link', 'rel', 'openid2.local_id', 'href');
  445 + $this->version = 2;
  446 +
  447 + if (!$server) {
  448 + # The same with openid 1.1
  449 + $server = $this->htmlTag($content, 'link', 'rel', 'openid.server', 'href');
  450 + $delegate = $this->htmlTag($content, 'link', 'rel', 'openid.delegate', 'href');
  451 + $this->version = 1;
  452 + }
  453 +
  454 + if ($server) {
  455 + # We found an OpenID2 OP Endpoint
  456 + if ($delegate) {
  457 + # We have also found an OP-Local ID.
  458 + $this->identity = $delegate;
  459 + }
  460 + $this->server = $server;
  461 + return $server;
  462 + }
  463 +
  464 + throw new ErrorException('No servers found!');
  465 + }
  466 + throw new ErrorException('Endless redirection!');
  467 + }
  468 +
  469 + protected function sregParams()
  470 + {
  471 + $params = array();
  472 + # We always use SREG 1.1, even if the server is advertising only support for 1.0.
  473 + # That's because it's fully backwards compatibile with 1.0, and some providers
  474 + # advertise 1.0 even if they accept only 1.1. One such provider is myopenid.com
  475 + $params['openid.ns.sreg'] = 'http://openid.net/extensions/sreg/1.1';
  476 + if ($this->required) {
  477 + $params['openid.sreg.required'] = array();
  478 + foreach ($this->required as $required) {
  479 + if (!isset(self::$ax_to_sreg[$required])) continue;
  480 + $params['openid.sreg.required'][] = self::$ax_to_sreg[$required];
  481 + }
  482 + $params['openid.sreg.required'] = implode(',', $params['openid.sreg.required']);
  483 + }
  484 +
  485 + if ($this->optional) {
  486 + $params['openid.sreg.optional'] = array();
  487 + foreach ($this->optional as $optional) {
  488 + if (!isset(self::$ax_to_sreg[$optional])) continue;
  489 + $params['openid.sreg.optional'][] = self::$ax_to_sreg[$optional];
  490 + }
  491 + $params['openid.sreg.optional'] = implode(',', $params['openid.sreg.optional']);
  492 + }
  493 + return $params;
  494 + }
  495 +
  496 + protected function axParams()
  497 + {
  498 + $params = array();
  499 + if ($this->required || $this->optional) {
  500 + $params['openid.ns.ax'] = 'http://openid.net/srv/ax/1.0';
  501 + $params['openid.ax.mode'] = 'fetch_request';
  502 + $this->aliases = array();
  503 + $counts = array();
  504 + $required = array();
  505 + $optional = array();
  506 + foreach (array('required','optional') as $type) {
  507 + foreach ($this->$type as $alias => $field) {
  508 + if (is_int($alias)) $alias = strtr($field, '/', '_');
  509 + $this->aliases[$alias] = 'http://axschema.org/' . $field;
  510 + if (empty($counts[$alias])) $counts[$alias] = 0;
  511 + $counts[$alias] += 1;
  512 + ${$type}[] = $alias;
  513 + }
  514 + }
  515 + foreach ($this->aliases as $alias => $ns) {
  516 + $params['openid.ax.type.' . $alias] = $ns;
  517 + }
  518 + foreach ($counts as $alias => $count) {
  519 + if ($count == 1) continue;
  520 + $params['openid.ax.count.' . $alias] = $count;
  521 + }
  522 +
  523 + # Don't send empty ax.requied and ax.if_available.
  524 + # Google and possibly other providers refuse to support ax when one of these is empty.
  525 + if($required) {
  526 + $params['openid.ax.required'] = implode(',', $required);
  527 + }
  528 + if($optional) {
  529 + $params['openid.ax.if_available'] = implode(',', $optional);
  530 + }
  531 + }
  532 + return $params;
  533 + }
  534 +
  535 + protected function authUrl_v1()
  536 + {
  537 + $returnUrl = $this->returnUrl;
  538 + # If we have an openid.delegate that is different from our claimed id,
  539 + # we need to somehow preserve the claimed id between requests.
  540 + # The simplest way is to just send it along with the return_to url.
  541 + if($this->identity != $this->claimed_id) {
  542 + $returnUrl .= (strpos($returnUrl, '?') ? '&' : '?') . 'openid.claimed_id=' . $this->claimed_id;
  543 + }
  544 +
  545 + $params = array(
  546 + 'openid.return_to' => $returnUrl,
  547 + 'openid.mode' => 'checkid_setup',
  548 + 'openid.identity' => $this->identity,
  549 + 'openid.trust_root' => $this->trustRoot,
  550 + ) + $this->sregParams();
  551 +
  552 + return $this->build_url(parse_url($this->server)
  553 + , array('query' => http_build_query($params, '', '&')));
  554 + }
  555 +
  556 + protected function authUrl_v2($identifier_select)
  557 + {
  558 + $params = array(
  559 + 'openid.ns' => 'http://specs.openid.net/auth/2.0',
  560 + 'openid.mode' => 'checkid_setup',
  561 + 'openid.return_to' => $this->returnUrl,
  562 + 'openid.realm' => $this->trustRoot,
  563 + );
  564 + if ($this->ax) {
  565 + $params += $this->axParams();
  566 + }
  567 + if ($this->sreg) {
  568 + $params += $this->sregParams();
  569 + }
  570 + if (!$this->ax && !$this->sreg) {
  571 + # If OP doesn't advertise either SREG, nor AX, let's send them both
  572 + # in worst case we don't get anything in return.
  573 + $params += $this->axParams() + $this->sregParams();
  574 + }
  575 +
  576 + if ($identifier_select) {
  577 + $params['openid.identity'] = $params['openid.claimed_id']
  578 + = 'http://specs.openid.net/auth/2.0/identifier_select';
  579 + } else {
  580 + $params['openid.identity'] = $this->identity;
  581 + $params['openid.claimed_id'] = $this->claimed_id;
  582 + }
  583 +
  584 + return $this->build_url(parse_url($this->server)
  585 + , array('query' => http_build_query($params, '', '&')));
  586 + }
  587 +
  588 + /**
  589 + * Returns authentication url. Usually, you want to redirect your user to it.
  590 + * @return String The authentication url.
  591 + * @param String $select_identifier Whether to request OP to select identity for an user in OpenID 2. Does not affect OpenID 1.
  592 + * @throws ErrorException
  593 + */
  594 + function authUrl($identifier_select = null)
  595 + {
  596 + if (!$this->server) $this->discover($this->identity);
  597 +
  598 + if ($this->version == 2) {
  599 + if ($identifier_select === null) {
  600 + return $this->authUrl_v2($this->identifier_select);
  601 + }
  602 + return $this->authUrl_v2($identifier_select);
  603 + }
  604 + return $this->authUrl_v1();
  605 + }
  606 +
  607 + /**
  608 + * Performs OpenID verification with the OP.
  609 + * @return Bool Whether the verification was successful.
  610 + * @throws ErrorException
  611 + */
  612 + function validate()
  613 + {
  614 + $this->claimed_id = isset($this->data['openid_claimed_id'])?$this->data['openid_claimed_id']:$this->data['openid_identity'];
  615 + $params = array(
  616 + 'openid.assoc_handle' => $this->data['openid_assoc_handle'],
  617 + 'openid.signed' => $this->data['openid_signed'],
  618 + 'openid.sig' => $this->data['openid_sig'],
  619 + );
  620 +
  621 + if (isset($this->data['openid_ns'])) {
  622 + # We're dealing with an OpenID 2.0 server, so let's set an ns
  623 + # Even though we should know location of the endpoint,
  624 + # we still need to verify it by discovery, so $server is not set here
  625 + $params['openid.ns'] = 'http://specs.openid.net/auth/2.0';
  626 + } elseif (isset($this->data['openid_claimed_id'])
  627 + && $this->data['openid_claimed_id'] != $this->data['openid_identity']
  628 + ) {
  629 + # If it's an OpenID 1 provider, and we've got claimed_id,
  630 + # we have to append it to the returnUrl, like authUrl_v1 does.
  631 + $this->returnUrl .= (strpos($this->returnUrl, '?') ? '&' : '?')
  632 + . 'openid.claimed_id=' . $this->claimed_id;
  633 + }
  634 +
  635 + if ($this->data['openid_return_to'] != $this->returnUrl) {
  636 + # The return_to url must match the url of current request.
  637 + # I'm assuing that noone will set the returnUrl to something that doesn't make sense.
  638 + return false;
  639 + }
  640 +
  641 + $server = $this->discover($this->claimed_id);
  642 +
  643 + foreach (explode(',', $this->data['openid_signed']) as $item) {
  644 + # Checking whether magic_quotes_gpc is turned on, because
  645 + # the function may fail if it is. For example, when fetching
  646 + # AX namePerson, it might containg an apostrophe, which will be escaped.
  647 + # In such case, validation would fail, since we'd send different data than OP
  648 + # wants to verify. stripslashes() should solve that problem, but we can't
  649 + # use it when magic_quotes is off.
  650 + $value = $this->data['openid_' . str_replace('.','_',$item)];
  651 + $params['openid.' . $item] = get_magic_quotes_gpc() ? stripslashes($value) : $value;
  652 +
  653 + }
  654 +
  655 + $params['openid.mode'] = 'check_authentication';
  656 + $response = $this->request($server, 'POST', $params);
  657 + return preg_match('/is_valid\s*:\s*true/i', $response);
  658 + }
  659 +
  660 + protected function getAxAttributes()
  661 + {
  662 + $alias = null;
  663 + if (isset($this->data['openid_ns_ax'])
  664 + && $this->data['openid_ns_ax'] != 'http://openid.net/srv/ax/1.0'
  665 + ) { # It's the most likely case, so we'll check it before
  666 + $alias = 'ax';
  667 + } else {
  668 + # 'ax' prefix is either undefined, or points to another extension,
  669 + # so we search for another prefix
  670 + foreach ($this->data as $key => $val) {
  671 + if (substr($key, 0, strlen('openid_ns_')) == 'openid_ns_'
  672 + && $val == 'http://openid.net/srv/ax/1.0'
  673 + ) {
  674 + $alias = substr($key, strlen('openid_ns_'));
  675 + break;
  676 + }
  677 + }
  678 + }
  679 + if (!$alias) {
  680 + # An alias for AX schema has not been found,
  681 + # so there is no AX data in the OP's response
  682 + return array();
  683 + }
  684 +
  685 + $attributes = array();
  686 + foreach ($this->data as $key => $value) {
  687 + $keyMatch = 'openid_' . $alias . '_value_';
  688 + if (substr($key, 0, strlen($keyMatch)) != $keyMatch) {
  689 + continue;
  690 + }
  691 + $key = substr($key, strlen($keyMatch));
  692 + if (!isset($this->data['openid_' . $alias . '_type_' . $key])) {
  693 + # OP is breaking the spec by returning a field without
  694 + # associated ns. This shouldn't happen, but it's better
  695 + # to check, than cause an E_NOTICE.
  696 + continue;
  697 + }
  698 + $key = substr($this->data['openid_' . $alias . '_type_' . $key],
  699 + strlen('http://axschema.org/'));
  700 + $attributes[$key] = $value;
  701 + }
  702 + return $attributes;
  703 + }
  704 +
  705 + protected function getSregAttributes()
  706 + {
  707 + $attributes = array();
  708 + $sreg_to_ax = array_flip(self::$ax_to_sreg);
  709 + foreach ($this->data as $key => $value) {
  710 + $keyMatch = 'openid_sreg_';
  711 + if (substr($key, 0, strlen($keyMatch)) != $keyMatch) {
  712 + continue;
  713 + }
  714 + $key = substr($key, strlen($keyMatch));
  715 + if (!isset($sreg_to_ax[$key])) {
  716 + # The field name isn't part of the SREG spec, so we ignore it.
  717 + continue;
  718 + }
  719 + $attributes[$sreg_to_ax[$key]] = $value;
  720 + }
  721 + return $attributes;
  722 + }
  723 +
  724 + /**
  725 + * Gets AX/SREG attributes provided by OP. should be used only after successful validaton.
  726 + * Note that it does not guarantee that any of the required/optional parameters will be present,
  727 + * or that there will be no other attributes besides those specified.
  728 + * In other words. OP may provide whatever information it wants to.
  729 + * * SREG names will be mapped to AX names.
  730 + * * @return Array Array of attributes with keys being the AX schema names, e.g. 'contact/email'
  731 + * @see http://www.axschema.org/types/
  732 + */
  733 + function getAttributes()
  734 + {
  735 + if (isset($this->data['openid_ns'])
  736 + && $this->data['openid_ns'] == 'http://specs.openid.net/auth/2.0'
  737 + ) { # OpenID 2.0
  738 + # We search for both AX and SREG attributes, with AX taking precedence.
  739 + return $this->getAxAttributes() + $this->getSregAttributes();
  740 + }
  741 + return $this->getSregAttributes();
  742 + }
  743 +}
... ...
pacotes/openid/provider/example-mysql.php 0 → 100644
... ... @@ -0,0 +1,194 @@
  1 +<?php
  2 +/**
  3 + * This example shows several things:
  4 + * - How a setup interface should look like.
  5 + * - How to use a mysql table for authentication
  6 + * - How to store associations in mysql table, instead of php sessions.
  7 + * - How to store realm authorizations.
  8 + * - How to send AX/SREG parameters.
  9 + * For the example to work, you need to create the necessary tables:
  10 +CREATE TABLE Users (
  11 + id INT NOT NULL auto_increment PRIMARY KEY,
  12 + login VARCHAR(32) NOT NULL,
  13 + password CHAR(40) NOT NULL,
  14 + firstName VARCHAR(32) NOT NULL,
  15 + lastName VARCHAR(32) NOT NULL
  16 +);
  17 +
  18 +CREATE TABLE AllowedSites (
  19 + user INT NOT NULL,
  20 + realm TEXT NOT NULL,
  21 + attributes TEXT NOT NULL,
  22 + INDEX(user)
  23 +);
  24 +
  25 +CREATE TABLE Associations (
  26 + id INT NOT NULL PRIMARY KEY,
  27 + data TEXT NOT NULL
  28 +);
  29 + *
  30 + * This is only an example. Don't use it in your code as-is.
  31 + * It has several security flaws, which you shouldn't copy (like storing plaintext login and password in forms).
  32 + *
  33 + * This setup could be very easily flooded with many associations,
  34 + * since non-private ones aren't automatically deleted.
  35 + * You could prevent this by storing a date of association and removing old ones,
  36 + * or by setting $this->dh = false;
  37 + * However, the latter one would disable stateful mode, unless connecting via HTTPS.
  38 + */
  39 +require 'provider.php';
  40 +
  41 +mysql_connect();
  42 +mysql_select_db('test');
  43 +
  44 +function getUserData($handle=null)
  45 +{
  46 + if(isset($_POST['login'],$_POST['password'])) {
  47 + $login = mysql_real_escape_string($_POST['login']);
  48 + $password = sha1($_POST['password']);
  49 + $q = mysql_query("SELECT * FROM Users WHERE login = '$login' AND password = '$password'");
  50 + if($data = mysql_fetch_assoc($q)) {
  51 + return $data;
  52 + }
  53 + if($handle) {
  54 + echo 'Wrong login/password.';
  55 + }
  56 + }
  57 + if($handle) {
  58 + ?>
  59 + <form action="" method="post">
  60 + <input type="hidden" name="openid.assoc_handle" value="<?php echo $handle?>">
  61 + Login: <input type="text" name="login"><br>
  62 + Password: <input type="password" name="password"><br>
  63 + <button>Submit</button>
  64 + </form>
  65 + <?php
  66 + die();
  67 + }
  68 +}
  69 +
  70 +class MysqlProvider extends LightOpenIDProvider
  71 +{
  72 + private $attrMap = array(
  73 + 'namePerson/first' => 'First name',
  74 + 'namePerson/last' => 'Last name',
  75 + 'namePerson/friendly' => 'Nickname (login)'
  76 + );
  77 +
  78 + private $attrFieldMap = array(
  79 + 'namePerson/first' => 'firstName',
  80 + 'namePerson/last' => 'lastName',
  81 + 'namePerson/friendly' => 'login'
  82 + );
  83 +
  84 + function setup($identity, $realm, $assoc_handle, $attributes)
  85 + {
  86 + $data = getUserData($assoc_handle);
  87 + echo '<form action="" method="post">'
  88 + . '<input type="hidden" name="openid.assoc_handle" value="' . $assoc_handle . '">'
  89 + . '<input type="hidden" name="login" value="' . $_POST['login'] .'">'
  90 + . '<input type="hidden" name="password" value="' . $_POST['password'] .'">'
  91 + . "<b>$realm</b> wishes to authenticate you.";
  92 + if($attributes['required'] || $attributes['optional']) {
  93 + echo " It also requests following information (required fields marked with *):"
  94 + . '<ul>';
  95 +
  96 + foreach($attributes['required'] as $attr) {
  97 + if(isset($this->attrMap[$attr])) {
  98 + echo '<li>'
  99 + . '<input type="checkbox" name="attributes[' . $attr . ']"> '
  100 + . $this->attrMap[$attr] . '(*)</li>';
  101 + }
  102 + }
  103 +
  104 + foreach($attributes['optional'] as $attr) {
  105 + if(isset($this->attrMap[$attr])) {
  106 + echo '<li>'
  107 + . '<input type="checkbox" name="attributes[' . $attr . ']"> '
  108 + . $this->attrMap[$attr] . '</li>';
  109 + }
  110 + }
  111 + echo '</ul>';
  112 + }
  113 + echo '<br>'
  114 + . '<button name="once">Allow once</button> '
  115 + . '<button name="always">Always allow</button> '
  116 + . '<button name="cancel">cancel</button> '
  117 + . '</form>';
  118 + }
  119 +
  120 + function checkid($realm, &$attributes)
  121 + {
  122 + if(isset($_POST['cancel'])) {
  123 + $this->cancel();
  124 + }
  125 +
  126 + $data = getUserData();
  127 + if(!$data) {
  128 + return false;
  129 + }
  130 + $realm = mysql_real_escape_string($realm);
  131 + $q = mysql_query("SELECT attributes FROM AllowedSites WHERE user = '{$data['id']}' AND realm = '$realm'");
  132 +
  133 + $attrs = array();
  134 + if($attrs = mysql_fetch_row($q)) {
  135 + $attrs = explode(',', $attributes[0]);
  136 + } elseif(isset($_POST['attributes'])) {
  137 + $attrs = array_keys($_POST['attributes']);
  138 + } elseif(!isset($_POST['once']) && !isset($_POST['always'])) {
  139 + return false;
  140 + }
  141 +
  142 + $attributes = array();
  143 + foreach($attrs as $attr) {
  144 + if(isset($this->attrFieldMap[$attr])) {
  145 + $attributes[$attr] = $data[$this->attrFieldMap[$attr]];
  146 + }
  147 + }
  148 +
  149 + if(isset($_POST['always'])) {
  150 + $attrs = mysql_real_escape_string(implode(',', array_keys($attributes)));
  151 + mysql_query("REPLACE INTO AllowedSites VALUES('{$data['id']}', '$realm', '$attrs')");
  152 + }
  153 +
  154 + return $this->serverLocation . '?' . $data['login'];
  155 + }
  156 +
  157 + function assoc_handle()
  158 + {
  159 + # We generate an integer assoc handle, because it's just faster to look up an integer later.
  160 + $q = mysql_query("SELECT MAX(id) FROM Associations");
  161 + $result = mysql_fetch_row($q);
  162 + return $q[0]+1;
  163 + }
  164 +
  165 + function setAssoc($handle, $data)
  166 + {
  167 + $data = mysql_real_escape_string(serialize($data));
  168 + mysql_query("REPLACE INTO Associations VALUES('$handle', '$data')");
  169 + }
  170 +
  171 + function getAssoc($handle)
  172 + {
  173 + if(!is_numeric($handle)) {
  174 + return false;
  175 + }
  176 + $q = mysql_query("SELECT data FROM Associations WHERE id = '$handle'");
  177 + $data = mysql_fetch_row($q);
  178 + if(!$data) {
  179 + return false;
  180 + }
  181 + return unserialize($data[0]);
  182 + }
  183 +
  184 + function delAssoc($handle)
  185 + {
  186 + if(!is_numeric($handle)) {
  187 + return false;
  188 + }
  189 + mysql_query("DELETE FROM Associations WHERE id = '$handle'");
  190 + }
  191 +
  192 +}
  193 +$op = new MysqlProvider;
  194 +$op->server();
... ...
pacotes/openid/provider/example.php 0 → 100644
... ... @@ -0,0 +1,53 @@
  1 +<?php
  2 +/**
  3 + * This example shows how to create a basic provider usin HTTP Authentication.
  4 + * This is only an example. You shouldn't use it as-is in your code.
  5 + */
  6 +require 'provider.php';
  7 +
  8 +class BasicProvider extends LightOpenIDProvider
  9 +{
  10 + public $select_id = true;
  11 + public $login = '';
  12 + public $password = '';
  13 +
  14 + function __construct()
  15 + {
  16 + parent::__construct();
  17 +
  18 + # If we use select_id, we must disable it for identity pages,
  19 + # so that an RP can discover it and get proper data (i.e. without select_id)
  20 + if(isset($_GET['id'])) {
  21 + $this->select_id = false;
  22 + }
  23 + }
  24 +
  25 + function setup($identity, $realm, $assoc_handle, $attributes)
  26 + {
  27 + header('WWW-Authenticate: Basic realm="' . $this->data['openid_realm'] . '"');
  28 + header('HTTP/1.0 401 Unauthorized');
  29 + }
  30 +
  31 + function checkid($realm, &$attributes)
  32 + {
  33 + if(!isset($_SERVER['PHP_AUTH_USER'])) {
  34 + return false;
  35 + }
  36 +
  37 + if ($_SERVER['PHP_AUTH_USER'] == $this->login
  38 + && $_SERVER['PHP_AUTH_PW'] == $this->password
  39 + ) {
  40 + # Returning identity
  41 + # It can be any url that leads here, or to any other place that hosts
  42 + # an XRDS document pointing here.
  43 + return $this->serverLocation . '?id=' . $this->login;
  44 + }
  45 +
  46 + return false;
  47 + }
  48 +
  49 +}
  50 +$op = new BasicProvider;
  51 +$op->login = 'test';
  52 +$op->password = 'test';
  53 +$op->server();
... ...
pacotes/openid/provider/provider.php 0 → 100644
... ... @@ -0,0 +1,833 @@
  1 +<?php
  2 +/**
  3 + * Using this class, you can easily set up an OpenID Provider.
  4 + * It's independent of LightOpenID class.
  5 + * It requires either GMP or BCMath for session encryption,
  6 + * but will work without them (although either via SSL, or in stateless mode only).
  7 + * Also, it requires PHP >= 5.1.2
  8 + *
  9 + * This is an alpha version, using it in production code is not recommended,
  10 + * until you are *sure* that it works and is secure.
  11 + *
  12 + * Please send me messages about your testing results
  13 + * (even if successful, so I know that it has been tested).
  14 + * Also, if you think there's a way to make it easier to use, tell me -- it's an alpha for a reason.
  15 + * Same thing applies to bugs in code, suggestions,
  16 + * and everything else you'd like to say about the library.
  17 + *
  18 + * There's no usage documentation here, see the examples.
  19 + *
  20 + * @author Mewp
  21 + * @copyright Copyright (c) 2010, Mewp
  22 + * @license http://www.opensource.org/licenses/mit-license.php MIT
  23 + */
  24 +ini_set('error_log','log');
  25 +abstract class LightOpenIDProvider
  26 +{
  27 + # URL-s to XRDS and server location.
  28 + public $xrdsLocation, $serverLocation;
  29 +
  30 + # Should we operate in server, or signon mode?
  31 + public $select_id = false;
  32 +
  33 + # Lifetime of an association.
  34 + protected $assoc_lifetime = 600;
  35 +
  36 + # Variables below are either set automatically, or are constant.
  37 + # -----
  38 + # Can we support DH?
  39 + protected $dh = true;
  40 + protected $ns = 'http://specs.openid.net/auth/2.0';
  41 + protected $data, $assoc;
  42 +
  43 + # Default DH parameters as defined in the specification.
  44 + protected $default_modulus;
  45 + protected $default_gen = 'Ag==';
  46 +
  47 + # AX <-> SREG transform
  48 + protected $ax_to_sreg = array(
  49 + 'namePerson/friendly' => 'nickname',
  50 + 'contact/email' => 'email',
  51 + 'namePerson' => 'fullname',
  52 + 'birthDate' => 'dob',
  53 + 'person/gender' => 'gender',
  54 + 'contact/postalCode/home' => 'postcode',
  55 + 'contact/country/home' => 'country',
  56 + 'pref/language' => 'language',
  57 + 'pref/timezone' => 'timezone',
  58 + );
  59 +
  60 + # Math
  61 + private $add, $mul, $pow, $mod, $div, $powmod;
  62 + # -----
  63 +
  64 + # ------------------------------------------------------------------------ #
  65 + # Functions you probably want to implement when extending the class.
  66 +
  67 + /**
  68 + * Checks whether an user is authenticated.
  69 + * The function should determine what fields it wants to send to the RP,
  70 + * and put them in the $attributes array.
  71 + * @param Array $attributes
  72 + * @param String $realm Realm used for authentication.
  73 + * @return String OP-local identifier of an authenticated user, or an empty value.
  74 + */
  75 + abstract function checkid($realm, &$attributes);
  76 +
  77 + /**
  78 + * Displays an user interface for inputting user's login and password.
  79 + * Attributes are always AX field namespaces, with stripped host part.
  80 + * For example, the $attributes array may be:
  81 + * array( 'required' => array('namePerson/friendly', 'contact/email'),
  82 + * 'optional' => array('pref/timezone', 'pref/language')
  83 + * @param String $identity Discovered identity string. May be used to extract login, unless using $this->select_id
  84 + * @param String $realm Realm used for authentication.
  85 + * @param String Association handle. must be sent as openid.assoc_handle in $_GET or $_POST in subsequent requests.
  86 + * @param Array User attributes requested by the RP.
  87 + */
  88 + abstract function setup($identity, $realm, $assoc_handle, $attributes);
  89 +
  90 + /**
  91 + * Stores an association.
  92 + * If you want to use php sessions in your provider code, you have to replace it.
  93 + * @param String $handle Association handle -- should be used as a key.
  94 + * @param Array $assoc Association data.
  95 + */
  96 + protected function setAssoc($handle, $assoc)
  97 + {
  98 + if(session_id()) session_destroy();
  99 + session_id($assoc['handle']);
  100 + session_start();
  101 + $_SESSION['assoc'] = $assoc;
  102 + session_commit();
  103 + session_id('');
  104 + }
  105 +
  106 + /**
  107 + * Retreives association data.
  108 + * If you want to use php sessions in your provider code, you have to replace it.
  109 + * @param String $handle Association handle.
  110 + * @return Array Association data.
  111 + */
  112 + protected function getAssoc($handle)
  113 + {
  114 + if(session_id()) session_destroy();
  115 + session_id($handle);
  116 + session_start();
  117 + if(empty($_SESSION['assoc'])) {
  118 + return null;
  119 + }
  120 + return $_SESSION['assoc'];
  121 + session_commit();
  122 + session_id('');
  123 + }
  124 +
  125 + /**
  126 + * Deletes an association.
  127 + * If you want to use php sessions in your provider code, you have to replace it.
  128 + * @param String $handle Association handle.
  129 + */
  130 + protected function delAssoc($handle)
  131 + {
  132 + if(session_id()) session_destroy();
  133 + session_id($handle);
  134 + session_start();
  135 + session_destroy();
  136 + session_id('');
  137 + }
  138 +
  139 + # ------------------------------------------------------------------------ #
  140 + # Functions that you might want to implement.
  141 +
  142 + /**
  143 + * Redirects the user to an url.
  144 + * @param String $location The url that the user will be redirected to.
  145 + */
  146 + protected function redirect($location)
  147 + {
  148 + header('Location: ' . $location);
  149 + die();
  150 + }
  151 +
  152 + /**
  153 + * Generates a new association handle.
  154 + * @return string
  155 + */
  156 + protected function assoc_handle()
  157 + {
  158 + return sha1(microtime());
  159 + }
  160 +
  161 + /**
  162 + * Generates a random shared secret.
  163 + * @return string
  164 + */
  165 + protected function shared_secret($hash)
  166 + {
  167 + $length = 20;
  168 + if($hash == 'sha256') {
  169 + $length = 256;
  170 + }
  171 +
  172 + $secret = '';
  173 + for($i = 0; $i < $length; $i++) {
  174 + $secret .= mt_rand(0,255);
  175 + }
  176 +
  177 + return $secret;
  178 + }
  179 +
  180 + /**
  181 + * Generates a private key.
  182 + * @param int $length Length of the key.
  183 + */
  184 + protected function keygen($length)
  185 + {
  186 + $key = '';
  187 + for($i = 1; $i < $length; $i++) {
  188 + $key .= mt_rand(0,9);
  189 + }
  190 + $key .= mt_rand(1,9);
  191 +
  192 + return $key;
  193 + }
  194 +
  195 + # ------------------------------------------------------------------------ #
  196 + # Functions that you probably shouldn't touch.
  197 +
  198 + function __construct()
  199 + {
  200 + $this->default_modulus =
  201 + 'ANz5OguIOXLsDhmYmsWizjEOHTdxfo2Vcbt2I3MYZuYe91ouJ4mLBX+YkcLiemOcPy'
  202 + . 'm2CBRYHNOyyjmG0mg3BVd9RcLn5S3IHHoXGHblzqdLFEi/368Ygo79JRnxTkXjgmY0'
  203 + . 'rxlJ5bU1zIKaSDuKdiI+XUkKJX8Fvf8W8vsixYOr';
  204 +
  205 + $location = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://'
  206 + . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  207 + $location = preg_replace('/\?.*/','',$location);
  208 + $this->serverLocation = $location;
  209 + $location .= (strpos($location, '?') ? '&' : '?') . 'xrds';
  210 + $this->xrdsLocation = $location;
  211 +
  212 + $this->data = $_GET + $_POST;
  213 +
  214 + # We choose GMP if avaiable, and bcmath otherwise
  215 + if(function_exists('gmp_add')) {
  216 + $this->add = 'gmp_add';
  217 + $this->mul = 'gmp_mul';
  218 + $this->pow = 'gmp_pow';
  219 + $this->mod = 'gmp_mod';
  220 + $this->div = 'gmp_div';
  221 + $this->powmod = 'gmp_powm';
  222 + } elseif(function_exists('bcadd')) {
  223 + $this->add = 'bcadd';
  224 + $this->mul = 'bcmul';
  225 + $this->pow = 'bcpow';
  226 + $this->mod = 'bcmod';
  227 + $this->div = 'bcdiv';
  228 + $this->powmod = 'bcpowmod';
  229 + } else {
  230 + # If neither are avaiable, we can't use DH
  231 + $this->dh = false;
  232 + }
  233 +
  234 + # However, we do require the hash functions.
  235 + # They should be built-in anyway.
  236 + if(!function_exists('hash_algos')) {
  237 + $this->dh = false;
  238 + }
  239 + }
  240 +
  241 + /**
  242 + * Displays an XRDS document, or redirects to it.
  243 + * By default, it detects whether it should display or redirect automatically.
  244 + * @param bool|null $force When true, always display the document, when false always redirect.
  245 + */
  246 + function xrds($force=null)
  247 + {
  248 + if($force) {
  249 + echo $this->xrdsContent();
  250 + die();
  251 + } elseif($force === false) {
  252 + header('X-XRDS-Location: '. $this->xrdsLocation);
  253 + return;
  254 + }
  255 +
  256 + if (isset($_GET['xrds'])
  257 + || (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'application/xrds+xml') !== false)
  258 + ) {
  259 + header('Content-Type: application/xrds+xml');
  260 + echo $this->xrdsContent();
  261 + die();
  262 + }
  263 +
  264 + header('X-XRDS-Location: ' . $this->xrdsLocation);
  265 + }
  266 +
  267 + /**
  268 + * Returns the content of the XRDS document
  269 + * @return String The XRDS document.
  270 + */
  271 + protected function xrdsContent()
  272 + {
  273 + $lines = array(
  274 + '<?xml version="1.0" encoding="UTF-8"?>',
  275 + '<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">',
  276 + '<XRD>',
  277 + ' <Service>',
  278 + ' <Type>' . $this->ns . '/' . ($this->select_id ? 'server' : 'signon') .'</Type>',
  279 + ' <URI>' . $this->serverLocation . '</URI>',
  280 + ' </Service>',
  281 + '</XRD>',
  282 + '</xrds:XRDS>'
  283 + );
  284 + return implode("\n", $lines);
  285 + }
  286 +
  287 + /**
  288 + * Does everything that a provider has to -- in one function.
  289 + */
  290 + function server()
  291 + {
  292 + if(isset($this->data['openid_assoc_handle'])) {
  293 + $this->assoc = $this->getAssoc($this->data['openid_assoc_handle']);
  294 + if(isset($this->assoc['data'])) {
  295 + # We have additional data stored for setup.
  296 + $this->data += $this->assoc['data'];
  297 + unset($this->assoc['data']);
  298 + }
  299 + }
  300 +
  301 + if (isset($this->data['openid_ns'])
  302 + && $this->data['openid_ns'] == $this->ns
  303 + ) {
  304 + if(!isset($this->data['openid_mode'])) $this->errorResponse();
  305 +
  306 + switch($this->data['openid_mode'])
  307 + {
  308 + case 'checkid_immediate':
  309 + case 'checkid_setup':
  310 + $this->checkRealm();
  311 + # We support AX xor SREG.
  312 + $attributes = $this->ax();
  313 + if(!$attributes) {
  314 + $attributes = $this->sreg();
  315 + }
  316 +
  317 + # Even if some user is authenticated, we need to know if it's
  318 + # the same one that want's to authenticate.
  319 + # Of course, if we use select_id, we accept any user.
  320 + if (($identity = $this->checkid($this->data['openid_realm'], $attrValues))
  321 + && ($this->select_id || $identity == $this->data['openid_identity'])
  322 + ) {
  323 + $this->positiveResponse($identity, $attrValues);
  324 + } elseif($this->data['openid_mode'] == 'checkid_immediate') {
  325 + $this->redirect($this->response(array('openid.mode' => 'setup_needed')));
  326 + } else {
  327 + if(!$this->assoc) {
  328 + $this->generateAssociation();
  329 + $this->assoc['private'] = true;
  330 + }
  331 + $this->assoc['data'] = $this->data;
  332 + $this->setAssoc($this->assoc['handle'], $this->assoc);
  333 + $this->setup($this->data['openid_identity'],
  334 + $this->data['openid_realm'],
  335 + $this->assoc['handle'],
  336 + $attributes);
  337 + }
  338 + break;
  339 + case 'associate':
  340 + $this->associate();
  341 + break;
  342 + case 'check_authentication':
  343 + $this->checkRealm();
  344 + if($this->verify()) {
  345 + echo "ns:$this->ns\nis_valid:true";
  346 + if(strpos($this->data['openid_signed'],'invalidate_handle') !== false) {
  347 + echo "\ninvalidate_handle:" . $this->data['openid_invalidate_handle'];
  348 + }
  349 + } else {
  350 + echo "ns:$this->ns\nis_valid:false";
  351 + }
  352 + die();
  353 + break;
  354 + default:
  355 + $this->errorResponse();
  356 + }
  357 + } else {
  358 + $this->xrds();
  359 + }
  360 + }
  361 +
  362 + protected function checkRealm()
  363 + {
  364 + if (!isset($this->data['openid_return_to'], $this->data['openid_realm'])) {
  365 + $this->errorResponse();
  366 + }
  367 +
  368 + $realm = str_replace('\*', '[^/]', preg_quote($this->data['openid_realm']));
  369 + if(!preg_match("#^$realm#", $this->data['openid_return_to'])) {
  370 + $this->errorResponse();
  371 + }
  372 + }
  373 +
  374 + protected function ax()
  375 + {
  376 + # Namespace prefix that the fields must have.
  377 + $ns = 'http://axschema.org/';
  378 +
  379 + # First, we must find out what alias is used for AX.
  380 + # Let's check the most likely one
  381 + $alias = null;
  382 + if (isset($this->data['openid_ns_ax'])
  383 + && $this->data['openid_ns_ax'] == 'http://openid.net/srv/ax/1.0'
  384 + ) {
  385 + $alias = 'ax';
  386 + } else {
  387 + foreach($this->data as $name => $value) {
  388 + if ($value == 'http://openid.net/srv/ax/1.0'
  389 + && preg_match('/openid_ns_(.+)/', $name, $m)
  390 + ) {
  391 + $alias = $m[1];
  392 + break;
  393 + }
  394 + }
  395 + }
  396 +
  397 + if(!$alias) {
  398 + return null;
  399 + }
  400 +
  401 + $fields = array();
  402 + # Now, we must search again, this time for field aliases
  403 + foreach($this->data as $name => $value) {
  404 + if (strpos($name, 'openid_' . $alias . '_type') === false
  405 + || strpos($value, $ns) === false) {
  406 + continue;
  407 + }
  408 +
  409 + $name = substr($name, strlen('openid_' . $alias . '_type_'));
  410 + $value = substr($value, strlen($ns));
  411 +
  412 + $fields[$name] = $value;
  413 + }
  414 +
  415 + # Then, we find out what fields are required and optional
  416 + $required = array();
  417 + $if_available = array();
  418 + foreach(array('required','if_available') as $type) {
  419 + if(empty($this->data["openid_{$alias}_{$type}"])) {
  420 + continue;
  421 + }
  422 + $attributes = explode(',', $this->data["openid_{$alias}_{$type}"]);
  423 + foreach($attributes as $attr) {
  424 + if(empty($fields[$attr])) {
  425 + # There is an undefined field here, so we ignore it.
  426 + continue;
  427 + }
  428 +
  429 + ${$type}[] = $fields[$attr];
  430 + }
  431 + }
  432 +
  433 + $this->data['ax'] = true;
  434 + return array('required' => $required, 'optional' => $if_available);
  435 + }
  436 +
  437 + protected function sreg()
  438 + {
  439 + $sreg_to_ax = array_flip($this->ax_to_sreg);
  440 +
  441 + $attributes = array('required' => array(), 'optional' => array());
  442 +
  443 + if (empty($this->data['openid_sreg_required'])
  444 + && empty($this->data['openid_sreg_optional'])
  445 + ) {
  446 + return $attributes;
  447 + }
  448 +
  449 + foreach(array('required', 'optional') as $type) {
  450 + foreach(explode(',',$this->data['openid_sreg_' . $type]) as $attr) {
  451 + if(empty($sreg_to_ax[$attr])) {
  452 + # Undefined attribute in SREG request.
  453 + # Shouldn't happen, but we check anyway.
  454 + continue;
  455 + }
  456 +
  457 + $attributes[$type][] = $sreg_to_ax[$attr];
  458 + }
  459 + }
  460 +
  461 + return $attributes;
  462 + }
  463 +
  464 + /**
  465 + * Aids an RP in assertion verification.
  466 + * @return bool Information whether the verification suceeded.
  467 + */
  468 + protected function verify()
  469 + {
  470 + # Firstly, we need to make sure that there's an association.
  471 + # Otherwise the verification will fail,
  472 + # because we've signed assoc_handle in the assertion
  473 + if(empty($this->assoc)) {
  474 + return false;
  475 + }
  476 +
  477 + # Next, we check that it's a private association,
  478 + # i.e. one made without RP input.
  479 + # Otherwise, the RP shouldn't ask us to verify.
  480 + if(empty($this->assoc['private'])) {
  481 + return false;
  482 + }
  483 +
  484 + # Now we have to check if the nonce is correct, to prevent replay attacks.
  485 + if($this->data['openid_response_nonce'] != $this->assoc['nonce']) {
  486 + return false;
  487 + }
  488 +
  489 + # Getting the signed fields for signature.
  490 + $sig = array();
  491 + $signed = explode(',', $this->data['openid_signed']);
  492 + foreach($signed as $field) {
  493 + $name = strtr($field, '.', '_');
  494 + if(!isset($this->data['openid_' . $name])) {
  495 + return false;
  496 + }
  497 +
  498 + $sig[$field] = $this->data['openid_' . $name];
  499 + }
  500 +
  501 + # Computing the signature and checking if it matches.
  502 + $sig = $this->keyValueForm($sig);
  503 + if ($this->data['openid_sig'] !=
  504 + base64_encode(hash_hmac($this->assoc['hash'], $sig, $this->assoc['mac'], true))
  505 + ) {
  506 + return false;
  507 + }
  508 +
  509 + # Clearing the nonce, so that it won't be used again.
  510 + $this->assoc['nonce'] = null;
  511 +
  512 + if(empty($this->assoc['private'])) {
  513 + # Commiting changes to the association.
  514 + $this->setAssoc($this->assoc['handle'], $this->assoc);
  515 + } else {
  516 + # Private associations shouldn't be used again, se we can as well delete them.
  517 + $this->delAssoc($this->assoc['handle']);
  518 + }
  519 +
  520 + # Nothing has failed, so the verification was a success.
  521 + return true;
  522 + }
  523 +
  524 + /**
  525 + * Performs association with an RP.
  526 + */
  527 + protected function associate()
  528 + {
  529 + # Rejecting no-encryption without TLS.
  530 + if(empty($_SERVER['HTTPS']) && $this->data['openid_session_type'] == 'no-encryption') {
  531 + $this->directErrorResponse();
  532 + }
  533 +
  534 + # Checking whether we support DH at all.
  535 + if (!$this->dh && substr($this->data['openid_session_type'], 0, 2) == 'DH') {
  536 + $this->redirect($this->response(array(
  537 + 'openid.error' => 'DH not supported',
  538 + 'openid.error_code' => 'unsupported-type',
  539 + 'openid.session_type' => 'no-encryption'
  540 + )));
  541 + }
  542 +
  543 + # Creating the association
  544 + $this->assoc = array();
  545 + $this->assoc['hash'] = $this->data['openid_assoc_type'] == 'HMAC-SHA256' ? 'sha256' : 'sha1';
  546 + $this->assoc['handle'] = $this->assoc_handle();
  547 +
  548 + # Getting the shared secret
  549 + if($this->data['openid_session_type'] == 'no-encryption') {
  550 + $this->assoc['mac'] = base64_encode($this->shared_secret($this->assoc['hash']));
  551 + } else {
  552 + $this->dh();
  553 + }
  554 +
  555 + # Preparing the direct response...
  556 + $response = array(
  557 + 'ns' => $this->ns,
  558 + 'assoc_handle' => $this->assoc['handle'],
  559 + 'assoc_type' => $this->data['openid_assoc_type'],
  560 + 'session_type' => $this->data['openid_session_type'],
  561 + 'expires_in' => $this->assoc_lifetime
  562 + );
  563 +
  564 + if(isset($this->assoc['dh_server_public'])) {
  565 + $response['dh_server_public'] = $this->assoc['dh_server_public'];
  566 + $response['enc_mac_key'] = $this->assoc['mac'];
  567 + } else {
  568 + $response['mac_key'] = $this->assoc['mac'];
  569 + }
  570 +
  571 + # ...and sending it.
  572 + echo $this->keyValueForm($response);
  573 + die();
  574 + }
  575 +
  576 + /**
  577 + * Creates a private association.
  578 + */
  579 + protected function generateAssociation()
  580 + {
  581 + $this->assoc = array();
  582 + # We use sha1 by default.
  583 + $this->assoc['hash'] = 'sha1';
  584 + $this->assoc['mac'] = $this->shared_secret('sha1');
  585 + $this->assoc['handle'] = $this->assoc_handle();
  586 + }
  587 +
  588 + /**
  589 + * Encrypts the MAC key using DH key exchange.
  590 + */
  591 + protected function dh()
  592 + {
  593 + if(empty($this->data['openid_dh_modulus'])) {
  594 + $this->data['openid_dh_modulus'] = $this->default_modulus;
  595 + }
  596 +
  597 + if(empty($this->data['openid_dh_gen'])) {
  598 + $this->data['openid_dh_gen'] = $this->default_gen;
  599 + }
  600 +
  601 + if(empty($this->data['openid_dh_consumer_public'])) {
  602 + $this->directErrorResponse();
  603 + }
  604 +
  605 + $modulus = $this->b64dec($this->data['openid_dh_modulus']);
  606 + $gen = $this->b64dec($this->data['openid_dh_gen']);
  607 + $consumerKey = $this->b64dec($this->data['openid_dh_consumer_public']);
  608 +
  609 + $privateKey = $this->keygen(strlen($modulus));
  610 + $publicKey = $this->powmod($gen, $privateKey, $modulus);
  611 + $ss = $this->powmod($consumerKey, $privateKey, $modulus);
  612 +
  613 + $mac = $this->x_or(hash($this->assoc['hash'], $ss, true), $this->shared_secret($this->assoc['hash']));
  614 + $this->assoc['dh_server_public'] = $this->decb64($publicKey);
  615 + $this->assoc['mac'] = base64_encode($mac);
  616 + }
  617 +
  618 + /**
  619 + * XORs two strings.
  620 + * @param String $a
  621 + * @param String $b
  622 + * @return String $a ^ $b
  623 + */
  624 + protected function x_or($a, $b)
  625 + {
  626 + $length = strlen($a);
  627 + for($i = 0; $i < $length; $i++) {
  628 + $a[$i] = $a[$i] ^ $b[$i];
  629 + }
  630 +
  631 + return $a;
  632 + }
  633 +
  634 + /**
  635 + * Prepares an indirect response url.
  636 + * @param array $params Parameters to be sent.
  637 + */
  638 + protected function response($params)
  639 + {
  640 + $params += array('openid.ns' => $this->ns);
  641 + return $this->data['openid_return_to']
  642 + . (strpos($this->data['openid_return_to'],'?') ? '&' : '?')
  643 + . http_build_query($params, '', '&');
  644 + }
  645 +
  646 + /**
  647 + * Outputs a direct error.
  648 + */
  649 + protected function errorResponse()
  650 + {
  651 + if(!empty($this->data['openid_return_to'])) {
  652 + $response = array(
  653 + 'openid.mode' => 'error',
  654 + 'openid.error' => 'Invalid request'
  655 + );
  656 + $this->redirect($this->response($response));
  657 + } else {
  658 + header('HTTP/1.1 400 Bad Request');
  659 + $response = array(
  660 + 'ns' => $this->ns,
  661 + 'error' => 'Invalid request'
  662 + );
  663 + echo $this->keyValueForm($response);
  664 + }
  665 + die();
  666 + }
  667 +
  668 + /**
  669 + * Sends an positive assertion.
  670 + * @param String $identity the OP-Local Identifier that is being authenticated.
  671 + * @param Array $attributes User attributes to be sent.
  672 + */
  673 + protected function positiveResponse($identity, $attributes)
  674 + {
  675 + # We generate a private association if there is none established.
  676 + if(!$this->assoc) {
  677 + $this->generateAssociation();
  678 + $this->assoc['private'] = true;
  679 + }
  680 +
  681 + # We set openid.identity (and openid.claimed_id if necessary) to our $identity
  682 + if($this->data['openid_identity'] == $this->data['openid_claimed_id']) {
  683 + $this->data['openid_claimed_id'] = $identity;
  684 + }
  685 + $this->data['openid_identity'] = $identity;
  686 +
  687 + # Preparing fields to be signed
  688 + $params = array(
  689 + 'op_endpoint' => $this->serverLocation,
  690 + 'claimed_id' => $this->data['openid_claimed_id'],
  691 + 'identity' => $this->data['openid_identity'],
  692 + 'return_to' => $this->data['openid_return_to'],
  693 + 'realm' => $this->data['openid_realm'],
  694 + 'response_nonce' => gmdate("Y-m-d\TH:i:s\Z"),
  695 + 'assoc_handle' => $this->assoc['handle'],
  696 + );
  697 +
  698 + $params += $this->responseAttributes($attributes);
  699 +
  700 + # Has the RP used an invalid association handle?
  701 + if (isset($this->data['openid_assoc_handle'])
  702 + && $this->data['openid_assoc_handle'] != $this->assoc['handle']
  703 + ) {
  704 + $params['invalidate_handle'] = $this->data['openid_assoc_handle'];
  705 + }
  706 +
  707 + # Signing the $params
  708 + $sig = hash_hmac($this->assoc['hash'], $this->keyValueForm($params), $this->assoc['mac'], true);
  709 + $req = array(
  710 + 'openid.mode' => 'id_res',
  711 + 'openid.signed' => implode(',', array_keys($params)),
  712 + 'openid.sig' => base64_encode($sig),
  713 + );
  714 +
  715 + # Saving the nonce and commiting the association.
  716 + $this->assoc['nonce'] = $params['response_nonce'];
  717 + $this->setAssoc($this->assoc['handle'], $this->assoc);
  718 +
  719 + # Preparing and sending the response itself
  720 + foreach($params as $name => $value) {
  721 + $req['openid.' . $name] = $value;
  722 + }
  723 +
  724 + $this->redirect($this->response($req));
  725 + }
  726 +
  727 + /**
  728 + * Prepares an array of attributes to send
  729 + */
  730 + protected function responseAttributes($attributes)
  731 + {
  732 + if(!$attributes) return array();
  733 +
  734 + $ns = 'http://axschema.org/';
  735 +
  736 + $response = array();
  737 + if(isset($this->data['ax'])) {
  738 + $response['ns.ax'] = 'http://openid.net/srv/ax/1.0';
  739 + foreach($attributes as $name => $value) {
  740 + $alias = strtr($name, '/', '_');
  741 + $response['ax.type.' . $alias] = $ns . $name;
  742 + $response['ax.value.' . $alias] = $value;
  743 + }
  744 + return $response;
  745 + }
  746 +
  747 + foreach($attributes as $name => $value) {
  748 + if(!isset($this->ax_to_sreg[$name])) {
  749 + continue;
  750 + }
  751 +
  752 + $response['sreg.' . $this->ax_to_sreg[$name]] = $value;
  753 + }
  754 + return $response;
  755 + }
  756 +
  757 + /**
  758 + * Encodes fields in key-value form.
  759 + * @param Array $params Fields to be encoded.
  760 + * @return String $params in key-value form.
  761 + */
  762 + protected function keyValueForm($params)
  763 + {
  764 + $str = '';
  765 + foreach($params as $name => $value) {
  766 + $str .= "$name:$value\n";
  767 + }
  768 +
  769 + return $str;
  770 + }
  771 +
  772 + /**
  773 + * Responds with an information that the user has canceled authentication.
  774 + */
  775 + protected function cancel()
  776 + {
  777 + $this->redirect($this->response(array('openid.mode' => 'cancel')));
  778 + }
  779 +
  780 + /**
  781 + * Converts base64 encoded number to it's decimal representation.
  782 + * @param String $str base64 encoded number.
  783 + * @return String Decimal representation of that number.
  784 + */
  785 + protected function b64dec($str)
  786 + {
  787 + $bytes = unpack('C*', base64_decode($str));
  788 + $n = 0;
  789 + foreach($bytes as $byte) {
  790 + $n = $this->add($this->mul($n, 256), $byte);
  791 + }
  792 +
  793 + return $n;
  794 + }
  795 +
  796 + /**
  797 + * Complements b64dec.
  798 + */
  799 + protected function decb64($num)
  800 + {
  801 + $bytes = array();
  802 + while($num) {
  803 + array_unshift($bytes, $this->mod($num, 256));
  804 + $num = $this->div($num, 256);
  805 + }
  806 +
  807 + if($bytes && $bytes[0] > 127) {
  808 + array_unshift($bytes,0);
  809 + }
  810 +
  811 + array_unshift($bytes, 'C*');
  812 +
  813 + return base64_encode(call_user_func_array('pack', $bytes));
  814 + }
  815 +
  816 + function __call($name, $args)
  817 + {
  818 + switch($name) {
  819 + case 'add':
  820 + case 'mul':
  821 + case 'pow':
  822 + case 'mod':
  823 + case 'div':
  824 + case 'powmod':
  825 + if(function_exists('gmp_strval')) {
  826 + return gmp_strval(call_user_func_array($this->$name, $args));
  827 + }
  828 + return call_user_func_array($this->$name, $args);
  829 + default:
  830 + throw new BadMethodCallException();
  831 + }
  832 + }
  833 +}
... ...
pacotes/twitteroauth/DOCUMENTATION 0 → 100644
... ... @@ -0,0 +1,120 @@
  1 +TwitterOAuth documentation.
  2 +
  3 +
  4 +
  5 +GET THE CODE
  6 +====================
  7 +You can pull the latest development version using git:
  8 +git clone git://github.com/abraham/twitteroauth.git
  9 +
  10 +Or you can download the latest release by visiting:
  11 +http://github.com/abraham/twitteroauth/downloads
  12 +
  13 +
  14 +FLOW OVERVIEW
  15 +====================
  16 +1) Build TwitterOAuth object using client credentials.
  17 +2) Request temporary credentials from Twitter.
  18 +3) Build authorize URL for Twitter.
  19 +4) Redirect user to authorize URL.
  20 +5) User authorizes access and returns from Twitter.
  21 +6) Rebuild TwitterOAuth object with client credentials and temporary credentials.
  22 +7) Get token credentials from Twitter.
  23 +8) Rebuild TwitterOAuth object with client credentials and token credentials.
  24 +9) Query Twitter API.
  25 +
  26 +
  27 +TERMINOLOGY
  28 +====================
  29 +The terminology has changed since 0.1.x to better match the draft-hammer-oauth IETF
  30 +RFC. You can read that at http://tools.ietf.org/html/draft-hammer-oauth. Some of the
  31 +terms will differ from those Twitter uses as well.
  32 +
  33 +client credentials - Consumer key/secret you get when registering an app with Twitter.
  34 +temporary credentials - Previously known as the request token.
  35 +token credentials - Previously known as the access token.
  36 +
  37 +
  38 +PARAMETERS
  39 +====================
  40 +There are a number of parameters you can modify after creating a TwitterOAuth object.
  41 +
  42 +Switch to XML instead of JSON.
  43 +$connection->format = 'xml';
  44 +
  45 +Stop auto decoding JSON.
  46 +$connection->decode_json = FALSE;
  47 +
  48 +Custom useragent.
  49 +$connection->useragent = 'Custom useragent string';
  50 +
  51 +Verify Twitters SSL certificate.
  52 +$connection->ssl_verifypeer = TRUE;
  53 +
  54 +There are several more you can find in TwitterOAuth.php.
  55 +
  56 +
  57 +
  58 +EXTENDED FLOW USING EXAMPLE CODE
  59 +====================
  60 +To use TwitterOAuth with the Twitter API you need TwitterOAuth.php, OAuth.php and
  61 +client credentials. You can get client credentials by registering your application at
  62 +https://twitter.com/apps.
  63 +
  64 +The example files are explained below.
  65 +
  66 +0) Users start out on connect.php which displays the "Sign in with Twitter" image hyperlinked
  67 +to redirect.php. This button should be displayed on your homepage in your login section. The
  68 +client credentials are saved in config.php as CONSUMER_KEY and CONSUMER_SECRET. You can
  69 +save a static callback URL in the app settings page, in the config file or use a dynamic
  70 +callback URL later in step 2. In example use http://example.com/callback.php.
  71 +
  72 +1) When a user lands on redirect.php we build a new TwitterOAuth object using the client
  73 +credentials. If you have your own configuration method feel free to use it instead of config.php.
  74 +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);// Use config.php client credentials
  75 +$connection = new TwitterOAuth('abc890', '123xyz');
  76 +
  77 +2) Using the built $connection object you will ask Twitter for temporary credentials. If you
  78 +wish to have a dynamic callback URL for each user you can do pass a URL as a parameter.
  79 +$temporary_credentials = $connection->getRequestToken(); // Use applications registered callback.
  80 +$temporary_credentials = $connection->getRequestToken('http://example.com/callback.php?');
  81 +
  82 +3) Now that we have temporary credentials the user has to go to Twitter and authorize the app
  83 +to access and updates their data. You can also pass a second parameter of FALSE to not use Sign
  84 +in with Twitter: http://apiwiki.twitter.com/Sign-in-with-Twitter.
  85 +$redirect_url = $connection->getAuthorizeURL($temporary_credentials); // Use Sign in with Twitter
  86 +$redirect_url = $connection->getAuthorizeURL($temporary_credentials, FALSE);
  87 +
  88 +4) You will now have a Twitter URL that you must send the user to. You can add parameters and
  89 +they will return with the user in step 5.
  90 +https://twitter.com/oauth/authenticate?oauth_token=xyz123
  91 +https://twitter.com/oauth/authenticate?oauth_token=xyz123&info=abc // info will return with user
  92 +
  93 +5) The user is now on twitter.com and may have to login. Once authenticated with Twitter they will
  94 +will either have to click on allow/deny, or will be automatically redirected back to the callback.
  95 +
  96 +6) Now that the user has returned to callback.php and allowed access we need to build a new
  97 +TwitterOAuth object using the temporary credentials.
  98 +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $_SESSION['oauth_token'],
  99 +$_SESSION['oauth_token_secret']);
  100 +
  101 +7) Now we ask Twitter for long lasting token credentials. These are specific to the application
  102 +and user and will act like password to make future requests. If a dynamic callback URL was used
  103 +you will also have to pass the oauth_varifier parameter. Normally the token credentials would
  104 +get saved in your database but for this example we are just using sessions.
  105 +$token_credentials = $connection->getAccessToken(); // Used applications registered callback URL
  106 +$token_credentials = $connection->getAccessToken($_REQUEST['oauth_verifier']);
  107 +
  108 +7a) After getting the token credentials we redirect the user to index.php.
  109 +
  110 +8) With the token credentials we build a new TwitterOAuth object.
  111 +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token_credentials['oauth_token'],
  112 +$token_credentials['oauth_token_secret']);
  113 +
  114 +9) And finally we can make requests authenticated as the user. You can GET, POST, and DELETE API
  115 +methods. Directly copy the path from the API documentation and add an array of any parameter
  116 +you wish to include for the API method such as curser or in_reply_to_status_id.
  117 +$content = $connection->get('account/verify_credentials');
  118 +$connection->post('statuses/update', array('status' => 'Text of status here',
  119 +'in_reply_to_status_id' => 123456));
  120 +$content = $connection->delete('statuses/destroy/12345');
0 121 \ No newline at end of file
... ...
pacotes/twitteroauth/LICENSE.txt 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +Copyright (c) 2009 Abraham Williams - http://abrah.am - abraham@poseurte.ch
  2 +
  3 +Permission is hereby granted, free of charge, to any person
  4 +obtaining a copy of this software and associated documentation
  5 +files (the "Software"), to deal in the Software without
  6 +restriction, including without limitation the rights to use,
  7 +copy, modify, merge, publish, distribute, sublicense, and/or sell
  8 +copies of the Software, and to permit persons to whom the
  9 +Software is furnished to do so, subject to the following
  10 +conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be
  13 +included in all copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  17 +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19 +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20 +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21 +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22 +OTHER DEALINGS IN THE SOFTWARE.
... ...
pacotes/twitteroauth/README.txt 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +Abraham Williams | abraham@poseurte.ch | http://abrah.am | @abraham
  2 +
  3 +The first PHP library for working with Twitter's OAuth API.
  4 +
  5 +Documentation: http://wiki.github.com/abraham/twitteroauth/documentation
  6 +Source: http://github.com/abraham/twitteroauth
  7 +Twitter: http://apiwiki.twitter.com
... ...
pacotes/twitteroauth/callback.php 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +<?php
  2 +/**
  3 + * @file
  4 + * Take the user when they return from Twitter. Get access tokens.
  5 + * Verify credentials and redirect to based on response from Twitter.
  6 + */
  7 +
  8 +/* Start session and load lib */
  9 +session_name("openid");
  10 +session_start();
  11 +require_once('twitteroauth/twitteroauth.php');
  12 +require_once('config.php');
  13 +
  14 +/* If the oauth_token is old redirect to the connect page. */
  15 +if (isset($_REQUEST['oauth_token']) && $_SESSION['oauth_token'] !== $_REQUEST['oauth_token']) {
  16 + $_SESSION['oauth_status'] = 'oldtoken';
  17 + header('Location: ./clearsessions.php');
  18 +}
  19 +
  20 +/* Create TwitteroAuth object with app key/secret and token key/secret from default phase */
  21 +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $_SESSION['oauth_token'], $_SESSION['oauth_token_secret']);
  22 +
  23 +/* Request access tokens from twitter */
  24 +$access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']);
  25 +
  26 +/* Save the access tokens. Normally these would be saved in a database for future use. */
  27 +$_SESSION['access_token'] = $access_token;
  28 +
  29 +/* Remove no longer needed request tokens */
  30 +unset($_SESSION['oauth_token']);
  31 +unset($_SESSION['oauth_token_secret']);
  32 +
  33 +/* If HTTP response is 200 continue otherwise send to connect page to retry */
  34 +if (200 == $connection->http_code) {
  35 + /* The user has been verified and the access tokens can be saved for future use */
  36 + $_SESSION['status'] = 'verified';
  37 + header('Location: ./index.php');
  38 +} else {
  39 + /* Save HTTP status for error dialog on connnect page.*/
  40 + header('Location: ./clearsessions.php');
  41 +}
... ...
pacotes/twitteroauth/clearsessions.php 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<?php
  2 +/**
  3 + * @file
  4 + * Clears PHP sessions and redirects to the connect page.
  5 + */
  6 +
  7 +/* Load and clear sessions */
  8 +session_start("openid");
  9 +session_destroy();
  10 +
  11 +/* Redirect to page with the connect to Twitter option. */
  12 +header('Location: ../openid/login.php?login&erro=ok');
  13 +?>
0 14 \ No newline at end of file
... ...
pacotes/twitteroauth/config.php 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * A single location to store configuration.
  6 + */
  7 +include_once("../../ms_configura.php");
  8 +define('CONSUMER_KEY', $twitteroauth["consumerkey"]);
  9 +define('CONSUMER_SECRET', $twitteroauth["consumersecret"]);
  10 +$protocolo = explode("/",$_SERVER['SERVER_PROTOCOL']);
  11 +$urlaplic = strtolower($protocolo[0])."://".$_SERVER['HTTP_HOST']."/".basename($locaplic);
  12 +define('OAUTH_CALLBACK', $urlaplic."/pacotes/twitteroauth/callback.php");
  13 +?>
0 14 \ No newline at end of file
... ...
pacotes/twitteroauth/connect.php 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * Check if consumer token is set and if so send user to get a request token.
  6 + */
  7 +
  8 +/**
  9 + * Exit with an error message if the CONSUMER_KEY or CONSUMER_SECRET is not defined.
  10 + */
  11 +//require_once('config.php');
  12 +//include_once("redirect.php");
  13 +/*
  14 +if (CONSUMER_KEY === '' || CONSUMER_SECRET === '') {
  15 + echo 'You need a consumer key and secret to test the sample code. Get one from <a href="https://twitter.com/apps">https://twitter.com/apps</a>';
  16 + exit;
  17 +}
  18 +*/
  19 +// Build an image link to start the redirect process. */
  20 +//$content = '<a href="./redirect.php"><img src="./images/lighter.png" alt="Sign in with Twitter"/></a>';
  21 +
  22 +/* Include HTML to display on the page. */
  23 +//include('html.inc');
... ...
pacotes/twitteroauth/html.inc 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2 + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4 + <head>
  5 + <title>Twitter OAuth in PHP</title>
  6 + <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  7 + <style type="text/css">
  8 + img {border-width: 0}
  9 + * {font-family:'Lucida Grande', sans-serif;}
  10 + </style>
  11 + </head>
  12 + <body>
  13 + <div>
  14 + <h2>Welcome to a Twitter OAuth PHP example.</h2>
  15 +
  16 + <p>This site is a basic showcase of Twitters OAuth authentication method. If you are having issues try <a href='./clearsessions.php'>clearing your session</a>.</p>
  17 +
  18 + <p>
  19 + Links:
  20 + <a href='http://github.com/abraham/twitteroauth'>Source Code</a> &amp;
  21 + <a href='http://wiki.github.com/abraham/twitteroauth/documentation'>Documentation</a> |
  22 + Contact @<a href='http://twitter.com/abraham'>abraham</a>
  23 + </p>
  24 + <hr />
  25 + <?php if (isset($menu)) { ?>
  26 + <?php echo $menu; ?>
  27 + <?php } ?>
  28 + </div>
  29 + <?php if (isset($status_text)) { ?>
  30 + <?php echo '<h3>'.$status_text.'</h3>'; ?>
  31 + <?php } ?>
  32 + <p>
  33 + <pre>
  34 + <?php print_r($content); ?>
  35 + </pre>
  36 + </p>
  37 +
  38 + </body>
  39 +</html>
... ...
pacotes/twitteroauth/images/darker.png 0 → 100644
... ... @@ -0,0 +1,793 @@
  1 +
  2 +
  3 +
  4 +
  5 +
  6 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  7 + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  8 +
  9 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  10 + <head>
  11 + <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  12 + <meta http-equiv="X-UA-Compatible" content="chrome=1">
  13 + <title>images/darker.png at master from abraham's twitteroauth - GitHub</title>
  14 + <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub" />
  15 + <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub" />
  16 +
  17 + <link href="https://assets1.github.com/stylesheets/bundle_common.css?6847bdee64e5b0e2ee04e4e961f33e28593984a2" media="screen" rel="stylesheet" type="text/css" />
  18 +<link href="https://assets0.github.com/stylesheets/bundle_github.css?6847bdee64e5b0e2ee04e4e961f33e28593984a2" media="screen" rel="stylesheet" type="text/css" />
  19 +
  20 + <script type="text/javascript" charset="utf-8">
  21 + var GitHub = {}
  22 + var github_user = null
  23 +
  24 + </script>
  25 + <script src="https://assets2.github.com/javascripts/jquery/jquery-1.4.2.min.js?6847bdee64e5b0e2ee04e4e961f33e28593984a2" type="text/javascript"></script>
  26 + <script src="https://assets3.github.com/javascripts/bundle_common.js?6847bdee64e5b0e2ee04e4e961f33e28593984a2" type="text/javascript"></script>
  27 +<script src="https://assets3.github.com/javascripts/bundle_github.js?6847bdee64e5b0e2ee04e4e961f33e28593984a2" type="text/javascript"></script>
  28 +
  29 + <script type="text/javascript" charset="utf-8">
  30 + GitHub.spy({
  31 + repo: "abraham/twitteroauth"
  32 + })
  33 + </script>
  34 +
  35 +
  36 +
  37 +
  38 +
  39 +
  40 + <link href="https://github.com/abraham/twitteroauth/commits/master.atom" rel="alternate" title="Recent Commits to twitteroauth:master" type="application/atom+xml" />
  41 +
  42 + <meta name="description" content="The first PHP Library to support OAuth for Twitter's REST API." />
  43 + <script type="text/javascript">
  44 + GitHub.nameWithOwner = GitHub.nameWithOwner || "abraham/twitteroauth";
  45 + GitHub.currentRef = 'master';
  46 + </script>
  47 +
  48 +
  49 + <script type="text/javascript">
  50 + var _gaq = _gaq || [];
  51 + _gaq.push(['_setAccount', 'UA-3769691-2']);
  52 + _gaq.push(['_trackPageview']);
  53 + (function() {
  54 + var ga = document.createElement('script');
  55 + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
  56 + ga.setAttribute('async', 'true');
  57 + document.documentElement.firstChild.appendChild(ga);
  58 + })();
  59 + </script>
  60 +
  61 + </head>
  62 +
  63 +
  64 +
  65 + <body class="logged_out ">
  66 +
  67 +
  68 +
  69 + <script type="text/javascript">
  70 + var _kmq = _kmq || [];
  71 + function _kms(u){
  72 + var s = document.createElement('script'); var f = document.getElementsByTagName('script')[0]; s.type = 'text/javascript'; s.async = true;
  73 + s.src = u; f.parentNode.insertBefore(s, f);
  74 + }
  75 + _kms('//i.kissmetrics.com/i.js');_kms('//doug1izaerwt3.cloudfront.net/406e8bf3a2b8846ead55afb3cfaf6664523e3a54.1.js');
  76 + </script>
  77 +
  78 +
  79 +
  80 +
  81 +
  82 +
  83 +
  84 +
  85 + <div class="subnavd" id="main">
  86 + <div id="header" class="true">
  87 +
  88 + <a class="logo boring" href="https://github.com">
  89 + <img src="/images/modules/header/logov3.png?changed" class="default" alt="github" />
  90 + <![if !IE]>
  91 + <img src="/images/modules/header/logov3-hover.png" class="hover" alt="github" />
  92 + <![endif]>
  93 + </a>
  94 +
  95 +
  96 + <div class="topsearch">
  97 +
  98 + <ul class="nav logged_out">
  99 + <li><a href="https://github.com">Home</a></li>
  100 + <li class="pricing"><a href="/plans">Pricing and Signup</a></li>
  101 + <li><a href="https://github.com/training">Training</a></li>
  102 + <li><a href="https://gist.github.com">Gist</a></li>
  103 + <li><a href="/blog">Blog</a></li>
  104 + <li><a href="https://github.com/login">Login</a></li>
  105 + </ul>
  106 +
  107 +</div>
  108 +
  109 + </div>
  110 +
  111 +
  112 +
  113 +
  114 + <div class="site">
  115 + <div class="pagehead repohead vis-public ">
  116 +
  117 +
  118 +
  119 + <div class="title-actions-bar">
  120 + <h1>
  121 + <a href="/abraham">abraham</a> / <strong><a href="https://github.com/abraham/twitteroauth">twitteroauth</a></strong>
  122 +
  123 +
  124 + </h1>
  125 +
  126 +
  127 + <ul class="actions">
  128 +
  129 +
  130 +
  131 + <li class="for-owner" style="display:none"><a href="https://github.com/abraham/twitteroauth/admin" class="minibutton btn-admin "><span><span class="icon"></span>Admin</span></a></li>
  132 + <li>
  133 + <a href="/abraham/twitteroauth/toggle_watch" class="minibutton btn-watch " id="watch_button" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', '0788e12631f37df2bd75592390a297816b6698da'); f.appendChild(s);f.submit();return false;" style="display:none"><span><span class="icon"></span>Watch</span></a>
  134 + <a href="/abraham/twitteroauth/toggle_watch" class="minibutton btn-watch " id="unwatch_button" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', '0788e12631f37df2bd75592390a297816b6698da'); f.appendChild(s);f.submit();return false;" style="display:none"><span><span class="icon"></span>Unwatch</span></a>
  135 + </li>
  136 +
  137 +
  138 + <li class="for-notforked" style="display:none"><a href="/abraham/twitteroauth/fork" class="minibutton btn-fork " id="fork_button" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', '0788e12631f37df2bd75592390a297816b6698da'); f.appendChild(s);f.submit();return false;"><span><span class="icon"></span>Fork</span></a></li>
  139 + <li class="for-hasfork" style="display:none"><a href="#" class="minibutton btn-fork " id="your_fork_button"><span><span class="icon"></span>Your Fork</span></a></li>
  140 +
  141 +
  142 +
  143 +
  144 +
  145 +
  146 + <li class="repostats">
  147 + <ul class="repo-stats">
  148 + <li class="watchers"><a href="/abraham/twitteroauth/watchers" title="Watchers" class="tooltipped downwards">591</a></li>
  149 + <li class="forks"><a href="/abraham/twitteroauth/network" title="Forks" class="tooltipped downwards">79</a></li>
  150 + </ul>
  151 + </li>
  152 + </ul>
  153 +
  154 + </div>
  155 +
  156 +
  157 + <ul class="tabs">
  158 + <li><a href="https://github.com/abraham/twitteroauth/tree/master" class="selected" highlight="repo_source">Source</a></li>
  159 + <li><a href="https://github.com/abraham/twitteroauth/commits/master" highlight="repo_commits">Commits</a></li>
  160 + <li><a href="/abraham/twitteroauth/network" highlight="repo_network">Network</a></li>
  161 + <li><a href="/abraham/twitteroauth/pulls" highlight="repo_pulls">Pull Requests (4)</a></li>
  162 +
  163 +
  164 +
  165 +
  166 +
  167 + <li><a href="/abraham/twitteroauth/issues" highlight="issues">Issues (34)</a></li>
  168 +
  169 +
  170 + <li><a href="/abraham/twitteroauth/wiki" highlight="repo_wiki">Wiki (3)</a></li>
  171 +
  172 + <li><a href="/abraham/twitteroauth/graphs" highlight="repo_graphs">Graphs</a></li>
  173 +
  174 + <li class="contextswitch nochoices">
  175 + <span class="toggle leftwards" >
  176 + <em>Branch:</em>
  177 + <code>master</code>
  178 + </span>
  179 + </li>
  180 + </ul>
  181 +
  182 + <div style="display:none" id="pl-description"><p><em class="placeholder">click here to add a description</em></p></div>
  183 + <div style="display:none" id="pl-homepage"><p><em class="placeholder">click here to add a homepage</em></p></div>
  184 +
  185 + <div class="subnav-bar">
  186 +
  187 + <ul>
  188 + <li>
  189 + <a href="#" class="dropdown">Switch Branches (3)</a>
  190 + <ul>
  191 +
  192 +
  193 +
  194 + <li><a href="/abraham/twitteroauth/blob/0.2.0/images/darker.png" action="show">0.2.0</a></li>
  195 +
  196 +
  197 +
  198 +
  199 + <li><a href="/abraham/twitteroauth/blob/gh-pages/images/darker.png" action="show">gh-pages</a></li>
  200 +
  201 +
  202 +
  203 + <li><strong>master &#x2713;</strong></li>
  204 +
  205 + </ul>
  206 + </li>
  207 + <li>
  208 + <a href="#" class="dropdown ">Switch Tags (5)</a>
  209 + <ul>
  210 +
  211 + <li><a href="/abraham/twitteroauth/blob/0.2.0-beta3/images/darker.png">0.2.0-beta3</a></li>
  212 +
  213 +
  214 + <li><a href="/abraham/twitteroauth/blob/0.2.0-beta2/images/darker.png">0.2.0-beta2</a></li>
  215 +
  216 +
  217 + <li><a href="/abraham/twitteroauth/blob/0.2.0-beta/images/darker.png">0.2.0-beta</a></li>
  218 +
  219 +
  220 + <li><a href="/abraham/twitteroauth/blob/0.1.1/images/darker.png">0.1.1</a></li>
  221 +
  222 +
  223 + <li><a href="/abraham/twitteroauth/blob/0.1.0/images/darker.png">0.1.0</a></li>
  224 +
  225 + </ul>
  226 +
  227 + </li>
  228 + <li>
  229 +
  230 + <a href="/abraham/twitteroauth/branches" class="manage">Branch List</a>
  231 +
  232 + </li>
  233 + </ul>
  234 +</div>
  235 +
  236 +
  237 +
  238 +
  239 +
  240 +
  241 +
  242 +
  243 +
  244 +
  245 +
  246 + <div id="repo_details" class="metabox clearfix">
  247 + <div id="repo_details_loader" class="metabox-loader" style="display:none">Sending Request&hellip;</div>
  248 +
  249 + <a href="/abraham/twitteroauth/downloads" class="download-source" id="download_button" title="Download source, tagged packages and binaries."><span class="icon"></span>Downloads</a>
  250 +
  251 + <div id="repository_desc_wrapper">
  252 + <div id="repository_description" rel="repository_description_edit">
  253 +
  254 + <p>The first PHP Library to support OAuth for Twitter's REST API.
  255 + <span id="read_more" style="display:none">&mdash; <a href="#readme">Read more</a></span>
  256 + </p>
  257 +
  258 + </div>
  259 +
  260 + <div id="repository_description_edit" style="display:none;" class="inline-edit">
  261 + <form action="/abraham/twitteroauth/admin/update" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="0788e12631f37df2bd75592390a297816b6698da" /></div>
  262 + <input type="hidden" name="field" value="repository_description">
  263 + <input type="text" class="textfield" name="value" value="The first PHP Library to support OAuth for Twitter's REST API.">
  264 + <div class="form-actions">
  265 + <button class="minibutton"><span>Save</span></button> &nbsp; <a href="#" class="cancel">Cancel</a>
  266 + </div>
  267 + </form>
  268 + </div>
  269 +
  270 +
  271 + <div class="repository-homepage" id="repository_homepage" rel="repository_homepage_edit">
  272 + <p><a href="http://twitteroauth.labs.poseurtech.com" rel="nofollow">http://twitteroauth.labs.poseurtech.com</a></p>
  273 + </div>
  274 +
  275 + <div id="repository_homepage_edit" style="display:none;" class="inline-edit">
  276 + <form action="/abraham/twitteroauth/admin/update" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="0788e12631f37df2bd75592390a297816b6698da" /></div>
  277 + <input type="hidden" name="field" value="repository_homepage">
  278 + <input type="text" class="textfield" name="value" value="http://twitteroauth.labs.poseurtech.com">
  279 + <div class="form-actions">
  280 + <button class="minibutton"><span>Save</span></button> &nbsp; <a href="#" class="cancel">Cancel</a>
  281 + </div>
  282 + </form>
  283 + </div>
  284 + </div>
  285 + <div class="rule "></div>
  286 + <div id="url_box" class="url-box">
  287 + <ul class="clone-urls">
  288 +
  289 +
  290 + <li id="http_clone_url"><a href="https://github.com/abraham/twitteroauth.git" data-permissions="Read-Only">HTTP</a></li>
  291 + <li id="public_clone_url"><a href="git://github.com/abraham/twitteroauth.git" data-permissions="Read-Only">Git Read-Only</a></li>
  292 +
  293 +
  294 + </ul>
  295 + <input type="text" spellcheck="false" id="url_field" class="url-field" />
  296 + <span style="display:none" id="url_box_clippy"></span>
  297 + <span id="clippy_tooltip_url_box_clippy" class="clippy-tooltip tooltipped" title="copy to clipboard">
  298 + <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  299 + width="14"
  300 + height="14"
  301 + class="clippy"
  302 + id="clippy" >
  303 + <param name="movie" value="https://assets2.github.com/flash/clippy.swf?v5"/>
  304 + <param name="allowScriptAccess" value="always" />
  305 + <param name="quality" value="high" />
  306 + <param name="scale" value="noscale" />
  307 + <param NAME="FlashVars" value="id=url_box_clippy&amp;copied=&amp;copyto=">
  308 + <param name="bgcolor" value="#FFFFFF">
  309 + <param name="wmode" value="opaque">
  310 + <embed src="https://assets2.github.com/flash/clippy.swf?v5"
  311 + width="14"
  312 + height="14"
  313 + name="clippy"
  314 + quality="high"
  315 + allowScriptAccess="always"
  316 + type="application/x-shockwave-flash"
  317 + pluginspage="http://www.macromedia.com/go/getflashplayer"
  318 + FlashVars="id=url_box_clippy&amp;copied=&amp;copyto="
  319 + bgcolor="#FFFFFF"
  320 + wmode="opaque"
  321 + />
  322 + </object>
  323 + </span>
  324 +
  325 + <p id="url_description">This URL has <strong>Read+Write</strong> access</p>
  326 + </div>
  327 + </div>
  328 +
  329 +
  330 +
  331 +
  332 + </div><!-- /.pagehead -->
  333 +
  334 +
  335 +
  336 +
  337 +
  338 +
  339 +
  340 +
  341 +
  342 +
  343 +
  344 +<script type="text/javascript">
  345 + GitHub.currentCommitRef = 'master'
  346 + GitHub.currentRepoOwner = 'abraham'
  347 + GitHub.currentRepo = "twitteroauth"
  348 + GitHub.downloadRepo = '/abraham/twitteroauth/archives/master'
  349 + GitHub.revType = "master"
  350 +
  351 + GitHub.controllerName = "blob"
  352 + GitHub.actionName = "show"
  353 + GitHub.currentAction = "blob#show"
  354 +
  355 +
  356 +
  357 +
  358 +</script>
  359 +
  360 +
  361 +
  362 +
  363 +
  364 +
  365 +
  366 +
  367 + <div id="commit">
  368 + <div class="group">
  369 +
  370 + <div class="envelope commit">
  371 + <div class="human">
  372 +
  373 + <div class="message"><pre><a href="/abraham/twitteroauth/commit/76446fa719466c09b20fe021bf9e92f54afc43e1">Added getXAuthToken method, updated documentation and fixed some spelling issues.</a> </pre></div>
  374 +
  375 +
  376 + <div class="actor">
  377 + <div class="gravatar">
  378 +
  379 + <img src="https://secure.gravatar.com/avatar/cfc268557922ae6f5464a8cb337ceac2?s=140&d=https%3A%2F%2Fgithub.com%2Fimages%2Fgravatars%2Fgravatar-140.png" alt="" width="30" height="30" />
  380 + </div>
  381 + <div class="name"><a href="/abraham">abraham</a> <span>(author)</span></div>
  382 + <div class="date">
  383 + <abbr class="relatize" title="2010-03-10 18:51:58">Wed Mar 10 18:51:58 -0800 2010</abbr>
  384 + </div>
  385 + </div>
  386 +
  387 +
  388 +
  389 + </div>
  390 + <div class="machine">
  391 + <span>c</span>ommit&nbsp;&nbsp;<a href="/abraham/twitteroauth/commit/76446fa719466c09b20fe021bf9e92f54afc43e1" hotkey="c">76446fa719466c09b20f</a><br />
  392 + <span>t</span>ree&nbsp;&nbsp;&nbsp;&nbsp;<a href="/abraham/twitteroauth/tree/76446fa719466c09b20fe021bf9e92f54afc43e1" hotkey="t">140d535db90866cac2a7</a><br />
  393 +
  394 + <span>p</span>arent&nbsp;
  395 +
  396 + <a href="/abraham/twitteroauth/tree/8da02a678b9c408eb8ca1ffd9c38323f2da632a5" hotkey="p">8da02a678b9c408eb8ca</a>
  397 +
  398 +
  399 + </div>
  400 + </div>
  401 +
  402 + </div>
  403 + </div>
  404 +
  405 +
  406 +
  407 +
  408 + <div id="path">
  409 + <b><a href="/abraham/twitteroauth/tree/master">twitteroauth</a></b> / <a href="/abraham/twitteroauth/tree/master/images">images</a> / darker.png <span style="display:none" id="clippy_4055">images/darker.png</span>
  410 +
  411 + <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  412 + width="110"
  413 + height="14"
  414 + class="clippy"
  415 + id="clippy" >
  416 + <param name="movie" value="https://assets2.github.com/flash/clippy.swf?v5"/>
  417 + <param name="allowScriptAccess" value="always" />
  418 + <param name="quality" value="high" />
  419 + <param name="scale" value="noscale" />
  420 + <param NAME="FlashVars" value="id=clippy_4055&amp;copied=copied!&amp;copyto=copy to clipboard">
  421 + <param name="bgcolor" value="#FFFFFF">
  422 + <param name="wmode" value="opaque">
  423 + <embed src="https://assets2.github.com/flash/clippy.swf?v5"
  424 + width="110"
  425 + height="14"
  426 + name="clippy"
  427 + quality="high"
  428 + allowScriptAccess="always"
  429 + type="application/x-shockwave-flash"
  430 + pluginspage="http://www.macromedia.com/go/getflashplayer"
  431 + FlashVars="id=clippy_4055&amp;copied=copied!&amp;copyto=copy to clipboard"
  432 + bgcolor="#FFFFFF"
  433 + wmode="opaque"
  434 + />
  435 + </object>
  436 +
  437 +
  438 + </div>
  439 +
  440 + <div id="files">
  441 + <div class="file">
  442 + <div class="meta">
  443 + <div class="info">
  444 + <span class="icon"><img alt="Txt" height="16" src="https://assets3.github.com/images/icons/txt.png?6847bdee64e5b0e2ee04e4e961f33e28593984a2" width="16" /></span>
  445 + <span class="mode" title="File Mode">100644</span>
  446 +
  447 + <span>2.37 kb</span>
  448 + </div>
  449 + <ul class="actions">
  450 +
  451 + <li><a href="/abraham/twitteroauth/raw/master/images/darker.png" id="raw-url">raw</a></li>
  452 +
  453 + <li><a href="/abraham/twitteroauth/commits/master/images/darker.png">history</a></li>
  454 + </ul>
  455 + </div>
  456 +
  457 + <div class="data type-text">
  458 +
  459 + <div class="image">
  460 +
  461 +
  462 + <img src="/abraham/twitteroauth/raw/master/images/darker.png" />
  463 +
  464 + </div>
  465 +
  466 + </div>
  467 +
  468 +
  469 + </div>
  470 + </div>
  471 +
  472 +
  473 +
  474 + </div>
  475 +
  476 +
  477 + </div>
  478 +
  479 + <div id="footer" class="clearfix">
  480 + <div class="site">
  481 + <div class="sponsor">
  482 + <a href="http://www.rackspace.com" class="logo">
  483 + <img alt="Dedicated Server" src="https://assets0.github.com/images/modules/footer/rackspace_logo.png?v2?6847bdee64e5b0e2ee04e4e961f33e28593984a2" />
  484 + </a>
  485 + Powered by the <a href="http://www.rackspace.com ">Dedicated
  486 + Servers</a> and<br/> <a href="http://www.rackspacecloud.com">Cloud
  487 + Computing</a> of Rackspace Hosting<span>&reg;</span>
  488 + </div>
  489 +
  490 + <ul class="links">
  491 + <li class="blog"><a href="https://github.com/blog">Blog</a></li>
  492 + <li><a href="http://support.github.com">Support</a></li>
  493 + <li><a href="https://github.com/training">Training</a></li>
  494 + <li><a href="http://jobs.github.com">Job Board</a></li>
  495 + <li><a href="http://shop.github.com">Shop</a></li>
  496 + <li><a href="https://github.com/contact">Contact</a></li>
  497 + <li><a href="http://develop.github.com">API</a></li>
  498 + <li><a href="http://status.github.com">Status</a></li>
  499 + </ul>
  500 + <ul class="sosueme">
  501 + <li class="main">&copy; 2010 <span id="_rrt" title="0.19761s from fe5.rs.github.com">GitHub</span> Inc. All rights reserved.</li>
  502 + <li><a href="/site/terms">Terms of Service</a></li>
  503 + <li><a href="/site/privacy">Privacy</a></li>
  504 + <li><a href="https://github.com/security">Security</a></li>
  505 + </ul>
  506 + </div>
  507 + </div><!-- /#footer -->
  508 +
  509 +
  510 +
  511 +
  512 + <!-- current locale: -->
  513 + <div class="locales">
  514 + <div class="site">
  515 +
  516 + <ul class="choices clearfix limited-locales">
  517 + <li><span class="current">English</span></li>
  518 +
  519 + <li><a rel="nofollow" href="?locale=de">Deutsch</a></li>
  520 +
  521 + <li><a rel="nofollow" href="?locale=fr">Français</a></li>
  522 +
  523 + <li><a rel="nofollow" href="?locale=ja">日本語</a></li>
  524 +
  525 + <li><a rel="nofollow" href="?locale=pt-BR">Português (BR)</a></li>
  526 +
  527 + <li><a rel="nofollow" href="?locale=ru">Русский</a></li>
  528 +
  529 + <li><a rel="nofollow" href="?locale=zh">中文</a></li>
  530 +
  531 + <li class="all"><a href="#" class="minibutton btn-forward js-all-locales"><span><span class="icon"></span>See all available languages</span></a></li>
  532 + </ul>
  533 +
  534 + <div class="all-locales clearfix">
  535 + <h3>Your current locale selection: <strong>English</strong>. Choose another?</h3>
  536 +
  537 +
  538 + <ul class="choices">
  539 +
  540 + <li><a rel="nofollow" href="?locale=en">English</a></li>
  541 +
  542 + <li><a rel="nofollow" href="?locale=af">Afrikaans</a></li>
  543 +
  544 + <li><a rel="nofollow" href="?locale=ca">Català</a></li>
  545 +
  546 + <li><a rel="nofollow" href="?locale=cs">Čeština</a></li>
  547 +
  548 + </ul>
  549 +
  550 + <ul class="choices">
  551 +
  552 + <li><a rel="nofollow" href="?locale=de">Deutsch</a></li>
  553 +
  554 + <li><a rel="nofollow" href="?locale=es">Español</a></li>
  555 +
  556 + <li><a rel="nofollow" href="?locale=fr">Français</a></li>
  557 +
  558 + <li><a rel="nofollow" href="?locale=hr">Hrvatski</a></li>
  559 +
  560 + </ul>
  561 +
  562 + <ul class="choices">
  563 +
  564 + <li><a rel="nofollow" href="?locale=id">Indonesia</a></li>
  565 +
  566 + <li><a rel="nofollow" href="?locale=it">Italiano</a></li>
  567 +
  568 + <li><a rel="nofollow" href="?locale=ja">日本語</a></li>
  569 +
  570 + <li><a rel="nofollow" href="?locale=nl">Nederlands</a></li>
  571 +
  572 + </ul>
  573 +
  574 + <ul class="choices">
  575 +
  576 + <li><a rel="nofollow" href="?locale=no">Norsk</a></li>
  577 +
  578 + <li><a rel="nofollow" href="?locale=pl">Polski</a></li>
  579 +
  580 + <li><a rel="nofollow" href="?locale=pt-BR">Português (BR)</a></li>
  581 +
  582 + <li><a rel="nofollow" href="?locale=ru">Русский</a></li>
  583 +
  584 + </ul>
  585 +
  586 + <ul class="choices">
  587 +
  588 + <li><a rel="nofollow" href="?locale=sr">Српски</a></li>
  589 +
  590 + <li><a rel="nofollow" href="?locale=sv">Svenska</a></li>
  591 +
  592 + <li><a rel="nofollow" href="?locale=zh">中文</a></li>
  593 +
  594 + </ul>
  595 +
  596 + </div>
  597 +
  598 + </div>
  599 + <div class="fade"></div>
  600 + </div>
  601 +
  602 +
  603 +
  604 + <script>window._auth_token = "0788e12631f37df2bd75592390a297816b6698da"</script>
  605 + <div id="keyboard_shortcuts_pane" style="display:none">
  606 + <h2>Keyboard Shortcuts</h2>
  607 +
  608 + <div class="columns threecols">
  609 + <div class="column first">
  610 + <h3>Site wide shortcuts</h3>
  611 + <dl class="keyboard-mappings">
  612 + <dt>s</dt>
  613 + <dd>Focus site search</dd>
  614 + </dl>
  615 + <dl class="keyboard-mappings">
  616 + <dt>?</dt>
  617 + <dd>Bring up this help dialog</dd>
  618 + </dl>
  619 + </div><!-- /.column.first -->
  620 + <div class="column middle">
  621 + <h3>Commit list</h3>
  622 + <dl class="keyboard-mappings">
  623 + <dt>j</dt>
  624 + <dd>Move selected down</dd>
  625 + </dl>
  626 + <dl class="keyboard-mappings">
  627 + <dt>k</dt>
  628 + <dd>Move selected up</dd>
  629 + </dl>
  630 + <dl class="keyboard-mappings">
  631 + <dt>t</dt>
  632 + <dd>Open tree</dd>
  633 + </dl>
  634 + <dl class="keyboard-mappings">
  635 + <dt>p</dt>
  636 + <dd>Open parent</dd>
  637 + </dl>
  638 + <dl class="keyboard-mappings">
  639 + <dt>c <em>or</em> o <em>or</em> enter</dt>
  640 + <dd>Open commit</dd>
  641 + </dl>
  642 + </div><!-- /.column.first -->
  643 + <div class="column last">
  644 + <h3>Pull request list</h3>
  645 + <dl class="keyboard-mappings">
  646 + <dt>j</dt>
  647 + <dd>Move selected down</dd>
  648 + </dl>
  649 + <dl class="keyboard-mappings">
  650 + <dt>k</dt>
  651 + <dd>Move selected up</dd>
  652 + </dl>
  653 + <dl class="keyboard-mappings">
  654 + <dt>o <em>or</em> enter</dt>
  655 + <dd>Open issue</dd>
  656 + </dl>
  657 + </div><!-- /.columns.last -->
  658 + </div><!-- /.columns.equacols -->
  659 +
  660 + <div class="rule"></div>
  661 +
  662 + <h3>Issues</h3>
  663 +
  664 + <div class="columns threecols">
  665 + <div class="column first">
  666 + <dl class="keyboard-mappings">
  667 + <dt>j</dt>
  668 + <dd>Move selected down</dd>
  669 + </dl>
  670 + <dl class="keyboard-mappings">
  671 + <dt>k</dt>
  672 + <dd>Move selected up</dd>
  673 + </dl>
  674 + <dl class="keyboard-mappings">
  675 + <dt>x</dt>
  676 + <dd>Toggle select target</dd>
  677 + </dl>
  678 + <dl class="keyboard-mappings">
  679 + <dt>o <em>or</em> enter</dt>
  680 + <dd>Open issue</dd>
  681 + </dl>
  682 + </div><!-- /.column.first -->
  683 + <div class="column middle">
  684 + <dl class="keyboard-mappings">
  685 + <dt>I</dt>
  686 + <dd>Mark selected as read</dd>
  687 + </dl>
  688 + <dl class="keyboard-mappings">
  689 + <dt>U</dt>
  690 + <dd>Mark selected as unread</dd>
  691 + </dl>
  692 + <dl class="keyboard-mappings">
  693 + <dt>e</dt>
  694 + <dd>Close selected</dd>
  695 + </dl>
  696 + <dl class="keyboard-mappings">
  697 + <dt>y</dt>
  698 + <dd>Remove selected from view</dd>
  699 + </dl>
  700 + </div><!-- /.column.middle -->
  701 + <div class="column last">
  702 + <dl class="keyboard-mappings">
  703 + <dt>c</dt>
  704 + <dd>Create issue</dd>
  705 + </dl>
  706 + <dl class="keyboard-mappings">
  707 + <dt>l</dt>
  708 + <dd>Create label</dd>
  709 + </dl>
  710 + <dl class="keyboard-mappings">
  711 + <dt>i</dt>
  712 + <dd>Back to inbox</dd>
  713 + </dl>
  714 + <dl class="keyboard-mappings">
  715 + <dt>u</dt>
  716 + <dd>Back to issues</dd>
  717 + </dl>
  718 + <dl class="keyboard-mappings">
  719 + <dt>/</dt>
  720 + <dd>Focus issues search</dd>
  721 + </dl>
  722 + </div>
  723 + </div>
  724 +
  725 + <div class="rule"></div>
  726 +
  727 + <h3>Network Graph</h3>
  728 + <div class="columns equacols">
  729 + <div class="column first">
  730 + <dl class="keyboard-mappings">
  731 + <dt>← <em>or</em> h</dt>
  732 + <dd>Scroll left</dd>
  733 + </dl>
  734 + <dl class="keyboard-mappings">
  735 + <dt>→ <em>or</em> l</dt>
  736 + <dd>Scroll right</dd>
  737 + </dl>
  738 + <dl class="keyboard-mappings">
  739 + <dt>↑ <em>or</em> k</dt>
  740 + <dd>Scroll up</dd>
  741 + </dl>
  742 + <dl class="keyboard-mappings">
  743 + <dt>↓ <em>or</em> j</dt>
  744 + <dd>Scroll down</dd>
  745 + </dl>
  746 + <dl class="keyboard-mappings">
  747 + <dt>t</dt>
  748 + <dd>Toggle visibility of head labels</dd>
  749 + </dl>
  750 + </div><!-- /.column.first -->
  751 + <div class="column last">
  752 + <dl class="keyboard-mappings">
  753 + <dt>shift ← <em>or</em> shift h</dt>
  754 + <dd>Scroll all the way left</dd>
  755 + </dl>
  756 + <dl class="keyboard-mappings">
  757 + <dt>shift → <em>or</em> shift l</dt>
  758 + <dd>Scroll all the way right</dd>
  759 + </dl>
  760 + <dl class="keyboard-mappings">
  761 + <dt>shift ↑ <em>or</em> shift k</dt>
  762 + <dd>Scroll all the way up</dd>
  763 + </dl>
  764 + <dl class="keyboard-mappings">
  765 + <dt>shift ↓ <em>or</em> shift j</dt>
  766 + <dd>Scroll all the way down</dd>
  767 + </dl>
  768 + </div><!-- /.column.last -->
  769 + </div>
  770 +
  771 +</div>
  772 +
  773 +
  774 + <!--[if IE 8]>
  775 + <script type="text/javascript" charset="utf-8">
  776 + $(document.body).addClass("ie8")
  777 + </script>
  778 + <![endif]-->
  779 +
  780 + <!--[if IE 7]>
  781 + <script type="text/javascript" charset="utf-8">
  782 + $(document.body).addClass("ie7")
  783 + </script>
  784 + <![endif]-->
  785 +
  786 + <script type="text/javascript">
  787 + _kmq.push(['trackClick', 'entice-signup-button', 'Entice banner clicked']);
  788 +
  789 + </script>
  790 +
  791 + </body>
  792 +</html>
  793 +
... ...
pacotes/twitteroauth/images/lighter.png 0 → 100644
... ... @@ -0,0 +1,793 @@
  1 +
  2 +
  3 +
  4 +
  5 +
  6 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  7 + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  8 +
  9 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  10 + <head>
  11 + <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  12 + <meta http-equiv="X-UA-Compatible" content="chrome=1">
  13 + <title>images/lighter.png at master from abraham's twitteroauth - GitHub</title>
  14 + <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub" />
  15 + <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub" />
  16 +
  17 + <link href="https://assets1.github.com/stylesheets/bundle_common.css?6847bdee64e5b0e2ee04e4e961f33e28593984a2" media="screen" rel="stylesheet" type="text/css" />
  18 +<link href="https://assets0.github.com/stylesheets/bundle_github.css?6847bdee64e5b0e2ee04e4e961f33e28593984a2" media="screen" rel="stylesheet" type="text/css" />
  19 +
  20 + <script type="text/javascript" charset="utf-8">
  21 + var GitHub = {}
  22 + var github_user = null
  23 +
  24 + </script>
  25 + <script src="https://assets2.github.com/javascripts/jquery/jquery-1.4.2.min.js?6847bdee64e5b0e2ee04e4e961f33e28593984a2" type="text/javascript"></script>
  26 + <script src="https://assets3.github.com/javascripts/bundle_common.js?6847bdee64e5b0e2ee04e4e961f33e28593984a2" type="text/javascript"></script>
  27 +<script src="https://assets3.github.com/javascripts/bundle_github.js?6847bdee64e5b0e2ee04e4e961f33e28593984a2" type="text/javascript"></script>
  28 +
  29 + <script type="text/javascript" charset="utf-8">
  30 + GitHub.spy({
  31 + repo: "abraham/twitteroauth"
  32 + })
  33 + </script>
  34 +
  35 +
  36 +
  37 +
  38 +
  39 +
  40 + <link href="https://github.com/abraham/twitteroauth/commits/master.atom" rel="alternate" title="Recent Commits to twitteroauth:master" type="application/atom+xml" />
  41 +
  42 + <meta name="description" content="The first PHP Library to support OAuth for Twitter's REST API." />
  43 + <script type="text/javascript">
  44 + GitHub.nameWithOwner = GitHub.nameWithOwner || "abraham/twitteroauth";
  45 + GitHub.currentRef = 'master';
  46 + </script>
  47 +
  48 +
  49 + <script type="text/javascript">
  50 + var _gaq = _gaq || [];
  51 + _gaq.push(['_setAccount', 'UA-3769691-2']);
  52 + _gaq.push(['_trackPageview']);
  53 + (function() {
  54 + var ga = document.createElement('script');
  55 + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
  56 + ga.setAttribute('async', 'true');
  57 + document.documentElement.firstChild.appendChild(ga);
  58 + })();
  59 + </script>
  60 +
  61 + </head>
  62 +
  63 +
  64 +
  65 + <body class="logged_out ">
  66 +
  67 +
  68 +
  69 + <script type="text/javascript">
  70 + var _kmq = _kmq || [];
  71 + function _kms(u){
  72 + var s = document.createElement('script'); var f = document.getElementsByTagName('script')[0]; s.type = 'text/javascript'; s.async = true;
  73 + s.src = u; f.parentNode.insertBefore(s, f);
  74 + }
  75 + _kms('//i.kissmetrics.com/i.js');_kms('//doug1izaerwt3.cloudfront.net/406e8bf3a2b8846ead55afb3cfaf6664523e3a54.1.js');
  76 + </script>
  77 +
  78 +
  79 +
  80 +
  81 +
  82 +
  83 +
  84 +
  85 + <div class="subnavd" id="main">
  86 + <div id="header" class="true">
  87 +
  88 + <a class="logo boring" href="https://github.com">
  89 + <img src="/images/modules/header/logov3.png?changed" class="default" alt="github" />
  90 + <![if !IE]>
  91 + <img src="/images/modules/header/logov3-hover.png" class="hover" alt="github" />
  92 + <![endif]>
  93 + </a>
  94 +
  95 +
  96 + <div class="topsearch">
  97 +
  98 + <ul class="nav logged_out">
  99 + <li><a href="https://github.com">Home</a></li>
  100 + <li class="pricing"><a href="/plans">Pricing and Signup</a></li>
  101 + <li><a href="https://github.com/training">Training</a></li>
  102 + <li><a href="https://gist.github.com">Gist</a></li>
  103 + <li><a href="/blog">Blog</a></li>
  104 + <li><a href="https://github.com/login">Login</a></li>
  105 + </ul>
  106 +
  107 +</div>
  108 +
  109 + </div>
  110 +
  111 +
  112 +
  113 +
  114 + <div class="site">
  115 + <div class="pagehead repohead vis-public ">
  116 +
  117 +
  118 +
  119 + <div class="title-actions-bar">
  120 + <h1>
  121 + <a href="/abraham">abraham</a> / <strong><a href="https://github.com/abraham/twitteroauth">twitteroauth</a></strong>
  122 +
  123 +
  124 + </h1>
  125 +
  126 +
  127 + <ul class="actions">
  128 +
  129 +
  130 +
  131 + <li class="for-owner" style="display:none"><a href="https://github.com/abraham/twitteroauth/admin" class="minibutton btn-admin "><span><span class="icon"></span>Admin</span></a></li>
  132 + <li>
  133 + <a href="/abraham/twitteroauth/toggle_watch" class="minibutton btn-watch " id="watch_button" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', '0788e12631f37df2bd75592390a297816b6698da'); f.appendChild(s);f.submit();return false;" style="display:none"><span><span class="icon"></span>Watch</span></a>
  134 + <a href="/abraham/twitteroauth/toggle_watch" class="minibutton btn-watch " id="unwatch_button" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', '0788e12631f37df2bd75592390a297816b6698da'); f.appendChild(s);f.submit();return false;" style="display:none"><span><span class="icon"></span>Unwatch</span></a>
  135 + </li>
  136 +
  137 +
  138 + <li class="for-notforked" style="display:none"><a href="/abraham/twitteroauth/fork" class="minibutton btn-fork " id="fork_button" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', '0788e12631f37df2bd75592390a297816b6698da'); f.appendChild(s);f.submit();return false;"><span><span class="icon"></span>Fork</span></a></li>
  139 + <li class="for-hasfork" style="display:none"><a href="#" class="minibutton btn-fork " id="your_fork_button"><span><span class="icon"></span>Your Fork</span></a></li>
  140 +
  141 +
  142 +
  143 +
  144 +
  145 +
  146 + <li class="repostats">
  147 + <ul class="repo-stats">
  148 + <li class="watchers"><a href="/abraham/twitteroauth/watchers" title="Watchers" class="tooltipped downwards">591</a></li>
  149 + <li class="forks"><a href="/abraham/twitteroauth/network" title="Forks" class="tooltipped downwards">79</a></li>
  150 + </ul>
  151 + </li>
  152 + </ul>
  153 +
  154 + </div>
  155 +
  156 +
  157 + <ul class="tabs">
  158 + <li><a href="https://github.com/abraham/twitteroauth/tree/master" class="selected" highlight="repo_source">Source</a></li>
  159 + <li><a href="https://github.com/abraham/twitteroauth/commits/master" highlight="repo_commits">Commits</a></li>
  160 + <li><a href="/abraham/twitteroauth/network" highlight="repo_network">Network</a></li>
  161 + <li><a href="/abraham/twitteroauth/pulls" highlight="repo_pulls">Pull Requests (4)</a></li>
  162 +
  163 +
  164 +
  165 +
  166 +
  167 + <li><a href="/abraham/twitteroauth/issues" highlight="issues">Issues (34)</a></li>
  168 +
  169 +
  170 + <li><a href="/abraham/twitteroauth/wiki" highlight="repo_wiki">Wiki (3)</a></li>
  171 +
  172 + <li><a href="/abraham/twitteroauth/graphs" highlight="repo_graphs">Graphs</a></li>
  173 +
  174 + <li class="contextswitch nochoices">
  175 + <span class="toggle leftwards" >
  176 + <em>Branch:</em>
  177 + <code>master</code>
  178 + </span>
  179 + </li>
  180 + </ul>
  181 +
  182 + <div style="display:none" id="pl-description"><p><em class="placeholder">click here to add a description</em></p></div>
  183 + <div style="display:none" id="pl-homepage"><p><em class="placeholder">click here to add a homepage</em></p></div>
  184 +
  185 + <div class="subnav-bar">
  186 +
  187 + <ul>
  188 + <li>
  189 + <a href="#" class="dropdown">Switch Branches (3)</a>
  190 + <ul>
  191 +
  192 +
  193 +
  194 + <li><a href="/abraham/twitteroauth/blob/0.2.0/images/lighter.png" action="show">0.2.0</a></li>
  195 +
  196 +
  197 +
  198 +
  199 + <li><a href="/abraham/twitteroauth/blob/gh-pages/images/lighter.png" action="show">gh-pages</a></li>
  200 +
  201 +
  202 +
  203 + <li><strong>master &#x2713;</strong></li>
  204 +
  205 + </ul>
  206 + </li>
  207 + <li>
  208 + <a href="#" class="dropdown ">Switch Tags (5)</a>
  209 + <ul>
  210 +
  211 + <li><a href="/abraham/twitteroauth/blob/0.2.0-beta3/images/lighter.png">0.2.0-beta3</a></li>
  212 +
  213 +
  214 + <li><a href="/abraham/twitteroauth/blob/0.2.0-beta2/images/lighter.png">0.2.0-beta2</a></li>
  215 +
  216 +
  217 + <li><a href="/abraham/twitteroauth/blob/0.2.0-beta/images/lighter.png">0.2.0-beta</a></li>
  218 +
  219 +
  220 + <li><a href="/abraham/twitteroauth/blob/0.1.1/images/lighter.png">0.1.1</a></li>
  221 +
  222 +
  223 + <li><a href="/abraham/twitteroauth/blob/0.1.0/images/lighter.png">0.1.0</a></li>
  224 +
  225 + </ul>
  226 +
  227 + </li>
  228 + <li>
  229 +
  230 + <a href="/abraham/twitteroauth/branches" class="manage">Branch List</a>
  231 +
  232 + </li>
  233 + </ul>
  234 +</div>
  235 +
  236 +
  237 +
  238 +
  239 +
  240 +
  241 +
  242 +
  243 +
  244 +
  245 +
  246 + <div id="repo_details" class="metabox clearfix">
  247 + <div id="repo_details_loader" class="metabox-loader" style="display:none">Sending Request&hellip;</div>
  248 +
  249 + <a href="/abraham/twitteroauth/downloads" class="download-source" id="download_button" title="Download source, tagged packages and binaries."><span class="icon"></span>Downloads</a>
  250 +
  251 + <div id="repository_desc_wrapper">
  252 + <div id="repository_description" rel="repository_description_edit">
  253 +
  254 + <p>The first PHP Library to support OAuth for Twitter's REST API.
  255 + <span id="read_more" style="display:none">&mdash; <a href="#readme">Read more</a></span>
  256 + </p>
  257 +
  258 + </div>
  259 +
  260 + <div id="repository_description_edit" style="display:none;" class="inline-edit">
  261 + <form action="/abraham/twitteroauth/admin/update" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="0788e12631f37df2bd75592390a297816b6698da" /></div>
  262 + <input type="hidden" name="field" value="repository_description">
  263 + <input type="text" class="textfield" name="value" value="The first PHP Library to support OAuth for Twitter's REST API.">
  264 + <div class="form-actions">
  265 + <button class="minibutton"><span>Save</span></button> &nbsp; <a href="#" class="cancel">Cancel</a>
  266 + </div>
  267 + </form>
  268 + </div>
  269 +
  270 +
  271 + <div class="repository-homepage" id="repository_homepage" rel="repository_homepage_edit">
  272 + <p><a href="http://twitteroauth.labs.poseurtech.com" rel="nofollow">http://twitteroauth.labs.poseurtech.com</a></p>
  273 + </div>
  274 +
  275 + <div id="repository_homepage_edit" style="display:none;" class="inline-edit">
  276 + <form action="/abraham/twitteroauth/admin/update" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="0788e12631f37df2bd75592390a297816b6698da" /></div>
  277 + <input type="hidden" name="field" value="repository_homepage">
  278 + <input type="text" class="textfield" name="value" value="http://twitteroauth.labs.poseurtech.com">
  279 + <div class="form-actions">
  280 + <button class="minibutton"><span>Save</span></button> &nbsp; <a href="#" class="cancel">Cancel</a>
  281 + </div>
  282 + </form>
  283 + </div>
  284 + </div>
  285 + <div class="rule "></div>
  286 + <div id="url_box" class="url-box">
  287 + <ul class="clone-urls">
  288 +
  289 +
  290 + <li id="http_clone_url"><a href="https://github.com/abraham/twitteroauth.git" data-permissions="Read-Only">HTTP</a></li>
  291 + <li id="public_clone_url"><a href="git://github.com/abraham/twitteroauth.git" data-permissions="Read-Only">Git Read-Only</a></li>
  292 +
  293 +
  294 + </ul>
  295 + <input type="text" spellcheck="false" id="url_field" class="url-field" />
  296 + <span style="display:none" id="url_box_clippy"></span>
  297 + <span id="clippy_tooltip_url_box_clippy" class="clippy-tooltip tooltipped" title="copy to clipboard">
  298 + <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  299 + width="14"
  300 + height="14"
  301 + class="clippy"
  302 + id="clippy" >
  303 + <param name="movie" value="https://assets2.github.com/flash/clippy.swf?v5"/>
  304 + <param name="allowScriptAccess" value="always" />
  305 + <param name="quality" value="high" />
  306 + <param name="scale" value="noscale" />
  307 + <param NAME="FlashVars" value="id=url_box_clippy&amp;copied=&amp;copyto=">
  308 + <param name="bgcolor" value="#FFFFFF">
  309 + <param name="wmode" value="opaque">
  310 + <embed src="https://assets2.github.com/flash/clippy.swf?v5"
  311 + width="14"
  312 + height="14"
  313 + name="clippy"
  314 + quality="high"
  315 + allowScriptAccess="always"
  316 + type="application/x-shockwave-flash"
  317 + pluginspage="http://www.macromedia.com/go/getflashplayer"
  318 + FlashVars="id=url_box_clippy&amp;copied=&amp;copyto="
  319 + bgcolor="#FFFFFF"
  320 + wmode="opaque"
  321 + />
  322 + </object>
  323 + </span>
  324 +
  325 + <p id="url_description">This URL has <strong>Read+Write</strong> access</p>
  326 + </div>
  327 + </div>
  328 +
  329 +
  330 +
  331 +
  332 + </div><!-- /.pagehead -->
  333 +
  334 +
  335 +
  336 +
  337 +
  338 +
  339 +
  340 +
  341 +
  342 +
  343 +
  344 +<script type="text/javascript">
  345 + GitHub.currentCommitRef = 'master'
  346 + GitHub.currentRepoOwner = 'abraham'
  347 + GitHub.currentRepo = "twitteroauth"
  348 + GitHub.downloadRepo = '/abraham/twitteroauth/archives/master'
  349 + GitHub.revType = "master"
  350 +
  351 + GitHub.controllerName = "blob"
  352 + GitHub.actionName = "show"
  353 + GitHub.currentAction = "blob#show"
  354 +
  355 +
  356 +
  357 +
  358 +</script>
  359 +
  360 +
  361 +
  362 +
  363 +
  364 +
  365 +
  366 +
  367 + <div id="commit">
  368 + <div class="group">
  369 +
  370 + <div class="envelope commit">
  371 + <div class="human">
  372 +
  373 + <div class="message"><pre><a href="/abraham/twitteroauth/commit/76446fa719466c09b20fe021bf9e92f54afc43e1">Added getXAuthToken method, updated documentation and fixed some spelling issues.</a> </pre></div>
  374 +
  375 +
  376 + <div class="actor">
  377 + <div class="gravatar">
  378 +
  379 + <img src="https://secure.gravatar.com/avatar/cfc268557922ae6f5464a8cb337ceac2?s=140&d=https%3A%2F%2Fgithub.com%2Fimages%2Fgravatars%2Fgravatar-140.png" alt="" width="30" height="30" />
  380 + </div>
  381 + <div class="name"><a href="/abraham">abraham</a> <span>(author)</span></div>
  382 + <div class="date">
  383 + <abbr class="relatize" title="2010-03-10 18:51:58">Wed Mar 10 18:51:58 -0800 2010</abbr>
  384 + </div>
  385 + </div>
  386 +
  387 +
  388 +
  389 + </div>
  390 + <div class="machine">
  391 + <span>c</span>ommit&nbsp;&nbsp;<a href="/abraham/twitteroauth/commit/76446fa719466c09b20fe021bf9e92f54afc43e1" hotkey="c">76446fa719466c09b20f</a><br />
  392 + <span>t</span>ree&nbsp;&nbsp;&nbsp;&nbsp;<a href="/abraham/twitteroauth/tree/76446fa719466c09b20fe021bf9e92f54afc43e1" hotkey="t">140d535db90866cac2a7</a><br />
  393 +
  394 + <span>p</span>arent&nbsp;
  395 +
  396 + <a href="/abraham/twitteroauth/tree/8da02a678b9c408eb8ca1ffd9c38323f2da632a5" hotkey="p">8da02a678b9c408eb8ca</a>
  397 +
  398 +
  399 + </div>
  400 + </div>
  401 +
  402 + </div>
  403 + </div>
  404 +
  405 +
  406 +
  407 +
  408 + <div id="path">
  409 + <b><a href="/abraham/twitteroauth/tree/master">twitteroauth</a></b> / <a href="/abraham/twitteroauth/tree/master/images">images</a> / lighter.png <span style="display:none" id="clippy_1778">images/lighter.png</span>
  410 +
  411 + <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  412 + width="110"
  413 + height="14"
  414 + class="clippy"
  415 + id="clippy" >
  416 + <param name="movie" value="https://assets1.github.com/flash/clippy.swf?v5"/>
  417 + <param name="allowScriptAccess" value="always" />
  418 + <param name="quality" value="high" />
  419 + <param name="scale" value="noscale" />
  420 + <param NAME="FlashVars" value="id=clippy_1778&amp;copied=copied!&amp;copyto=copy to clipboard">
  421 + <param name="bgcolor" value="#FFFFFF">
  422 + <param name="wmode" value="opaque">
  423 + <embed src="https://assets1.github.com/flash/clippy.swf?v5"
  424 + width="110"
  425 + height="14"
  426 + name="clippy"
  427 + quality="high"
  428 + allowScriptAccess="always"
  429 + type="application/x-shockwave-flash"
  430 + pluginspage="http://www.macromedia.com/go/getflashplayer"
  431 + FlashVars="id=clippy_1778&amp;copied=copied!&amp;copyto=copy to clipboard"
  432 + bgcolor="#FFFFFF"
  433 + wmode="opaque"
  434 + />
  435 + </object>
  436 +
  437 +
  438 + </div>
  439 +
  440 + <div id="files">
  441 + <div class="file">
  442 + <div class="meta">
  443 + <div class="info">
  444 + <span class="icon"><img alt="Txt" height="16" src="https://assets2.github.com/images/icons/txt.png?bd5b57138194d8b178fd949e16173262d8b89778" width="16" /></span>
  445 + <span class="mode" title="File Mode">100644</span>
  446 +
  447 + <span>2.49 kb</span>
  448 + </div>
  449 + <ul class="actions">
  450 +
  451 + <li><a href="/abraham/twitteroauth/raw/master/images/lighter.png" id="raw-url">raw</a></li>
  452 +
  453 + <li><a href="/abraham/twitteroauth/commits/master/images/lighter.png">history</a></li>
  454 + </ul>
  455 + </div>
  456 +
  457 + <div class="data type-text">
  458 +
  459 + <div class="image">
  460 +
  461 +
  462 + <img src="/abraham/twitteroauth/raw/master/images/lighter.png" />
  463 +
  464 + </div>
  465 +
  466 + </div>
  467 +
  468 +
  469 + </div>
  470 + </div>
  471 +
  472 +
  473 +
  474 + </div>
  475 +
  476 +
  477 + </div>
  478 +
  479 + <div id="footer" class="clearfix">
  480 + <div class="site">
  481 + <div class="sponsor">
  482 + <a href="http://www.rackspace.com" class="logo">
  483 + <img alt="Dedicated Server" src="https://assets0.github.com/images/modules/footer/rackspace_logo.png?v2?6847bdee64e5b0e2ee04e4e961f33e28593984a2" />
  484 + </a>
  485 + Powered by the <a href="http://www.rackspace.com ">Dedicated
  486 + Servers</a> and<br/> <a href="http://www.rackspacecloud.com">Cloud
  487 + Computing</a> of Rackspace Hosting<span>&reg;</span>
  488 + </div>
  489 +
  490 + <ul class="links">
  491 + <li class="blog"><a href="https://github.com/blog">Blog</a></li>
  492 + <li><a href="http://support.github.com">Support</a></li>
  493 + <li><a href="https://github.com/training">Training</a></li>
  494 + <li><a href="http://jobs.github.com">Job Board</a></li>
  495 + <li><a href="http://shop.github.com">Shop</a></li>
  496 + <li><a href="https://github.com/contact">Contact</a></li>
  497 + <li><a href="http://develop.github.com">API</a></li>
  498 + <li><a href="http://status.github.com">Status</a></li>
  499 + </ul>
  500 + <ul class="sosueme">
  501 + <li class="main">&copy; 2010 <span id="_rrt" title="0.09710s from fe1.rs.github.com">GitHub</span> Inc. All rights reserved.</li>
  502 + <li><a href="/site/terms">Terms of Service</a></li>
  503 + <li><a href="/site/privacy">Privacy</a></li>
  504 + <li><a href="https://github.com/security">Security</a></li>
  505 + </ul>
  506 + </div>
  507 + </div><!-- /#footer -->
  508 +
  509 +
  510 +
  511 +
  512 + <!-- current locale: -->
  513 + <div class="locales">
  514 + <div class="site">
  515 +
  516 + <ul class="choices clearfix limited-locales">
  517 + <li><span class="current">English</span></li>
  518 +
  519 + <li><a rel="nofollow" href="?locale=de">Deutsch</a></li>
  520 +
  521 + <li><a rel="nofollow" href="?locale=fr">Français</a></li>
  522 +
  523 + <li><a rel="nofollow" href="?locale=ja">日本語</a></li>
  524 +
  525 + <li><a rel="nofollow" href="?locale=pt-BR">Português (BR)</a></li>
  526 +
  527 + <li><a rel="nofollow" href="?locale=ru">Русский</a></li>
  528 +
  529 + <li><a rel="nofollow" href="?locale=zh">中文</a></li>
  530 +
  531 + <li class="all"><a href="#" class="minibutton btn-forward js-all-locales"><span><span class="icon"></span>See all available languages</span></a></li>
  532 + </ul>
  533 +
  534 + <div class="all-locales clearfix">
  535 + <h3>Your current locale selection: <strong>English</strong>. Choose another?</h3>
  536 +
  537 +
  538 + <ul class="choices">
  539 +
  540 + <li><a rel="nofollow" href="?locale=en">English</a></li>
  541 +
  542 + <li><a rel="nofollow" href="?locale=af">Afrikaans</a></li>
  543 +
  544 + <li><a rel="nofollow" href="?locale=ca">Català</a></li>
  545 +
  546 + <li><a rel="nofollow" href="?locale=cs">Čeština</a></li>
  547 +
  548 + </ul>
  549 +
  550 + <ul class="choices">
  551 +
  552 + <li><a rel="nofollow" href="?locale=de">Deutsch</a></li>
  553 +
  554 + <li><a rel="nofollow" href="?locale=es">Español</a></li>
  555 +
  556 + <li><a rel="nofollow" href="?locale=fr">Français</a></li>
  557 +
  558 + <li><a rel="nofollow" href="?locale=hr">Hrvatski</a></li>
  559 +
  560 + </ul>
  561 +
  562 + <ul class="choices">
  563 +
  564 + <li><a rel="nofollow" href="?locale=id">Indonesia</a></li>
  565 +
  566 + <li><a rel="nofollow" href="?locale=it">Italiano</a></li>
  567 +
  568 + <li><a rel="nofollow" href="?locale=ja">日本語</a></li>
  569 +
  570 + <li><a rel="nofollow" href="?locale=nl">Nederlands</a></li>
  571 +
  572 + </ul>
  573 +
  574 + <ul class="choices">
  575 +
  576 + <li><a rel="nofollow" href="?locale=no">Norsk</a></li>
  577 +
  578 + <li><a rel="nofollow" href="?locale=pl">Polski</a></li>
  579 +
  580 + <li><a rel="nofollow" href="?locale=pt-BR">Português (BR)</a></li>
  581 +
  582 + <li><a rel="nofollow" href="?locale=ru">Русский</a></li>
  583 +
  584 + </ul>
  585 +
  586 + <ul class="choices">
  587 +
  588 + <li><a rel="nofollow" href="?locale=sr">Српски</a></li>
  589 +
  590 + <li><a rel="nofollow" href="?locale=sv">Svenska</a></li>
  591 +
  592 + <li><a rel="nofollow" href="?locale=zh">中文</a></li>
  593 +
  594 + </ul>
  595 +
  596 + </div>
  597 +
  598 + </div>
  599 + <div class="fade"></div>
  600 + </div>
  601 +
  602 +
  603 +
  604 + <script>window._auth_token = "0788e12631f37df2bd75592390a297816b6698da"</script>
  605 + <div id="keyboard_shortcuts_pane" style="display:none">
  606 + <h2>Keyboard Shortcuts</h2>
  607 +
  608 + <div class="columns threecols">
  609 + <div class="column first">
  610 + <h3>Site wide shortcuts</h3>
  611 + <dl class="keyboard-mappings">
  612 + <dt>s</dt>
  613 + <dd>Focus site search</dd>
  614 + </dl>
  615 + <dl class="keyboard-mappings">
  616 + <dt>?</dt>
  617 + <dd>Bring up this help dialog</dd>
  618 + </dl>
  619 + </div><!-- /.column.first -->
  620 + <div class="column middle">
  621 + <h3>Commit list</h3>
  622 + <dl class="keyboard-mappings">
  623 + <dt>j</dt>
  624 + <dd>Move selected down</dd>
  625 + </dl>
  626 + <dl class="keyboard-mappings">
  627 + <dt>k</dt>
  628 + <dd>Move selected up</dd>
  629 + </dl>
  630 + <dl class="keyboard-mappings">
  631 + <dt>t</dt>
  632 + <dd>Open tree</dd>
  633 + </dl>
  634 + <dl class="keyboard-mappings">
  635 + <dt>p</dt>
  636 + <dd>Open parent</dd>
  637 + </dl>
  638 + <dl class="keyboard-mappings">
  639 + <dt>c <em>or</em> o <em>or</em> enter</dt>
  640 + <dd>Open commit</dd>
  641 + </dl>
  642 + </div><!-- /.column.first -->
  643 + <div class="column last">
  644 + <h3>Pull request list</h3>
  645 + <dl class="keyboard-mappings">
  646 + <dt>j</dt>
  647 + <dd>Move selected down</dd>
  648 + </dl>
  649 + <dl class="keyboard-mappings">
  650 + <dt>k</dt>
  651 + <dd>Move selected up</dd>
  652 + </dl>
  653 + <dl class="keyboard-mappings">
  654 + <dt>o <em>or</em> enter</dt>
  655 + <dd>Open issue</dd>
  656 + </dl>
  657 + </div><!-- /.columns.last -->
  658 + </div><!-- /.columns.equacols -->
  659 +
  660 + <div class="rule"></div>
  661 +
  662 + <h3>Issues</h3>
  663 +
  664 + <div class="columns threecols">
  665 + <div class="column first">
  666 + <dl class="keyboard-mappings">
  667 + <dt>j</dt>
  668 + <dd>Move selected down</dd>
  669 + </dl>
  670 + <dl class="keyboard-mappings">
  671 + <dt>k</dt>
  672 + <dd>Move selected up</dd>
  673 + </dl>
  674 + <dl class="keyboard-mappings">
  675 + <dt>x</dt>
  676 + <dd>Toggle select target</dd>
  677 + </dl>
  678 + <dl class="keyboard-mappings">
  679 + <dt>o <em>or</em> enter</dt>
  680 + <dd>Open issue</dd>
  681 + </dl>
  682 + </div><!-- /.column.first -->
  683 + <div class="column middle">
  684 + <dl class="keyboard-mappings">
  685 + <dt>I</dt>
  686 + <dd>Mark selected as read</dd>
  687 + </dl>
  688 + <dl class="keyboard-mappings">
  689 + <dt>U</dt>
  690 + <dd>Mark selected as unread</dd>
  691 + </dl>
  692 + <dl class="keyboard-mappings">
  693 + <dt>e</dt>
  694 + <dd>Close selected</dd>
  695 + </dl>
  696 + <dl class="keyboard-mappings">
  697 + <dt>y</dt>
  698 + <dd>Remove selected from view</dd>
  699 + </dl>
  700 + </div><!-- /.column.middle -->
  701 + <div class="column last">
  702 + <dl class="keyboard-mappings">
  703 + <dt>c</dt>
  704 + <dd>Create issue</dd>
  705 + </dl>
  706 + <dl class="keyboard-mappings">
  707 + <dt>l</dt>
  708 + <dd>Create label</dd>
  709 + </dl>
  710 + <dl class="keyboard-mappings">
  711 + <dt>i</dt>
  712 + <dd>Back to inbox</dd>
  713 + </dl>
  714 + <dl class="keyboard-mappings">
  715 + <dt>u</dt>
  716 + <dd>Back to issues</dd>
  717 + </dl>
  718 + <dl class="keyboard-mappings">
  719 + <dt>/</dt>
  720 + <dd>Focus issues search</dd>
  721 + </dl>
  722 + </div>
  723 + </div>
  724 +
  725 + <div class="rule"></div>
  726 +
  727 + <h3>Network Graph</h3>
  728 + <div class="columns equacols">
  729 + <div class="column first">
  730 + <dl class="keyboard-mappings">
  731 + <dt>← <em>or</em> h</dt>
  732 + <dd>Scroll left</dd>
  733 + </dl>
  734 + <dl class="keyboard-mappings">
  735 + <dt>→ <em>or</em> l</dt>
  736 + <dd>Scroll right</dd>
  737 + </dl>
  738 + <dl class="keyboard-mappings">
  739 + <dt>↑ <em>or</em> k</dt>
  740 + <dd>Scroll up</dd>
  741 + </dl>
  742 + <dl class="keyboard-mappings">
  743 + <dt>↓ <em>or</em> j</dt>
  744 + <dd>Scroll down</dd>
  745 + </dl>
  746 + <dl class="keyboard-mappings">
  747 + <dt>t</dt>
  748 + <dd>Toggle visibility of head labels</dd>
  749 + </dl>
  750 + </div><!-- /.column.first -->
  751 + <div class="column last">
  752 + <dl class="keyboard-mappings">
  753 + <dt>shift ← <em>or</em> shift h</dt>
  754 + <dd>Scroll all the way left</dd>
  755 + </dl>
  756 + <dl class="keyboard-mappings">
  757 + <dt>shift → <em>or</em> shift l</dt>
  758 + <dd>Scroll all the way right</dd>
  759 + </dl>
  760 + <dl class="keyboard-mappings">
  761 + <dt>shift ↑ <em>or</em> shift k</dt>
  762 + <dd>Scroll all the way up</dd>
  763 + </dl>
  764 + <dl class="keyboard-mappings">
  765 + <dt>shift ↓ <em>or</em> shift j</dt>
  766 + <dd>Scroll all the way down</dd>
  767 + </dl>
  768 + </div><!-- /.column.last -->
  769 + </div>
  770 +
  771 +</div>
  772 +
  773 +
  774 + <!--[if IE 8]>
  775 + <script type="text/javascript" charset="utf-8">
  776 + $(document.body).addClass("ie8")
  777 + </script>
  778 + <![endif]-->
  779 +
  780 + <!--[if IE 7]>
  781 + <script type="text/javascript" charset="utf-8">
  782 + $(document.body).addClass("ie7")
  783 + </script>
  784 + <![endif]-->
  785 +
  786 + <script type="text/javascript">
  787 + _kmq.push(['trackClick', 'entice-signup-button', 'Entice banner clicked']);
  788 +
  789 + </script>
  790 +
  791 + </body>
  792 +</html>
  793 +
... ...
pacotes/twitteroauth/index.php 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +<?php
  2 +/**
  3 + * @file
  4 + * User has successfully authenticated with Twitter. Access tokens saved to session and DB.
  5 + */
  6 +
  7 +/* Load required lib files. */
  8 +session_name("openid");
  9 +session_start();
  10 +require_once('twitteroauth/twitteroauth.php');
  11 +require_once('config.php');
  12 +
  13 +/* If access tokens are not available redirect to connect page. */
  14 +if (empty($_SESSION['access_token']) || empty($_SESSION['access_token']['oauth_token']) || empty($_SESSION['access_token']['oauth_token_secret'])) {
  15 + $_SESSION["openid"] = false;
  16 + session_destroy();
  17 + header('Location: ../openid/login.php?login&erro=ok');
  18 +}
  19 +/* Get user access tokens out of the session. */
  20 +$access_token = $_SESSION['access_token'];
  21 +
  22 +/* Create a TwitterOauth object with consumer/user tokens. */
  23 +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);
  24 +
  25 +/* If method is set change API call made. Test is called by default. */
  26 +$content = $connection->get('account/verify_credentials');
  27 +
  28 +$_SESSION["openid"] = true;
  29 +$_SESSION["openid_identifier"] = "http://twitter.com/".$content->screen_name;
  30 +$_SESSION["openidusuario"] = $content->screen_name;
  31 +$_SESSION["openidservico"] = "twitter";
  32 +$_SESSION["openidimagem"] = $content->profile_image_url;
  33 +$_SESSION["openidnome"] = $content->name;
  34 +header('Location: ../openid/login.php');
  35 +?>
... ...
pacotes/twitteroauth/redirect.php 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +<?php
  2 +$dadosurl = array_merge($_GET,$_POST);
  3 +require_once('config.php');
  4 +/* Start session and load library. */
  5 +session_name("openid");
  6 +session_start();
  7 +
  8 +require_once('twitteroauth/twitteroauth.php');
  9 +//require_once('config.php');
  10 +
  11 +/* Build TwitterOAuth object with client credentials. */
  12 +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
  13 +
  14 +/* Get temporary credentials. */
  15 +$request_token = $connection->getRequestToken(OAUTH_CALLBACK);
  16 +
  17 +/* Save temporary credentials to session. */
  18 +$_SESSION['oauth_token'] = $token = $request_token['oauth_token'];
  19 +$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret'];
  20 +$_SESSION['servico'] = "twitter";
  21 +
  22 +/* If last connection failed don't display authorization link. */
  23 +switch ($connection->http_code) {
  24 + case 200:
  25 + /* Build authorize URL and redirect user to Twitter. */
  26 + $url = $connection->getAuthorizeURL($token);
  27 + header('Location: '.$url );
  28 + break;
  29 + default:
  30 + /* Show notification if something went wrong. */
  31 + echo 'Could not connect to Twitter. Refresh the page or try again later.';
  32 +}
... ...
pacotes/twitteroauth/test.php 0 → 100644
... ... @@ -0,0 +1,374 @@
  1 +<?php
  2 +/**
  3 + * @file
  4 + *
  5 + */
  6 +
  7 +/* Load required lib files. */
  8 +session_start();
  9 +require_once('twitteroauth/twitteroauth.php');
  10 +require_once('config.php');
  11 +
  12 +/* If access tokens are not available redirect to connect page. */
  13 +if (empty($_SESSION['access_token']) || empty($_SESSION['access_token']['oauth_token']) || empty($_SESSION['access_token']['oauth_token_secret'])) {
  14 + header('Location: ./clearsessions.php');
  15 +}
  16 +/* Get user access tokens out of the session. */
  17 +$access_token = $_SESSION['access_token'];
  18 +
  19 +/* Create a TwitterOauth object with consumer/user tokens. */
  20 +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);
  21 +
  22 +/* If method is set change API call made. Test is called by default. */
  23 +$content = $connection->get('account/rate_limit_status');
  24 +echo "Current API hits remaining: {$content->remaining_hits}.";
  25 +
  26 +/* Get logged in user to help with tests. */
  27 +$user = $connection->get('account/verify_credentials');
  28 +
  29 +$active = FALSE;
  30 +if (empty($active) || empty($_GET['confirmed']) || $_GET['confirmed'] !== 'TRUE') {
  31 + echo '<h1>Warning! This page will make many requests to Twitter.</h1>';
  32 + echo '<h3>Performing these test might max out your rate limit.</h3>';
  33 + echo '<h3>Statuses/DMs will be created and deleted. Accounts will be un/followed.</h3>';
  34 + echo '<h3>Profile information/design will be changed.</h3>';
  35 + echo '<h2>USE A DEV ACCOUNT!</h2>';
  36 + echo '<h4>Before use you must set $active = TRUE in test.php</h4>';
  37 + echo '<a href="./test.php?confirmed=TRUE">Continue</a> or <a href="./index.php">go back</a>.';
  38 + exit;
  39 +}
  40 +
  41 +function twitteroauth_row($method, $response, $http_code, $parameters = '') {
  42 + echo '<tr>';
  43 + echo "<td><b>{$method}</b></td>";
  44 + switch ($http_code) {
  45 + case '200':
  46 + case '304':
  47 + $color = 'green';
  48 + break;
  49 + case '400':
  50 + case '401':
  51 + case '403':
  52 + case '404':
  53 + case '406':
  54 + $color = 'red';
  55 + break;
  56 + case '500':
  57 + case '502':
  58 + case '503':
  59 + $color = 'orange';
  60 + break;
  61 + default:
  62 + $color = 'grey';
  63 + }
  64 + echo "<td style='background: {$color};'>{$http_code}</td>";
  65 + if (!is_string($response)) {
  66 + $response = print_r($response, TRUE);
  67 + }
  68 + if (!is_string($parameters)) {
  69 + $parameters = print_r($parameters, TRUE);
  70 + }
  71 + echo '<td>', strlen($response), '</td>';
  72 + echo '<td>', $parameters, '</td>';
  73 + echo '</tr><tr>';
  74 + echo '<td colspan="4">', substr($response, 0, 400), '...</td>';
  75 + echo '</tr>';
  76 +
  77 +}
  78 +
  79 +function twitteroauth_header($header) {
  80 + echo '<tr><th colspan="4" style="background: grey;">', $header, '</th></tr>';
  81 +}
  82 +
  83 +/* Start table. */
  84 +echo '<br><br>';
  85 +echo '<table border="1" cellpadding="2" cellspacing="0">';
  86 +echo '<tr>';
  87 +echo '<th>API Method</th>';
  88 +echo '<th>HTTP Code</th>';
  89 +echo '<th>Response Length</th>';
  90 +echo '<th>Parameters</th>';
  91 +echo '</tr><tr>';
  92 +echo '<th colspan="4">Response Snippet</th>';
  93 +echo '</tr>';
  94 +
  95 +/**
  96 + * Help Methods.
  97 + */
  98 +twitteroauth_header('Help Methods');
  99 +
  100 +/* help/test */
  101 +twitteroauth_row('help/test', $connection->get('help/test'), $connection->http_code);
  102 +
  103 +
  104 +/**
  105 + * Timeline Methods.
  106 + */
  107 +twitteroauth_header('Timeline Methods');
  108 +
  109 +/* statuses/public_timeline */
  110 +twitteroauth_row('statuses/public_timeline', $connection->get('statuses/public_timeline'), $connection->http_code);
  111 +
  112 +/* statuses/public_timeline */
  113 +twitteroauth_row('statuses/home_timeline', $connection->get('statuses/home_timeline'), $connection->http_code);
  114 +
  115 +/* statuses/friends_timeline */
  116 +twitteroauth_row('statuses/friends_timeline', $connection->get('statuses/friends_timeline'), $connection->http_code);
  117 +
  118 +/* statuses/user_timeline */
  119 +twitteroauth_row('statuses/user_timeline', $connection->get('statuses/user_timeline'), $connection->http_code);
  120 +
  121 +/* statuses/mentions */
  122 +twitteroauth_row('statuses/mentions', $connection->get('statuses/mentions'), $connection->http_code);
  123 +
  124 +/* statuses/retweeted_by_me */
  125 +twitteroauth_row('statuses/retweeted_by_me', $connection->get('statuses/retweeted_by_me'), $connection->http_code);
  126 +
  127 +/* statuses/retweeted_to_me */
  128 +twitteroauth_row('statuses/retweeted_to_me', $connection->get('statuses/retweeted_to_me'), $connection->http_code);
  129 +
  130 +/* statuses/retweets_of_me */
  131 +twitteroauth_row('statuses/retweets_of_me', $connection->get('statuses/retweets_of_me'), $connection->http_code);
  132 +
  133 +
  134 +/**
  135 + * Status Methods.
  136 + */
  137 +twitteroauth_header('Status Methods');
  138 +
  139 +/* statuses/update */
  140 +date_default_timezone_set('GMT');
  141 +$parameters = array('status' => date(DATE_RFC822));
  142 +$status = $connection->post('statuses/update', $parameters);
  143 +twitteroauth_row('statuses/update', $status, $connection->http_code, $parameters);
  144 +
  145 +/* statuses/show */
  146 +$method = "statuses/show/{$status->id}";
  147 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  148 +
  149 +/* statuses/destroy */
  150 +$method = "statuses/destroy/{$status->id}";
  151 +twitteroauth_row($method, $connection->delete($method), $connection->http_code);
  152 +
  153 +/* statuses/retweet */
  154 +$method = 'statuses/retweet/6242973112';
  155 +twitteroauth_row($method, $connection->post($method), $connection->http_code);
  156 +
  157 +/* statuses/retweets */
  158 +$method = 'statuses/retweets/6242973112';
  159 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  160 +
  161 +
  162 +/**
  163 + * User Methods.
  164 + */
  165 +twitteroauth_header('User Methods');
  166 +
  167 +/* users/show */
  168 +$method = 'users/show/27831060';
  169 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  170 +
  171 +/* users/search */
  172 +$parameters = array('q' => 'oauth');
  173 +twitteroauth_row('users/search', $connection->get('users/search', $parameters), $connection->http_code, $parameters);
  174 +
  175 +/* statuses/friends */
  176 +$method = 'statuses/friends/27831060';
  177 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  178 +
  179 +/* statuses/followers */
  180 +$method = 'statuses/followers/27831060';
  181 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  182 +
  183 +
  184 +/**
  185 + * List Methods.
  186 + */
  187 +twitteroauth_header('List Methods');
  188 +
  189 +/* POST lists */
  190 +$method = "{$user->screen_name}/lists";
  191 +$parameters = array('name' => 'Twitter OAuth');
  192 +$list = $connection->post($method, $parameters);
  193 +twitteroauth_row($method, $list, $connection->http_code, $parameters);
  194 +
  195 +/* POST lists id */
  196 +$method = "{$user->screen_name}/lists/{$list->id}";
  197 +$parameters = array('name' => 'Twitter OAuth List 2');
  198 +$list = $connection->post($method, $parameters);
  199 +twitteroauth_row($method, $list, $connection->http_code, $parameters);
  200 +
  201 +/* GET lists */
  202 +$method = "{$user->screen_name}/lists";
  203 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  204 +
  205 +/* GET lists id */
  206 +$method = "{$user->screen_name}/lists/{$list->id}";
  207 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  208 +
  209 +/* DELETE list */
  210 +$method = "{$user->screen_name}/lists/{$list->id}";
  211 +twitteroauth_row($method, $connection->delete($method), $connection->http_code);
  212 +
  213 +/* GET list statuses */
  214 +$method = "oauthlib/lists/4097351/statuses";
  215 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  216 +
  217 +/* GET list members */
  218 +$method = "{$user->screen_name}/lists/memberships";
  219 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  220 +
  221 +
  222 +/* GET list subscriptions */
  223 +$method = "{$user->screen_name}/lists/subscriptions";
  224 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  225 +
  226 +
  227 +/**
  228 + * List Members Methods.
  229 + */
  230 +twitteroauth_header('List Members Methods');
  231 +
  232 +/* Create temp list for list member methods. */
  233 +$method = "{$user->screen_name}/lists";
  234 +$parameters = array('name' => 'Twitter OAuth Temp');
  235 +$list = $connection->post($method, $parameters);
  236 +
  237 +
  238 +/* POST list members */
  239 +$parameters = array('id' => 27831060);
  240 +$method = "{$user->screen_name}/{$list->id}/members";
  241 +twitteroauth_row($method, $connection->post($method, $parameters), $connection->http_code, $parameters);
  242 +
  243 +/* GET list members */
  244 +$method = "{$user->screen_name}/{$list->id}/members";
  245 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  246 +
  247 +/* GET list members id */
  248 +$method = "{$user->screen_name}/{$list->id}/members/27831060";
  249 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  250 +
  251 +/* DELETE list members */
  252 +$parameters = array('id' => 27831060);
  253 +$method = "{$user->screen_name}/{$list->id}/members";
  254 +twitteroauth_row($method, $connection->delete($method, $parameters), $connection->http_code, $parameters);
  255 +
  256 +/* Delete the temp list */
  257 +$method = "{$user->screen_name}/lists/{$list->id}";
  258 +$connection->delete($method);
  259 +
  260 +
  261 +/**
  262 + * List Subscribers Methods.
  263 + */
  264 +twitteroauth_header('List Subscribers Methods');
  265 +
  266 +
  267 +/* POST list subscribers */
  268 +$method = 'oauthlib/test-list/subscribers';
  269 +twitteroauth_row($method, $connection->post($method), $connection->http_code);
  270 +
  271 +/* GET list subscribers */
  272 +$method = 'oauthlib/test-list/subscribers';
  273 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  274 +
  275 +/* GET list subscribers id */
  276 +$method = "oauthlib/test-list/subscribers/{$user->id}";
  277 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  278 +
  279 +/* DELETE list subscribers */
  280 +$method = 'oauthlib/test-list/subscribers';
  281 +twitteroauth_row($method, $connection->delete($method), $connection->http_code);
  282 +
  283 +
  284 +/**
  285 + * Direct Message Methdos.
  286 + */
  287 +twitteroauth_header('Direct Message Methods');
  288 +
  289 +/* direct_messages/new */
  290 +$parameters = array('user_id' => $user->id, 'text' => 'Testing out @oauthlib code');
  291 +$method = 'direct_messages/new';
  292 +$dm = $connection->post($method, $parameters);
  293 +twitteroauth_row($method, $dm, $connection->http_code, $parameters);
  294 +
  295 +/* direct_messages */
  296 +$method = 'direct_messages';
  297 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  298 +
  299 +/* direct_messages/sent */
  300 +$method = 'direct_messages/sent';
  301 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  302 +
  303 +/* direct_messages/sent */
  304 +$method = "direct_messages/destroy/{$dm->id}";
  305 +twitteroauth_row($method, $connection->delete($method), $connection->http_code);
  306 +
  307 +
  308 +/**
  309 + * Friendships Methods.
  310 + */
  311 +twitteroauth_header('Friendships Methods');
  312 +
  313 +/* friendships/create */
  314 +$method = 'friendships/create/93915746';
  315 +twitteroauth_row($method, $connection->post($method), $connection->http_code);
  316 +
  317 +/* friendships/show */
  318 +$parameters = array('target_id' => 27831060);
  319 +$method = 'friendships/show';
  320 +twitteroauth_row($method, $connection->get($method, $parameters), $connection->http_code, $parameters);
  321 +
  322 +/* friendships/destroy */
  323 +$method = 'friendships/destroy/93915746';
  324 +twitteroauth_row($method, $connection->post($method), $connection->http_code);
  325 +
  326 +
  327 +/**
  328 + * Social Graph Methods.
  329 + */
  330 +twitteroauth_header('Social Graph Methods');
  331 +
  332 +/* friends/ids */
  333 +$method = 'friends/ids';
  334 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  335 +
  336 +/* friends/ids */
  337 +$method = 'friends/ids';
  338 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  339 +
  340 +
  341 +/**
  342 + * Account Methods.
  343 + */
  344 +twitteroauth_header('Account Methods');
  345 +
  346 +/* account/verify_credentials */
  347 +$method = 'account/verify_credentials';
  348 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  349 +
  350 +/* account/rate_limit_status */
  351 +$method = 'account/rate_limit_status';
  352 +twitteroauth_row($method, $connection->get($method), $connection->http_code);
  353 +
  354 +/* account/update_profile_colors */
  355 +$parameters = array('profile_background_color' => 'fff');
  356 +$method = 'account/update_profile_colors';
  357 +twitteroauth_row($method, $connection->post($method, $parameters), $connection->http_code, $parameters);
  358 +
  359 +/* account/update_profile */
  360 +$parameters = array('location' => 'Teh internets');
  361 +$method = 'account/update_profile';
  362 +twitteroauth_row($method, $connection->post($method, $parameters), $connection->http_code, $parameters);
  363 +
  364 +
  365 +
  366 +
  367 +/**
  368 + * OAuth Methods.
  369 + */
  370 +twitteroauth_header('OAuth Methods');
  371 +
  372 +/* oauth/request_token */
  373 +$oauth = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
  374 +twitteroauth_row('oauth/reqeust_token', $oauth->getRequestToken(), $oauth->http_code);
... ...
pacotes/twitteroauth/twitteroauth/OAuth.php 0 → 100644
... ... @@ -0,0 +1,874 @@
  1 +<?php
  2 +// vim: foldmethod=marker
  3 +
  4 +/* Generic exception class
  5 + */
  6 +class OAuthException extends Exception {
  7 + // pass
  8 +}
  9 +
  10 +class OAuthConsumer {
  11 + public $key;
  12 + public $secret;
  13 +
  14 + function __construct($key, $secret, $callback_url=NULL) {
  15 + $this->key = $key;
  16 + $this->secret = $secret;
  17 + $this->callback_url = $callback_url;
  18 + }
  19 +
  20 + function __toString() {
  21 + return "OAuthConsumer[key=$this->key,secret=$this->secret]";
  22 + }
  23 +}
  24 +
  25 +class OAuthToken {
  26 + // access tokens and request tokens
  27 + public $key;
  28 + public $secret;
  29 +
  30 + /**
  31 + * key = the token
  32 + * secret = the token secret
  33 + */
  34 + function __construct($key, $secret) {
  35 + $this->key = $key;
  36 + $this->secret = $secret;
  37 + }
  38 +
  39 + /**
  40 + * generates the basic string serialization of a token that a server
  41 + * would respond to request_token and access_token calls with
  42 + */
  43 + function to_string() {
  44 + return "oauth_token=" .
  45 + OAuthUtil::urlencode_rfc3986($this->key) .
  46 + "&oauth_token_secret=" .
  47 + OAuthUtil::urlencode_rfc3986($this->secret);
  48 + }
  49 +
  50 + function __toString() {
  51 + return $this->to_string();
  52 + }
  53 +}
  54 +
  55 +/**
  56 + * A class for implementing a Signature Method
  57 + * See section 9 ("Signing Requests") in the spec
  58 + */
  59 +abstract class OAuthSignatureMethod {
  60 + /**
  61 + * Needs to return the name of the Signature Method (ie HMAC-SHA1)
  62 + * @return string
  63 + */
  64 + abstract public function get_name();
  65 +
  66 + /**
  67 + * Build up the signature
  68 + * NOTE: The output of this function MUST NOT be urlencoded.
  69 + * the encoding is handled in OAuthRequest when the final
  70 + * request is serialized
  71 + * @param OAuthRequest $request
  72 + * @param OAuthConsumer $consumer
  73 + * @param OAuthToken $token
  74 + * @return string
  75 + */
  76 + abstract public function build_signature($request, $consumer, $token);
  77 +
  78 + /**
  79 + * Verifies that a given signature is correct
  80 + * @param OAuthRequest $request
  81 + * @param OAuthConsumer $consumer
  82 + * @param OAuthToken $token
  83 + * @param string $signature
  84 + * @return bool
  85 + */
  86 + public function check_signature($request, $consumer, $token, $signature) {
  87 + $built = $this->build_signature($request, $consumer, $token);
  88 + return $built == $signature;
  89 + }
  90 +}
  91 +
  92 +/**
  93 + * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
  94 + * where the Signature Base String is the text and the key is the concatenated values (each first
  95 + * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
  96 + * character (ASCII code 38) even if empty.
  97 + * - Chapter 9.2 ("HMAC-SHA1")
  98 + */
  99 +class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
  100 + function get_name() {
  101 + return "HMAC-SHA1";
  102 + }
  103 +
  104 + public function build_signature($request, $consumer, $token) {
  105 + $base_string = $request->get_signature_base_string();
  106 + $request->base_string = $base_string;
  107 +
  108 + $key_parts = array(
  109 + $consumer->secret,
  110 + ($token) ? $token->secret : ""
  111 + );
  112 +
  113 + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
  114 + $key = implode('&', $key_parts);
  115 +
  116 + return base64_encode(hash_hmac('sha1', $base_string, $key, true));
  117 + }
  118 +}
  119 +
  120 +/**
  121 + * The PLAINTEXT method does not provide any security protection and SHOULD only be used
  122 + * over a secure channel such as HTTPS. It does not use the Signature Base String.
  123 + * - Chapter 9.4 ("PLAINTEXT")
  124 + */
  125 +class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
  126 + public function get_name() {
  127 + return "PLAINTEXT";
  128 + }
  129 +
  130 + /**
  131 + * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
  132 + * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
  133 + * empty. The result MUST be encoded again.
  134 + * - Chapter 9.4.1 ("Generating Signatures")
  135 + *
  136 + * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
  137 + * OAuthRequest handles this!
  138 + */
  139 + public function build_signature($request, $consumer, $token) {
  140 + $key_parts = array(
  141 + $consumer->secret,
  142 + ($token) ? $token->secret : ""
  143 + );
  144 +
  145 + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
  146 + $key = implode('&', $key_parts);
  147 + $request->base_string = $key;
  148 +
  149 + return $key;
  150 + }
  151 +}
  152 +
  153 +/**
  154 + * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
  155 + * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
  156 + * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
  157 + * verified way to the Service Provider, in a manner which is beyond the scope of this
  158 + * specification.
  159 + * - Chapter 9.3 ("RSA-SHA1")
  160 + */
  161 +abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
  162 + public function get_name() {
  163 + return "RSA-SHA1";
  164 + }
  165 +
  166 + // Up to the SP to implement this lookup of keys. Possible ideas are:
  167 + // (1) do a lookup in a table of trusted certs keyed off of consumer
  168 + // (2) fetch via http using a url provided by the requester
  169 + // (3) some sort of specific discovery code based on request
  170 + //
  171 + // Either way should return a string representation of the certificate
  172 + protected abstract function fetch_public_cert(&$request);
  173 +
  174 + // Up to the SP to implement this lookup of keys. Possible ideas are:
  175 + // (1) do a lookup in a table of trusted certs keyed off of consumer
  176 + //
  177 + // Either way should return a string representation of the certificate
  178 + protected abstract function fetch_private_cert(&$request);
  179 +
  180 + public function build_signature($request, $consumer, $token) {
  181 + $base_string = $request->get_signature_base_string();
  182 + $request->base_string = $base_string;
  183 +
  184 + // Fetch the private key cert based on the request
  185 + $cert = $this->fetch_private_cert($request);
  186 +
  187 + // Pull the private key ID from the certificate
  188 + $privatekeyid = openssl_get_privatekey($cert);
  189 +
  190 + // Sign using the key
  191 + $ok = openssl_sign($base_string, $signature, $privatekeyid);
  192 +
  193 + // Release the key resource
  194 + openssl_free_key($privatekeyid);
  195 +
  196 + return base64_encode($signature);
  197 + }
  198 +
  199 + public function check_signature($request, $consumer, $token, $signature) {
  200 + $decoded_sig = base64_decode($signature);
  201 +
  202 + $base_string = $request->get_signature_base_string();
  203 +
  204 + // Fetch the public key cert based on the request
  205 + $cert = $this->fetch_public_cert($request);
  206 +
  207 + // Pull the public key ID from the certificate
  208 + $publickeyid = openssl_get_publickey($cert);
  209 +
  210 + // Check the computed signature against the one passed in the query
  211 + $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
  212 +
  213 + // Release the key resource
  214 + openssl_free_key($publickeyid);
  215 +
  216 + return $ok == 1;
  217 + }
  218 +}
  219 +
  220 +class OAuthRequest {
  221 + private $parameters;
  222 + private $http_method;
  223 + private $http_url;
  224 + // for debug purposes
  225 + public $base_string;
  226 + public static $version = '1.0';
  227 + public static $POST_INPUT = 'php://input';
  228 +
  229 + function __construct($http_method, $http_url, $parameters=NULL) {
  230 + @$parameters or $parameters = array();
  231 + $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
  232 + $this->parameters = $parameters;
  233 + $this->http_method = $http_method;
  234 + $this->http_url = $http_url;
  235 + }
  236 +
  237 +
  238 + /**
  239 + * attempt to build up a request from what was passed to the server
  240 + */
  241 + public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
  242 + $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
  243 + ? 'http'
  244 + : 'https';
  245 + @$http_url or $http_url = $scheme .
  246 + '://' . $_SERVER['HTTP_HOST'] .
  247 + ':' .
  248 + $_SERVER['SERVER_PORT'] .
  249 + $_SERVER['REQUEST_URI'];
  250 + @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
  251 +
  252 + // We weren't handed any parameters, so let's find the ones relevant to
  253 + // this request.
  254 + // If you run XML-RPC or similar you should use this to provide your own
  255 + // parsed parameter-list
  256 + if (!$parameters) {
  257 + // Find request headers
  258 + $request_headers = OAuthUtil::get_headers();
  259 +
  260 + // Parse the query-string to find GET parameters
  261 + $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
  262 +
  263 + // It's a POST request of the proper content-type, so parse POST
  264 + // parameters and add those overriding any duplicates from GET
  265 + if ($http_method == "POST"
  266 + && @strstr($request_headers["Content-Type"],
  267 + "application/x-www-form-urlencoded")
  268 + ) {
  269 + $post_data = OAuthUtil::parse_parameters(
  270 + file_get_contents(self::$POST_INPUT)
  271 + );
  272 + $parameters = array_merge($parameters, $post_data);
  273 + }
  274 +
  275 + // We have a Authorization-header with OAuth data. Parse the header
  276 + // and add those overriding any duplicates from GET or POST
  277 + if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
  278 + $header_parameters = OAuthUtil::split_header(
  279 + $request_headers['Authorization']
  280 + );
  281 + $parameters = array_merge($parameters, $header_parameters);
  282 + }
  283 +
  284 + }
  285 +
  286 + return new OAuthRequest($http_method, $http_url, $parameters);
  287 + }
  288 +
  289 + /**
  290 + * pretty much a helper function to set up the request
  291 + */
  292 + public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
  293 + @$parameters or $parameters = array();
  294 + $defaults = array("oauth_version" => OAuthRequest::$version,
  295 + "oauth_nonce" => OAuthRequest::generate_nonce(),
  296 + "oauth_timestamp" => OAuthRequest::generate_timestamp(),
  297 + "oauth_consumer_key" => $consumer->key);
  298 + if ($token)
  299 + $defaults['oauth_token'] = $token->key;
  300 +
  301 + $parameters = array_merge($defaults, $parameters);
  302 +
  303 + return new OAuthRequest($http_method, $http_url, $parameters);
  304 + }
  305 +
  306 + public function set_parameter($name, $value, $allow_duplicates = true) {
  307 + if ($allow_duplicates && isset($this->parameters[$name])) {
  308 + // We have already added parameter(s) with this name, so add to the list
  309 + if (is_scalar($this->parameters[$name])) {
  310 + // This is the first duplicate, so transform scalar (string)
  311 + // into an array so we can add the duplicates
  312 + $this->parameters[$name] = array($this->parameters[$name]);
  313 + }
  314 +
  315 + $this->parameters[$name][] = $value;
  316 + } else {
  317 + $this->parameters[$name] = $value;
  318 + }
  319 + }
  320 +
  321 + public function get_parameter($name) {
  322 + return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
  323 + }
  324 +
  325 + public function get_parameters() {
  326 + return $this->parameters;
  327 + }
  328 +
  329 + public function unset_parameter($name) {
  330 + unset($this->parameters[$name]);
  331 + }
  332 +
  333 + /**
  334 + * The request parameters, sorted and concatenated into a normalized string.
  335 + * @return string
  336 + */
  337 + public function get_signable_parameters() {
  338 + // Grab all parameters
  339 + $params = $this->parameters;
  340 +
  341 + // Remove oauth_signature if present
  342 + // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
  343 + if (isset($params['oauth_signature'])) {
  344 + unset($params['oauth_signature']);
  345 + }
  346 +
  347 + return OAuthUtil::build_http_query($params);
  348 + }
  349 +
  350 + /**
  351 + * Returns the base string of this request
  352 + *
  353 + * The base string defined as the method, the url
  354 + * and the parameters (normalized), each urlencoded
  355 + * and the concated with &.
  356 + */
  357 + public function get_signature_base_string() {
  358 + $parts = array(
  359 + $this->get_normalized_http_method(),
  360 + $this->get_normalized_http_url(),
  361 + $this->get_signable_parameters()
  362 + );
  363 +
  364 + $parts = OAuthUtil::urlencode_rfc3986($parts);
  365 +
  366 + return implode('&', $parts);
  367 + }
  368 +
  369 + /**
  370 + * just uppercases the http method
  371 + */
  372 + public function get_normalized_http_method() {
  373 + return strtoupper($this->http_method);
  374 + }
  375 +
  376 + /**
  377 + * parses the url and rebuilds it to be
  378 + * scheme://host/path
  379 + */
  380 + public function get_normalized_http_url() {
  381 + $parts = parse_url($this->http_url);
  382 +
  383 + $port = @$parts['port'];
  384 + $scheme = $parts['scheme'];
  385 + $host = $parts['host'];
  386 + $path = @$parts['path'];
  387 +
  388 + $port or $port = ($scheme == 'https') ? '443' : '80';
  389 +
  390 + if (($scheme == 'https' && $port != '443')
  391 + || ($scheme == 'http' && $port != '80')) {
  392 + $host = "$host:$port";
  393 + }
  394 + return "$scheme://$host$path";
  395 + }
  396 +
  397 + /**
  398 + * builds a url usable for a GET request
  399 + */
  400 + public function to_url() {
  401 + $post_data = $this->to_postdata();
  402 + $out = $this->get_normalized_http_url();
  403 + if ($post_data) {
  404 + $out .= '?'.$post_data;
  405 + }
  406 + return $out;
  407 + }
  408 +
  409 + /**
  410 + * builds the data one would send in a POST request
  411 + */
  412 + public function to_postdata() {
  413 + return OAuthUtil::build_http_query($this->parameters);
  414 + }
  415 +
  416 + /**
  417 + * builds the Authorization: header
  418 + */
  419 + public function to_header($realm=null) {
  420 + $first = true;
  421 + if($realm) {
  422 + $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
  423 + $first = false;
  424 + } else
  425 + $out = 'Authorization: OAuth';
  426 +
  427 + $total = array();
  428 + foreach ($this->parameters as $k => $v) {
  429 + if (substr($k, 0, 5) != "oauth") continue;
  430 + if (is_array($v)) {
  431 + throw new OAuthException('Arrays not supported in headers');
  432 + }
  433 + $out .= ($first) ? ' ' : ',';
  434 + $out .= OAuthUtil::urlencode_rfc3986($k) .
  435 + '="' .
  436 + OAuthUtil::urlencode_rfc3986($v) .
  437 + '"';
  438 + $first = false;
  439 + }
  440 + return $out;
  441 + }
  442 +
  443 + public function __toString() {
  444 + return $this->to_url();
  445 + }
  446 +
  447 +
  448 + public function sign_request($signature_method, $consumer, $token) {
  449 + $this->set_parameter(
  450 + "oauth_signature_method",
  451 + $signature_method->get_name(),
  452 + false
  453 + );
  454 + $signature = $this->build_signature($signature_method, $consumer, $token);
  455 + $this->set_parameter("oauth_signature", $signature, false);
  456 + }
  457 +
  458 + public function build_signature($signature_method, $consumer, $token) {
  459 + $signature = $signature_method->build_signature($this, $consumer, $token);
  460 + return $signature;
  461 + }
  462 +
  463 + /**
  464 + * util function: current timestamp
  465 + */
  466 + private static function generate_timestamp() {
  467 + return time();
  468 + }
  469 +
  470 + /**
  471 + * util function: current nonce
  472 + */
  473 + private static function generate_nonce() {
  474 + $mt = microtime();
  475 + $rand = mt_rand();
  476 +
  477 + return md5($mt . $rand); // md5s look nicer than numbers
  478 + }
  479 +}
  480 +
  481 +class OAuthServer {
  482 + protected $timestamp_threshold = 300; // in seconds, five minutes
  483 + protected $version = '1.0'; // hi blaine
  484 + protected $signature_methods = array();
  485 +
  486 + protected $data_store;
  487 +
  488 + function __construct($data_store) {
  489 + $this->data_store = $data_store;
  490 + }
  491 +
  492 + public function add_signature_method($signature_method) {
  493 + $this->signature_methods[$signature_method->get_name()] =
  494 + $signature_method;
  495 + }
  496 +
  497 + // high level functions
  498 +
  499 + /**
  500 + * process a request_token request
  501 + * returns the request token on success
  502 + */
  503 + public function fetch_request_token(&$request) {
  504 + $this->get_version($request);
  505 +
  506 + $consumer = $this->get_consumer($request);
  507 +
  508 + // no token required for the initial token request
  509 + $token = NULL;
  510 +
  511 + $this->check_signature($request, $consumer, $token);
  512 +
  513 + // Rev A change
  514 + $callback = $request->get_parameter('oauth_callback');
  515 + $new_token = $this->data_store->new_request_token($consumer, $callback);
  516 +
  517 + return $new_token;
  518 + }
  519 +
  520 + /**
  521 + * process an access_token request
  522 + * returns the access token on success
  523 + */
  524 + public function fetch_access_token(&$request) {
  525 + $this->get_version($request);
  526 +
  527 + $consumer = $this->get_consumer($request);
  528 +
  529 + // requires authorized request token
  530 + $token = $this->get_token($request, $consumer, "request");
  531 +
  532 + $this->check_signature($request, $consumer, $token);
  533 +
  534 + // Rev A change
  535 + $verifier = $request->get_parameter('oauth_verifier');
  536 + $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
  537 +
  538 + return $new_token;
  539 + }
  540 +
  541 + /**
  542 + * verify an api call, checks all the parameters
  543 + */
  544 + public function verify_request(&$request) {
  545 + $this->get_version($request);
  546 + $consumer = $this->get_consumer($request);
  547 + $token = $this->get_token($request, $consumer, "access");
  548 + $this->check_signature($request, $consumer, $token);
  549 + return array($consumer, $token);
  550 + }
  551 +
  552 + // Internals from here
  553 + /**
  554 + * version 1
  555 + */
  556 + private function get_version(&$request) {
  557 + $version = $request->get_parameter("oauth_version");
  558 + if (!$version) {
  559 + // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
  560 + // Chapter 7.0 ("Accessing Protected Ressources")
  561 + $version = '1.0';
  562 + }
  563 + if ($version !== $this->version) {
  564 + throw new OAuthException("OAuth version '$version' not supported");
  565 + }
  566 + return $version;
  567 + }
  568 +
  569 + /**
  570 + * figure out the signature with some defaults
  571 + */
  572 + private function get_signature_method(&$request) {
  573 + $signature_method =
  574 + @$request->get_parameter("oauth_signature_method");
  575 +
  576 + if (!$signature_method) {
  577 + // According to chapter 7 ("Accessing Protected Ressources") the signature-method
  578 + // parameter is required, and we can't just fallback to PLAINTEXT
  579 + throw new OAuthException('No signature method parameter. This parameter is required');
  580 + }
  581 +
  582 + if (!in_array($signature_method,
  583 + array_keys($this->signature_methods))) {
  584 + throw new OAuthException(
  585 + "Signature method '$signature_method' not supported " .
  586 + "try one of the following: " .
  587 + implode(", ", array_keys($this->signature_methods))
  588 + );
  589 + }
  590 + return $this->signature_methods[$signature_method];
  591 + }
  592 +
  593 + /**
  594 + * try to find the consumer for the provided request's consumer key
  595 + */
  596 + private function get_consumer(&$request) {
  597 + $consumer_key = @$request->get_parameter("oauth_consumer_key");
  598 + if (!$consumer_key) {
  599 + throw new OAuthException("Invalid consumer key");
  600 + }
  601 +
  602 + $consumer = $this->data_store->lookup_consumer($consumer_key);
  603 + if (!$consumer) {
  604 + throw new OAuthException("Invalid consumer");
  605 + }
  606 +
  607 + return $consumer;
  608 + }
  609 +
  610 + /**
  611 + * try to find the token for the provided request's token key
  612 + */
  613 + private function get_token(&$request, $consumer, $token_type="access") {
  614 + $token_field = @$request->get_parameter('oauth_token');
  615 + $token = $this->data_store->lookup_token(
  616 + $consumer, $token_type, $token_field
  617 + );
  618 + if (!$token) {
  619 + throw new OAuthException("Invalid $token_type token: $token_field");
  620 + }
  621 + return $token;
  622 + }
  623 +
  624 + /**
  625 + * all-in-one function to check the signature on a request
  626 + * should guess the signature method appropriately
  627 + */
  628 + private function check_signature(&$request, $consumer, $token) {
  629 + // this should probably be in a different method
  630 + $timestamp = @$request->get_parameter('oauth_timestamp');
  631 + $nonce = @$request->get_parameter('oauth_nonce');
  632 +
  633 + $this->check_timestamp($timestamp);
  634 + $this->check_nonce($consumer, $token, $nonce, $timestamp);
  635 +
  636 + $signature_method = $this->get_signature_method($request);
  637 +
  638 + $signature = $request->get_parameter('oauth_signature');
  639 + $valid_sig = $signature_method->check_signature(
  640 + $request,
  641 + $consumer,
  642 + $token,
  643 + $signature
  644 + );
  645 +
  646 + if (!$valid_sig) {
  647 + throw new OAuthException("Invalid signature");
  648 + }
  649 + }
  650 +
  651 + /**
  652 + * check that the timestamp is new enough
  653 + */
  654 + private function check_timestamp($timestamp) {
  655 + if( ! $timestamp )
  656 + throw new OAuthException(
  657 + 'Missing timestamp parameter. The parameter is required'
  658 + );
  659 +
  660 + // verify that timestamp is recentish
  661 + $now = time();
  662 + if (abs($now - $timestamp) > $this->timestamp_threshold) {
  663 + throw new OAuthException(
  664 + "Expired timestamp, yours $timestamp, ours $now"
  665 + );
  666 + }
  667 + }
  668 +
  669 + /**
  670 + * check that the nonce is not repeated
  671 + */
  672 + private function check_nonce($consumer, $token, $nonce, $timestamp) {
  673 + if( ! $nonce )
  674 + throw new OAuthException(
  675 + 'Missing nonce parameter. The parameter is required'
  676 + );
  677 +
  678 + // verify that the nonce is uniqueish
  679 + $found = $this->data_store->lookup_nonce(
  680 + $consumer,
  681 + $token,
  682 + $nonce,
  683 + $timestamp
  684 + );
  685 + if ($found) {
  686 + throw new OAuthException("Nonce already used: $nonce");
  687 + }
  688 + }
  689 +
  690 +}
  691 +
  692 +class OAuthDataStore {
  693 + function lookup_consumer($consumer_key) {
  694 + // implement me
  695 + }
  696 +
  697 + function lookup_token($consumer, $token_type, $token) {
  698 + // implement me
  699 + }
  700 +
  701 + function lookup_nonce($consumer, $token, $nonce, $timestamp) {
  702 + // implement me
  703 + }
  704 +
  705 + function new_request_token($consumer, $callback = null) {
  706 + // return a new token attached to this consumer
  707 + }
  708 +
  709 + function new_access_token($token, $consumer, $verifier = null) {
  710 + // return a new access token attached to this consumer
  711 + // for the user associated with this token if the request token
  712 + // is authorized
  713 + // should also invalidate the request token
  714 + }
  715 +
  716 +}
  717 +
  718 +class OAuthUtil {
  719 + public static function urlencode_rfc3986($input) {
  720 + if (is_array($input)) {
  721 + return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
  722 + } else if (is_scalar($input)) {
  723 + return str_replace(
  724 + '+',
  725 + ' ',
  726 + str_replace('%7E', '~', rawurlencode($input))
  727 + );
  728 + } else {
  729 + return '';
  730 + }
  731 +}
  732 +
  733 +
  734 + // This decode function isn't taking into consideration the above
  735 + // modifications to the encoding process. However, this method doesn't
  736 + // seem to be used anywhere so leaving it as is.
  737 + public static function urldecode_rfc3986($string) {
  738 + return urldecode($string);
  739 + }
  740 +
  741 + // Utility function for turning the Authorization: header into
  742 + // parameters, has to do some unescaping
  743 + // Can filter out any non-oauth parameters if needed (default behaviour)
  744 + public static function split_header($header, $only_allow_oauth_parameters = true) {
  745 + $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
  746 + $offset = 0;
  747 + $params = array();
  748 + while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
  749 + $match = $matches[0];
  750 + $header_name = $matches[2][0];
  751 + $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
  752 + if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
  753 + $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content);
  754 + }
  755 + $offset = $match[1] + strlen($match[0]);
  756 + }
  757 +
  758 + if (isset($params['realm'])) {
  759 + unset($params['realm']);
  760 + }
  761 +
  762 + return $params;
  763 + }
  764 +
  765 + // helper to try to sort out headers for people who aren't running apache
  766 + public static function get_headers() {
  767 + if (function_exists('apache_request_headers')) {
  768 + // we need this to get the actual Authorization: header
  769 + // because apache tends to tell us it doesn't exist
  770 + $headers = apache_request_headers();
  771 +
  772 + // sanitize the output of apache_request_headers because
  773 + // we always want the keys to be Cased-Like-This and arh()
  774 + // returns the headers in the same case as they are in the
  775 + // request
  776 + $out = array();
  777 + foreach( $headers AS $key => $value ) {
  778 + $key = str_replace(
  779 + " ",
  780 + "-",
  781 + ucwords(strtolower(str_replace("-", " ", $key)))
  782 + );
  783 + $out[$key] = $value;
  784 + }
  785 + } else {
  786 + // otherwise we don't have apache and are just going to have to hope
  787 + // that $_SERVER actually contains what we need
  788 + $out = array();
  789 + if( isset($_SERVER['CONTENT_TYPE']) )
  790 + $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
  791 + if( isset($_ENV['CONTENT_TYPE']) )
  792 + $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
  793 +
  794 + foreach ($_SERVER as $key => $value) {
  795 + if (substr($key, 0, 5) == "HTTP_") {
  796 + // this is chaos, basically it is just there to capitalize the first
  797 + // letter of every word that is not an initial HTTP and strip HTTP
  798 + // code from przemek
  799 + $key = str_replace(
  800 + " ",
  801 + "-",
  802 + ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
  803 + );
  804 + $out[$key] = $value;
  805 + }
  806 + }
  807 + }
  808 + return $out;
  809 + }
  810 +
  811 + // This function takes a input like a=b&a=c&d=e and returns the parsed
  812 + // parameters like this
  813 + // array('a' => array('b','c'), 'd' => 'e')
  814 + public static function parse_parameters( $input ) {
  815 + if (!isset($input) || !$input) return array();
  816 +
  817 + $pairs = explode('&', $input);
  818 +
  819 + $parsed_parameters = array();
  820 + foreach ($pairs as $pair) {
  821 + $split = explode('=', $pair, 2);
  822 + $parameter = OAuthUtil::urldecode_rfc3986($split[0]);
  823 + $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
  824 +
  825 + if (isset($parsed_parameters[$parameter])) {
  826 + // We have already recieved parameter(s) with this name, so add to the list
  827 + // of parameters with this name
  828 +
  829 + if (is_scalar($parsed_parameters[$parameter])) {
  830 + // This is the first duplicate, so transform scalar (string) into an array
  831 + // so we can add the duplicates
  832 + $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
  833 + }
  834 +
  835 + $parsed_parameters[$parameter][] = $value;
  836 + } else {
  837 + $parsed_parameters[$parameter] = $value;
  838 + }
  839 + }
  840 + return $parsed_parameters;
  841 + }
  842 +
  843 + public static function build_http_query($params) {
  844 + if (!$params) return '';
  845 +
  846 + // Urlencode both keys and values
  847 + $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
  848 + $values = OAuthUtil::urlencode_rfc3986(array_values($params));
  849 + $params = array_combine($keys, $values);
  850 +
  851 + // Parameters are sorted by name, using lexicographical byte value ordering.
  852 + // Ref: Spec: 9.1.1 (1)
  853 + uksort($params, 'strcmp');
  854 +
  855 + $pairs = array();
  856 + foreach ($params as $parameter => $value) {
  857 + if (is_array($value)) {
  858 + // If two or more parameters share the same name, they are sorted by their value
  859 + // Ref: Spec: 9.1.1 (1)
  860 + natsort($value);
  861 + foreach ($value as $duplicate_value) {
  862 + $pairs[] = $parameter . '=' . $duplicate_value;
  863 + }
  864 + } else {
  865 + $pairs[] = $parameter . '=' . $value;
  866 + }
  867 + }
  868 + // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
  869 + // Each name-value pair is separated by an '&' character (ASCII code 38)
  870 + return implode('&', $pairs);
  871 + }
  872 +}
  873 +
  874 +?>
... ...
pacotes/twitteroauth/twitteroauth/twitteroauth.php 0 → 100644
... ... @@ -0,0 +1,245 @@
  1 +<?php
  2 +
  3 +/*
  4 + * Abraham Williams (abraham@abrah.am) http://abrah.am
  5 + *
  6 + * The first PHP Library to support OAuth for Twitter's REST API.
  7 + */
  8 +
  9 +/* Load OAuth lib. You can find it at http://oauth.net */
  10 +require_once('OAuth.php');
  11 +
  12 +/**
  13 + * Twitter OAuth class
  14 + */
  15 +class TwitterOAuth {
  16 + /* Contains the last HTTP status code returned. */
  17 + public $http_code;
  18 + /* Contains the last API call. */
  19 + public $url;
  20 + /* Set up the API root URL. */
  21 + public $host = "https://api.twitter.com/1/";
  22 + /* Set timeout default. */
  23 + public $timeout = 30;
  24 + /* Set connect timeout. */
  25 + public $connecttimeout = 30;
  26 + /* Verify SSL Cert. */
  27 + public $ssl_verifypeer = FALSE;
  28 + /* Respons format. */
  29 + public $format = 'json';
  30 + /* Decode returned json data. */
  31 + public $decode_json = TRUE;
  32 + /* Contains the last HTTP headers returned. */
  33 + public $http_info;
  34 + /* Set the useragnet. */
  35 + public $useragent = 'TwitterOAuth v0.2.0-beta2';
  36 + /* Immediately retry the API call if the response was not successful. */
  37 + //public $retry = TRUE;
  38 +
  39 +
  40 +
  41 +
  42 + /**
  43 + * Set API URLS
  44 + */
  45 + function accessTokenURL() { return 'https://api.twitter.com/oauth/access_token'; }
  46 + function authenticateURL() { return 'https://twitter.com/oauth/authenticate'; }
  47 + function authorizeURL() { return 'https://twitter.com/oauth/authorize'; }
  48 + function requestTokenURL() { return 'https://api.twitter.com/oauth/request_token'; }
  49 +
  50 + /**
  51 + * Debug helpers
  52 + */
  53 + function lastStatusCode() { return $this->http_status; }
  54 + function lastAPICall() { return $this->last_api_call; }
  55 +
  56 + /**
  57 + * construct TwitterOAuth object
  58 + */
  59 + function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
  60 + $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
  61 + $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
  62 + if (!empty($oauth_token) && !empty($oauth_token_secret)) {
  63 + $this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
  64 + } else {
  65 + $this->token = NULL;
  66 + }
  67 + }
  68 +
  69 +
  70 + /**
  71 + * Get a request_token from Twitter
  72 + *
  73 + * @returns a key/value array containing oauth_token and oauth_token_secret
  74 + */
  75 + function getRequestToken($oauth_callback = NULL) {
  76 + $parameters = array();
  77 + if (!empty($oauth_callback)) {
  78 + $parameters['oauth_callback'] = $oauth_callback;
  79 + }
  80 + $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters);
  81 + $token = OAuthUtil::parse_parameters($request);
  82 + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
  83 + return $token;
  84 + }
  85 +
  86 + /**
  87 + * Get the authorize URL
  88 + *
  89 + * @returns a string
  90 + */
  91 + function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) {
  92 + if (is_array($token)) {
  93 + $token = $token['oauth_token'];
  94 + }
  95 + if (empty($sign_in_with_twitter)) {
  96 + return $this->authorizeURL() . "?oauth_token={$token}";
  97 + } else {
  98 + return $this->authenticateURL() . "?oauth_token={$token}";
  99 + }
  100 + }
  101 +
  102 + /**
  103 + * Exchange request token and secret for an access token and
  104 + * secret, to sign API calls.
  105 + *
  106 + * @returns array("oauth_token" => "the-access-token",
  107 + * "oauth_token_secret" => "the-access-secret",
  108 + * "user_id" => "9436992",
  109 + * "screen_name" => "abraham")
  110 + */
  111 + function getAccessToken($oauth_verifier = FALSE) {
  112 + $parameters = array();
  113 + if (!empty($oauth_verifier)) {
  114 + $parameters['oauth_verifier'] = $oauth_verifier;
  115 + }
  116 + $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters);
  117 + $token = OAuthUtil::parse_parameters($request);
  118 + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
  119 + return $token;
  120 + }
  121 +
  122 + /**
  123 + * One time exchange of username and password for access token and secret.
  124 + *
  125 + * @returns array("oauth_token" => "the-access-token",
  126 + * "oauth_token_secret" => "the-access-secret",
  127 + * "user_id" => "9436992",
  128 + * "screen_name" => "abraham",
  129 + * "x_auth_expires" => "0")
  130 + */
  131 + function getXAuthToken($username, $password) {
  132 + $parameters = array();
  133 + $parameters['x_auth_username'] = $username;
  134 + $parameters['x_auth_password'] = $password;
  135 + $parameters['x_auth_mode'] = 'client_auth';
  136 + $request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters);
  137 + $token = OAuthUtil::parse_parameters($request);
  138 + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
  139 + return $token;
  140 + }
  141 +
  142 + /**
  143 + * GET wrapper for oAuthRequest.
  144 + */
  145 + function get($url, $parameters = array()) {
  146 + $response = $this->oAuthRequest($url, 'GET', $parameters);
  147 + if ($this->format === 'json' && $this->decode_json) {
  148 + return json_decode($response);
  149 + }
  150 + return $response;
  151 + }
  152 +
  153 + /**
  154 + * POST wrapper for oAuthRequest.
  155 + */
  156 + function post($url, $parameters = array()) {
  157 + $response = $this->oAuthRequest($url, 'POST', $parameters);
  158 + if ($this->format === 'json' && $this->decode_json) {
  159 + return json_decode($response);
  160 + }
  161 + return $response;
  162 + }
  163 +
  164 + /**
  165 + * DELETE wrapper for oAuthReqeust.
  166 + */
  167 + function delete($url, $parameters = array()) {
  168 + $response = $this->oAuthRequest($url, 'DELETE', $parameters);
  169 + if ($this->format === 'json' && $this->decode_json) {
  170 + return json_decode($response);
  171 + }
  172 + return $response;
  173 + }
  174 +
  175 + /**
  176 + * Format and sign an OAuth / API request
  177 + */
  178 + function oAuthRequest($url, $method, $parameters) {
  179 + if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) {
  180 + $url = "{$this->host}{$url}.{$this->format}";
  181 + }
  182 + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
  183 + $request->sign_request($this->sha1_method, $this->consumer, $this->token);
  184 + switch ($method) {
  185 + case 'GET':
  186 + return $this->http($request->to_url(), 'GET');
  187 + default:
  188 + return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata());
  189 + }
  190 + }
  191 +
  192 + /**
  193 + * Make an HTTP request
  194 + *
  195 + * @return API results
  196 + */
  197 + function http($url, $method, $postfields = NULL) {
  198 + $this->http_info = array();
  199 + $ci = curl_init();
  200 + /* Curl settings */
  201 + curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent);
  202 + curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);
  203 + curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);
  204 + curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
  205 + curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:'));
  206 + curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);
  207 + curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
  208 + curl_setopt($ci, CURLOPT_HEADER, FALSE);
  209 +
  210 + switch ($method) {
  211 + case 'POST':
  212 + curl_setopt($ci, CURLOPT_POST, TRUE);
  213 + if (!empty($postfields)) {
  214 + curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
  215 + }
  216 + break;
  217 + case 'DELETE':
  218 + curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
  219 + if (!empty($postfields)) {
  220 + $url = "{$url}?{$postfields}";
  221 + }
  222 + }
  223 +
  224 + curl_setopt($ci, CURLOPT_URL, $url);
  225 + $response = curl_exec($ci);
  226 + $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
  227 + $this->http_info = array_merge($this->http_info, curl_getinfo($ci));
  228 + $this->url = $url;
  229 + curl_close ($ci);
  230 + return $response;
  231 + }
  232 +
  233 + /**
  234 + * Get the header info to store.
  235 + */
  236 + function getHeader($ch, $header) {
  237 + $i = strpos($header, ':');
  238 + if (!empty($i)) {
  239 + $key = str_replace('-', '_', strtolower(substr($header, 0, $i)));
  240 + $value = trim(substr($header, $i + 2));
  241 + $this->http_header[$key] = $value;
  242 + }
  243 + return strlen($header);
  244 + }
  245 +}
... ...
testainstal.php
... ... @@ -115,7 +115,8 @@ $tabelas = array(
115 115 "i3geoadmin_grupos"=>"it,es,en,desc_grupo,id_grupo,nome_grupo",
116 116 "i3geoadmin_subgrupos"=>"it,es,en,desc_subgrupo,id_subgrupo,nome_subgrupo",
117 117 "i3geoadmin_temas"=>"it,es,en,kmz_tema,nacessos,id_tema,kml_tema,ogc_tema,download_tema,tags_tema,tipoa_tema,link_tema,desc_tema,nome_tema,codigo_tema",
118   - "i3geoadmin_menus"=>"it,es,en,publicado_menu,perfil_menu,aberto,desc_menu,id_menu,nome_menu"
  118 + "i3geoadmin_menus"=>"it,es,en,publicado_menu,perfil_menu,aberto,desc_menu,id_menu,nome_menu",
  119 + "i3geoadmin_comentarios"=>"comentario,data,openidnome,openidimagem,openidservico,openidusuario,openidurl,id_tema"
119 120 );
120 121 include_once("admin/php/conexao.php");
121 122 foreach(array_keys($tabelas) as $tabela)
... ...