Jump to content
Larry Ullman's Book Forums

Antonio Conte

Members
  • Posts

    1084
  • Joined

  • Last visited

  • Days Won

    126

Everything posted by Antonio Conte

  1. It's Swedish tobacco. I know Camel, Lucky Strike and some other brands has started selling swedish snus in the US as well. It's similar to chewing tobacco, but not the same. It's generally considered better health wise, and also a lot better for your mouth. Our tobacco does not require spitting neither. As said, you generally use it under you upper lip instead of the bottom. Read the wiki link if you are interested. Scandinavia is generally very heavy on coffee consumption. We drink in average double the amount of coffee per person to USA as seen here: http://chartsbin.com/view/581 Some of this is probably because of our cold climate. It's easily minus 20-30 degrees Celsius in the winter. (-4 to -22 Fahrenheit)
  2. I think this is because of how date and time objects work. You cannot add a zero to a timestamp and expect it to be the same. From experience in other languages, this must be done by formatting the date instead of changing the datetime itself.
  3. After some thoughts, do I really need the double hashing? I used the site wide hash the last time I wrote a similar class, but I felt the need for unique hashing too. I'm thinking about conflicts here. I have often heard that double hashing, for example md5( md5('password') ), is discouraged, but how does that compare when you use the first hash as salt instead? My code is in practice doing something very similar. // My hashing method $hashed_password = $this->hash( $password, $this->hash($username, HASH_SALT) ); // Double md5 $hashed_password = md5( md5($password) ); Even thought the sha256 is a lot stronger than the md5 algorithm, I kind of feel I might end up weakening the hash instead of strengthening it. My thought is to write a function that will create a new salt based on both the site wide salt and the username. A quick unpolished version from the top of my head to illustrate this: // Create a hash based on salt. $this->hash( $password, $this->create_new_salt( HASH_SALT, $username) ); private function create_new_salt( $salt, $input) { // Get salt length $salt_length = strlen($salt); $input_length = strlen($input); return substring($salt, - (int)($salt_length/4)) . chr($input[0]-3) . chr($input[1]-2). chr($input[2]-1). substring($salt, 0, (int)($salt_length/4)); } Not a very good function yet, but I feel it has potential. By switching some the input from the site salt and username, the salt will be very hard to guess. Notice that I discuss this for the sake of it, not because I think it will be unbreakable. I also know that production code will need something more robust than this... As I said. From the top of my head for the sake of discussion. The point here being that you need the functionality of the black box to verity passwords. How it works it not very important, but the end result will be a harder to guess salt for the hash function. Interested in your thoughts on this. Edit: Random_salt was a bad name for the function. Not random, just a new construct of the old.
  4. I need coffee in the mornings to function properly. I prefer really black and aromatic coffee, and love a strong Espresso. Also use a Swedish tobacco called "Snus" which is excellent with coffee. It's similar to your chewing tobacco, but you place it under you upper lip instead. I also very often want coffee after dinner. http://en.wikipedia.org/wiki/Snus Any smokers here? Sure you can relate to the tobacco and coffee combination.
  5. Ah, sorry then. I'm no expert when it comes to jQuery. As I've never seen that before, I just thought you'd misunderstood something. Sorry.
  6. jQuery is a JavaScript library that is client side. PHP and the $_POST array are server side. jQuery cannot validate the post array, that you'll have to do with PHP. jQuery can grab IDs, classes and elements from a html page, thought. $(#id), $(.class), $(selector)
  7. That's what github said too. It's pushState
  8. Yes. If you are able to spot obvious security flaws, please point them out. I can't really see any though. The method set_user_details(), not shown here, simply assign the db keys to the corresponding session key. It's private and not callable outside the class. Btw: no need to quote my long post. Edit: good idea regarding the email. The usernames are changeable, that's why I went with email. Maybe I'll just keep usernames unchanchable and use those instead. They too are unique, which is some of the point. Good input here. Hoping for more.
  9. Table joins are very easy in Yii by the look of it. A simple google search for 'yii query' gave me this link: http://www.yiiframework.com/doc/guide/1.1/en/database.query-builder You would do something like this: $user = Yii::app()->db->createCommand() ->select('id, username, profile') ->from('tbl_user u') ->join('tbl_profile p', 'u.id = p.user_id') ->join('tbl_another o', 'u.another_id = o.another_id') ->join('tbl_mother m', 'u.mother_id = m.mother_id') ->where('id=:id', array(':id'=>$id)) ->queryRow() Never used Yii, but a simple google search can solve most of your problems.
  10. Hey, everyone Coding a small application with user authentication. Never done this before as I've not been secure enough regarding my abilities to create something secure. Regarding password security: My passwords are saved using double hashing. First, the users's email is hashed with the sha256 algorithm together with a site-wide salt using the function below. I then use the same hashing function to hash the user's password together with the unique salt. That means that password will differ for each user even if they use the same password. Don't mind the functionality of $mysqli->query(), etc. I use my own class. public function login( $email, $password ) { // Get DB connection $mysqli = new Database(); $mysqli->escape($email); $user = $mysqli->query("SELECT * FROM bet_users WHERE email = '$email' LIMIT 1"); // Get user from DB // Make sure we found a user ( An array ) if ( is_array($user) ) { // Get special hash $hash = $this->hash($email, HASH_SALT); // Site wide salt // Check hashed passwords if ( $user['password'] == $this->hash($password, $hash) ) // Hash $password with unique salt { // Prevent session hijack Util::validate_session($email); // Set user details $this->set_user_details($user); // User is logged in return true; } // Wrong password return false; } } private function hash( $input, $salt ) { // Initialize an incremental hashing context $hashed = hash_init('sha256', HASH_HMAC, $salt); // Set active hashing context hash_update($hashed, $input); // Return hashed password return hash_final($hashed); } Regarding login checks: I only add $_SESSION['admin'] to the session array if the queried user has admin status in the DB. My checks looks like this and uses the session hijacking check below. I use these function like Util::is_logged_in() and Util::is_admin(). public static function is_logged_in() { return isset($_SESSION['user_id']) && self::validate_session($_SESSION['email']); } public static function is_admin() { return self::is_logged_in() && isset($_SESSION['admin']) && $_SESSION['admin'] == true; } Here's the function to prevent session hijack: public static function validate_session( $email = null ) { // Set hashed http user agent $agent = md5($_SERVER['HTTP_USER_AGENT'].$email); // Check for instance if ( isset($_SESSION['initiated']) == false || isset($_SESSION['HTTP_USER_AGENT']) == false ) { // Create new id session_regenerate_id(TRUE); $_SESSION = array(); $_SESSION['initiated'] = true; // Set hashed http user agent $_SESSION['HTTP_USER_AGENT'] = $agent; } if ( isset($_SESSION['initiated']) && isset($_SESSION['HTTP_USER_AGENT']) ) { // Validate the agent and initiated if ( ($_SESSION['HTTP_USER_AGENT'] == $agent) && $_SESSION['initiated'] ) { return true; } else { // Destroy session session_destroy(); return false; } } return false; } How would you say the security is here? Is the security good? Any improvements I can make? Thanks for any answers.
  11. Yes, you do need to perform multiple inserts and a JOIN query here. If each salt is unique, you need to insert it into a salt table with the user_id/email/something unique as the foreign key. INSERT INTO salt ( user_id, salt ) Values(1, 'unique-salt-for-user-id-1'); INSERT INTO user ( user_id, card_number) VALUES ( 1, AES_ENCRYPT('the_card_number', 'unique-salt-for-user-id-1') ); When you need the salt again, you need to select the salt too: SELECT user.user_id , AES_DECRYPT(user.card_number, salt.salt) as card_number FROM user as user INNER JOIN salt as salt ON ( user.user_id = salt.user_id) LIMIT 1 That's the general idea.
  12. Lot of logic here to display tables. This is not tabular data, and it's really making your script more difficult to understand than needed. Use divs and format them with CSS instead. Now back to your issue: I would build a multidimensional session array along the pages that map subjects to categories. This is an illustration in pseudo code. $_SESSION['category_table_key'] = array( "subject_table_key" => array(), // Array is all info from DB query ( aka the row = mysqli_fetch_array() call) "subject_table_key" => array(), "subject_table_key" => array(), ); This is a (probably) working second page. You need to add output and such, but session array should be built correctly. if ( isset($_POST['submitted1']) && isset($_POST['category']) && count( $_POST['category']) == 3 ) { // Start building main query $start = "SELECT category_subject.category_id, category_subject.subject_id, subjects FROM category_subject INNER JOIN category ON category_subject.category_id = category.category_id INNER JOIN subject ON category_subject.subject_id = subject.subject_id WHERE "; // We will join where clause later // Build where clause array used in query foreach ( $_POST['category'] as $key => $value ) { $subject_category[] = "category_subject.category_id = {$key}"; } // Create where clause for all selected subjects (Notice implode with OR. Will give us all subjects for selected categories) $where = implode(" OR ", $subject_category); // Concatenate final query $query = $start.$where; // Run query $result = mysqli_query( $dbc, $query ); // Add to session while( $row = mysqli_fetch_array( $result, MYSQLI_ASSOC )) { // Here we have it. Add all subjects to the correct session key ($row['category_id'] $_SESSION[$row['category_id']] = $row; // You can specify output here too... } // Check session array. it will hold all info about courses in selected categories. echo '<pre>' , print_r($_POST), '</pre>'; } Third page is now very simple foreach ( $_POST as $category => $courses) { echo $category.' has these courses:'; foreach ( $courses as $course ) { echo $course.' ': } }
  13. Yeah, it works like a charm! Thanks for your help. You are right, though. I didn't think about the URL change. You are right when you say it's often the ID that changes, but I didn't think about that when I answered the first time around. I wouldn't know how to pull this off, but I think you may be right about the iframe. The div is actually called "frame" if you look at the html. Actually sent an email to github asking how they did it. Hope we get our answer.
  14. Yeah, really hate that too. I prefer Eclipse for PHP. I don't know why, I just do. For Java, I need NetBeans because the debugger is so awesome. You can stop execution at given points and look at what the objects are storing and look at the methods calls. I had this assignment where we should write a validator for Xhtml. Because you need to figure out "the state" of code, a large switch statements who called the next method. We had to do this char-for-char to figure out what kind of tag it was and whether it was valid or not. No way I would've found my bug without NetBeans! Don't know if you can do something like that in PHP, but at least we have print_r() and var_dump().
  15. You are correct. The DB will truncate the left over content, but you should make sure the users know this too.
  16. Looked at the page code now. They are definitely using a JS slider here. You can see they have a wrapper div starting down to the "file / comits / branches" navigation. That wrapper div probably has a large site-width at least double, I would guess three times, the normal page width, but content is hidden with overflow: hidden. Inside that wrapper, they have similar looking divs left aligned to the width of the site. They just then have to make sure the active page is the one aligned correctly inside the wrapper. The divs are probably always laying there empty before a link is clicked. That's why you'll see a nice transition even before the content should be loaded. I would also guess they cache some of the content you have already seen. Just my guess here. This is a pretty common way of doing sliders, but I must agree Github just takes it to the next level!
  17. Very easy to do this in PHP. $length = 150; // Set a length $limited = mb_substr($_POST['name'], 0, $length); // See Post here.
  18. Ever seen a referee write down a match as started 20:45 and 7 seconds? Guess that won't be a problem. Jon: Very good post. I get that feeling too. You just want to go on explaining. Loved your use of date_format()... I did pretty much the same in PHP, but I started to hating the solution pretty fast. That worked seamlessly. In the end, I prefer Paul's solution as I can scratch the splitting. I just used each of the function to create new columns for them: SELECT DATE_FORMAT(games.kickoff_time, '%d:%m:%Y %H:%i') as kickoff, YEAR(games.kickoff_time) as year, MONTH(games.kickoff_time) as month, DAYOFMONTH(games.kickoff_time) as day, HOUR(games.kickoff_time) as hour, MINUTE(games.kickoff_time) as min FROM .... Thanks, guys. Maybe I'll create a new thread for the html generation part.
  19. A little embarrassing, but I must've just read wrong. The exams are coming, so I haven't touch the book in a couple of weeks. Just wanted to see what other people felt about the book as I really like it a lot so far.
  20. Thanks, Paul. That's actually pretty brilliant. The easier, the better, you know.
  21. Great feedback on this book at Amazon. Five stars in all five votes. Not bad. Not bad! How is the sale going, Larry?
  22. That's why I said the array seemed strange. It's just a nasty array. // Get array size $size = count($_SESSION['curtain_basket']); // Keep count $num = 0; // loop that shit for ( $i=0; $i < $size; $i++ ) { $num += (int) $_SESSION['curtain_basket'][$i]['final_curtain_quote']; } Paul: Never mind about the objects yet. They are not so hard to get, but you won't need them yet is what I take for your explanation. Tell me how that code works.
  23. I'm building something cool with JQuery and PHP. I display info and a countdown for the next upcoming football match using some plugin developed in JQuery. You can see it here: http://dev.juvenorge.com/ My timestamps are saved as yyyy-mm-dd hh:mm in the database. I struggle a little bit with transforming that format into a date string the Date object in JavaScript will accept. Any recommendations for me? Btw: I meant to bring this up to: The plugin uses a format called DHMS I don't think I can change. I basically builds the whole markup up the timer, which I just hates. I would've liked the markup to be placed inside the Html markup by PHP, then retrieved and altered by the plugin. Any ideas where to start?
×
×
  • Create New...