Users Sessions

Exported Procedures

Base_Users_Sessions_Replace

DROP   PROCEDURE Base_Users_Sessions_Replace;
DELIMITER //
CREATE PROCEDURE Base_Users_Sessions_Replace
(
  $email                           CHAR(99),
  $password                        CHAR(99)
)
SQL SECURITY DEFINER
COMMENT 'EXPORT'
BEGIN

SET @status    = "";
SET @sessionid = "";
SET @USER      = 0;
SET @idtype    = "";

CALL Base_Users_Sessions_Replace_Inout( $email, $password, @status, @sessionid, @USER, @idtype );

SELECT @status AS status, @sessionid AS sessionid, @USER AS USER, @idtype AS idtype;

END
//
DELIMITER ;
CREATE OR ALTER PROCEDURE Base_Users_Sessions_Replace
(
  @email                           CHAR(99),
  @password                        CHAR(99)
)
AS
BEGIN

SET @status    = "";
SET @sessionid = "";
SET @USER      = 0;
SET @idtype    = "";

CALL Base_Users_Sessions_Replace_Inout( $email, $password, @status, @sessionid, @USER, @idtype );

SELECT @status AS status, @sessionid AS sessionid, @USER AS USER, @idtype AS idtype;

END
//
DELIMITER ;

Deprecated

DROP   PROCEDURE Users_Sessions_Replace;
DELIMITER //
CREATE PROCEDURE Users_Sessions_Replace
(
  $email                           CHAR(99),
  $password                        CHAR(99)
)
SQL SECURITY DEFINER
COMMENT 'EXPORT'
BEGIN

SET @status    = "";
SET @sessionid = "";
SET @USER      = 0;
SET @idtype    = "";

CALL Base_Users_Sessions_Replace_Inout( $email, $password, @status, @sessionid, @USER, @idtype );

SELECT @status AS status, @sessionid AS sessionid, @USER AS USER, @idtype AS idtype;

END
//
DELIMITER ;

Base_Users_Authenticate

DROP   PROCEDURE Base_Users_Authenticate;
DELIMITER //
CREATE PROCEDURE Base_Users_Authenticate
(
    $Sid  TEXT
)
SQL SECURITY DEFINER
COMMENT 'EXPORT'
BEGIN

    IF @@read_only THEN

        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'READ_ONLY';

    ELSEIF NOT Base_Users_Sessions_Verify( $Sid ) THEN

        CALL Base_Users_Sessions_Terminate( $Sid );

        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INVALID_SESSION IN Base_Users_Authenticate';

    ELSE

        CALL Base_Users_Sessions_Extend_Expiry( $Sid );

        SELECT    email, USER, given_name, family_name, type AS idtype, group_code, last_login, user_status, user_hash, 0 AS read_only
        FROM      base_users_sessions
        LEFT JOIN view_base_users USING (email)
        WHERE     sid = $Sid;

    END IF;

END
//
DELIMITER ;

Deprecated.

DROP   PROCEDURE Users_Authenticate;
DELIMITER //
CREATE PROCEDURE Users_Authenticate
(
  $Sid CHAR(64)
)
SQL SECURITY DEFINER
COMMENT 'EXPORT'
BEGIN

CALL Base_Users_Authenticate( $Sid );

END
//
DELIMITER ;

Base_Users_Authorize_SessionID

DROP   PROCEDURE Base_Users_Authorize_SessionID;
DELIMITER //
CREATE PROCEDURE Base_Users_Authorize_SessionID
(
      $Sid          CHAR(64),
  OUT $Email        CHAR(99),
  OUT $USER          INT(11),
  OUT $IDType    VARCHAR(20)
)
SQL SECURITY INVOKER
BEGIN

IF @@read_only THEN

    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'READ_ONLY';

ELSE

    CALL Base_Users_Authorise_Sessionid( $Sid, $Email, $USER, $IDType );

END IF;

END
//
DELIMITER ;

Base Users Sessions

Base_Users_Sessions

DROP   PROCEDURE Base_Users_Sessions;
DELIMITER //
CREATE PROCEDURE Base_Users_Sessions
(
  $Sid                             CHAR(64),
  $USER                            CHAR(64),
  $user_hash                       CHAR(64),
  $order                           CHAR(99),
  $limit                            INT(11),
  $offset                           INT(11)
)
SQL SECURITY INVOKER
BEGIN

IF @@read_only THEN

    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'READ_ONLY';

END IF;

END
//
DELIMITER ;

Base_Users_Sessions_Replace_Inout

DROP   PROCEDURE Base_Users_Sessions_Replace_Inout;
DELIMITER //
CREATE PROCEDURE Base_Users_Sessions_Replace_Inout
(
      $email                         CHAR(99),
      $password                      CHAR(99),
INOUT $status                        CHAR(99),
INOUT $sessionid                     CHAR(64),
INOUT $USER                           INT(11),
INOUT $idtype                        CHAR(20)
)
SQL SECURITY INVOKER
BEGIN

    CALL Base_Users_Sessions_Replace_w_DeviceID_Inout
    (
        '',
        $email,
        $password,
        $status,
        $sessionid,
        $USER,
        $idtype
    );

