<!--
 -
 -  $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
 -
-->
<v:page name="blog-home-page"
        xmlns:vm="http://www.openlinksw.com/vspx/ods/"
        xmlns:v="http://www.openlinksw.com/vspx/"
        doctype="-//W3C//DTD XHTML 1.0 Transitional//EN"
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <v:variable name="login_blocked" type="varchar" default="null" persist="0"/>
  <v:variable name="login_attempts" type="integer" default="0" persist="0" />
  <v:variable name="wa_name" type="varchar" default="null" persist="0" param-name="wa_name"/>
  <v:variable name="is_cookie_session" type="int" default="0" persist="0" param-name="noparams"/>
  <v:variable name="login_ip" type="varchar" default="null" persist="1"/>
  <!-- OAuth signin -->
  <v:variable name="token" type="varchar" default="null" param-name="token"/>
  <v:variable name="cb" type="varchar" default="null" param-name="cb"/>
  <v:variable name="a_name" type="varchar" default="null" persist="0" />
  <v:variable name="a_descr" type="varchar" default="null" persist="0" />
  <v:variable name="_ver" type="varchar" default="1" persist="0" param-name="ver" />
  <v:variable name="_uname" type="varchar" default="null" persist="temp" />
  <v:on-init><![CDATA[
    declare cookie_vec, sid, cookie_str any;

    set http_charset='UTF-8';

    if (self.token is null)
      {
        self.vc_redirect ('error.vspx');
        return;
      }

    declare exit handler for not found {
     self.vc_redirect ('error.vspx');
     return;
    };
    select U_NAME, a_name into self._uname, self.a_name
      	from OAUTH.DBA.SESSIONS, OAUTH.DBA.APP_REG, DB.DBA.SYS_USERS
        where U_ID = a_owner and a_id = s_a_id and s_req_key = self.token;

    cookie_str := http_request_header (self.vc_event.ve_lines, 'Cookie', null, null);
    if (cookie_str is not null)
      {
	cookie_vec := split_and_decode (cookie_str, 0, '\0\0;=');
	for (declare i, l int, i := 0, l := length (cookie_vec); i < l; i := i + 1)
	   {
	     cookie_vec [i] := trim (cookie_vec [i]);
	   }
       }
    else
      cookie_vec := vector ();
    --cookie_vec := vsp_ua_get_cookie_vec(self.vc_event.ve_lines);

    -- let's check session user
    if (get_keyword('sid', self.vc_event.ve_params) is not null or get_keyword('sid', cookie_vec) is not null)
      {
         declare uid1, sid1 any;
	 sid1 := get_keyword ('sid', self.vc_event.ve_params, get_keyword ('sid', cookie_vec));
	 uid1 := (select VS_UID from VSPX_SESSION where VS_SID = sid1 and VS_REALM = 'wa');
	 if (self._uname <> uid1) -- session of somebody else !
	   {
	     delete from VSPX_SESSION where VS_SID = sid1 and VS_REALM = 'wa';
	     commit work;
	     goto cont;
	   }
      }

    if (get_keyword('sid', self.vc_event.ve_params) is null and get_keyword('sid', cookie_vec) is not null
    	and self.token is not null)
      {
        declare pars, pos any;
        pars := self.vc_event.ve_params;
	sid := get_keyword('sid', cookie_vec);
	pos := position ('sid', pars);
	if (pos > 0)
	  {
	     pars [pos] := sid;
	     pos := position ('realm', pars);
	     if (pos > 0)
	       pars[pos] := 'wa';
	  }
        else
          {
             pars := vector_concat (pars, vector ('sid', sid, 'realm', 'wa')) ;
          }
        self.vc_event.ve_params := pars;
      }
      cont:;
]]></v:on-init>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="login.css" />
    <title>OAuth Authentication</title>
  </head>
  <body>
    <div id="PG">
      <div id="MD">
        <div id="login_page">
	  <v:login name="login1" realm="wa" mode="url" user-password-check="OAUTH..web_user_password_check">
          <div id="id_col">
            <div id="site_id">
              <p><img class="id_logo" src="images/odslogo_200.png" alt="ods logo icon" /></p>
            </div>
          </div>
          <div id="form_col">
            <h1 class="page_title">
              <img class="openid_logo" alt="OpenID Logo" src="images/oauth.png"/> OAuth Authorization Service
            </h1>
	    <div id="login_form_ctr">
	      <v:template type="if-no-login" name="login_if_no_login">
		<h2>Please log in to
            <?vsp
              declare copy varchar;
              copy := null; --(select top 1 WS_WEB_TITLE from WA_SETTINGS);

              if (copy = '' or copy is null)
                http(sys_stat ('st_host_name'));
              else
                http(copy);
            ?>
		  </h2>
              <div id="login_form">
                <form> <!-- just to keep validator happy on this mockup -->
		  <label for="login_frm_username">User ID</label>
		  <v:text name="username" type="hidden" value="--self._uname" xhtml_id="login_frm_username" /><?V self._uname ?><br />
		  <label for="password">Password</label>
		  <v:text name="password" value="" xhtml_id="login_frm_password" type="password" />
		  <div class="login_frm_button_row">
		    <v:button action="simple" name="login" value="Login" xhtml_id="login_frm_b_login">
		      <v:on-post> <![CDATA[
              declare _blocked_until any;
	      _blocked_until := null;
	      --_blocked_until := (select WAB_DISABLE_UNTIL from WA_BLOCKED_IP where WAB_IP = http_client_ip ());
              if (_blocked_until is not null and _blocked_until > now ())
                {
                  self.login_blocked := 'Too many failed attempts. Try again in an hour.';
                  return;
                }

              self.login_attempts := coalesce(self.login_attempts, 0) + 1;

              if (self.login_attempts > 6)
                {
                  ; --insert replacing WA_BLOCKED_IP (WAB_IP, WAB_DISABLE_UNTIL) values (http_client_ip(), dateadd('hour', 1, now()));
                }
]]></v:on-post>
                <v:before-render><![CDATA[
  if (self.login_blocked is not null)
     control.vc_enabled := 0;
]]></v:before-render>
		    </v:button>
		    <v:button action="simple" name="cancel" value="Cancel" xhtml_id="login_frm_b_login">
		      <v:on-post><![CDATA[
			self.vc_redirect (self.cb);
			]]></v:on-post>
		    </v:button>
		  </div>
                </form>
              </div> <!-- login_form -->
	      <p class="login_frm_guide">A <?V http_client_ip () ?> trying to access <i><?V self.a_name ?></i>,
		please login to authorize or decline the request.
	      </p>
	    </v:template>
