Advertisement
Guest User

Untitled

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