END
//
DELIMITER ;

Base_Users_Sessions_Replace_w_DeviceID_Inout

DROP   PROCEDURE Base_Users_Sessions_Replace_w_DeviceID_Inout;
DELIMITER //
CREATE PROCEDURE Base_Users_Sessions_Replace_w_DeviceID_Inout
(
      $deviceid                      CHAR(99),
      $email                         CHAR(99),
      $password                      CHAR(99),
INOUT $status                        CHAR(99),
INOUT $sessionid                     CHAR(64),
INOUT $USER                           INT(11),
INOUT $idtype                        CHAR(20)
)
SQL SECURITY INVOKER
BEGIN

DECLARE $start          TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
DECLARE $authenticated  BOOL      DEFAULT  0;
DECLARE $salt           TEXT      DEFAULT '';
DECLARE $phash1         TEXT      DEFAULT '';
DECLARE $phash2         TEXT      DEFAULT '';
DECLARE $invalid        INT       DEFAULT  0;
DECLARE $group_code     TEXT      DEFAULT '';
DECLARE $csrf           TEXT      DEFAULT '';

IF @@read_only THEN

    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'READ_ONLY';

ELSE

    #
    #   Housekeeping
    #

    DELETE FROM base_users_sessions WHERE expiry < UNIX_TIMESTAMP();

    IF ("" = $deviceid AND "" = $email) OR "" = $password THEN

        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INVALID_CREDENTIALS';

    ELSE

        IF EXISTS( SELECT * FROM base_users_mobiles WHERE user_mobile_device_id=$email ) THEN

            SELECT USER             INTO $USER   FROM base_users_mobiles WHERE user_mobile_device_id = $email;
            SELECT user_mobile_salt INTO $salt   FROM base_users_mobiles WHERE user_mobile_device_id = $email;
            SELECT user_mobile_hash INTO $phash1 FROM base_users_mobiles WHERE user_mobile_device_id = $email;

        ELSEIF EXISTS( SELECT * FROM base_users_device_logins WHERE user_device_login_guid = $deviceid ) THEN

            SELECT USER                   INTO $USER   FROM base_users_device_logins WHERE user_device_login_guid = $deviceid ORDER BY user_device_login_created DESC LIMIT 1;
            SELECT user_device_login_salt INTO $salt   FROM base_users_device_logins WHERE user_device_login_guid = $deviceid ORDER BY user_device_login_created DESC LIMIT 1;
            SELECT user_device_login_hash INTO $phash1 FROM base_users_device_logins WHERE user_device_login_guid = $deviceid ORDER BY user_device_login_created DESC LIMIT 1;

        ELSE

            SELECT USER             INTO $USER       FROM base_users WHERE email=$email;
            SELECT user_salt        INTO $salt       FROM base_users WHERE email=$email;
            SELECT password_hash    INTO $phash1     FROM base_users WHERE email=$email;

        END IF;

        SET $phash2 = ComputeHash( $salt, $password );

        IF $phash1=$phash2 THEN
            SET $authenticated = TRUE;
        ELSE
            SET $authenticated = FALSE;
        END IF;

        IF NOT $USER THEN

            IF NOT EXISTS( SELECT * FROM base_users_invalid WHERE email=$email ) THEN
                REPLACE INTO base_users_invalid
                (  email, invalid_logins, invalid_sent )
                VALUES
                ( $email,              0,            0 );
            END IF;

            SELECT invalid_logins INTO $invalid FROM base_users_invalid WHERE email=$email;

            UPDATE base_users_invalid SET invalid_logins = invalid_logins + 1, invalid_sent=0 WHERE email=$email;

            DO SLEEP( $invalid - TIMESTAMPDIFF( SECOND, NOW(), $start ) );

            IF $invalid > 4 THEN
                SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INVALID_LOGINS';
            ELSE
                SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INVALID_CREDENTIALS';
            END IF;

        ELSE

            SELECT email, invalid_logins INTO $email, $invalid FROM base_users WHERE USER=$USER;

            #
            #   First, if unauthenticated, update invalid_logins so that this is promplty incremented when brute-forced.
            #

            IF NOT $authenticated THEN
                UPDATE base_users SET invalid_logins = invalid_logins + 1 WHERE USER=$USER;
            END IF;

            #
            #   Second, do annoying sleep.
            #

            DO SLEEP( $invalid - TIMESTAMPDIFF( SECOND, NOW(), $start ) );

            #
            #   Third, if passed magic threshold of invalid logins fail on INVALID_LOGINS (ignore empty password).
            #

            IF $invalid > 4 AND "" != $password THEN
                SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INVALID_LOGINS';
            END IF;

            #
            #   Fourth, if unauthenticated, fail on password.  
            #

            IF NOT $authenticated THEN

                SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INVALID_CREDENTIALS';

            ELSE

                SELECT group_code INTO $group_code FROM base_groups_members LEFT JOIN base_groups USING (GROUP_ID) WHERE USER=$USER;

                #
                #   Ensure unique sessionid
                #

                SET $sessionid = GenerateSalt();
                WHILE EXISTS( SELECT * FROM base_users_sessions WHERE sid=$sessionid ) DO
                    SET $sessionid = GenerateSalt();
                END WHILE;

                SET $csrf = GenerateSalt();
                WHILE EXISTS( SELECT * FROM base_users_sessions WHERE csrf=$csrf ) DO
                    SET $csrf = GenerateSalt();
                END WHILE;

                REPLACE INTO base_users_sessions
                (         sid,  csrf,  AUTH_USER,  email,  group_code,  created,  updated,                  expiry )
                VALUES
                (  $sessionid, $csrf,      $USER, $email, $group_code,    NOW(),    NOW(), UNIX_TIMESTAMP() + 3600 );

                UPDATE base_users SET invalid_logins = 0, last_login=NOW(), visits = visits + 1 WHERE USER=$USER;

                REPLACE INTO base_users_sessions_log
                (        sid,  AUTH_USER,  email,  group_code,  created,  updated,                  expiry )
                VALUES
                ( $sessionid,      $USER, $email, $group_code,    NOW(),    NOW(), UNIX_TIMESTAMP() + 3600 );

                SELECT "OK", type INTO $status, $idtype FROM view_base_users WHERE email=$email;

            END IF;

        END IF;

    END IF;

