<?vsp
--  
--  $Id$
--  
--  This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
--  project.
--  
--  Copyright (C) 1998-2018 OpenLink Software
--  
--  This project is free software; you can redistribute it and/or modify it
--  under the terms of the GNU General Public License as published by the
--  Free Software Foundation; only version 2 of the License, dated June 1991.
--  
--  This program is distributed in the hope that it will be useful, but
--  WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
--  General Public License for more details.
--  
--  You should have received a copy of the GNU General Public License along
--  with this program; if not, write to the Free Software Foundation, Inc.,
--  51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
--  
--  

 declare url, ret, cnt, oi_srv, oi_delegate, oi_ident, this_page, xt, hdr, host, oi_mode any;
 declare setup_url, oi_handle, trust_root, oi_sig, oi_signed, oi_key varchar;
 declare ses, flds, check_immediate any;

-- dbg_printf ('==========================================================');
-- dbg_obj_print (params);
 
 host := http_request_header (lines, 'Host');
 
 this_page := 'http://' || host || http_path (); 
 trust_root := 'http://' || host;

 oi_ident := {?'openid_url'};
 oi_mode := {?'openid.mode'};

 http_header ('Cache-Control: private, proxy-revalidate\r\n');
 -- Start handshake
 if (oi_ident is not null)
   {
     url := trim(oi_ident);
     declare exit handler for sqlstate '*'
     {
	-- dbg_obj_print (__SQL_MESSAGE);
         http ('{err_code: "openid.url",err_text: "The URL cannot be retrieved"}');
         return;
     };
     if (not length (url) or url not like 'http%://%')
       {
         http ('{err_code: "openid.url",err_text: "Invalid URL"}');
         return;
       }  
    again:
     hdr := null;
     cnt := DB.DBA.HTTP_CLIENT_EXT (url=>url, headers=>hdr);

--     dbg_obj_print (hdr);
     if (hdr [0] like 'HTTP/1._ 30_ %')
       {
         declare loc any;
	 loc := http_request_header (hdr, 'Location', null, null);
	 url := WS.WS.EXPAND_URL (url, loc); 
         oi_ident := url;
	 goto again;
       }
       
     xt := xtree_doc (cnt, 2);

     oi_srv := cast (xpath_eval ('//link[@rel="openid.server"]/@href', xt) as varchar);
     oi_delegate := cast (xpath_eval ('//link[@rel="openid.delegate"]/@href', xt) as varchar);

     if (oi_srv is null)
       {
         http ('{err_code: "openid.server",err_text: "The OpenID server cannot be located"}');
         return;
       }  

     if (oi_delegate is not null)
       oi_ident := oi_delegate;

     oi_handle := null;
     oi_key := '';
     check_immediate := sprintf ('%s?openid.mode=associate', oi_srv);
     cnt := http_client (url=>check_immediate);
     cnt := split_and_decode (cnt, 0, '\0\0\x0A:');
     oi_handle := get_keyword ('assoc_handle', cnt, null);
     oi_key := get_keyword ('mac_key', cnt, '');

     check_immediate := 
     sprintf ('%s?openid.mode=checkid_setup&openid.identity=%U&openid.return_to=%U&openid.trust_root=%U', 
    	oi_srv, oi_ident, this_page, trust_root);
     if (length (oi_handle))
       check_immediate := check_immediate || sprintf ('&openid.assoc_handle=%U', oi_handle);

     check_immediate := check_immediate || sprintf ('&openid.sreg.optional=%U', 'email,fullname');

     http (sprintf ('{checkid_immediate_url: "%s", id_server: "%s", clean_identity_url: "%s", openid_key: "%s" }', 
		    check_immediate, oi_srv, oi_ident, oi_key));  
   }
 else if (oi_mode = 'id_res')
   {
     declare qry_str, nam, mail varchar;
--     dbg_obj_print (params);
     qry_str := http_request_get ('QUERY_STRING');
     setup_url := {?'openid.user_setup_url'};  
     oi_handle := {?'openid.assoc_handle'};  
     oi_ident := {?'openid.identity'};
     --oi_srv := {?'openid_server'};
     --trust_root := {?'trust_root'};
     oi_sig := {?'openid.sig'};
     oi_signed := {?'openid.signed'};

     nam := {?'openid.sreg.fullname'};
     mail := {?'openid.sreg.email'}; 

     --dbg_obj_print (oi_handle,oi_ident,oi_sig,oi_signed, {?'openid.return_to'});
     if (oi_sig is null)
       {
         --dbg_obj_print ('setup_url=', setup_url);
?>
<html><body><script>
if (parent.location.host == location.host)
  parent.OpenID_callback_fail("<?vsp http (coalesce (setup_url, '')); ?>");
</script></body></html>
<?vsp
       } 
     else 
       {
?>
<html><body><script>
if (window.opener) {
    var pwin = window.opener;
    if (pwin.OpenID_callback_pass) {
	    pwin.OpenID_callback_pass("<?V oi_ident ?>", "<?V oi_sig ?>", "<?vsp http(qry_str); ?>", "<?V nam ?>", "<?V mail ?>");
	    window.close();
    }  else {
          alert("Error: browser weirdness.  Please report this.");
    }
} else if (parent.location.host == location.host) {
    if (parent.OpenID_callback_pass) {
	    parent.OpenID_callback_pass("<?V oi_ident ?>", "<?V oi_sig ?>", "<?vsp http(qry_str); ?>", "<?V nam ?>", "<?V mail ?>");
    } else {
          alert("Error: browser weirdness.  parent location = " + parent.location);
	  document.write("Please report your browser so we can fix this.");
    }
}
</script></body></html>
<?vsp
       }
   } 
 else if (oi_mode = 'cancel')
   {
?>
<html><body><script>
if (window.opener) {
    var pwin = window.opener;
    if (pwin.OpenID_callback_pass) {
	    window.close();
    }  else {
          alert("Error: browser weirdness.  Please report this.");
    }
} else if (parent.location.host == location.host) {
    if (parent.OpenID_callback_pass) {
    } else {
          alert("Error: browser weirdness.  parent location = " + parent.location);
	  document.write("Please report your browser so we can fix this.");
    }
}
</script></body></html>
<?vsp
   }
 else
  {
?>
<html><body><script>
  if (parent.location.host == location.host) 
    parent.OpenID_general_error({err_code: "gen_error",err_text: "Unexpected error occurred when establishing OpenID sequence."});
</script></body></html>
<?vsp
  }
?>
