daily pastebin goal
11%
SHARE
TWEET

Untitled

a guest Apr 16th, 2018 61 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. require_once('vendor/autoload.php');
  3. use \Firebase\JWT\JWT;
  4.  
  5. date_default_timezone_set('Europe/Copenhagen');
  6.  
  7. class Ssas {
  8.  
  9.     private static $mysqlServer = 'localhost';
  10.     private static $mysqlUser = 'root';
  11.     private static $mysqlPass = 'ssas';
  12.     private static $mysqlDb = 'ssas';
  13.     private static $key = "sUp3r5ecr3t";
  14.     private static $data;
  15.     private static $image_dir = "/var/www/html/uploads/";
  16.  
  17.     function __construct(){
  18.         $link = mysql_connect(self::$mysqlServer, self::$mysqlUser, self::$mysqlPass);
  19.         $db_selected = mysql_select_db(self::$mysqlDb, $link);
  20.     }
  21.  
  22.     // Custom implementaion of MySQL query execution in PHP.
  23.     // Someone mentioned that an "improved" version exists, but this works for now...
  24.     function execute($query_str, $split = false){
  25.         $result;
  26.         if ($split) $query_str = explode(';', $query_str);
  27.         else $query_str = str_split($query_str, strlen($query_str));
  28.         foreach ($query_str as &$query) {
  29.             if($query) $result = mysql_query($query);
  30.         }
  31.         return $result;
  32.     }
  33.  
  34.     // This function will authenticate a user based on the token cookie.
  35.     // returns true if the user is authenticated, otherwise return false
  36.     // if the token is invalid or has expired the method will call exit() and not return anything
  37.     function authenticate(){
  38.         if(isset($_COOKIE['token'])){
  39.             try{
  40.                 //Retrieves the JWT token from the cookie
  41.                 $token = $_COOKIE['token'];
  42.  
  43.                 //Decrypts the token. This call will throw an exception if the token is invalid
  44.                 $token = (array) JWT::decode($token,self::$key,array('HS512'));
  45.  
  46.                 //Extracts the user data from the token
  47.                 self::$data = (array) $token['data'];
  48.  
  49.                 //Check that the user actually exists (could have been removed)
  50.                 $uid = self::getUid();
  51.                 $uname = self::getUsername();
  52.                 if (self::verifyInput($uname)) {
  53.                     $query = "PREPARE stmt1 FROM 'SELECT id FROM user WHERE id = ? AND username = ?';
  54.                     SET @param1 = ".$uid.";
  55.                     SET @param2 = '".$uname."';
  56.                     EXECUTE stmt1 USING @param1, @param2;";
  57.                     $result = self::execute($query, true);
  58.  
  59.                     if (mysql_num_rows($result) > 0) return true;
  60.                 }
  61.                
  62.                 //If the query did not succeed, then there is something wrong!
  63.                 throw new Exception('Authentication failed!');
  64.  
  65.             } catch (Exception $e){
  66.  
  67.                 //This will happend if
  68.                 //  1) The token has expired
  69.                 //  2) The token is not valid
  70.                 //  3) No user matching the user data exists
  71.  
  72.                 self::logout();
  73.                 header("Location: index.php");
  74.                 exit(); //Just to be sure
  75.  
  76.             }
  77.         }
  78.        return false; //Could not authenticate
  79.     }
  80.  
  81.     // This function will destroy the token cookie if it exists
  82.     function logout(){
  83.         if(isset($_COOKIE['token'])){
  84.             unset($_COOKIE['token']);
  85.             setcookie('token', '', time() - 3600);
  86.         }
  87.     }
  88.  
  89.     // This function will check if the user is logged in
  90.     // If the user is not authenticated, the the method will try to authenticate.
  91.     // returns true if the user is logged in otherwise false
  92.     function isUserLoggedIn(){
  93.         if(!isset(self::$data) && isset($_COOKIE['token'])) self::authenticate();
  94.         return isset(self::$data);
  95.     }
  96.  
  97.     // This function will return to logged in users id (if authenticated)
  98.     function &getUid(){
  99.     if(self::isUserLoggedIn()) return self::$data['uid'];
  100.     }
  101.  
  102.     // This function will return to logged in users username (if authenticated)
  103.     function &getUsername(){
  104.     if(self::isUserLoggedIn()) return self::$data['username'];
  105.     }
  106.  
  107.     // This function will create a new user with the given username password combo
  108.     // returns true if the user was created, otherwise error message
  109.     function createUser($username, $password){
  110.         if($username == "") return "username can't be empty";
  111.         if($password == "") return "password can't be empty";
  112.  
  113.         if (!(self::verifyInput($username) && self::verifyInput($password))) {
  114.             // Bad user input, like illegal character/byte
  115.             return "bad character";    
  116.         }
  117.  
  118.         //Inserts username and password into the database
  119.         $query = "PREPARE stmt2 FROM 'INSERT INTO user(username,password) VALUES (?,?)';
  120.         SET @param1 = '".$username."';
  121.         SET @param2 = '".$password."';
  122.         EXECUTE stmt2 USING @param1, @param2;";
  123.         self::execute($query, true);
  124.  
  125.         //If exactly one row was affected then we know that the user was inserted.
  126.         if (mysql_affected_rows() == 1) return true;
  127.         return "user could not be created";
  128.     }
  129.  
  130.     // This function will login with the given username password combo
  131.     // returns true if the login was successful, otherwise error message
  132.     function login($username, $password){
  133.  
  134.         //Query to get the username and real password,
  135.         $query = "PREPARE stmt3 FROM 'SELECT id,password FROM user WHERE username = ?';
  136.         SET @param1 = '".$username."';
  137.         EXECUTE stmt3 USING @param1;";
  138.         $result = self::execute($query,true);
  139.  
  140.         if (mysql_num_rows($result) > 0) {
  141.             $row = mysql_fetch_assoc($result);
  142.             $uid = $row['id'];
  143.             $password_real = $row['password'];
  144.         } else {
  145.             return "username and password does not match";
  146.         }
  147.  
  148.         // If the real password matches the one given, then the login succeeds.
  149.         if(isset($password_real) && ($password === $password_real)){
  150.             //Generates random tokenid
  151.             //TODO Maybe store some of this server side... (Stateful or stateless?)
  152.             $tokenId = base64_encode(mcrypt_create_iv(32,MCRYPT_DEV_URANDOM));
  153.  
  154.             $issuedAt = time(); //time of issue
  155.             $notBefore = $issuedAt; //can be used to say that a token is not valid before a given time (not used)
  156.             $expire = $notBefore + 3600 * 24 * 90; //token expires in 90 days
  157.             $data = [
  158.                 'iat' => $issuedAt,
  159.                 'jti' => $tokenId,
  160.                 'nbf' => $notBefore,
  161.                 'exp' => $expire,
  162.                 'data' => [
  163.                     'uid' => $uid,
  164.                     'username' => $username
  165.                 ]
  166.             ];
  167.  
  168.             //Computes the encrypted token
  169.             $jwt = JWT::encode($data,self::$key,'HS512');
  170.  
  171.             //Sets to cookie to never expire as the token itself contains the expiration date (Mimimum exposure)
  172.             setcookie("token", $jwt, -1);
  173.             return true;
  174.         } else return "username and password does not match";
  175.  
  176.         return "could not login";
  177.     }
  178.  
  179.     // This function uploads the given image
  180.     // returns true if the image was successfully uploaded, otherwise error message.
  181.     function uploadImage($img){
  182.         if(self::isUserLoggedIn()){
  183.             $uid = self::getUid();
  184.             $query = "PREPARE stmt4 FROM 'INSERT INTO image(owner_id) VALUES(?)';
  185.             SET @param1 = ".$uid.";
  186.             EXECUTE stmt4 USING @param1;";
  187.             $result = self::execute($query, true);
  188.             if($result) {
  189.                 $iid = mysql_insert_id();
  190.                 self::save_image($img, $iid);
  191.                 return true;
  192.             }            
  193.             return "Image could not be uploaded";
  194.         }
  195.         return "Image could not be uploaded2";
  196.     }
  197.  
  198.     // This function will lookup a users id given the username
  199.     // returns the user id if exists, otherwise false
  200.     private function getUserId($username){
  201.  
  202.         $query = "PREPARE stmt5 FROM 'SELECT id FROM user WHERE username = ?';
  203.         SET @param1 = '".$username."';
  204.         EXECUTE stmt5 USING @param1;";
  205.         $result = self::execute($query, true);
  206.         if (mysql_num_rows($result) > 0) {
  207.             $row = mysql_fetch_assoc($result);
  208.             return $row['id'];
  209.         }
  210.         return false;
  211.     }
  212.  
  213.     // This function will remove sharing with the given user for the given image
  214.     // returns true if the operation was successful, otherwise false
  215.     function removeShare($iid, $username){
  216.  
  217.         if(self::isUserLoggedIn() && self::isOwner($iid)){
  218.             $uid = self::getUserId($username);
  219.             if($uid == false) return false;
  220.  
  221.             //Removing sharing of image from database
  222.             $query = "PREPARE stmt 6 FROM 'DELETE FROM shared_image WHERE image_id = ? AND user_id = ?';
  223.             SET @param1 = ".$iid.";
  224.             SET @param2 = ".$uid.";
  225.             EXECUTE stmt6 USING @param1,@param2;";
  226.             self::execute($query, true);
  227.  
  228.             return mysql_affected_rows() == 1;
  229.         }
  230.         return false;
  231.     }
  232.  
  233.     // This function will share the given image with the given user
  234.     // returns true if the image was shared, otherwise false
  235.     function shareImage($iid, $username)
  236.     {
  237.         //The user must be owner of the image to share it
  238.         if(self::isUserLoggedIn() && self::isOwner($iid)){
  239.  
  240.             //Getting uid from username
  241.             $uid = self::getUserId($username);
  242.  
  243.             //Inserting sharing of image into database
  244.             $query = "PREPARE stmt7 FROM 'INSERT INTO shared_image VALUES (?,?)';
  245.             SET @param1 = ".$uid.";
  246.             SET @param2 = ".$iid.";
  247.             EXECUTE stmt7 USING @param1,@param2;";
  248.             self::execute($query, true);
  249.  
  250.             return mysql_affected_rows() == 1;
  251.         }
  252.         return false;
  253.     }
  254.  
  255.     // This function returns a list of users whom the given image can be shared with
  256.     // returns a list of users if successful, otherwise false
  257.     function getUsersToShareWith($iid){
  258.         if(self::isUserLoggedIn()){//&& self::isOwner($iid)){
  259.             $users = array();
  260.  
  261.             // Query database for users to share with, which is everyone but the owner
  262.             // and those whom the image is already shared with.
  263.             $uid = self::getUid();
  264.             $query = "PREPARE stmt8 FROM 'SELECT id,username FROM user WHERE id <> ? AND id NOT IN (SELECT user_id FROM shared_image WHERE image_id = ?)';
  265.             SET @param1 = ".$uid.";
  266.             SET @param2 = ".$iid.";
  267.             EXECUTE stmt8 USING @param1,@param2;";
  268.             $result = self::execute($query,true);
  269.  
  270.             if (mysql_num_rows($result) > 0) {
  271.                 while ($row = mysql_fetch_assoc($result)) {
  272.                     $users[] = new user($row['id'], $row['username']);
  273.                 }
  274.             } else {
  275.                 return "No users to share this with.";
  276.             }          
  277.  
  278.             return $users;
  279.         }
  280.         return false;
  281.     }
  282.  
  283.     // This function returns a list of users whom the given image is shared with.
  284.     // returns a list of users if successful, otherwise false
  285.     function sharedWith($iid){
  286.         if(self::isUserLoggedIn()) {
  287.             $users = array();
  288.            
  289.             $query = "PREPARE stmt9 FROM 'SELECT id,username FROM user INNER JOIN shared_image ON id = user_id WHERE image_id = ?';
  290.             SET @param1 = ".$iid.";
  291.             EXECUTE stmt9 USING @param1;";
  292.             $result = self::execute($query,true);
  293.  
  294.             if (mysql_num_rows($result) > 0) {
  295.                 while ($row = mysql_fetch_assoc($result)) {
  296.                     $users[] = new user($row['id'], $row['username']);
  297.                 }
  298.             }
  299.  
  300.             return $users;
  301.         }
  302.         return false;
  303.     }
  304.  
  305.     // This function saves the image to a file with the corresponding image id as the name.
  306.     // TODO: Find out how to handle the file permissions.
  307.     function save_image($img, $iid){
  308.         $data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $img));
  309.         $file = self::$image_dir.$iid;
  310.         file_put_contents($file, $data);
  311.         chmod($file, 0777); // This works for now, but probably isn't necessary... right?
  312.     }
  313.  
  314.     // This function loads the image file with the corresponding image id.
  315.     // TODO: Find out how to handle the file permissions.
  316.     function loadImage($iid){
  317.         $file = self::$image_dir.$iid;
  318.         $type = pathinfo($file, PATHINFO_EXTENSION);   
  319.         $data = file_get_contents($file);
  320.         $img = 'data:image/' . $type . ';base64,' . base64_encode($data);      
  321.         return $img;
  322.     }
  323.  
  324.     // This function returns a list of all images shared with the loggedin user
  325.     // returns a list of images if successful, otherwise false
  326.     function getImages(){
  327.         if(self::isUserLoggedIn()){
  328.             $images = array();
  329.            
  330.             // The images to display should either be those owned by the user
  331.             // or those ahred with the user and should not be duplicated.
  332.             $uid = self::getUid();
  333.             $query = "PREPARE stmt10 FROM 'SELECT DISTINCT image.id,owner_id,username,createdDate FROM image INNER JOIN user on user.id = owner_id LEFT JOIN shared_image ON image_id = image.id WHERE user_id = ? OR owner_id = ? ORDER BY createdDate DESC';
  334.             SET @param1 = ".$uid.";
  335.             SET @param2 = ".$uid.";
  336.             EXECUTE stmt10 USING @param1,@param2;";
  337.             $result = self::execute($query,true);
  338.  
  339.             if (mysql_num_rows($result) > 0) {
  340.                 while ($row = mysql_fetch_assoc($result)) {
  341.                     $iid = $row['id'];
  342.                     $img = self::loadImage($iid);
  343.                     $images[] = new Image($iid, $row['owner_id'], $row['username'], $img, $row['createdDate']);
  344.                 }
  345.             }
  346.  
  347.             return $images;
  348.         }
  349.         return false;
  350.     }
  351.  
  352.     // This function returns the given image iff the loggedin user have access to it
  353.     // returns the image if successful, otherwise false
  354.     function getImage($iid)
  355.     {
  356.         if(self::isUserLoggedIn())
  357.         {
  358.             $uid = self::getUid();
  359.             $query = "PREPARE stmt11 FROM 'SELECT image.id,owner_id,username,createdDate FROM image INNER JOIN user ON user.id = owner_id LEFT JOIN shared_image ON image_id = image.id WHERE (user_id = ? OR owner_id = ?) AND image.id = ?';
  360.             SET @param1 = ".$uid.";
  361.             SET @param2 = ".$uid.";
  362.             SET @param3 = ".$iid.";
  363.             EXECUTE stmt11 USING @param1,@param2,@param3;";
  364.             $result = self::execute($query, true);
  365.            
  366.             if (mysql_num_rows($result) > 0) {
  367.                 $row = mysql_fetch_assoc($result);
  368.            
  369.                 $img = self::loadImage($iid);
  370.                 return new Image($iid, $row['owner_id'], $row['username'], $img, $row['createdDate']);
  371.             }
  372.             return null;
  373.         }
  374.  
  375.         return false;
  376.     }
  377.  
  378.     // This function will post given comment to given image iff the loggedin user has access to post
  379.     // returns true if successful, otherwise false
  380.     function comment($iid, $comment)
  381.     {
  382.         if(self::isUserLoggedIn() && self::verifyShare(self::getUid(), $iid))
  383.         {
  384.             $uid = self::getUid();
  385.             $query = "PREPARE stmt12 FROM 'INSERT INTO post(text, user_id, image_id) VALUES (?,?,?)';
  386.             SET @param1 = '".$comment."';
  387.             SET @param2 = ".$uid.";
  388.             SET @param3 = ".$iid.";
  389.             EXECUTE stmt12 USING @param1,@param2,@param3;";
  390.             $result = self::execute($query,true);
  391.             return mysql_affected_rows() == 1;
  392.         }
  393.         return false;
  394.     }
  395.  
  396.     // This function gets all comments for the given image
  397.     // returns a list of comments if successful, otherwise false
  398.     function getComments($iid)
  399.     {
  400.         if(self::isUserLoggedIn() && self::verifyShare(self::getUid(), $iid))
  401.         {          
  402.             $comments = array();
  403.  
  404.             $query = "PREPARE stmt13 FROM 'SELECT post.id,username,text,createdDate FROM post INNER JOIN user ON user_id = user.id WHERE image_id = ? ORDER BY createdDate ASC';
  405.             SET @param1 = ".$iid.";
  406.             EXECUTE stmt13 USING @param1;";
  407.             $result = self::execute($query,true);
  408.  
  409.             if (mysql_num_rows($result) > 0) {
  410.                 while ($row = mysql_fetch_assoc($result)) {
  411.                     // Only include verified comments
  412.                     $text = $row['text'];
  413.                     if ((self::verifyInput($text))) {
  414.                         $comments[] = new Comment($row['id'], $row['username'], $text, $row['createdDate']);
  415.                     }
  416.                 }
  417.             }
  418.  
  419.             return $comments;
  420.         }
  421.         return false;
  422.     }
  423.  
  424.     // This function checks if the loggedin user is owner of the given image
  425.     // returns true if the loggedin user is owner, otherwise false
  426.     function isOwner($iid){
  427.         $uid = self::getUid();
  428.         $query = "PREPARE stmt14 FROM 'SELECT id FROM image WHERE owner_id = ? AND id = ?';
  429.         SET @param1 = ".$uid.";
  430.         SET @param2 = ".$iid.";
  431.         EXECUTE stmt14 USING @param1,@param2;";
  432.         $result = self::execute($query,true);
  433.         return mysql_num_rows($result) > 0;
  434.     }
  435.  
  436.     // This function will verify whether the given user input is bad.
  437.     // This is to prevent malicious users from sending bad input, e.g. NULL,
  438.     // which would cause the MySQL service to crash.
  439.     // Returns true if no bad input is detected, otherwise false.
  440.     function verifyInput($input) {
  441.         $valid = !(eval('"'.$input.'"===NULL;') || eval('"'.$input.'"==="\0";'));
  442.         return $valid;
  443.     }
  444.  
  445.     // This function checks if the loggedin user is either owner or has access to the given image
  446.     // returns true if the loggedin user has access, otherwise false
  447.     function verifyShare($uid, $iid)
  448.     {
  449.         $query = "PREPARE stmt15 FROM 'SELECT id FROM image LEFT JOIN shared_image ON image_id = id WHERE (user_id = ? OR owner_id = ?) AND id = ?';
  450.         SET @param1 = ".$uid.";
  451.         SET @param2 = ".$uid.";
  452.         SET @param3 = ".$iid.";
  453.         EXECUTE stmt15 USING @param1,@param2,@param3;";
  454.         $result = self::execute($query,true);
  455.         return mysql_num_rows($result) > 0;
  456.     }
  457. }
  458.  
  459. class User{
  460.     private $_id;
  461.     private $_name;
  462.  
  463.     public function __construct($id, $name){
  464.         $this -> _id = $id;
  465.         $this -> _name = $name;
  466.     }
  467.  
  468.     public function getName(){ return $this -> _name; }
  469.     public function getId(){ return $this -> _id; }
  470. }
  471.  
  472. // This class is kind of obsolete, but still used.
  473. // Might be used in the future to, like, maybe store images in a database?
  474. class Image{
  475.  
  476.     private $_id;
  477.     private $_ownerId;
  478.     private $_image;
  479.     private $_username;
  480.     private $_datetime;
  481.  
  482.     public function __construct($id, $ownerId, $username, $image, $datetime){
  483.         $this -> _id = $id;
  484.         $this -> _ownerId = $ownerId;
  485.         $this -> _image = $image;
  486.         $this -> _username = $username;
  487.         $this -> _datetime = new DateTime($datetime);
  488.     }
  489.  
  490.     public function getId() { return $this -> _id; }
  491.     public function getOwnerId() { return $this -> _ownerId; }
  492.     public function getUser() { return $this -> _username; }
  493.     public function getImage() { return $this -> _image; }
  494.     public function getAge() {
  495.         $date = $this -> _datetime;
  496.         $currentDate = new DateTime();
  497.         $dateDiff = $date -> diff($currentDate);
  498.         $years = $dateDiff -> y;
  499.         $months = $dateDiff -> m;
  500.         $days = $dateDiff -> d;
  501.         $hours = $dateDiff -> h;
  502.         $minutes = $dateDiff -> i;
  503.         $seconds = $dateDiff -> s;
  504.  
  505.  
  506.         if($years > 1) return $years .' years';
  507.         if($years > 0) return $years .' year';
  508.         if($months > 1) return $months .' months';
  509.         if($months > 0) return $months .' month';
  510.         if($days > 1) return $days .' days';
  511.         if($days > 0) return $days .' day';
  512.         if($hours > 1) return $hours .' hours';
  513.         if($hours > 0) return $hours .' hour';
  514.         if($minutes > 1) return $minutes .' minutes';
  515.         if($minutes > 0) return $minutes .' minute';
  516.         if($seconds > 1) return $seconds .' seconds';
  517.         if($seconds >= 0) return $seconds .' second';
  518.         return "Error!";
  519.     }
  520. }
  521.  
  522. class Comment{
  523.     private $_id;
  524.     private $_userName;
  525.     private $_text;
  526.     private $_datetime;
  527.  
  528.     public function __construct($id, $userName, $text, $datetime){
  529.         $this -> _id = $id;
  530.         $this -> _userName = $userName;
  531.         $this -> _text = $text;
  532.         $this -> _datetime = new DateTime($datetime);
  533.     }
  534.  
  535.     public function getId() { return $this -> _id; }
  536.     public function getUser() { return $this -> _userName; }
  537.     public function getText() { return $this -> _text; }
  538.     public function getAge() {
  539.         $date = $this -> _datetime;
  540.         $currentDate = new DateTime();
  541.         $dateDiff = $date -> diff($currentDate);
  542.         $years = $dateDiff -> y;
  543.         $months = $dateDiff -> m;
  544.         $days = $dateDiff -> d;
  545.         $hours = $dateDiff -> h;
  546.         $minutes = $dateDiff -> i;
  547.         $seconds = $dateDiff -> s;
  548.  
  549.  
  550.         if($years > 1) return $years .' years';
  551.         if($years > 0) return $years .' year';
  552.         if($months > 1) return $months .' months';
  553.         if($months > 0) return $months .' month';
  554.         if($days > 1) return $days .' days';
  555.         if($days > 0) return $days .' day';
  556.         if($hours > 1) return $hours .' hours';
  557.         if($hours > 0) return $hours .' hour';
  558.         if($minutes > 1) return $minutes .' minutes';
  559.         if($minutes > 0) return $minutes .' minute';
  560.         if($seconds > 1) return $seconds .' seconds';
  561.         if($seconds >= 0) return $seconds .' second';
  562.         return "Error!";
  563.     }
  564. }
  565. ?>
RAW Paste Data
Top