END IF;

END
//
DELIMITER ;

Base_Users_Sessions_Retrieve_Current

DROP   PROCEDURE Base_Users_Sessions_Retrieve_Current;
DELIMITER //
CREATE PROCEDURE Base_Users_Sessions_Retrieve_Current
(
  $Sid                             CHAR(64)
)
SQL SECURITY INVOKER
BEGIN

IF @@read_only THEN

    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'READ_ONLY';

ELSE

    SELECT * FROM view_base_users_sessions WHERE sessionid=$Sid;

END IF;

END
//
DELIMITER ;

Base_Users_Sessions_Terminate

DROP   PROCEDURE Base_Users_Sessions_Terminate;
DELIMITER //
CREATE PROCEDURE Base_Users_Sessions_Terminate
(
  $Sid                             CHAR(99)
)
SQL SECURITY INVOKER
BEGIN

IF @@read_only THEN

    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'READ_ONLY';

ELSE

    DELETE FROM base_users_sessions WHERE sid=$Sid;

END IF;

END
//
DELIMITER ;

Base_Users_Sessions_Verify

DROP   FUNCTION Base_Users_Sessions_Verify;
DELIMITER //
CREATE FUNCTION Base_Users_Sessions_Verify
(
  $Sid CHAR(64)
)
RETURNS BOOLEAN
READS SQL DATA
SQL SECURITY DEFINER
BEGIN

    DECLARE $expiry INT;
    DECLARE $now    INT;
    DECLARE $ret    BOOL DEFAULT FALSE;

    SET $now    = UNIX_TIMESTAMP();
    SET $ret    = False;

    SELECT expiry INTO $expiry FROM base_users_sessions WHERE sid=$Sid;

    IF $now < $expiry THEN
        SET $ret = True;
    END IF;

    return $ret;

END
//
DELIMITER ;

Deprecated.

DROP   FUNCTION Users_Sessions_Verify;
DELIMITER //
CREATE FUNCTION Users_Sessions_Verify
(
  $Sid CHAR(64)
)
RETURNS BOOLEAN
READS SQL DATA
SQL SECURITY DEFINER
BEGIN

DECLARE $expiry INT;
DECLARE $now    INT;
DECLARE $ret    BOOL DEFAULT FALSE;

IF @@read_only THEN

    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'READ_ONLY';

ELSE

    SET $now    = UNIX_TIMESTAMP();
    SET $ret    = False;

    SELECT expiry INTO $expiry FROM base_users_sessions WHERE sid=$Sid;

    IF $now < $expiry THEN
        SET $ret = True;
    END IF;

END IF;

return $ret;

END
//
DELIMITER ;

Base_Users_Sessions_Extend_Expiry

DROP   PROCEDURE base_users_sessions_extend_expiry;
DELIMITER //
CREATE PROCEDURE base_users_sessions_extend_expiry
(
  $Sid CHAR(64)
)
SQL SECURITY INVOKER
BEGIN

    DECLARE $expiry   INT;
    DECLARE $now      INT;
    DECLARE $ret      BOOL;
    DECLARE read_only BOOL;

    IF @@read_only THEN

        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'READ_ONLY';

    ELSE

        SELECT expiry
        INTO  $expiry
        FROM   base_users_sessions
        WHERE  sid = $Sid;

        SET $now = UNIX_TIMESTAMP();

        IF $now < $expiry THEN

            UPDATE base_users_sessions
            SET
                updated = NOW(),
                expiry  = $now + 14400

            WHERE sid = $Sid;

        ELSE

            CALL Base_Users_Sessions_Terminate( $Sid );

        END IF;

    END IF;

END
//
DELIMITER ;