summaryrefslogtreecommitdiffabout
path: root/test
Unidiff
Diffstat (limited to 'test') (more/less context) (ignore whitespace changes)
-rw-r--r--test/OP.cc16
-rw-r--r--test/RP.cc6
-rw-r--r--test/kingate_openid_message.h4
3 files changed, 13 insertions, 13 deletions
diff --git a/test/OP.cc b/test/OP.cc
index 851d831..6012b2e 100644
--- a/test/OP.cc
+++ b/test/OP.cc
@@ -1,127 +1,127 @@
1#include <uuid/uuid.h> 1#include <uuid/uuid.h>
2#include <iostream> 2#include <iostream>
3#include <cassert> 3#include <cassert>
4#include <string> 4#include <string>
5#include <ext/algorithm> 5#include <ext/algorithm>
6using namespace std; 6using namespace std;
7#include <kingate/exception.h> 7#include <kingate/exception.h>
8#include <kingate/plaincgi.h> 8#include <kingate/plaincgi.h>
9#include <kingate/cgi_gateway.h> 9#include <kingate/cgi_gateway.h>
10#include <opkele/exception.h> 10#include <opkele/exception.h>
11#include <opkele/util.h> 11#include <opkele/util.h>
12#include <opkele/uris.h> 12#include <opkele/uris.h>
13#include <opkele/extension.h> 13#include <opkele/extension.h>
14#include <opkele/association.h> 14#include <opkele/association.h>
15#include <opkele/debug.h> 15#include <opkele/debug.h>
16#include <opkele/verify_op.h> 16#include <opkele/verify_op.h>
17#include <opkele/sreg.h> 17#include <opkele/sreg.h>
18 18
19#include "sqlite.h" 19#include "sqlite.h"
20#include "kingate_openid_message.h" 20#include "kingate_openid_message.h"
21 21
22static const string get_self_url(const kingate::cgi_gateway& gw) { 22static const string get_self_url(const kingate::cgi_gateway& gw) {
23 bool s = gw.has_meta("SSL_PROTOCOL_VERSION"); 23 bool s = gw.has_meta("SSL_PROTOCOL_VERSION");
24 string rv = s?"https://":"http://"; 24 string rv = s?"https://":"http://";
25 rv += gw.http_request_header("Host"); 25 rv += gw.http_request_header("Host");
26 const string& port = gw.get_meta("SERVER_PORT"); 26 const string& port = gw.get_meta("SERVER_PORT");
27 if( port!=(s?"443":"80") ) { 27 if( port!=(s?"443":"80") ) {
28 rv += ':'; rv += port; 28 rv += ':'; rv += port;
29 } 29 }
30 rv += gw.get_meta("REQUEST_URI"); 30 rv += gw.get_meta("REQUEST_URI");
31 string::size_type q = rv.find('?'); 31 string::size_type q = rv.find('?');
32 if(q!=string::npos) 32 if(q!=string::npos)
33 rv.erase(q); 33 rv.erase(q);
34 return rv; 34 return rv;
35} 35}
36 36
37class opdb_t : public sqlite3_t { 37class opdb_t : public sqlite3_t {
38 public: 38 public:
39 opdb_t() 39 opdb_t()
40 : sqlite3_t("/tmp/OP.db") { 40 : sqlite3_t("/tmp/OP.db") {
41 assert(_D); 41 assert(_D);
42 char **resp; int nr,nc; char *errm; 42 char **resp; int nr,nc; char *errm;
43 if(sqlite3_get_table( 43 if(sqlite3_get_table(
44 _D, "SELECT a_op FROM assoc LIMIT 0", 44 _D, "SELECT a_op FROM assoc LIMIT 0",
45 &resp,&nr,&nc,&errm)!=SQLITE_OK) { 45 &resp,&nr,&nc,&errm)!=SQLITE_OK) {
46 extern const char *__OP_db_bootstrap; 46 extern const char *__OP_db_bootstrap;
47 DOUT_("Bootstrapping DB"); 47 DOUT_("Bootstrapping DB");
48 if(sqlite3_exec(_D,__OP_db_bootstrap,NULL,NULL,&errm)!=SQLITE_OK) 48 if(sqlite3_exec(_D,__OP_db_bootstrap,NULL,NULL,&errm)!=SQLITE_OK)
49 throw opkele::exception(OPKELE_CP_ string("Failed to boostrap SQLite database: ")+errm); 49 throw opkele::exception(OPKELE_CP_ string("Failed to boostrap SQLite database: ")+errm);
50 }else 50 }else
51 sqlite3_free_table(resp); 51 sqlite3_free_table(resp);
52 } 52 }
53}; 53};
54 54
55class example_op_t : public opkele::verify_OP { 55class example_op_t : public opkele::verify_OP {
56 public: 56 public:
57 kingate::cgi_gateway& gw; 57 kingate::cgi_gateway& gw;
58 opdb_t db; 58 opdb_t db;
59 kingate::cookie htc; 59 kingate::cookie htc;
60 60
61 61
62 example_op_t(kingate::cgi_gateway& gw) 62 example_op_t(kingate::cgi_gateway& g)
63 : gw(gw) { 63 : gw(g) {
64 try { 64 try {
65 htc = gw.cookies.get_cookie("htop_session"); 65 htc = gw.cookies.get_cookie("htop_session");
66 sqlite3_mem_t<char*> S = sqlite3_mprintf( 66 sqlite3_mem_t<char*> S = sqlite3_mprintf(
67 "SELECT 1 FROM ht_sessions WHERE hts_id=%Q", 67 "SELECT 1 FROM ht_sessions WHERE hts_id=%Q",
68 htc.get_value().c_str()); 68 htc.get_value().c_str());
69 sqlite3_table_t T; int nr,nc; 69 sqlite3_table_t T; int nr,nc;
70 db.get_table(S,T,&nr,&nc); 70 db.get_table(S,T,&nr,&nc);
71 if(nr<1) 71 if(nr<1)
72 throw kingate::exception_notfound(CODEPOINT,"forcing cookie generation"); 72 throw kingate::exception_notfound(CODEPOINT,"forcing cookie generation");
73 }catch(kingate::exception_notfound& kenf) { 73 }catch(kingate::exception_notfound& kenf) {
74 uuid_t uuid; uuid_generate(uuid); 74 uuid_t uuid; uuid_generate(uuid);
75 htc = kingate::cookie("htop_session",opkele::util::encode_base64(uuid,sizeof(uuid))); 75 htc = kingate::cookie("htop_session",opkele::util::encode_base64(uuid,sizeof(uuid)));
76 sqlite3_mem_t<char*> S = sqlite3_mprintf( 76 sqlite3_mem_t<char*> S = sqlite3_mprintf(
77 "INSERT INTO ht_sessions (hts_id) VALUES (%Q)", 77 "INSERT INTO ht_sessions (hts_id) VALUES (%Q)",
78 htc.get_value().c_str()); 78 htc.get_value().c_str());
79 db.exec(S); 79 db.exec(S);
80 } 80 }
81 } 81 }
82 82
83 void set_authorized(bool a) { 83 void set_authorized(bool a) {
84 sqlite3_mem_t<char*> 84 sqlite3_mem_t<char*>
85 S = sqlite3_mprintf( 85 S = sqlite3_mprintf(
86 "UPDATE ht_sessions" 86 "UPDATE ht_sessions"
87 " SET authorized=%d" 87 " SET authorized=%d"
88 " WHERE hts_id=%Q", 88 " WHERE hts_id=%Q",
89 (int)a,htc.get_value().c_str()); 89 (int)a,htc.get_value().c_str());
90 db.exec(S); 90 db.exec(S);
91 } 91 }
92 bool get_authorized() { 92 bool get_authorized() {
93 sqlite3_mem_t<char*> 93 sqlite3_mem_t<char*>
94 S = sqlite3_mprintf( 94 S = sqlite3_mprintf(
95 "SELECT authorized" 95 "SELECT authorized"
96 " FROM ht_sessions" 96 " FROM ht_sessions"
97 " WHERE hts_id=%Q", 97 " WHERE hts_id=%Q",
98 htc.get_value().c_str()); 98 htc.get_value().c_str());
99 sqlite3_table_t T; int nr,nc; 99 sqlite3_table_t T; int nr,nc;
100 db.get_table(S,T,&nr,&nc); 100 db.get_table(S,T,&nr,&nc);
101 assert(nr==1); assert(nc=1); 101 assert(nr==1); assert(nc=1);
102 return opkele::util::string_to_long(T.get(1,0,nc)); 102 return opkele::util::string_to_long(T.get(1,0,nc));
103 } 103 }
104 104
105 ostream& cookie_header(ostream& o) const { 105 ostream& cookie_header(ostream& o) const {
106 o << "Set-Cookie: " << htc.set_cookie_header() << "\n"; 106 o << "Set-Cookie: " << htc.set_cookie_header() << "\n";
107 return o; 107 return o;
108 } 108 }
109 109
110 opkele::assoc_t alloc_assoc(const string& type,size_t klength,bool sl) { 110 opkele::assoc_t alloc_assoc(const string& type,size_t klength,bool sl) {
111 uuid_t uuid; uuid_generate(uuid); 111 uuid_t uuid; uuid_generate(uuid);
112 string a_handle = opkele::util::encode_base64(uuid,sizeof(uuid)); 112 string a_handle = opkele::util::encode_base64(uuid,sizeof(uuid));
113 opkele::secret_t a_secret; 113 opkele::secret_t a_secret;
114 generate_n( 114 generate_n(
115 back_insert_iterator<opkele::secret_t>(a_secret),klength, 115 back_insert_iterator<opkele::secret_t>(a_secret),klength,
116 rand ); 116 rand );
117 string ssecret; a_secret.to_base64(ssecret); 117 string ssecret; a_secret.to_base64(ssecret);
118 time_t now = time(0); 118 time_t now = time(0);
119 int expires_in = sl?3600*2:3600*24*7*2; 119 int expires_in = sl?3600*2:3600*24*7*2;
120 sqlite3_mem_t<char*> 120 sqlite3_mem_t<char*>
121 S = sqlite3_mprintf( 121 S = sqlite3_mprintf(
122 "INSERT INTO assoc" 122 "INSERT INTO assoc"
123 " (a_handle,a_type,a_ctime,a_etime,a_secret,a_stateless)" 123 " (a_handle,a_type,a_ctime,a_etime,a_secret,a_stateless)"
124 " VALUES (" 124 " VALUES ("
125 " %Q,%Q,datetime('now')," 125 " %Q,%Q,datetime('now'),"
126 " datetime('now','+%d seconds')," 126 " datetime('now','+%d seconds'),"
127 " %Q,%d );", 127 " %Q,%d );",
@@ -139,265 +139,265 @@ class example_op_t : public opkele::verify_OP {
139 sqlite3_mem_t<char*> 139 sqlite3_mem_t<char*>
140 S = sqlite3_mprintf( 140 S = sqlite3_mprintf(
141 "SELECT" 141 "SELECT"
142 " a_handle,a_type,a_secret,a_stateless," 142 " a_handle,a_type,a_secret,a_stateless,"
143 " strftime('%%s',a_etime) AS a_etime," 143 " strftime('%%s',a_etime) AS a_etime,"
144 " a_itime" 144 " a_itime"
145 " FROM assoc" 145 " FROM assoc"
146 " WHERE a_handle=%Q AND a_itime IS NULL" 146 " WHERE a_handle=%Q AND a_itime IS NULL"
147 " AND datetime('now') < a_etime" 147 " AND datetime('now') < a_etime"
148 " LIMIT 1", 148 " LIMIT 1",
149 h.c_str() ); 149 h.c_str() );
150 sqlite3_table_t T; 150 sqlite3_table_t T;
151 int nr,nc; 151 int nr,nc;
152 db.get_table(S,T,&nr,&nc); 152 db.get_table(S,T,&nr,&nc);
153 if(nr<1) 153 if(nr<1)
154 throw opkele::failed_lookup(OPKELE_CP_ 154 throw opkele::failed_lookup(OPKELE_CP_
155 "couldn't retrieve valid unexpired assoc"); 155 "couldn't retrieve valid unexpired assoc");
156 assert(nr==1); assert(nc==6); 156 assert(nr==1); assert(nc==6);
157 opkele::secret_t secret; opkele::util::decode_base64(T.get(1,2,nc),secret); 157 opkele::secret_t secret; opkele::util::decode_base64(T.get(1,2,nc),secret);
158 return opkele::assoc_t(new opkele::association( 158 return opkele::assoc_t(new opkele::association(
159 "", h, T.get(1,1,nc), secret, 159 "", h, T.get(1,1,nc), secret,
160 strtol(T.get(1,4,nc),0,0), 160 strtol(T.get(1,4,nc),0,0),
161 strtol(T.get(1,3,nc),0,0) )); 161 strtol(T.get(1,3,nc),0,0) ));
162 } 162 }
163 163
164 string& alloc_nonce(string& nonce) { 164 string& alloc_nonce(string& nonce) {
165 uuid_t uuid; uuid_generate(uuid); 165 uuid_t uuid; uuid_generate(uuid);
166 nonce += opkele::util::encode_base64(uuid,sizeof(uuid)); 166 nonce += opkele::util::encode_base64(uuid,sizeof(uuid));
167 sqlite3_mem_t<char*> 167 sqlite3_mem_t<char*>
168 S = sqlite3_mprintf( 168 S = sqlite3_mprintf(
169 "INSERT INTO nonces" 169 "INSERT INTO nonces"
170 " (n_once) VALUES (%Q)", 170 " (n_once) VALUES (%Q)",
171 nonce.c_str() ); 171 nonce.c_str() );
172 db.exec(S); 172 db.exec(S);
173 return nonce; 173 return nonce;
174 } 174 }
175 bool check_nonce(const string& nonce) { 175 bool check_nonce(const string& nonce) {
176 sqlite3_mem_t<char*> 176 sqlite3_mem_t<char*>
177 S = sqlite3_mprintf( 177 S = sqlite3_mprintf(
178 "SELECT 1" 178 "SELECT 1"
179 " FROM nonces" 179 " FROM nonces"
180 " WHERE n_once=%Q AND n_itime IS NULL", 180 " WHERE n_once=%Q AND n_itime IS NULL",
181 nonce.c_str()); 181 nonce.c_str());
182 sqlite3_table_t T; 182 sqlite3_table_t T;
183 int nr,nc; 183 int nr,nc;
184 db.get_table(S,T,&nr,&nc); 184 db.get_table(S,T,&nr,&nc);
185 return nr>=1; 185 return nr>=1;
186 } 186 }
187 void invalidate_nonce(const string& nonce) { 187 void invalidate_nonce(const string& nonce) {
188 sqlite3_mem_t<char*> 188 sqlite3_mem_t<char*>
189 S = sqlite3_mprintf( 189 S = sqlite3_mprintf(
190 "UPDATE nonces" 190 "UPDATE nonces"
191 " SET n_itime=datetime('now')" 191 " SET n_itime=datetime('now')"
192 " WHERE n_once=%Q", 192 " WHERE n_once=%Q",
193 nonce.c_str()); 193 nonce.c_str());
194 db.exec(S); 194 db.exec(S);
195 } 195 }
196 196
197 const string get_op_endpoint() const { 197 const string get_op_endpoint() const {
198 return get_self_url(gw); 198 return get_self_url(gw);
199 } 199 }
200 200
201}; 201};
202 202
203int main(int argc,char *argv[]) { 203int main(int,char **) {
204 try { 204 try {
205 kingate::plaincgi_interface ci; 205 kingate::plaincgi_interface ci;
206 kingate::cgi_gateway gw(ci); 206 kingate::cgi_gateway gw(ci);
207 string op; 207 string op;
208 try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { } 208 try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { }
209 string message; 209 string message;
210 if(op=="set_password") { 210 if(op=="set_password") {
211 example_op_t OP(gw); 211 example_op_t OP(gw);
212 string password = gw.get_param("password"); 212 string password = gw.get_param("password");
213 sqlite3_mem_t<char*> 213 sqlite3_mem_t<char*>
214 Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); 214 Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1");
215 sqlite3_table_t T; int nr,nc; 215 sqlite3_table_t T; int nr,nc;
216 OP.db.get_table(Sget,T,&nr,&nc); 216 OP.db.get_table(Sget,T,&nr,&nc);
217 if(nr>=1) 217 if(nr>=1)
218 throw opkele::exception(OPKELE_CP_ "Password already set"); 218 throw opkele::exception(OPKELE_CP_ "Password already set");
219 sqlite3_mem_t<char*> 219 sqlite3_mem_t<char*>
220 Sset = sqlite3_mprintf( 220 Sset = sqlite3_mprintf(
221 "INSERT INTO setup (s_password) VALUES (%Q)", 221 "INSERT INTO setup (s_password) VALUES (%Q)",
222 password.c_str()); 222 password.c_str());
223 OP.db.exec(Sset); 223 OP.db.exec(Sset);
224 op.clear(); 224 op.clear();
225 message = "password set"; 225 message = "password set";
226 }else if(op=="login") { 226 }else if(op=="login") {
227 example_op_t OP(gw); 227 example_op_t OP(gw);
228 string password = gw.get_param("password"); 228 string password = gw.get_param("password");
229 sqlite3_mem_t<char*> 229 sqlite3_mem_t<char*>
230 Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); 230 Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1");
231 sqlite3_table_t T; int nr,nc; 231 sqlite3_table_t T; int nr,nc;
232 OP.db.get_table(Sget,T,&nr,&nc); 232 OP.db.get_table(Sget,T,&nr,&nc);
233 if(nr<1) 233 if(nr<1)
234 throw opkele::exception(OPKELE_CP_ "no password set"); 234 throw opkele::exception(OPKELE_CP_ "no password set");
235 if(password!=T.get(1,0,nc)) 235 if(password!=T.get(1,0,nc))
236 throw opkele::exception(OPKELE_CP_ "wrong password"); 236 throw opkele::exception(OPKELE_CP_ "wrong password");
237 OP.set_authorized(true); 237 OP.set_authorized(true);
238 op.clear(); 238 op.clear();
239 message = "logged in"; 239 message = "logged in";
240 OP.cookie_header(cout); 240 OP.cookie_header(cout);
241 }else if(op=="logout") { 241 }else if(op=="logout") {
242 example_op_t OP(gw); 242 example_op_t OP(gw);
243 OP.set_authorized(false); 243 OP.set_authorized(false);
244 op.clear(); 244 op.clear();
245 message = "logged out"; 245 message = "logged out";
246 } 246 }
247 string om; 247 string omode;
248 try { om = gw.get_param("openid.mode"); }catch(kingate::exception_notfound&) { } 248 try { omode = gw.get_param("openid.mode"); }catch(kingate::exception_notfound&) { }
249 if(op=="xrds") { 249 if(op=="xrds") {
250 cout << 250 cout <<
251 "Content-type: application/xrds+xml\n\n" 251 "Content-type: application/xrds+xml\n\n"
252 "<?xml version='1.0' encoding='utf-8'?>" 252 "<?xml version='1.0' encoding='utf-8'?>"
253 "<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns='xri://$xrd*($v*2.0)'>" 253 "<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns='xri://$xrd*($v*2.0)'>"
254 "<XRD>" 254 "<XRD>"
255 "<Service>" 255 "<Service>"
256 "<Type>" STURI_OPENID20 "</Type>" 256 "<Type>" STURI_OPENID20 "</Type>"
257 "<URI>" << get_self_url(gw) << "</URI>" 257 "<URI>" << get_self_url(gw) << "</URI>"
258 "</Service>"; 258 "</Service>";
259 if(gw.has_param("idsel")){ 259 if(gw.has_param("idsel")){
260 cout << 260 cout <<
261 "<Service>" 261 "<Service>"
262 "<Type>" STURI_OPENID20_OP "</Type>" 262 "<Type>" STURI_OPENID20_OP "</Type>"
263 "<URI>" << get_self_url(gw) << "</URI>"; 263 "<URI>" << get_self_url(gw) << "</URI>";
264 } 264 }
265 cout << 265 cout <<
266 "</XRD>" 266 "</XRD>"
267 "</xrds:XRDS>"; 267 "</xrds:XRDS>";
268 }else if(op=="id_res" || op=="cancel") { 268 }else if(op=="id_res" || op=="cancel") {
269 kingate_openid_message_t inm(gw); 269 kingate_openid_message_t inm(gw);
270 example_op_t OP(gw); 270 example_op_t OP(gw);
271 if(gw.get_param("hts_id")!=OP.htc.get_value()) 271 if(gw.get_param("hts_id")!=OP.htc.get_value())
272 throw opkele::exception(OPKELE_CP_ "toying around, huh?"); 272 throw opkele::exception(OPKELE_CP_ "toying around, huh?");
273 opkele::sreg_t sreg; 273 opkele::sreg_t sreg;
274 OP.checkid_(inm,sreg); 274 OP.checkid_(inm,sreg);
275 OP.cookie_header(cout); 275 OP.cookie_header(cout);
276 opkele::openid_message_t om; 276 opkele::openid_message_t om;
277 if(op=="id_res") { 277 if(op=="id_res") {
278 if(!OP.get_authorized()) 278 if(!OP.get_authorized())
279 throw opkele::exception(OPKELE_CP_ "not logged in"); 279 throw opkele::exception(OPKELE_CP_ "not logged in");
280 if(OP.is_id_select()) { 280 if(OP.is_id_select()) {
281 OP.select_identity( get_self_url(gw), get_self_url(gw) ); 281 OP.select_identity( get_self_url(gw), get_self_url(gw) );
282 } 282 }
283 sreg.set_field(opkele::sreg_t::field_nickname,"anonymous"); 283 sreg.set_field(opkele::sreg_t::field_nickname,"anonymous");
284 sreg.set_field(opkele::sreg_t::field_fullname,"Ann O'Nymus"); 284 sreg.set_field(opkele::sreg_t::field_fullname,"Ann O'Nymus");
285 sreg.set_field(opkele::sreg_t::field_gender,"F"); 285 sreg.set_field(opkele::sreg_t::field_gender,"F");
286 sreg.setup_response(); 286 sreg.setup_response();
287 cout << 287 cout <<
288 "Status: 302 Going back to RP with id_res\n" 288 "Status: 302 Going back to RP with id_res\n"
289 "Location: " << OP.id_res(om,sreg).append_query(OP.get_return_to()) 289 "Location: " << OP.id_res(om,sreg).append_query(OP.get_return_to())
290 << "\n\n"; 290 << "\n\n";
291 }else{ 291 }else{
292 cout << 292 cout <<
293 "Status: 302 Going back to RP with cancel\n" 293 "Status: 302 Going back to RP with cancel\n"
294 "Location: " << OP.cancel(om).append_query(OP.get_return_to()) 294 "Location: " << OP.cancel(om).append_query(OP.get_return_to())
295 << "\n\n"; 295 << "\n\n";
296 } 296 }
297 om.to_keyvalues(clog); 297 om.to_keyvalues(clog);
298 }else if(om=="associate") { 298 }else if(omode=="associate") {
299 kingate_openid_message_t inm(gw); 299 kingate_openid_message_t inm(gw);
300 opkele::openid_message_t oum; 300 opkele::openid_message_t oum;
301 example_op_t OP(gw); 301 example_op_t OP(gw);
302 OP.associate(oum,inm); 302 OP.associate(oum,inm);
303 cout << "Content-type: text/plain\n\n"; 303 cout << "Content-type: text/plain\n\n";
304 oum.to_keyvalues(cout); 304 oum.to_keyvalues(cout);
305 }else if(om=="checkid_setup") { 305 }else if(omode=="checkid_setup") {
306 kingate_openid_message_t inm(gw); 306 kingate_openid_message_t inm(gw);
307 example_op_t OP(gw); 307 example_op_t OP(gw);
308 OP.checkid_(inm,0); 308 OP.checkid_(inm,0);
309 OP.cookie_header(cout) << 309 OP.cookie_header(cout) <<
310 "Content-type: text/html\n" 310 "Content-type: text/html\n"
311 "\n" 311 "\n"
312 312
313 "<html>" 313 "<html>"
314 "<head>" 314 "<head>"
315 "<title>test OP: confirm authentication</title>" 315 "<title>test OP: confirm authentication</title>"
316 "</head>" 316 "</head>"
317 "<body>" 317 "<body>"
318 "realm: " << OP.get_realm() << "<br/>" 318 "realm: " << OP.get_realm() << "<br/>"
319 "return_to: " << OP.get_return_to() << "<br/>" 319 "return_to: " << OP.get_return_to() << "<br/>"
320 "claimed_id: " << OP.get_claimed_id() << "<br/>" 320 "claimed_id: " << OP.get_claimed_id() << "<br/>"
321 "identity: " << OP.get_identity() << "<br/>"; 321 "identity: " << OP.get_identity() << "<br/>";
322 if(OP.is_id_select()) { 322 if(OP.is_id_select()) {
323 OP.select_identity( get_self_url(gw), get_self_url(gw) ); 323 OP.select_identity( get_self_url(gw), get_self_url(gw) );
324 cout << 324 cout <<
325 "selected claimed_id: " << OP.get_claimed_id() << "<br/>" 325 "selected claimed_id: " << OP.get_claimed_id() << "<br/>"
326 "selected identity: " << OP.get_identity() << "<br/>"; 326 "selected identity: " << OP.get_identity() << "<br/>";
327 } 327 }
328 cout << 328 cout <<
329 "<form method='post'>"; 329 "<form method='post'>";
330 inm.to_htmlhiddens(cout); 330 inm.to_htmlhiddens(cout);
331 cout << 331 cout <<
332 "<input type='hidden' name='hts_id'" 332 "<input type='hidden' name='hts_id'"
333 " value='" << opkele::util::attr_escape(OP.htc.get_value()) << "'/>" 333 " value='" << opkele::util::attr_escape(OP.htc.get_value()) << "'/>"
334 "<input type='submit' name='op' value='id_res'/>" 334 "<input type='submit' name='op' value='id_res'/>"
335 "<input type='submit' name='op' value='cancel'/>" 335 "<input type='submit' name='op' value='cancel'/>"
336 "</form>" 336 "</form>"
337 "</body>" 337 "</body>"
338 "</html>"; 338 "</html>";
339 }else if(om=="check_authentication") { 339 }else if(omode=="check_authentication") {
340 kingate_openid_message_t inm(gw); 340 kingate_openid_message_t inm(gw);
341 example_op_t OP(gw); 341 example_op_t OP(gw);
342 opkele::openid_message_t oum; 342 opkele::openid_message_t oum;
343 OP.check_authentication(oum,inm); 343 OP.check_authentication(oum,inm);
344 cout << "Content-type: text/plain\n\n"; 344 cout << "Content-type: text/plain\n\n";
345 oum.to_keyvalues(cout); 345 oum.to_keyvalues(cout);
346 oum.to_keyvalues(clog); 346 oum.to_keyvalues(clog);
347 }else{ 347 }else{
348 example_op_t OP(gw); 348 example_op_t OP(gw);
349 string idsel; 349 string idsel;
350 if(gw.has_param("idsel")) 350 if(gw.has_param("idsel"))
351 idsel = "&idsel=idsel"; 351 idsel = "&idsel=idsel";
352 OP.cookie_header(cout) << 352 OP.cookie_header(cout) <<
353 "Content-type: text/html\n" 353 "Content-type: text/html\n"
354 "X-XRDS-Location: " << get_self_url(gw) << "?op=xrds" << idsel << "\n" 354 "X-XRDS-Location: " << get_self_url(gw) << "?op=xrds" << idsel << "\n"
355 "\n" 355 "\n"
356 356
357 "<html>" 357 "<html>"
358 "<head>" 358 "<head>"
359 "<title>test OP</title>" 359 "<title>test OP</title>"
360 "<link rel='openid.server' href='" << get_self_url(gw) << "'/>" 360 "<link rel='openid.server' href='" << get_self_url(gw) << "'/>"
361 "</head>" 361 "</head>"
362 "<body>" 362 "<body>"
363 "test openid 2.0 endpoint" 363 "test openid 2.0 endpoint"
364 "<br/>" 364 "<br/>"
365 "<a href='" << get_self_url(gw) << "?op=xrds" << idsel << "'>XRDS document</a>" 365 "<a href='" << get_self_url(gw) << "?op=xrds" << idsel << "'>XRDS document</a>"
366 "<br/>" 366 "<br/>"
367 "<h1>" << message << "</h1>"; 367 "<h1>" << message << "</h1>";
368 sqlite3_mem_t<char*> 368 sqlite3_mem_t<char*>
369 S = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); 369 S = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1");
370 sqlite3_table_t T; int nr,nc; 370 sqlite3_table_t T; int nr,nc;
371 OP.db.get_table(S,T,&nr,&nc); 371 OP.db.get_table(S,T,&nr,&nc);
372 if(nr<1) { 372 if(nr<1) {
373 cout << 373 cout <<
374 "<form method='post'>" 374 "<form method='post'>"
375 "set password " 375 "set password "
376 "<input type='hidden' name='op' value='set_password'/>" 376 "<input type='hidden' name='op' value='set_password'/>"
377 "<input type='password' name='password' value=''/>" 377 "<input type='password' name='password' value=''/>"
378 "<input type='submit' name='submit' value='submit'/>" 378 "<input type='submit' name='submit' value='submit'/>"
379 "</form>"; 379 "</form>";
380 }else if(OP.get_authorized()) { 380 }else if(OP.get_authorized()) {
381 cout << 381 cout <<
382 "<br/>" 382 "<br/>"
383 "<a href='" << get_self_url(gw) << "?op=logout'>logout</a>"; 383 "<a href='" << get_self_url(gw) << "?op=logout'>logout</a>";
384 }else{ 384 }else{
385 cout << 385 cout <<
386 "<form method='post'>" 386 "<form method='post'>"
387 "login " 387 "login "
388 "<input type='hidden' name='op' value='login'/>" 388 "<input type='hidden' name='op' value='login'/>"
389 "<input type='password' name='password' value=''/>" 389 "<input type='password' name='password' value=''/>"
390 "<input type='submit' name='submit' value='submit'/>" 390 "<input type='submit' name='submit' value='submit'/>"
391 "</form>"; 391 "</form>";
392 } 392 }
393 cout << "</body>"; 393 cout << "</body>";
394 } 394 }
395#ifdef OPKELE_HAVE_KONFORKA 395#ifdef OPKELE_HAVE_KONFORKA
396 }catch(konforka::exception& e) { 396 }catch(konforka::exception& e) {
397#else 397#else
398 }catch(std::exception& e){ 398 }catch(std::exception& e){
399#endif 399#endif
400 DOUT_("Oops: " << e.what()); 400 DOUT_("Oops: " << e.what());
401 cout << "Content-Type: text/plain\n\n" 401 cout << "Content-Type: text/plain\n\n"
402 "Exception:\n" 402 "Exception:\n"
403 " what: " << e.what() << endl; 403 " what: " << e.what() << endl;
diff --git a/test/RP.cc b/test/RP.cc
index e9744a4..99a792c 100644
--- a/test/RP.cc
+++ b/test/RP.cc
@@ -1,126 +1,126 @@
1#include <uuid/uuid.h> 1#include <uuid/uuid.h>
2#include <iostream> 2#include <iostream>
3#include <cassert> 3#include <cassert>
4#include <stdexcept> 4#include <stdexcept>
5#include <string> 5#include <string>
6#include <set> 6#include <set>
7#include <iterator> 7#include <iterator>
8using namespace std; 8using namespace std;
9#include <kingate/exception.h> 9#include <kingate/exception.h>
10#include <kingate/plaincgi.h> 10#include <kingate/plaincgi.h>
11#include <kingate/cgi_gateway.h> 11#include <kingate/cgi_gateway.h>
12#include <opkele/exception.h> 12#include <opkele/exception.h>
13#include <opkele/types.h> 13#include <opkele/types.h>
14#include <opkele/util.h> 14#include <opkele/util.h>
15#include <opkele/uris.h> 15#include <opkele/uris.h>
16#include <opkele/discovery.h> 16#include <opkele/discovery.h>
17#include <opkele/association.h> 17#include <opkele/association.h>
18#include <opkele/sreg.h> 18#include <opkele/sreg.h>
19using namespace opkele; 19using namespace opkele;
20#include <opkele/prequeue_rp.h> 20#include <opkele/prequeue_rp.h>
21#include <opkele/debug.h> 21#include <opkele/debug.h>
22 22
23#include "sqlite.h" 23#include "sqlite.h"
24#include "kingate_openid_message.h" 24#include "kingate_openid_message.h"
25 25
26#undef DUMB_RP 26#undef DUMB_RP
27 27
28#ifdef DUMB_RP 28#ifdef DUMB_RP
29# define DUMBTHROW throw opkele::dumb_RP(OPKELE_CP_ "This RP is dumb") 29# define DUMBTHROW throw opkele::dumb_RP(OPKELE_CP_ "This RP is dumb")
30#else 30#else
31# define DUMBTHROW (void)0 31# define DUMBTHROW (void)0
32#endif 32#endif
33 33
34class rpdb_t : public sqlite3_t { 34class rpdb_t : public sqlite3_t {
35 public: 35 public:
36 rpdb_t() 36 rpdb_t()
37 : sqlite3_t("/tmp/RP.db") { 37 : sqlite3_t("/tmp/RP.db") {
38 assert(_D); 38 assert(_D);
39 char **resp; int nrow,ncol; char *errm; 39 char **resp; int nrow,ncol; char *errm;
40 if(sqlite3_get_table( 40 if(sqlite3_get_table(
41 _D,"SELECT a_op FROM assoc LIMIT 0", 41 _D,"SELECT a_op FROM assoc LIMIT 0",
42 &resp,&nrow,&ncol,&errm)!=SQLITE_OK) { 42 &resp,&nrow,&ncol,&errm)!=SQLITE_OK) {
43 extern const char *__RP_db_bootstrap; 43 extern const char *__RP_db_bootstrap;
44 DOUT_("Bootstrapping DB"); 44 DOUT_("Bootstrapping DB");
45 if(sqlite3_exec(_D,__RP_db_bootstrap,NULL,NULL,&errm)!=SQLITE_OK) 45 if(sqlite3_exec(_D,__RP_db_bootstrap,NULL,NULL,&errm)!=SQLITE_OK)
46 throw opkele::exception(OPKELE_CP_ string("Failed to bootstrap SQLite database: ")+errm); 46 throw opkele::exception(OPKELE_CP_ string("Failed to bootstrap SQLite database: ")+errm);
47 }else 47 }else
48 sqlite3_free_table(resp); 48 sqlite3_free_table(resp);
49 49
50 } 50 }
51}; 51};
52 52
53class example_rp_t : public opkele::prequeue_RP { 53class example_rp_t : public opkele::prequeue_RP {
54 public: 54 public:
55 mutable rpdb_t db; 55 mutable rpdb_t db;
56 kingate::cookie htc; 56 kingate::cookie htc;
57 long as_id; 57 long as_id;
58 int ordinal; 58 int ordinal;
59 kingate::cgi_gateway& gw; 59 kingate::cgi_gateway& gw;
60 60
61 example_rp_t(kingate::cgi_gateway& gw) 61 example_rp_t(kingate::cgi_gateway& g)
62 : ordinal(0), have_eqtop(false), gw(gw), as_id(-1) { 62 : as_id(-1), ordinal(0), gw(g), have_eqtop(false) {
63 try { 63 try {
64 htc = gw.cookies.get_cookie("ht_session"); 64 htc = gw.cookies.get_cookie("ht_session");
65 as_id = opkele::util::string_to_long(gw.get_param("asid")); 65 as_id = opkele::util::string_to_long(gw.get_param("asid"));
66 }catch(kingate::exception_notfound& kenf) { 66 }catch(kingate::exception_notfound& kenf) {
67 uuid_t uuid; uuid_generate(uuid); 67 uuid_t uuid; uuid_generate(uuid);
68 htc = kingate::cookie("ht_session",util::encode_base64(uuid,sizeof(uuid))); 68 htc = kingate::cookie("ht_session",util::encode_base64(uuid,sizeof(uuid)));
69 sqlite3_mem_t<char*> S = sqlite3_mprintf( 69 sqlite3_mem_t<char*> S = sqlite3_mprintf(
70 "INSERT INTO ht_sessions (hts_id) VALUES (%Q)", 70 "INSERT INTO ht_sessions (hts_id) VALUES (%Q)",
71 htc.get_value().c_str()); 71 htc.get_value().c_str());
72 db.exec(S); 72 db.exec(S);
73 } 73 }
74 } 74 }
75 75
76 /* Global persistent store */ 76 /* Global persistent store */
77 77
78 opkele::assoc_t store_assoc( 78 opkele::assoc_t store_assoc(
79 const string& OP,const string& handle, 79 const string& OP,const string& handle,
80 const string& type,const secret_t& secret, 80 const string& type,const secret_t& secret,
81 int expires_in) { 81 int expires_in) {
82 DUMBTHROW; 82 DUMBTHROW;
83 DOUT_("Storing '" << handle << "' assoc with '" << OP << "'"); 83 DOUT_("Storing '" << handle << "' assoc with '" << OP << "'");
84 time_t exp = time(0)+expires_in; 84 time_t exp = time(0)+expires_in;
85 sqlite3_mem_t<char*> 85 sqlite3_mem_t<char*>
86 S = sqlite3_mprintf( 86 S = sqlite3_mprintf(
87 "INSERT INTO assoc" 87 "INSERT INTO assoc"
88 " (a_op,a_handle,a_type,a_ctime,a_etime,a_secret)" 88 " (a_op,a_handle,a_type,a_ctime,a_etime,a_secret)"
89 " VALUES (" 89 " VALUES ("
90 " %Q,%Q,%Q," 90 " %Q,%Q,%Q,"
91 " datetime('now'), datetime('now','+%d seconds')," 91 " datetime('now'), datetime('now','+%d seconds'),"
92 " %Q" 92 " %Q"
93 " );", OP.c_str(), handle.c_str(), type.c_str(), 93 " );", OP.c_str(), handle.c_str(), type.c_str(),
94 expires_in, 94 expires_in,
95 util::encode_base64(&(secret.front()),secret.size()).c_str() ); 95 util::encode_base64(&(secret.front()),secret.size()).c_str() );
96 db.exec(S); 96 db.exec(S);
97 return opkele::assoc_t(new opkele::association( 97 return opkele::assoc_t(new opkele::association(
98 OP, handle, type, secret, exp, false )); 98 OP, handle, type, secret, exp, false ));
99 } 99 }
100 100
101 opkele::assoc_t find_assoc( 101 opkele::assoc_t find_assoc(
102 const string& OP) { 102 const string& OP) {
103 DUMBTHROW; 103 DUMBTHROW;
104 DOUT_("Looking for an assoc with '" << OP << '\''); 104 DOUT_("Looking for an assoc with '" << OP << '\'');
105 sqlite3_mem_t<char*> 105 sqlite3_mem_t<char*>
106 S = sqlite3_mprintf( 106 S = sqlite3_mprintf(
107 "SELECT" 107 "SELECT"
108 " a_op,a_handle,a_type,a_secret," 108 " a_op,a_handle,a_type,a_secret,"
109 " strftime('%%s',a_etime) AS a_etime" 109 " strftime('%%s',a_etime) AS a_etime"
110 " FROM assoc" 110 " FROM assoc"
111 " WHERE a_op=%Q AND a_itime IS NULL AND NOT a_stateless" 111 " WHERE a_op=%Q AND a_itime IS NULL AND NOT a_stateless"
112 " AND ( a_etime > datetime('now','-30 seconds') )" 112 " AND ( a_etime > datetime('now','-30 seconds') )"
113 " LIMIT 1", 113 " LIMIT 1",
114 OP.c_str()); 114 OP.c_str());
115 sqlite3_table_t T; 115 sqlite3_table_t T;
116 int nr,nc; 116 int nr,nc;
117 db.get_table(S,T,&nr,&nc); 117 db.get_table(S,T,&nr,&nc);
118 if(nr<1) 118 if(nr<1)
119 throw opkele::failed_lookup(OPKELE_CP_ "Couldn't find unexpired handle"); 119 throw opkele::failed_lookup(OPKELE_CP_ "Couldn't find unexpired handle");
120 assert(nr==1); 120 assert(nr==1);
121 assert(nc==5); 121 assert(nc==5);
122 secret_t secret; 122 secret_t secret;
123 util::decode_base64(T.get(1,3,nc),secret); 123 util::decode_base64(T.get(1,3,nc),secret);
124 DOUT_(" found '" << T.get(1,1,nc) << '\''); 124 DOUT_(" found '" << T.get(1,1,nc) << '\'');
125 return opkele::assoc_t(new opkele::association( 125 return opkele::assoc_t(new opkele::association(
126 T.get(1,0,nc), T.get(1,1,nc), T.get(1,2,nc), 126 T.get(1,0,nc), T.get(1,1,nc), T.get(1,2,nc),
@@ -290,129 +290,129 @@ class example_rp_t : public opkele::prequeue_RP {
290 db.exec(S); 290 db.exec(S);
291 _nid = nid; 291 _nid = nid;
292 } 292 }
293 const string get_normalized_id() const { 293 const string get_normalized_id() const {
294 assert(as_id>=0); 294 assert(as_id>=0);
295 if(_nid.empty()) { 295 if(_nid.empty()) {
296 sqlite3_mem_t<char*> S = sqlite3_mprintf( 296 sqlite3_mem_t<char*> S = sqlite3_mprintf(
297 "SELECT as_normalized_id" 297 "SELECT as_normalized_id"
298 " FROM" 298 " FROM"
299 " auth_sessions" 299 " auth_sessions"
300 " WHERE" 300 " WHERE"
301 " hts_id=%Q AND as_id=%ld", 301 " hts_id=%Q AND as_id=%ld",
302 htc.get_value().c_str(),as_id); 302 htc.get_value().c_str(),as_id);
303 sqlite3_table_t T; int nr,nc; 303 sqlite3_table_t T; int nr,nc;
304 db.get_table(S,T,&nr,&nc); 304 db.get_table(S,T,&nr,&nc);
305 assert(nr==1); assert(nc==1); 305 assert(nr==1); assert(nc==1);
306 _nid = T.get(1,0,nc); 306 _nid = T.get(1,0,nc);
307 } 307 }
308 return _nid; 308 return _nid;
309 } 309 }
310 310
311 const string get_this_url() const { 311 const string get_this_url() const {
312 bool s = gw.has_meta("SSL_PROTOCOL_VERSION"); 312 bool s = gw.has_meta("SSL_PROTOCOL_VERSION");
313 string rv = s?"https://":"http://"; 313 string rv = s?"https://":"http://";
314 rv += gw.http_request_header("Host"); 314 rv += gw.http_request_header("Host");
315 const string& port = gw.get_meta("SERVER_PORT"); 315 const string& port = gw.get_meta("SERVER_PORT");
316 if( port!=(s?"443":"80") ) { 316 if( port!=(s?"443":"80") ) {
317 rv += ':'; rv += port; 317 rv += ':'; rv += port;
318 } 318 }
319 rv += gw.get_meta("REQUEST_URI"); 319 rv += gw.get_meta("REQUEST_URI");
320 return rv; 320 return rv;
321 } 321 }
322 322
323 void initiate(const string& usi) { 323 void initiate(const string& usi) {
324 allocate_asid(); 324 allocate_asid();
325 prequeue_RP::initiate(usi); 325 prequeue_RP::initiate(usi);
326 } 326 }
327 327
328 string get_self_url() const { 328 string get_self_url() const {
329 string rv = get_this_url(); 329 string rv = get_this_url();
330 string::size_type q = rv.find('?'); 330 string::size_type q = rv.find('?');
331 if(q!=string::npos) 331 if(q!=string::npos)
332 rv.erase(q); 332 rv.erase(q);
333 return rv; 333 return rv;
334 } 334 }
335 335
336 void allocate_asid() { 336 void allocate_asid() {
337 sqlite3_mem_t<char*> S = sqlite3_mprintf( 337 sqlite3_mem_t<char*> S = sqlite3_mprintf(
338 "INSERT INTO auth_sessions (hts_id)" 338 "INSERT INTO auth_sessions (hts_id)"
339 " VALUES (%Q)", 339 " VALUES (%Q)",
340 htc.get_value().c_str()); 340 htc.get_value().c_str());
341 db.exec(S); 341 db.exec(S);
342 as_id = sqlite3_last_insert_rowid(db); 342 as_id = sqlite3_last_insert_rowid(db);
343 DOUT_("Allocated authentication session id "<<as_id); 343 DOUT_("Allocated authentication session id "<<as_id);
344 assert(as_id>=0); 344 assert(as_id>=0);
345 } 345 }
346 346
347#ifdef DUMB_RP 347#ifdef DUMB_RP
348 virtual assoc_t associate(const string& OP) { 348 virtual assoc_t associate(const string& OP) {
349 DUMBTHROW; 349 DUMBTHROW;
350 } 350 }
351#endif 351#endif
352}; 352};
353 353
354int main(int argc,char *argv[]) { 354int main(int,char **) {
355 try { 355 try {
356 kingate::plaincgi_interface ci; 356 kingate::plaincgi_interface ci;
357 kingate::cgi_gateway gw(ci); 357 kingate::cgi_gateway gw(ci);
358 string op; 358 string op;
359 try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { } 359 try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { }
360 if(op=="initiate") { 360 if(op=="initiate") {
361 example_rp_t rp(gw); 361 example_rp_t rp(gw);
362 string usi = gw.get_param("openid_identity"); 362 string usi = gw.get_param("openid_identity");
363 rp.initiate(usi); 363 rp.initiate(usi);
364 opkele::sreg_t sreg(opkele::sreg_t::fields_NONE,opkele::sreg_t::fields_ALL); 364 opkele::sreg_t sreg(opkele::sreg_t::fields_NONE,opkele::sreg_t::fields_ALL);
365 opkele::openid_message_t cm; 365 opkele::openid_message_t cm;
366 string loc; 366 string loc;
367 cout << 367 cout <<
368 "Set-Cookie: " << rp.htc.set_cookie_header() << "\n" 368 "Set-Cookie: " << rp.htc.set_cookie_header() << "\n"
369 "Status: 302 Going to OP\n" 369 "Status: 302 Going to OP\n"
370 "Location: " << ( 370 "Location: " << (
371 loc = rp.checkid_(cm,opkele::mode_checkid_setup, 371 loc = rp.checkid_(cm,opkele::mode_checkid_setup,
372 rp.get_self_url()+ 372 rp.get_self_url()+
373 "?op=confirm&asid="+opkele::util::long_to_string(rp.as_id), 373 "?op=confirm&asid="+opkele::util::long_to_string(rp.as_id),
374 rp.get_self_url(),&sreg).append_query(rp.get_endpoint().uri) 374 rp.get_self_url(),&sreg).append_query(rp.get_endpoint().uri)
375 ) 375 )
376 << "\n\n"; 376 << "\n\n";
377 DOUT_("Going to " << loc); 377 DOUT_("Going to " << loc);
378 }else if(op=="confirm") { 378 }else if(op=="confirm") {
379 kingate_openid_message_t om(gw); 379 kingate_openid_message_t om(gw);
380 example_rp_t rp(gw); 380 example_rp_t rp(gw);
381 opkele::sreg_t sreg(opkele::sreg_t::fields_NONE,opkele::sreg_t::fields_ALL); 381 opkele::sreg_t sreg(opkele::sreg_t::fields_NONE,opkele::sreg_t::fields_ALL);
382 rp.id_res(om,&sreg); 382 rp.id_res(om,&sreg);
383 cout << 383 cout <<
384 "Content-Type: text/plain\n\n"; 384 "Content-Type: text/plain\n\n";
385 for(opkele::basic_openid_message::fields_iterator i=om.fields_begin(); 385 for(opkele::basic_openid_message::fields_iterator i=om.fields_begin();
386 i!=om.fields_end();++i) { 386 i!=om.fields_end();++i) {
387 cout << *i << '=' << om.get_field(*i) << endl; 387 cout << *i << '=' << om.get_field(*i) << endl;
388 } 388 }
389 cout << endl 389 cout << endl
390 << "SREG fields: " << sreg.has_fields << endl; 390 << "SREG fields: " << sreg.has_fields << endl;
391 }else{ 391 }else{
392 cout << 392 cout <<
393 "Content-type: text/html\n\n" 393 "Content-type: text/html\n\n"
394 394
395 "<html>" 395 "<html>"
396 "<head><title>test RP</title></head>" 396 "<head><title>test RP</title></head>"
397 "<body>" 397 "<body>"
398 "<form action='' method='post'>" 398 "<form action='' method='post'>"
399 "<input type='hidden' name='op' value='initiate' />" 399 "<input type='hidden' name='op' value='initiate' />"
400 "<input type='text' name='openid_identity'/>" 400 "<input type='text' name='openid_identity'/>"
401 "<input type='submit' name='submit' value='submit' />" 401 "<input type='submit' name='submit' value='submit' />"
402 "</form>" 402 "</form>"
403 "<br/><br/>" 403 "<br/><br/>"
404 "<a href='?op=initiate&amp;openid_identity=www.myopenid.com&amp;dummy=" << time(0) << "'>login with myopenid.com account</a>" 404 "<a href='?op=initiate&amp;openid_identity=www.myopenid.com&amp;dummy=" << time(0) << "'>login with myopenid.com account</a>"
405 "<br/>" 405 "<br/>"
406 "</body" 406 "</body"
407 "</html>" 407 "</html>"
408 ; 408 ;
409 } 409 }
410#ifdef OPKELE_HAVE_KONFORKA 410#ifdef OPKELE_HAVE_KONFORKA
411 }catch(konforka::exception& e) { 411 }catch(konforka::exception& e) {
412#else 412#else
413 }catch(std::exception& e){ 413 }catch(std::exception& e){
414#endif 414#endif
415 DOUT_("Oops: " << e.what()); 415 DOUT_("Oops: " << e.what());
416 cout << "Content-Type: text/plain\n\n" 416 cout << "Content-Type: text/plain\n\n"
417 "Exception:\n" 417 "Exception:\n"
418 " what: " << e.what() << endl; 418 " what: " << e.what() << endl;
diff --git a/test/kingate_openid_message.h b/test/kingate_openid_message.h
index 37dcdfa..7029ff7 100644
--- a/test/kingate_openid_message.h
+++ b/test/kingate_openid_message.h
@@ -1,109 +1,109 @@
1template<typename IT> 1template<typename IT>
2class join_iterator : public iterator< 2class join_iterator : public iterator<
3 input_iterator_tag,typename IT::value_type, 3 input_iterator_tag,typename IT::value_type,
4 void,typename IT::pointer,typename IT::reference> { 4 void,typename IT::pointer,typename IT::reference> {
5 public: 5 public:
6 typedef pair<IT,IT> range_t; 6 typedef pair<IT,IT> range_t;
7 typedef list<range_t> ranges_t; 7 typedef list<range_t> ranges_t;
8 ranges_t ranges; 8 ranges_t ranges;
9 9
10 join_iterator() { } 10 join_iterator() { }
11 11
12 bool cleanup() { 12 bool cleanup() {
13 bool rv = false; 13 bool rv = false;
14 while(!(ranges.empty() || ranges.front().first!=ranges.front().second)) { 14 while(!(ranges.empty() || ranges.front().first!=ranges.front().second)) {
15 ranges.pop_front(); rv = true; 15 ranges.pop_front(); rv = true;
16 } 16 }
17 return rv; 17 return rv;
18 } 18 }
19 19
20 join_iterator<IT>& add_range(const IT& b,const IT& e) { 20 join_iterator<IT>& add_range(const IT& b,const IT& e) {
21 ranges.push_back(typename ranges_t::value_type(b,e)); 21 ranges.push_back(typename ranges_t::value_type(b,e));
22 cleanup(); 22 cleanup();
23 return *this; 23 return *this;
24 } 24 }
25 25
26 bool operator==(const join_iterator<IT>& x) const { 26 bool operator==(const join_iterator<IT>& x) const {
27 return ranges==x.ranges; } 27 return ranges==x.ranges; }
28 bool operator!=(const join_iterator<IT>& x) const { 28 bool operator!=(const join_iterator<IT>& x) const {
29 return ranges!=x.ranges; } 29 return ranges!=x.ranges; }
30 30
31 typename IT::reference operator*() const { 31 typename IT::reference operator*() const {
32 assert(!ranges.empty()); 32 assert(!ranges.empty());
33 assert(ranges.front().first!=ranges.front().second); 33 assert(ranges.front().first!=ranges.front().second);
34 return *ranges.front().first; } 34 return *ranges.front().first; }
35 typename IT::pointer operator->() const { 35 typename IT::pointer operator->() const {
36 assert(!ranges.empty()); 36 assert(!ranges.empty());
37 assert(ranges.front().first!=ranges.front().second); 37 assert(ranges.front().first!=ranges.front().second);
38 return ranges.front().first.operator->(); } 38 return ranges.front().first.operator->(); }
39 39
40 join_iterator<IT>& operator++() { 40 join_iterator<IT>& operator++() {
41 cleanup(); 41 cleanup();
42 if(ranges.empty()) return *this; 42 if(ranges.empty()) return *this;
43 do { 43 do {
44 ++ranges.front().first; 44 ++ranges.front().first;
45 }while(cleanup() && !ranges.empty()); 45 }while(cleanup() && !ranges.empty());
46 return *this; 46 return *this;
47 } 47 }
48 join_iterator<IT> operator++(int) { 48 join_iterator<IT> operator++(int) {
49 join_iterator<IT> rv(*this); 49 join_iterator<IT> rv(*this);
50 ++(*this); return rv; } 50 ++(*this); return rv; }
51}; 51};
52 52
53template<typename IT> 53template<typename IT>
54class cut_prefix_filterator : public opkele::util::basic_filterator<IT> { 54class cut_prefix_filterator : public opkele::util::basic_filterator<IT> {
55 public: 55 public:
56 string pfx; 56 string pfx;
57 mutable string tmp; 57 mutable string tmp;
58 58
59 cut_prefix_filterator() { } 59 cut_prefix_filterator() { }
60 cut_prefix_filterator(const IT& bi,const IT&ei,const string& pfx) 60 cut_prefix_filterator(const IT& _bi,const IT&_ei,const string& p)
61 : opkele::util::basic_filterator<IT>(bi,ei), pfx(pfx) { 61 : opkele::util::basic_filterator<IT>(_bi,_ei), pfx(p) {
62 this->prepare(); 62 this->prepare();
63 } 63 }
64 64
65 bool is_interesting() const { 65 bool is_interesting() const {
66 return pfx.length()==0 || !strncmp(this->it->c_str(),pfx.c_str(),pfx.length()); 66 return pfx.length()==0 || !strncmp(this->it->c_str(),pfx.c_str(),pfx.length());
67 } 67 }
68 68
69 typename IT::reference operator*() const { 69 typename IT::reference operator*() const {
70 assert(!this->empty); 70 assert(!this->empty);
71 tmp = *this->it; tmp.erase(0,pfx.length()); 71 tmp = *this->it; tmp.erase(0,pfx.length());
72 return tmp; } 72 return tmp; }
73 typename IT::pointer operator->() const { 73 typename IT::pointer operator->() const {
74 assert(!this->empty); 74 assert(!this->empty);
75 return &this->operator*(); } 75 return &this->operator*(); }
76}; 76};
77 77
78class kingate_openid_message_t : public opkele::basic_openid_message { 78class kingate_openid_message_t : public opkele::basic_openid_message {
79 typedef join_iterator<kingate::cgi_gateway::params_t::const_iterator> jitterator; 79 typedef join_iterator<kingate::cgi_gateway::params_t::const_iterator> jitterator;
80 typedef opkele::util::map_keys_iterator< 80 typedef opkele::util::map_keys_iterator<
81 jitterator, 81 jitterator,
82 fields_iterator::value_type, 82 fields_iterator::value_type,
83 fields_iterator::reference, 83 fields_iterator::reference,
84 fields_iterator::pointer> keys_iterator; 84 fields_iterator::pointer> keys_iterator;
85 typedef cut_prefix_filterator<keys_iterator> pfilterator; 85 typedef cut_prefix_filterator<keys_iterator> pfilterator;
86 public: 86 public:
87 const kingate::cgi_gateway& gw; 87 const kingate::cgi_gateway& gw;
88 88
89 kingate_openid_message_t(const kingate::cgi_gateway& g) : gw(g) { } 89 kingate_openid_message_t(const kingate::cgi_gateway& g) : gw(g) { }
90 90
91 bool has_field(const string& n) const { 91 bool has_field(const string& n) const {
92 return gw.has_param("openid."+n); } 92 return gw.has_param("openid."+n); }
93 const string& get_field(const string& n) const try { 93 const string& get_field(const string& n) const try {
94 return gw.get_param("openid."+n); }catch(kingate::exception_notfound& nf) { 94 return gw.get_param("openid."+n); }catch(kingate::exception_notfound& nf) {
95 throw opkele::failed_lookup(OPKELE_CP_ nf.what()); } 95 throw opkele::failed_lookup(OPKELE_CP_ nf.what()); }
96 96
97 fields_iterator fields_begin() const { 97 fields_iterator fields_begin() const {
98 return 98 return
99 pfilterator( keys_iterator( 99 pfilterator( keys_iterator(
100 jitterator() 100 jitterator()
101 .add_range( gw.get.begin(), gw.get.end() ) 101 .add_range( gw.get.begin(), gw.get.end() )
102 .add_range( gw.post.begin(), gw.post.end() ), 102 .add_range( gw.post.begin(), gw.post.end() ),
103 jitterator() 103 jitterator()
104 ), keys_iterator(), "openid." ); 104 ), keys_iterator(), "openid." );
105 } 105 }
106 fields_iterator fields_end() const { 106 fields_iterator fields_end() const {
107 return pfilterator(); 107 return pfilterator();
108 } 108 }
109}; 109};