<?vsp
      if (self.login_blocked is not null)
        http(self.login_blocked);
      else
        {
          if (self.login_attempts > 0 and self.sid is null)
            {
?>
        <div class="login_error_ctr">
          <p class="login_error">
            <img class="warn_img" src="images/warn_16.png"/>
            <span class="err_msg">Invalid member ID or password</span>
          </p>
        </div>
<?vsp
            }
        }
?>
            </div> <!-- login_form_ctr -->
	  <v:template type="if-login" name="login_if_login">
	    <div>
	      <div class="login_frm_guide">
		A client from address: <?V http_client_ip () ?> trying to access
		<?V self.a_name ?> <br />
		<?vsp if (length (self.a_descr)) { ?> <?V self.a_descr ?><br /> <?vsp } ?>
		You need to authorize or decline the request.
		<br/>
		<br/>
	      </div>
	      <div>
		<v:button action="simple" name="decl" value="Decline">
		  <v:on-post><![CDATA[
		    self.vc_redirect (self.cb);
		    ]]></v:on-post>
		</v:button>
		<v:button action="simple" name="accept" value="Authorize">
		  <v:on-post><![CDATA[
		  update OAUTH..SESSIONS set
		  	s_state = 2,
		  	s_sid = self.sid,
			s_url_cb = self.cb
		  	where s_req_key = self.token and s_ip = http_client_ip () and s_state = 1;
		  commit work;
		  self.vc_redirect (self.cb);
		  ]]></v:on-post>
	        </v:button>
	    </div>
	    </div>
	  </v:template>
          </div> <!-- form_col -->
        <v:on-post><![CDATA[
  declare cook_str, expire varchar;
  if (self.vc_authenticated and length (self.sid))
    {
      declare expire varchar;
      expire := sprintf (' expires=%s;', date_rfc1123 (dateadd ('hour', 1, now())));
      cook_str := sprintf ('Set-Cookie: sid=%s;%s path=/\r\n', self.sid, expire);

      if (strstr (http_header_get (), 'Set-Cookie: sid=') is null)
        {
          cook_str := concat (http_header_get (), cook_str);
          http_header (cook_str);
        }
    }
]]></v:on-post>
  <v:after-data-bind><![CDATA[

  if (length (self.sid))
    {
      declare exit handler for not found {
        self.sid := null;
        self.vc_authenticated := 0;
        control.vl_authenticated := 0;
        connection_vars_set (null);
        return;
      };
      select a_name, a_descr into self.a_name, self.a_descr
      	from OAUTH.DBA.SESSIONS, OAUTH.DBA.APP_REG, DB.DBA.SYS_USERS, DB.DBA.VSPX_SESSION
        where VS_SID = self.sid and VS_REALM = self.realm and U_NAME = VS_UID and U_ID = a_owner and a_id = s_a_id
        and s_req_key = self.token;
    }

  if (length (self.sid) and length (self.login_ip) and self.login_ip <> http_client_ip ())
    {
      delete from VSPX_SESSION where VS_SID = self.sid and VS_REALM = self.realm;
      self.sid := null;
      self.vc_authenticated := 0;
      control.vl_authenticated := 0;
      connection_vars_set (null);
      self.vc_redirect ('login.vspx');
      return;
    }
  else if (length (self.sid) and self.login_ip is null)
    self.login_ip := http_client_ip ();

    ]]></v:after-data-bind>
      </v:login>
	</div> <!-- login_page -->
      </div> <!-- MD -->
      <div id="FT">
        <div id="FT_LC">
          <a href="http://www.openlinksw.com/virtuoso"><img alt="Powered by OpenLink Virtuoso Universal Server" src="images/virt_power_no_border.png" border="0"/>
          </a>
        </div>
	<div id="FT_RC">
	  <div id="copyright_ctr">Copyright &amp;copy; 1998-<?V "LEFT" (datestring (now()), 4) ?> OpenLink Software</div>
        </div> <!-- FT_R -->
      </div>
    </div> <!-- PG -->
  </body>
</html>
</v:page>
