summaryrefslogtreecommitdiffabout
path: root/test
authorMichael Krelin <hacker@klever.net>2008-02-04 22:39:59 (UTC)
committer Michael Krelin <hacker@klever.net>2008-02-04 22:39:59 (UTC)
commit9163a26ec8839a31df888920418280a62ebc5595 (patch) (unidiff)
tree55339b4ecf0a3f24817eb5cc1b0b24f831ac895b /test
parentc0eeee1cfd41d0f5f6ff6ac3d6fe021421376a69 (diff)
downloadlibopkele-9163a26ec8839a31df888920418280a62ebc5595.zip
libopkele-9163a26ec8839a31df888920418280a62ebc5595.tar.gz
libopkele-9163a26ec8839a31df888920418280a62ebc5595.tar.bz2
reworked extensions framework
* changed {checkid,id_res}_hook to {rp,op}_{checkid,id_res}_hook * deprecated older hooks, although implemented it in sreg and chain extensions * added extension processing to basic_op * added sreg to test OP Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (limited to 'test') (more/less context) (ignore whitespace changes)
-rw-r--r--test/OP.cc10
1 files changed, 8 insertions, 2 deletions
diff --git a/test/OP.cc b/test/OP.cc
index 1196c0c..c919d7f 100644
--- a/test/OP.cc
+++ b/test/OP.cc
@@ -1,112 +1,113 @@
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 18
18#include "sqlite.h" 19#include "sqlite.h"
19#include "kingate_openid_message.h" 20#include "kingate_openid_message.h"
20 21
21static const string get_self_url(const kingate::cgi_gateway& gw) { 22static const string get_self_url(const kingate::cgi_gateway& gw) {
22 bool s = gw.has_meta("SSL_PROTOCOL_VERSION"); 23 bool s = gw.has_meta("SSL_PROTOCOL_VERSION");
23 string rv = s?"https://":"http://"; 24 string rv = s?"https://":"http://";
24 rv += gw.http_request_header("Host"); 25 rv += gw.http_request_header("Host");
25 const string& port = gw.get_meta("SERVER_PORT"); 26 const string& port = gw.get_meta("SERVER_PORT");
26 if( port!=(s?"443":"80") ) { 27 if( port!=(s?"443":"80") ) {
27 rv += ':'; rv += port; 28 rv += ':'; rv += port;
28 } 29 }
29 rv += gw.get_meta("REQUEST_URI"); 30 rv += gw.get_meta("REQUEST_URI");
30 string::size_type q = rv.find('?'); 31 string::size_type q = rv.find('?');
31 if(q!=string::npos) 32 if(q!=string::npos)
32 rv.erase(q); 33 rv.erase(q);
33 return rv; 34 return rv;
34} 35}
35 36
36class opdb_t : public sqlite3_t { 37class opdb_t : public sqlite3_t {
37 public: 38 public:
38 opdb_t() 39 opdb_t()
39 : sqlite3_t("/tmp/OP.db") { 40 : sqlite3_t("/tmp/OP.db") {
40 assert(_D); 41 assert(_D);
41 char **resp; int nr,nc; char *errm; 42 char **resp; int nr,nc; char *errm;
42 if(sqlite3_get_table( 43 if(sqlite3_get_table(
43 _D, "SELECT a_op FROM assoc LIMIT 0", 44 _D, "SELECT a_op FROM assoc LIMIT 0",
44 &resp,&nr,&nc,&errm)!=SQLITE_OK) { 45 &resp,&nr,&nc,&errm)!=SQLITE_OK) {
45 extern const char *__OP_db_bootstrap; 46 extern const char *__OP_db_bootstrap;
46 DOUT_("Bootstrapping DB"); 47 DOUT_("Bootstrapping DB");
47 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)
48 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);
49 }else 50 }else
50 sqlite3_free_table(resp); 51 sqlite3_free_table(resp);
51 } 52 }
52}; 53};
53 54
54class example_op_t : public opkele::verify_op { 55class example_op_t : public opkele::verify_op {
55 public: 56 public:
56 kingate::cgi_gateway& gw; 57 kingate::cgi_gateway& gw;
57 opdb_t db; 58 opdb_t db;
58 kingate::cookie htc; 59 kingate::cookie htc;
59 60
60 61
61 example_op_t(kingate::cgi_gateway& gw) 62 example_op_t(kingate::cgi_gateway& gw)
62 : gw(gw) { 63 : gw(gw) {
63 try { 64 try {
64 htc = gw.cookies.get_cookie("htop_session"); 65 htc = gw.cookies.get_cookie("htop_session");
65 sqlite3_mem_t<char*> S = sqlite3_mprintf( 66 sqlite3_mem_t<char*> S = sqlite3_mprintf(
66 "SELECT 1 FROM ht_sessions WHERE hts_id=%Q", 67 "SELECT 1 FROM ht_sessions WHERE hts_id=%Q",
67 htc.get_value().c_str()); 68 htc.get_value().c_str());
68 sqlite3_table_t T; int nr,nc; 69 sqlite3_table_t T; int nr,nc;
69 db.get_table(S,T,&nr,&nc); 70 db.get_table(S,T,&nr,&nc);
70 if(nr<1) 71 if(nr<1)
71 throw kingate::exception_notfound(CODEPOINT,"forcing cookie generation"); 72 throw kingate::exception_notfound(CODEPOINT,"forcing cookie generation");
72 }catch(kingate::exception_notfound& kenf) { 73 }catch(kingate::exception_notfound& kenf) {
73 uuid_t uuid; uuid_generate(uuid); 74 uuid_t uuid; uuid_generate(uuid);
74 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)));
75 sqlite3_mem_t<char*> S = sqlite3_mprintf( 76 sqlite3_mem_t<char*> S = sqlite3_mprintf(
76 "INSERT INTO ht_sessions (hts_id) VALUES (%Q)", 77 "INSERT INTO ht_sessions (hts_id) VALUES (%Q)",
77 htc.get_value().c_str()); 78 htc.get_value().c_str());
78 db.exec(S); 79 db.exec(S);
79 } 80 }
80 } 81 }
81 82
82 void set_authorized(bool a) { 83 void set_authorized(bool a) {
83 sqlite3_mem_t<char*> 84 sqlite3_mem_t<char*>
84 S = sqlite3_mprintf( 85 S = sqlite3_mprintf(
85 "UPDATE ht_sessions" 86 "UPDATE ht_sessions"
86 " SET authorized=%d" 87 " SET authorized=%d"
87 " WHERE hts_id=%Q", 88 " WHERE hts_id=%Q",
88 (int)a,htc.get_value().c_str()); 89 (int)a,htc.get_value().c_str());
89 db.exec(S); 90 db.exec(S);
90 } 91 }
91 bool get_authorized() { 92 bool get_authorized() {
92 sqlite3_mem_t<char*> 93 sqlite3_mem_t<char*>
93 S = sqlite3_mprintf( 94 S = sqlite3_mprintf(
94 "SELECT authorized" 95 "SELECT authorized"
95 " FROM ht_sessions" 96 " FROM ht_sessions"
96 " WHERE hts_id=%Q", 97 " WHERE hts_id=%Q",
97 htc.get_value().c_str()); 98 htc.get_value().c_str());
98 sqlite3_table_t T; int nr,nc; 99 sqlite3_table_t T; int nr,nc;
99 db.get_table(S,T,&nr,&nc); 100 db.get_table(S,T,&nr,&nc);
100 assert(nr==1); assert(nc=1); 101 assert(nr==1); assert(nc=1);
101 return opkele::util::string_to_long(T.get(1,0,nc)); 102 return opkele::util::string_to_long(T.get(1,0,nc));
102 } 103 }
103 104
104 ostream& cookie_header(ostream& o) const { 105 ostream& cookie_header(ostream& o) const {
105 o << "Set-Cookie: " << htc.set_cookie_header() << "\n"; 106 o << "Set-Cookie: " << htc.set_cookie_header() << "\n";
106 return o; 107 return o;
107 } 108 }
108 109
109 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) {
110 uuid_t uuid; uuid_generate(uuid); 111 uuid_t uuid; uuid_generate(uuid);
111 string a_handle = opkele::util::encode_base64(uuid,sizeof(uuid)); 112 string a_handle = opkele::util::encode_base64(uuid,sizeof(uuid));
112 opkele::secret_t a_secret; 113 opkele::secret_t a_secret;
@@ -176,204 +177,209 @@ class example_op_t : public opkele::verify_op {
176 S = sqlite3_mprintf( 177 S = sqlite3_mprintf(
177 "SELECT 1" 178 "SELECT 1"
178 " FROM nonces" 179 " FROM nonces"
179 " WHERE n_once=%Q AND n_itime IS NULL", 180 " WHERE n_once=%Q AND n_itime IS NULL",
180 nonce.c_str()); 181 nonce.c_str());
181 sqlite3_table_t T; 182 sqlite3_table_t T;
182 int nr,nc; 183 int nr,nc;
183 db.get_table(S,T,&nr,&nc); 184 db.get_table(S,T,&nr,&nc);
184 return nr>=1; 185 return nr>=1;
185 } 186 }
186 void invalidate_nonce(const string& nonce) { 187 void invalidate_nonce(const string& nonce) {
187 sqlite3_mem_t<char*> 188 sqlite3_mem_t<char*>
188 S = sqlite3_mprintf( 189 S = sqlite3_mprintf(
189 "UPDATE nonces" 190 "UPDATE nonces"
190 " SET n_itime=datetime('now')" 191 " SET n_itime=datetime('now')"
191 " WHERE n_once=%Q", 192 " WHERE n_once=%Q",
192 nonce.c_str()); 193 nonce.c_str());
193 db.exec(S); 194 db.exec(S);
194 } 195 }
195 196
196 const string get_op_endpoint() const { 197 const string get_op_endpoint() const {
197 return get_self_url(gw); 198 return get_self_url(gw);
198 } 199 }
199 200
200}; 201};
201 202
202int main(int argc,char *argv[]) { 203int main(int argc,char *argv[]) {
203 try { 204 try {
204 kingate::plaincgi_interface ci; 205 kingate::plaincgi_interface ci;
205 kingate::cgi_gateway gw(ci); 206 kingate::cgi_gateway gw(ci);
206 string op; 207 string op;
207 try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { } 208 try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { }
208 string message; 209 string message;
209 if(op=="set_password") { 210 if(op=="set_password") {
210 example_op_t OP(gw); 211 example_op_t OP(gw);
211 string password = gw.get_param("password"); 212 string password = gw.get_param("password");
212 sqlite3_mem_t<char*> 213 sqlite3_mem_t<char*>
213 Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); 214 Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1");
214 sqlite3_table_t T; int nr,nc; 215 sqlite3_table_t T; int nr,nc;
215 OP.db.get_table(Sget,T,&nr,&nc); 216 OP.db.get_table(Sget,T,&nr,&nc);
216 if(nr>=1) 217 if(nr>=1)
217 throw opkele::exception(OPKELE_CP_ "Password already set"); 218 throw opkele::exception(OPKELE_CP_ "Password already set");
218 sqlite3_mem_t<char*> 219 sqlite3_mem_t<char*>
219 Sset = sqlite3_mprintf( 220 Sset = sqlite3_mprintf(
220 "INSERT INTO setup (s_password) VALUES (%Q)", 221 "INSERT INTO setup (s_password) VALUES (%Q)",
221 password.c_str()); 222 password.c_str());
222 OP.db.exec(Sset); 223 OP.db.exec(Sset);
223 op.clear(); 224 op.clear();
224 message = "password set"; 225 message = "password set";
225 }else if(op=="login") { 226 }else if(op=="login") {
226 example_op_t OP(gw); 227 example_op_t OP(gw);
227 string password = gw.get_param("password"); 228 string password = gw.get_param("password");
228 sqlite3_mem_t<char*> 229 sqlite3_mem_t<char*>
229 Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); 230 Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1");
230 sqlite3_table_t T; int nr,nc; 231 sqlite3_table_t T; int nr,nc;
231 OP.db.get_table(Sget,T,&nr,&nc); 232 OP.db.get_table(Sget,T,&nr,&nc);
232 if(nr<1) 233 if(nr<1)
233 throw opkele::exception(OPKELE_CP_ "no password set"); 234 throw opkele::exception(OPKELE_CP_ "no password set");
234 if(password!=T.get(1,0,nc)) 235 if(password!=T.get(1,0,nc))
235 throw opkele::exception(OPKELE_CP_ "wrong password"); 236 throw opkele::exception(OPKELE_CP_ "wrong password");
236 OP.set_authorized(true); 237 OP.set_authorized(true);
237 op.clear(); 238 op.clear();
238 message = "logged in"; 239 message = "logged in";
239 OP.cookie_header(cout); 240 OP.cookie_header(cout);
240 }else if(op=="logout") { 241 }else if(op=="logout") {
241 example_op_t OP(gw); 242 example_op_t OP(gw);
242 OP.set_authorized(false); 243 OP.set_authorized(false);
243 op.clear(); 244 op.clear();
244 message = "logged out"; 245 message = "logged out";
245 } 246 }
246 string om; 247 string om;
247 try { om = gw.get_param("openid.mode"); }catch(kingate::exception_notfound&) { } 248 try { om = gw.get_param("openid.mode"); }catch(kingate::exception_notfound&) { }
248 if(op=="xrds") { 249 if(op=="xrds") {
249 cout << 250 cout <<
250 "Content-type: application/xrds+xml\n\n" 251 "Content-type: application/xrds+xml\n\n"
251 "<?xml version='1.0' encoding='utf-8'?>" 252 "<?xml version='1.0' encoding='utf-8'?>"
252 "<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)'>"
253 "<XRD>" 254 "<XRD>"
254 "<Service>" 255 "<Service>"
255 "<Type>" STURI_OPENID20 "</Type>" 256 "<Type>" STURI_OPENID20 "</Type>"
256 "<URI>" << get_self_url(gw) << "</URI>" 257 "<URI>" << get_self_url(gw) << "</URI>"
257 "</Service>"; 258 "</Service>";
258 if(gw.has_param("idsel")){ 259 if(gw.has_param("idsel")){
259 cout << 260 cout <<
260 "<Service>" 261 "<Service>"
261 "<Type>" STURI_OPENID20_OP "</Type>" 262 "<Type>" STURI_OPENID20_OP "</Type>"
262 "<URI>" << get_self_url(gw) << "</URI>"; 263 "<URI>" << get_self_url(gw) << "</URI>";
263 } 264 }
264 cout << 265 cout <<
265 "</XRD>" 266 "</XRD>"
266 "</xrds:XRDS>"; 267 "</xrds:XRDS>";
267 }else if(op=="id_res" || op=="cancel") { 268 }else if(op=="id_res" || op=="cancel") {
268 kingate_openid_message_t inm(gw); 269 kingate_openid_message_t inm(gw);
269 example_op_t OP(gw); 270 example_op_t OP(gw);
270 if(gw.get_param("hts_id")!=OP.htc.get_value()) 271 if(gw.get_param("hts_id")!=OP.htc.get_value())
271 throw opkele::exception(OPKELE_CP_ "toying around, huh?"); 272 throw opkele::exception(OPKELE_CP_ "toying around, huh?");
272 OP.checkid_(inm,0); 273 opkele::sreg_t sreg;
274 OP.checkid_(inm,sreg);
273 OP.cookie_header(cout); 275 OP.cookie_header(cout);
274 opkele::openid_message_t om; 276 opkele::openid_message_t om;
275 if(op=="id_res") { 277 if(op=="id_res") {
276 if(!OP.get_authorized()) 278 if(!OP.get_authorized())
277 throw opkele::exception(OPKELE_CP_ "not logged in"); 279 throw opkele::exception(OPKELE_CP_ "not logged in");
278 if(OP.is_id_select()) { 280 if(OP.is_id_select()) {
279 OP.select_identity( get_self_url(gw), get_self_url(gw) ); 281 OP.select_identity( get_self_url(gw), get_self_url(gw) );
280 } 282 }
283 sreg.set_field(opkele::sreg_t::field_nickname,"anonymous");
284 sreg.set_field(opkele::sreg_t::field_fullname,"Ann O'Nymus");
285 sreg.set_field(opkele::sreg_t::field_gender,"F");
286 sreg.setup_response();
281 cout << 287 cout <<
282 "Status: 302 Going back to RP with id_res\n" 288 "Status: 302 Going back to RP with id_res\n"
283 "Location: " << OP.id_res(om).append_query(OP.get_return_to()) 289 "Location: " << OP.id_res(om,sreg).append_query(OP.get_return_to())
284 << "\n\n"; 290 << "\n\n";
285 }else{ 291 }else{
286 cout << 292 cout <<
287 "Status: 302 Going back to RP with cancel\n" 293 "Status: 302 Going back to RP with cancel\n"
288 "Location: " << OP.cancel(om).append_query(OP.get_return_to()) 294 "Location: " << OP.cancel(om).append_query(OP.get_return_to())
289 << "\n\n"; 295 << "\n\n";
290 } 296 }
291 om.to_keyvalues(clog); 297 om.to_keyvalues(clog);
292 }else if(om=="associate") { 298 }else if(om=="associate") {
293 kingate_openid_message_t inm(gw); 299 kingate_openid_message_t inm(gw);
294 opkele::openid_message_t oum; 300 opkele::openid_message_t oum;
295 example_op_t OP(gw); 301 example_op_t OP(gw);
296 OP.associate(oum,inm); 302 OP.associate(oum,inm);
297 cout << "Content-type: text/plain\n\n"; 303 cout << "Content-type: text/plain\n\n";
298 oum.to_keyvalues(cout); 304 oum.to_keyvalues(cout);
299 }else if(om=="checkid_setup") { 305 }else if(om=="checkid_setup") {
300 kingate_openid_message_t inm(gw); 306 kingate_openid_message_t inm(gw);
301 example_op_t OP(gw); 307 example_op_t OP(gw);
302 OP.checkid_(inm,0); 308 OP.checkid_(inm,0);
303 OP.cookie_header(cout) << 309 OP.cookie_header(cout) <<
304 "Content-type: text/html\n" 310 "Content-type: text/html\n"
305 "\n" 311 "\n"
306 312
307 "<html>" 313 "<html>"
308 "<head>" 314 "<head>"
309 "<title>test OP: confirm authentication</title>" 315 "<title>test OP: confirm authentication</title>"
310 "</head>" 316 "</head>"
311 "<body>" 317 "<body>"
312 "realm: " << OP.get_realm() << "<br/>" 318 "realm: " << OP.get_realm() << "<br/>"
313 "return_to: " << OP.get_return_to() << "<br/>" 319 "return_to: " << OP.get_return_to() << "<br/>"
314 "claimed_id: " << OP.get_claimed_id() << "<br/>" 320 "claimed_id: " << OP.get_claimed_id() << "<br/>"
315 "identity: " << OP.get_identity() << "<br/>"; 321 "identity: " << OP.get_identity() << "<br/>";
316 if(OP.is_id_select()) { 322 if(OP.is_id_select()) {
317 OP.select_identity( get_self_url(gw), get_self_url(gw) ); 323 OP.select_identity( get_self_url(gw), get_self_url(gw) );
318 cout << 324 cout <<
319 "selected claimed_id: " << OP.get_claimed_id() << "<br/>" 325 "selected claimed_id: " << OP.get_claimed_id() << "<br/>"
320 "selected identity: " << OP.get_identity() << "<br/>"; 326 "selected identity: " << OP.get_identity() << "<br/>";
321 } 327 }
322 cout << 328 cout <<
323 "<form method='post'>"; 329 "<form method='post'>";
324 inm.to_htmlhiddens(cout); 330 inm.to_htmlhiddens(cout);
325 cout << 331 cout <<
326 "<input type='hidden' name='hts_id'" 332 "<input type='hidden' name='hts_id'"
327 " value='" << opkele::util::attr_escape(OP.htc.get_value()) << "'/>" 333 " value='" << opkele::util::attr_escape(OP.htc.get_value()) << "'/>"
328 "<input type='submit' name='op' value='id_res'/>" 334 "<input type='submit' name='op' value='id_res'/>"
329 "<input type='submit' name='op' value='cancel'/>" 335 "<input type='submit' name='op' value='cancel'/>"
330 "</form>" 336 "</form>"
331 "</body>" 337 "</body>"
332 "</html>"; 338 "</html>";
333 }else if(om=="check_authentication") { 339 }else if(om=="check_authentication") {
334 kingate_openid_message_t inm(gw); 340 kingate_openid_message_t inm(gw);
335 example_op_t OP(gw); 341 example_op_t OP(gw);
336 opkele::openid_message_t oum; 342 opkele::openid_message_t oum;
337 OP.check_authentication(oum,inm); 343 OP.check_authentication(oum,inm);
338 cout << "Content-type: text/plain\n\n"; 344 cout << "Content-type: text/plain\n\n";
339 oum.to_keyvalues(cout); 345 oum.to_keyvalues(cout);
340 oum.to_keyvalues(clog); 346 oum.to_keyvalues(clog);
341 }else{ 347 }else{
342 example_op_t OP(gw); 348 example_op_t OP(gw);
343 string idsel; 349 string idsel;
344 if(gw.has_param("idsel")) 350 if(gw.has_param("idsel"))
345 idsel = "&idsel=idsel"; 351 idsel = "&idsel=idsel";
346 OP.cookie_header(cout) << 352 OP.cookie_header(cout) <<
347 "Content-type: text/html\n" 353 "Content-type: text/html\n"
348 "X-XRDS-Location: " << get_self_url(gw) << "?op=xrds" << idsel << "\n" 354 "X-XRDS-Location: " << get_self_url(gw) << "?op=xrds" << idsel << "\n"
349 "\n" 355 "\n"
350 356
351 "<html>" 357 "<html>"
352 "<head>" 358 "<head>"
353 "<title>test OP</title>" 359 "<title>test OP</title>"
354 "<link rel='openid.server' href='" << get_self_url(gw) << "'/>" 360 "<link rel='openid.server' href='" << get_self_url(gw) << "'/>"
355 "</head>" 361 "</head>"
356 "<body>" 362 "<body>"
357 "test openid 2.0 endpoint" 363 "test openid 2.0 endpoint"
358 "<br/>" 364 "<br/>"
359 "<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>"
360 "<br/>" 366 "<br/>"
361 "<h1>" << message << "</h1>"; 367 "<h1>" << message << "</h1>";
362 sqlite3_mem_t<char*> 368 sqlite3_mem_t<char*>
363 S = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); 369 S = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1");
364 sqlite3_table_t T; int nr,nc; 370 sqlite3_table_t T; int nr,nc;
365 OP.db.get_table(S,T,&nr,&nc); 371 OP.db.get_table(S,T,&nr,&nc);
366 if(nr<1) { 372 if(nr<1) {
367 cout << 373 cout <<
368 "<form method='post'>" 374 "<form method='post'>"
369 "set password " 375 "set password "
370 "<input type='hidden' name='op' value='set_password'/>" 376 "<input type='hidden' name='op' value='set_password'/>"
371 "<input type='password' name='password' value=''/>" 377 "<input type='password' name='password' value=''/>"
372 "<input type='submit' name='submit' value='submit'/>" 378 "<input type='submit' name='submit' value='submit'/>"
373 "</form>"; 379 "</form>";
374 }else if(OP.get_authorized()) { 380 }else if(OP.get_authorized()) {
375 cout << 381 cout <<
376 "<br/>" 382 "<br/>"
377 "<a href='" << get_self_url(gw) << "?op=logout'>logout</a>"; 383 "<a href='" << get_self_url(gw) << "?op=logout'>logout</a>";
378 }else{ 384 }else{
379 cout << 385 cout <<