1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2012
    Posts
    11
    Rep Power
    0
    hey,
    Where cant i download the required files for the forgot password script?
    require("lib/rnum.php");
    require("lib/mail.php");
    require("lib/password.php");
    Thank you.
  2. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    436
    Rep Power
    8
    ok thanks, but Jacques, what program do you use to code this?

    And is it better to get all files in different maps or is it just that you can see the structure?

    But then I think I will post a new thread...
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Originally Posted by derplumo
    ok thanks, but Jacques, what program do you use to code this?
    For quickly writing a code snippet like this, I use Notepad++. For actual projects, I use Netbeans.



    Originally Posted by derplumo
    And is it better to get all files in different maps or is it just that you can see the structure?
    What do you mean by "map"?



    Originally Posted by derplumo
    But then I think I will post a new thread...
    Yeah.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  4. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    1
    Rep Power
    0
    Is there a reason why the emails are not hashed?

    I'm guessing that it's for the purpose of sending an email for a forgotten password request?

    Any vulnerabilities if one chooses to design the registration/login such that emails are used for usernames instead? (and therefore no actual usernames)
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    436
    Rep Power
    8
    Originally Posted by Jacques1
    What do you mean by "map"?
    the directory in which the files are stored, like:



    and I updated my forgot_password with point 2 of the previous page at line 131 to 238 (or what stands there), is this good or do I have to adapt more to make it like it should?

    What do I have to do with the $valid_token?
    Last edited by derplumo; May 18th, 2013 at 02:20 PM.
  6. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    436
    Rep Power
    8
    ok this is what I have now, but I have a question about line 126 and 141, why "$address_unsub_data_stmt" and not "$unsub_data_stmt"?

    and what is done at 141?

    forgot_password.php:
    PHP Code:
    <?php 

       
        
    require("common.php"); 
        require(
    "lib/rnum.php");
        require(
    "lib/mail.php");
        require(
    "lib/password.php"); 

    if(!empty(
    $_POST)) 

     if(
    filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) 
     {    
    $hash hash('sha256'$_POST['email']);
    $time = new DateTime('24 hours ago'); 
    $time_formatted $time->format('Y-m-d H:i:s'); 

    $count_stmt $db->prepare('  
    SELECT COUNT(*)  as count
    FROM sent_emails
    WHERE email_address = :email_address AND timestamp >= :time 
    '
    ); 
     
    $count_stmt->execute(array(  
            
    ':email_address' => $hash
            
    ':time' => $time_formatted  
        
    ));  

    $times $count_stmt->fetch(); 
         
    $email $_POST['email'];
        
    $user_stmt $db->prepare(
            SELECT 
                id 
            FROM 
                users 
            WHERE 
                email = :email 
        '
    ); 
        
    $user_stmt->execute(array( 
            
    ':email' => $_POST['email'
        )); 
        
    $user_id $user_stmt->fetchColumn(); 
        if(
    $user_id)
        {       
            if(
    $times['count'] < 10)
            {
                
    $deactivation_stmt $db->prepare(
                UPDATE 
                responses 
                SET 
                active = 0 
                WHERE 
                user = :user 
                '
    ); 
                
    $deactivation_stmt->execute(array( 
                
    ':user' => $user_id 
                
    )); 
                    
                
    $password_token rnum();
     
                 
    $query 
                INSERT INTO responses ( 
                reset_key,
                user,
                secret,
                request_timestamp,
                request_ip
                ) VALUES ( 
                :reset_key,
                :user,
                :secret,
                NOW(),
                :request_ip
                )"
    ;
     
                
    $secret password_hash($password_tokenPASSWORD_BCRYPT, array("cost" => 10));  
                
    $reset_key rnum();
                
    $user $user_id['id'];
                
    $request_ip getenv('REMOTE_ADDR');
        
                
    $query_params = array( 
                
    ':reset_key' => $reset_key,
                
    ':user' => $user,
                
    ':secret' => $secret,
                
    ':request_ip' => $request_ip
                
    ); 
                    
                
    $stmt $db->prepare($query); 
                
    $result $stmt->execute($query_params);                 
            
                
    $send_mail true;

            
                if(
    mail_f ($mail_to$mail_subject$mail_body) == 1)
                {
                    
    $new_stmt $db->prepare('  
                    INSERT INTO sent_emails (
                    email_address,
                    timestamp
                    ) VALUES (
                    :email_address,
                    NOW()
                    )'
    ); 
                     
    $new_stmt->execute(array(  
                    
    ':email_address' => $hash        
                    
    ));       
                }
            }
        }
        else{
            if(
    $times['count'] < 1)
            {            
                
    $email_adress $_POST["email"];  
                
    $hash hash('sha256'$email_adress);
                
                
    $unsub_data_stmt $db->prepare('   
                SELECT  
                unsubscribed 
                , email_key 
                FROM  
                unsubscribed_email_addresses  
                WHERE 
                email_address = :hash 
                '
    ); 
                
    $unsub_data_stmt->execute(array(   
                
    ':hash' => $hash  
                
    ));   
                
    $unsub_data $address_unsub_data_stmt->fetchColumn(); 

                
    $send_mail $valid_token false
                if ( 
    $unsub_data === false 
                { 
                    
    $send_mail true
                    
    $unsub_token rnum(); 
                    
    $unsubscribe_stmt $db->prepare('   
                    INSERT INTO unsubscribed_email_addresses (   
                    email_address 
                    , email_key 
                    ) VALUES (   
                    :email_key 
                    , :email_address  
                    )'
    );   
                    
    $valid_token $unsubscribe_stmt->execute(array( 
                    
    ':email_address' => $email_hash 
                    
    ,':email_key' => $unsub_token 
                    
    )); 
                } 
                elseif ( !
    $unsub_data['unsubscribed'] ) 
                { 
                    
    $send_mail $valid_token true
                    
    $unsub_token $unsub_data['email_key']; 
                } 
                if ( 
    $send_mail 
                { 
                    
    $url 'http://www.yourdomain.com/response_forgot_password.php?reset_key=';
                    
    $url .= $reset_key;
                    
    $url .= '&user=';
                    
    $url .= $user;
                    
    $url .= '&password_token=';
                    
    $url .= $password_token;
                    
    $url_2 'http://www.yourdomain/unsubscribe.php?email_key=';
                    
    $url_2 .= $unsub_token;
                    
    $url_2 .= '&email_address=';
                    
    $url_2 .= $email_hash;
                    
                    
    $mail_to      $email;
                    
    $mail_subject 'Forgot password';
                    
    $mail_body 'Click this link to reset your password:<br><br>';
                    
    $mail_body .= $url "<br><br><br>If you haven't asked for this mail, and don't want to receave please click this link:<br><br>" $url_2;
            
                    if( 
    mail_f($email_adress$mail_subject$mail_body) )  
                    {  
                        
    $sent_stmt $db->prepare('    
                        INSERT INTO sent_emails ( 
                        email_address,  
                        , timestamp  
                        ) VALUES (  
                        :email_address 
                        , NOW()  
                        )'
    );   
                        
    $sent_stmt->execute(array(    
                        
    ':email_address' => $hash          
                        
    )); 
                    } 
                }
            }
        }
     }
     echo 
    "Unless your limit has been reached, we'll send you an email";            
    }
    ?> <html>
    <body>                                       
    <form action="forgot_password.php" method="post"> 
        Email:
        <input type="text" name="email" value="" /> 
        <br /><br /> 
        <input type="submit" value="Login" /> 
    </form> 
    </body>
    </html>
  7. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Originally Posted by devver
    Is there a reason why the emails are not hashed?

    I'm guessing that it's for the purpose of sending an email for a forgotten password request?
    Yes. If you don't plan to send emails to your users, you don't need the addresses at all.



    Originally Posted by devver
    Any vulnerabilities if one chooses to design the registration/login such that emails are used for usernames instead? (and therefore no actual usernames)
    Using email addresses instead of user names is more secure and increases usability. Unlike user names, email addresses aren't public (or shouldn't be), so it's more difficult to find accounts to attack. The users also won't forget their email addresses, but they might forget an arbitrarily chosen name.

    However, email addresses are problematic with regard to privacy, because there's a huge risk of exposing their existence in one way or another. Either through error messages ("This address is not registered") or through subtle weaknesses. For example, most systems show a huge time difference when processing a valid email address vs. processing an invalid one. That's because login attempts with an invalid address are usually rejected very early, whereas valid ones require hashing the password, which is an expensive operation. By measuring the exact time, an attacker can determine whether someone is registered on a website or not. If you don't take care of that, this will violate your users' privacy.

    So websites with highly sensitive information (like a medical forum) shouldn't use email addresses for authentication -- and they should tell their members to use a disposeable address exclusively for this site.



    Originally Posted by derplumo
    the directory in which the files are stored, like:
    I've never heard the term "map" in this context. Anyway, the directory structure mainly depends on your own preferences. Choose a structure you find easy to understand. Usually, you have a main directory for the public PHP scripts and several subfolders for scripts you wanna include (libraries, function collections, configuration files etc.)

    As to the code:

    Something is wrong with your editor/IDE, because all code you edit ends up with a totally messed up indentation.

    I also don't understand why you removed all comments. The "#" comments were only for internal use, but the "//" explain what happens. I put them there for a reason.

    The email logic is broken now. Not sure why you put the message for the registered users into the "else" part for the unregistered visitors. Those are two completely different procedures, which never run together. Either you are registered, or you're not registered.

    Take a deep breath, get clear about the general logic and then only replace line 131 to 238 in your previous code. The refactoring only applies to the code for unregistered users. It basically replaces this:
    Code:
    if ($A)
    {
    	// do something
    	// do X
    	// do Y
    	// do Z
    }
    elseif ($B)
    {
    	// do something else
    	// do X
    	// do Y
    	// do Z
    }
    with this:
    Code:
    if ($A)
    {
    	// do something
    }
    elseif ($B)
    {
    	// do something else
    }
    
    if ($A || $B)
    {
    	// do X
    	// do Y
    	// do Z
    }
    So you avoid repeating the steps X, Y and Z for each case.

    After that, fix the indentation and the email texts.

    Registered users should get something like this:

    Code:
    Hallo,
    
    you or somebody else requested a password reset for your user account at http://yourdomain.com.
    
    To set a new password, please visit this link:
    
    http://yourdomain.com/password_reset.php?id=123456&secret_code=123456
    
    Do not share the secret code in this link until you've used it. The code will expire in 30 minutes. 
    
    If the request was not from you, simply ignore this email. Your password will _not_ be changed.
    
    Do you have further questions? Please contact us at info@yourdomain.com.
    
    Best regards,
    
    yourdomain.com
    Unregistered users should get something like this:

    Code:
    Hallo,
    
    you or somebody else entered your email address into the password reset form at http://yourdomain.com, but your address is not registered in our system.
    
    If you have an account on our website, you must have used a different email address. Please try again with your other addresses.
    
    If you did not use our form, we apologize for this email. Please ignore it. If you never want to receive the email again, you can mark your address as blocked in our system:
    
    http://yourdomain.com/no_emails.php?address=123456&code=123456
    
    Do you have further questions? Please contact us at info@yourdomain.com.
    
    Best regards,
    
    yourdomain.com
    Write actual emails, don't just send out a link. You don't wanna look like a spammer, so it's important to explain why you even sent this email.



    Originally Posted by derplumo
    ok this is what I have now, but I have a question about line 126 and 141, why "$address_unsub_data_stmt" and not "$unsub_data_stmt"?
    That's an error.



    Originally Posted by derplumo
    and what is done at 141?
    The "unsubscription" key doesn't work unless it's actually stored in the database. So you should check if the INSERT was successful. If it wasn't, simply leave out the part about the unsubscription. You don't want your users to click on a link telling them "Sorry, this key is invalid".
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  8. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    436
    Rep Power
    8
    done, forgot_password.php:

    PHP Code:
    <?php  


    require("common.php");  
    require(
    "lib/rnum.php"); 
    require(
    "lib/mail.php"); 
    require(
    "lib/password.php");  



    if(!empty(
    $_POST))  
    {  
        if(
    filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))  
        {     

            
    $hash hash('sha256'$_POST['email']); 
            
    $time = new DateTime('24 hours ago');  
            
    $time_formatted $time->format('Y-m-d H:i:s');  

            
    $count_stmt $db->prepare('   
                SELECT COUNT(*)  as count 
                FROM sent_emails 
                WHERE email_address = :email_address AND timestamp >= :time  
            '
    );  
            
    $count_stmt->execute(array(   
                
    ':email_address' => $hash,  
                
    ':time' => $time_formatted   
            
    ));   

            
    $times $count_stmt->fetch();  
            
    $email $_POST['email']; 
            
    $user_stmt $db->prepare('  
                SELECT  
                    id  
                FROM  
                    users  
                WHERE  
                    email = :email  
            '
    );  
            
    $user_stmt->execute(array(  
                
    ':email' => $_POST['email']  
            ));  
            
    $user_id $user_stmt->fetchColumn();  
            if(
    $user_id
            {        
                if(
    $times['count'] < 10
                { 
                    
    $deactivation_stmt $db->prepare('  
                    UPDATE  
                    responses  
                    SET  
                    active = 0  
                    WHERE  
                    user = :user  
                    '
    );  
                    
    $deactivation_stmt->execute(array(  
                    
    ':user' => $user_id  
                    
    ));  

                    
    $password_token rnum(); 

                    
    $query "  
                    INSERT INTO responses (  
                    reset_key, 
                    user, 
                    secret, 
                    request_timestamp, 
                    request_ip 
                    ) VALUES (  
                    :reset_key, 
                    :user, 
                    :secret, 
                    NOW(), 
                    :request_ip 
                    )"


                    
    $secret password_hash($password_tokenPASSWORD_BCRYPT, array("cost" => 10));   
                    
    $reset_key rnum(); 
                    
    $user $user_id['id']; 
                    
    $request_ip getenv('REMOTE_ADDR'); 

                    
    $query_params = array(  
                    
    ':reset_key' => $reset_key
                    
    ':user' => $user
                    
    ':secret' => $secret
                    
    ':request_ip' => $request_ip 
                    
    );  

                    
    $stmt $db->prepare($query);  
                    
    $result $stmt->execute($query_params);                  

                    
    $mail_to      $email
                    
    $mail_subject 'Forgot password'
                    
    $mail_body "Hallo,
                    <br><br>
                    you or somebody else entered your email address into the password reset form at http://yourdomain.com, but your address is not registered in our system.
                    <br><br>
                    If you have an account on our website, you must have used a different email address. Please try again with your other addresses.
                    <br><br>
                    If you did not use our form, we apologize for this email. Please ignore it. If you never want to receive the email again, you can mark your address as blocked in our system:
                    <br><br>
                    http://www.yourdomain.com/response_forgot_password.php?reset_key=" 
    $reset_key "&user=" $user "&password_token=" $password_token "
                    <br><br>
                    Do you have further questions? Please contact us at info@yourdomain.com.
                    <br><br>
                    Best regards,
                    <br><br>
                    yourdomain.com"
    ;


                    if(
    mail_f ($mail_to$mail_subject$mail_body) == 1
                    { 
                        
    $new_stmt $db->prepare('   
                        INSERT INTO sent_emails ( 
                        email_address, 
                        timestamp 
                        ) VALUES ( 
                        :email_address, 
                        NOW() 
                        )'
    );  
                        
    $new_stmt->execute(array(   
                        
    ':email_address' => $hash         
                        
    ));        
                    } 
                } 
            } 
            else{ 
                if(
    $times['count'] < 1
                { 
                    
    $email_adress $_POST["email"];   
                    
    $hash hash('sha256'$email_adress); 
                    
    # the following is for an unregistered address that hasn't reached its request limit yet 

                    # you only need one query 
                    
    $unsub_data_stmt $db->prepare('   
                        SELECT  
                            unsubscribed 
                            , email_key 
                        FROM  
                            unsubscribed_email_addresses  
                        WHERE 
                            email_address = :hash 
                    '
    ); 
                    
    $unsub_data_stmt->execute(array(   
                        
    ':hash' => $hash  
                    
    ));   
                    
    $unsub_data $unsub_data_stmt->fetchColumn(); 

                    
    // If we don't have a record of the address yet, or if the address isn't unsubscribed, 
                    // send an email; in case of a new record, generate a new token, otherwise, use the old one; 
                    // $valid_token determines whether the newly generated token has been stored and can actually 
                    // be used; if not, it shouldn't be in the mail 
                    
    $send_mail $valid_token false
                    if ( 
    $unsub_data === false 
                    { 
                        
    $send_mail true
                        
    $unsub_token rnum(); 
                        
    $unsubscribe_stmt $db->prepare('   
                            INSERT INTO unsubscribed_email_addresses (   
                                email_address 
                                , email_key 
                            ) VALUES (   
                                :email_key 
                                , :email_address  
                            )
                        '
    );   
                        
    $valid_token $unsubscribe_stmt->execute(array( 
                            
    ':email_address' => $email_hash 
                            
    ':email_key' => $unsub_token 
                        
    )); 
                    } 
                    elseif ( !
    $unsub_data['unsubscribed'] ) 
                    { 
                        
    $send_mail $valid_token true
                        
    $unsub_token $unsub_data['email_key']; 
                    } 

                    if ( 
    $send_mail 
                    { 
                        
    $email_adress $_POST["email"];
                        
    $mail_subject "Forgot password";
                        
    $mail_body "Hallo,
                                    <br><br>
                                    you or somebody else requested a password reset for your user account at http://yourdomain.com.
                                    <br><br>
                                    To set a new password, please visit this link:
                                    <br><br>
                                    http://www.yourdomain.com/password_reset.php?reset_key=" 
    $reset_key "&user=" $user "&password_token=" $password_token ."
                                    <br><br>
                                    Do not share the secret code in this link until you've used it. The code will expire in 30 minutes. 
                                    <br><br>
                                    If the request was not from you, simply ignore this email. Your password will _not_ be changed.
                                    <br><br>
                                    Do you have further questions? Please contact us at info@yourdomain.com.
                                    <br><br>
                                    Best regards,
                                    <br><br>
                                    yourdomain.com"
    ;

                        
    # put the mail text into an external template; only append the token if $valid_token 
                        
    if( mail_f($email_adress$mail_subject$mail_body) )  
                        {  
                            
    $sent_stmt $db->prepare('    
                                INSERT INTO sent_emails ( 
                                    email_address,  
                                    , timestamp  
                                ) VALUES (  
                                    :email_address 
                                    , NOW()  
                                ) 
                            '
    );   
                            
    $sent_stmt->execute(array(    
                                
    ':email_address' => $hash          
                            
    )); 
                        } 
                    }
                } 
            } 
            echo 
    "Unless your limit has been reached, we'll send you an email";
        } 
        else{ 
            echo 
    "This emailadress is invalid!"
        }                

    ?> <html> 
    <body> 
    <form action="forgot_password.php" method="post">  
    Email: 
    <input type="text" name="email" value="" />  
    <br /><br />  
    <input type="submit" value="Recover" />  
    </form>  
    </body> 
    </html>
    I now used NetBeans, it works great, thanks!

    And I have posted a new thread.
    Last edited by derplumo; May 19th, 2013 at 05:03 PM.
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Looking good so far. You didn't use the $valid_token, but nevermind.

    Test your script extensively and check the whole code again. After that, you should be done.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  10. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    2
    Rep Power
    0
    Originally Posted by Jacques1
    Anyway, I'm currently working on a class to wrap all user related functionalities in convenient methods (register, login, logout etc.). Maybe that would be a good addition to the tutorial.
    Could you share the class wrapper or is this something you haven't gotten to yet?

    Would also be nice to see this adopted into a basic MVC system so beginners can learn about making (arguably) better design choices from the get-go.

    On the topic of security:
    • Is it worth restricting the characters that are allowed for usernames (<,>, etc) so they can't be abused with html tags and being interpreted as code in some view when not sanitized?
    • Saw some mention of this but I agree this tutorial should be updated with the password_hash wrapper (github.com/ircmaxell/password_compat) since it's easy to use and that's where PHP is heading in 5.5 - everyone should be using this.
  11. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Originally Posted by brymaster
    Could you share the class wrapper or is this something you haven't gotten to yet?
    I haven't worked on it lately, but when it's done, I'll post it.



    Originally Posted by brymaster
    Would also be nice to see this adopted into a basic MVC system so beginners can learn about making (arguably) better design choices from the get-go.
    Not sure about that. The more advanced the architecture gets, the harder it is to understand. I mean, every PHP programmer understands plain PHP. But when you start adding a template engine, model classes, controllers etc., you'll lose a lot of people.

    And why invent your own MVC system when we already have dozens of them?



    Originally Posted by brymaster
    Is it worth restricting the characters that are allowed for usernames (<,>, etc) so they can't be abused with html tags and being interpreted as code in some view when not sanitized?
    No. Stripping off HTML tags or "dangerous" characters is the wrong approach -- even though it's extremely popular.

    First of all, what you have to do to make input secure always depends on the context. There is no "global sanitizing". The PHP developers tried it with the infamous "magic quotes", and they failed miserably.

    For example, removing "<", ">" etc. won't help you if the input already is in a JavaScript context (like a script container or an onclick attribute). It won't help you to prevent URL manipulation within a template. It won't help you to prevent SQL injections when inserting the user name into the database etc.

    Secondly, it's kind of stupid to limit the user just because the developers might fail to do their job. A while ago, there was an online banking application, which would not allow you to have SQL keywords like "SELECT", "DROP" etc. in your user data. Would you use that application? I wouldn't.

    So let your users enter any character they want. It's your job to properly escape it for the particular context.

    However, you shouldn't necessarily allow all Unicode characters, because many characters are hard to distinguish and might be abused to "mimic" another member.



    Originally Posted by brymaster
    Saw some mention of this but I agree this tutorial should be updated with the password_hash wrapper (github.com/ircmaxell/password_compat) since it's easy to use and that's where PHP is heading in 5.5 - everyone should be using this.
    Yes. What's even more important: bcrypt is an established and proven algorithm. It has undergone many professional reviews, tests and attacks. The fact that it's still alive means we can be pretty sure it actually works. That doesn't even remotely apply to a home-made algorithm. I mean, you can come up with all kinds of new algorithms, and they may all look totally valid. Problem is: You'll never know if they're actually secure. They could be totally broken due to some stupid mistake or a subtle mathematical issue. None of us knows.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  12. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    2
    Rep Power
    0
    Originally Posted by Jacques1
    I haven't worked on it lately, but when it's done, I'll post it.
    Thanks!

    Originally Posted by Jacques1
    So let your users enter any character they want. It's your job to properly escape it for the particular context.

    However, you shouldn't necessarily allow all Unicode characters, because many characters are hard to distinguish and might be abused to "mimic" another member.
    Great points. Those multi-line "Zalgo" (Unicode subscript and superscript) characters are especially annoying and would make for bad usernames so I can definitely see a case to limit certain sets. Something like that might also make a good addition to the tutorial.
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Location
    America
    Posts
    8
    Rep Power
    0

    Permissions?


    I love this code! I have been going over and over it understanding it the best i can. One thing that I am wondering about though is how would I go about adding a very very basic simple permissions system? Say I only one 3 groups. Me who has access to anything, a news poster has access to the news posting section and a mod who has access to a control panel to a game server. How would i do that? I have an idea but i dont think it would work.
  14. Lord of the Dance
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2003
    Posts
    3,663
    Rep Power
    1958
    Originally Posted by tcordero
    I love this code! I have been going over and over it understanding it the best i can. One thing that I am wondering about though is how would I go about adding a very very basic simple permissions system? Say I only one 3 groups. Me who has access to anything, a news poster has access to the news posting section and a mod who has access to a control panel to a game server. How would i do that? I have an idea but i dont think it would work.
    I suggest you create a new thread were you describe all your ideas and the part you want help with.
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Location
    America
    Posts
    8
    Rep Power
    0
    Originally Posted by MrFujin
    I suggest you create a new thread were you describe all your ideas and the part you want help with.
    Will do =)

IMN logo majestic logo threadwatch logo seochat tools logo