Checking if user is logged in before inserting into database

Checking if user is logged in before inserting into database

globalplaneglobalplane Posts: 70Questions: 12Answers: 0

What would be the best place to add a check that the user is logged in before performing an INSERT? If I have a variable set to true if logged in, then something like this:

if($_SESSION['loggedin']==true) {
 
$db->insert( 'staff-log', array(
        'user'   => $_SESSION['username'],
        'action' => $action,
        'values' => json_encode( $values ),
        'row'    => $id,
        'when'   => date('c')
    ) );
 
}

I'd prefer something built-in which gives feedback to the client-side, but I couldn't really understand the example in the Security section (I couldn't find where get() and set() are explained):

Editor::inst( $db, 'staff' )
    ->fields(
        Field::inst( 'name' )
            ->set( $_SESSION['access']['editing'] )
        Field::inst( 'location' )
            ->set( $_SESSION['access']['editing'] )
        Field::inst( 'salary' )
            ->get( $_SESSION['access']['admin'] )
            ->set( $_SESSION['access']['admin'] )
    );

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,722Questions: 1Answers: 10,108 Site admin

    Are they allowed to read the data if not logged in? If not, then you could to header('Location: ...'); if they aren't logged in, effectively never allowing them to interact with this script.

    If they can read the data, and it is just the insert / edit / delete actions you want to do the authentication check on, then you could use a custom validation method. Check if the user is logged in and access rights for the action being performed. If not, throw back an error message.

    Allan

  • globalplaneglobalplane Posts: 70Questions: 12Answers: 0
    edited May 2023

    Ok, I've mostly got this working, but I have a global validator on all three fields. And even though I'm submitting only one at a time, all three errors appear every time.

    Here's the request that gets sent, showing that only one field is being submitted:

    data[row_6967][enabled_id]=-1&action=edit

    And the error:

    Server code snippet:

            // Language
            Field::inst( 'IFNULL(languages.language_name, "* Not Set")', 'language_name')            
            ->searchPaneOptions( SearchPaneOptions::inst() ),
    
            Field::inst( 'IFNULL(mc_revs_language_id.value, -1)', 'language_id')
                ->validator( Validate::numeric() )
                ->validator( function ( $editor, $action, $data ) {
                    if ( $action !== Editor::ACTION_READ && $_SESSION['loggedin'] == false) {
                        return "Please log in first";
                    } else {
                        return true;
                    }
                } )
                ->options( Options::inst()
                    ->table( 'languages' )
                    ->value( 'languages.language_id' )
                    ->label( 'languages.language_name' )
                ),
    
            // Difficulty
            Field::inst( 'IFNULL(difficulty.full, "* Not Set")', 'difficulty')
            ->searchPaneOptions( SearchPaneOptions::inst() ),
    
            Field::inst( 'IFNULL(mc_revs_level.value, -1)', 'difficulty_id')
                ->validator( Validate::numeric() )
                ->validator( function ( $editor, $action, $data ) {
                    if ( $action !== Editor::ACTION_READ && $_SESSION['loggedin'] == false) {
                        return "Please log in first";
                    } else {
                        return true;
                    }
                } )
    
                ->options( Options::inst()
                    ->table( 'difficulty' )
                    ->value( 'difficulty.difficulty_index' )
                    ->label( 'difficulty.full' )
                    ->order('difficulty.list_order')
                ),
    
            // Enabled
    
            Field::inst( 'IFNULL(status_labels.status_label, "Unreviewed")', 'enabled' )
            ->searchPaneOptions( SearchPaneOptions::inst()),
    
            Field::inst( 'IFNULL(mc_revs_enabled.value, -1)', 'enabled_id' )
                ->validator( Validate::numeric() )
                ->validator( function ( $editor, $action, $data ) {
                    if ( $action !== Editor::ACTION_READ && $_SESSION['loggedin'] == false) {
                        return "Please log in first";
                    } else {
                        return true;
                    }
                } )
    
                ->options( Options::inst()
                    ->table( 'status_labels' )
                    ->value( 'status_labels.status_id' )
                    ->label( 'status_labels.status_label' )
                ),
    

    Also, just to mention, the documentation says:

    If the validation passes, return an empty string, null or simply have no return statement.

    But if I do any of those things, it says "Error" on the client. If I return true, then it works.


    Full server code:

    <?php
        ini_set('display_errors', 1);
        ini_set('display_startup_errors', 1);
        error_reporting(E_ALL);
    
        header('Content-Type: application/json; charset=utf-8');
    
        session_start();
    
    include( "/var/www/comprehensibleinputwiki.com/html/editor-php/lib/DataTables.php" );
    
    include_once('./dbconn.php');
    include_once('./account.php'); 
    
    function logChange ( $db, $action, $id, &$values ) {
    
        if(isset($values['difficulty_id'])){
            $db->insert( 'mc_revs_level', array(
                'mw_id'   => 5555,
                'row_index' => $id,
                'value' => $values['difficulty_id']
            ) );
        }
    
        if(isset($values['language_id'])){
            $db->insert( 'mc_revs_language_id', array(
                'mw_id'   => 5555,
                'row_index' => $id,
                'value' => $values['language_id']
            ) );
        }
    
        if(isset($values['enabled_id'])){
            $db->insert( 'mc_revs_enabled', array(
                'mw_id'   => 5555,
                'row_index' => $id,
                'value' => $values['enabled_id']
            ) );
        }
    }
    
    
     
    use 
        DataTables\Editor,
        DataTables\Editor\Field,
        DataTables\Editor\Format,
        DataTables\Editor\Mjoin,
        DataTables\Editor\Options,
        DataTables\Editor\Upload,
        DataTables\Editor\Validate,
        DataTables\Editor\ValidateOptions,
        DataTables\Editor\SearchPaneOptions;
    
    $editor = Editor::inst( $db, 'main_collection', 'main_index' )
        ->fields(
            Field::inst( 'main_collection.main_index' ),
            Field::inst( 'main_collection.id', 'vid')
                ->getFormatter( function ( $val, $data ) {
                    return '<iframe height="200" src="https://www.youtube-nocookie.com/embed/' . $val . '" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>';
                } ),
            Field::inst( 'yt_channel_ids.channelTitle', 'channelTitle' )
                ->searchPaneOptions( SearchPaneOptions::inst() ),
            
    
            // Language
            Field::inst( 'IFNULL(languages.language_name, "* Not Set")', 'language_name')            
            ->searchPaneOptions( SearchPaneOptions::inst() ),
    
            Field::inst( 'IFNULL(mc_revs_language_id.value, -1)', 'language_id')
                ->validator( Validate::numeric() )
                ->validator( function ( $editor, $action, $data ) {
                    if ( $action !== Editor::ACTION_READ && $_SESSION['loggedin'] == false) {
                        return "Please log in first";
                    } else {
                        return true;
                    }
                } )
                ->options( Options::inst()
                    ->table( 'languages' )
                    ->value( 'languages.language_id' )
                    ->label( 'languages.language_name' )
                ),
    
    
            // Title
            Field::inst( 'main_collection.title', 'title' ),
    
    
            // Difficulty
            Field::inst( 'IFNULL(difficulty.full, "* Not Set")', 'difficulty')
            ->searchPaneOptions( SearchPaneOptions::inst() ),
    
            Field::inst( 'IFNULL(mc_revs_level.value, -1)', 'difficulty_id')
                ->validator( Validate::numeric() )
                ->validator( function ( $editor, $action, $data ) {
                    if ( $action !== Editor::ACTION_READ && $_SESSION['loggedin'] == false) {
                        return "Please log in first";
                    } else {
                        return true;
                    }
                } )
    
                ->options( Options::inst()
                    ->table( 'difficulty' )
                    ->value( 'difficulty.difficulty_index' )
                    ->label( 'difficulty.full' )
                    ->order('difficulty.list_order')
                ),
    
            // Enabled
    
            Field::inst( 'IFNULL(status_labels.status_label, "Unreviewed")', 'enabled' )
            ->searchPaneOptions( SearchPaneOptions::inst()),
    
            Field::inst( 'IFNULL(mc_revs_enabled.value, -1)', 'enabled_id' )
                ->validator( Validate::numeric() )
                ->validator( function ( $editor, $action, $data ) {
                    if ( $action !== Editor::ACTION_READ && $_SESSION['loggedin'] == false) {
                        return "Please log in first";
                    } else {
                        return true;
                    }
                } )
    
                ->options( Options::inst()
                    ->table( 'status_labels' )
                    ->value( 'status_labels.status_id' )
                    ->label( 'status_labels.status_label' )
                ),
    
        )
    
        ->leftJoin(
            'mc_revs_language_id',
            'mc_revs_language_id.row_index = main_collection.main_index AND mc_revs_language_id.timestamp = (SELECT MAX(LIZ.timestamp) FROM mc_revs_language_id LIZ WHERE LIZ.row_index = main_collection.main_index)'
        )
        ->leftJoin(
            'mc_revs_level',
            'mc_revs_level.row_index = main_collection.main_index AND mc_revs_level.timestamp = (SELECT MAX(LZ.timestamp) FROM mc_revs_level LZ WHERE LZ.row_index = main_collection.main_index)'
        )
        ->leftJoin(
            'mc_revs_enabled',
            'mc_revs_enabled.row_index = main_collection.main_index AND mc_revs_enabled.timestamp = (SELECT MAX(EZ.timestamp) FROM mc_revs_enabled EZ WHERE EZ.row_index = main_collection.main_index)'
        )
        ->leftJoin(
            'yt_channel_ids',
            'yt_channel_ids.channelId = main_collection.channel'
        )
        ->leftJoin(
            'languages',
            'languages.language_id = mc_revs_language_id.value'
        )
        ->leftJoin(
            'difficulty',
            'difficulty.difficulty_index = mc_revs_level.value'
        )
        ->leftJoin(
            'status_labels',
            'mc_revs_enabled.value = status_labels.status_id'
        )
    
        ->on( 'postEdit', function ( $editor, $id, &$values, &$row ) {
            logChange( $editor->db(), 'insert', $id, $values );
        } )
        
        
        ->write( true )
        ->debug(true, './debug.log')
        ->process( $_POST )
        ->json();
    
  • allanallan Posts: 61,722Questions: 1Answers: 10,108 Site admin
    Answer ✓

    It looks like you've got the parameter named for a global validator on your field validators. It would be worth fixing that I reckon - it confused be a fair bit when looking at it. For example $editor in those functions is actually the value submitted.

    Your validator will run regardless of if the field is submitted or not (to allow for required validators). If $val is null then it was not submitted and in this case you should allow the validation to pass - i.e.:

    ->validator( function ( $val, $action ) {
      // Check if was submitted - if not allow validation to pass - nothing will happen on the field
      if ($val === null) {
        return true;
      }
      ....
    

    Allan

  • globalplaneglobalplane Posts: 70Questions: 12Answers: 0

    Oh, oops, sorry! Well, now I know I can just set a single global validator instead of three field validators and only get one error. Thanks!

Sign In or Register to comment.