From e89676d6ee1a5230c2fd2fce676a9668bb9f3dff Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Mon, 6 Apr 2015 18:48:52 +0200 Subject: [PATCH] Prevent download of deleted albums/photos, added code documentation, fixed error when logged out and opening a private photo --- php/access/Guest.php | 13 +++-- php/modules/Album.php | 23 ++++++++- php/modules/Photo.php | 112 ++++++++++++++++++++++++++++++++++++++---- src/scripts/photo.js | 13 +++-- 4 files changed, 143 insertions(+), 18 deletions(-) diff --git a/php/access/Guest.php b/php/access/Guest.php index e90587c..cbb06ae 100644 --- a/php/access/Guest.php +++ b/php/access/Guest.php @@ -97,8 +97,11 @@ class Guest extends Access { Module::dependencies(isset($_POST['photoID'], $_POST['albumID'], $_POST['password'])); $photo = new Photo($this->database, $this->plugins, null, $_POST['photoID']); - if ($photo->getPublic($_POST['password'])) echo json_encode($photo->get($_POST['albumID'])); - else echo 'Warning: Wrong password!'; + $pgP = $photo->getPublic($_POST['password']); + + if ($pgP===2) echo json_encode($photo->get($_POST['albumID'])); + else if ($pgP===1) echo 'Warning: Wrong password!'; + else if ($pgP===0) echo 'Warning: Photo private!'; } @@ -155,8 +158,10 @@ class Guest extends Access { Module::dependencies(isset($_GET['photoID'], $_GET['password'])); $photo = new Photo($this->database, $this->plugins, null, $_GET['photoID']); + $pgP = $photo->getPublic($_GET['password']); + # Photo Download - if ($photo->getPublic($_GET['password'])) { + if ($pgP===2) { # Photo Public $photo->getArchive(); @@ -164,7 +169,7 @@ class Guest extends Access { } else { # Photo Private - exit('Warning: Photo private or not downloadable!'); + exit('Warning: Photo private or password incorrect!'); } diff --git a/php/modules/Album.php b/php/modules/Album.php index dc690b0..d59b9c4 100644 --- a/php/modules/Album.php +++ b/php/modules/Album.php @@ -368,11 +368,30 @@ class Album extends Module { $zipTitle = 'Unsorted'; } - # Set title + # Get title from database when album is not a SmartAlbum if ($this->albumIDs!=0&&is_numeric($this->albumIDs)) { + $query = Database::prepare($this->database, "SELECT title FROM ? WHERE id = '?' LIMIT 1", array(LYCHEE_TABLE_ALBUMS, $this->albumIDs)); $album = $this->database->query($query); - $zipTitle = $album->fetch_object()->title; + + # Error in database query + if (!$album) { + Log::error($this->database, __METHOD__, __LINE__, $this->database->error); + return false; + } + + # Fetch object + $album = $album->fetch_object(); + + # Photo not found + if ($album===null) { + Log::error($this->database, __METHOD__, __LINE__, 'Album not found. Cannot start download.'); + return false; + } + + # Set title + $zipTitle = $album->title; + } # Escape title diff --git a/php/modules/Photo.php b/php/modules/Photo.php index c23ad4c..d02d676 100755 --- a/php/modules/Photo.php +++ b/php/modules/Photo.php @@ -571,6 +571,12 @@ class Photo extends Module { public function get($albumID) { + # Functions returns data of a photo + # Excepts the following: + # (string) $albumID = Album which is currently visible to the user + # Returns the following: + # (array) $photo + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -596,9 +602,9 @@ class Photo extends Module { if ($albumID!='false') { - # Show photo as public when parent album is public - # Check if parent album is available and not photo not unsorted - if ($photo['album']!=0) { + # Only show photo as public when parent album is public + # Check if parent album is not 'Unsorted' + if ($photo['album']!=='0') { # Get album $query = Database::prepare($this->database, "SELECT public FROM ? WHERE id = '?' LIMIT 1", array(LYCHEE_TABLE_ALBUMS, $photo['album'])); @@ -606,7 +612,7 @@ class Photo extends Module { $album = $albums->fetch_assoc(); # Parse album - $photo['public'] = ($album['public']=='1' ? '2' : $photo['public']); + $photo['public'] = ($album['public']==='1' ? '2' : $photo['public']); } @@ -624,6 +630,12 @@ class Photo extends Module { public function getInfo($url) { + # Functions returns information and metadata of a photo + # Excepts the following: + # (string) $url = Path to photo-file + # Returns the following: + # (array) $return + # Check dependencies self::dependencies(isset($this->database, $url)); @@ -726,6 +738,11 @@ class Photo extends Module { public function getArchive() { + # Functions starts a download of a photo + # Returns the following: + # (boolean + output) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -737,6 +754,18 @@ class Photo extends Module { $photos = $this->database->query($query); $photo = $photos->fetch_object(); + # Error in database query + if (!$photos) { + Log::error($this->database, __METHOD__, __LINE__, $this->database->error); + return false; + } + + # Photo not found + if ($photo===null) { + Log::error($this->database, __METHOD__, __LINE__, 'Album not found. Cannot start download.'); + return false; + } + # Get extension $extension = getExtension($photo->url); if ($extension===false) { @@ -773,6 +802,13 @@ class Photo extends Module { public function setTitle($title) { + # Functions sets the title of a photo + # Excepts the following: + # (string) $title = Title with a maximum length of 50 chars + # Returns the following: + # (boolean) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -799,6 +835,13 @@ class Photo extends Module { public function setDescription($description) { + # Functions sets the description of a photo + # Excepts the following: + # (string) $description = Description with a maximum length of 1000 chars + # Returns the following: + # (boolean) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -826,6 +869,11 @@ class Photo extends Module { public function setStar() { + # Functions stars a photo + # Returns the following: + # (boolean) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -865,6 +913,12 @@ class Photo extends Module { public function getPublic($password) { + # Functions checks if photo or parent album is public + # Returns the following: + # (int) 0 = Photo private and parent album private + # (int) 1 = Album public, but password incorrect + # (int) 2 = Photo public or album public and password correct + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -877,23 +931,41 @@ class Photo extends Module { $photo = $photos->fetch_object(); # Check if public - if ($photo->public==1) return true; - else { + if ($photo->public==='1') { + + # Photo public + return 2; + + } else { + + # Check if album public $album = new Album($this->database, null, null, $photo->album); - $acP = $album->checkPassword($password); $agP = $album->getPublic(); - if ($acP===true&&$agP===true) return true; + $acP = $album->checkPassword($password); + + # Album public and password correct + if ($agP===true&&$acP===true) return 2; + + # Album public, but password incorrect + if ($agP===true&&$acP===false) return 1; + } # Call plugins $this->plugins(__METHOD__, 1, func_get_args()); - return false; + # Photo private + return 0; } public function setPublic() { + # Functions toggles the public property of a photo + # Returns the following: + # (boolean) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -925,6 +997,11 @@ class Photo extends Module { function setAlbum($albumID) { + # Functions sets the parent album of a photo + # Returns the following: + # (boolean) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -948,6 +1025,13 @@ class Photo extends Module { public function setTags($tags) { + # Functions sets the tags of a photo + # Excepts the following: + # (string) $tags = Comma separated list of tags with a maximum length of 1000 chars + # Returns the following: + # (boolean) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -979,6 +1063,11 @@ class Photo extends Module { public function duplicate() { + # Functions duplicates a photo + # Returns the following: + # (boolean) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); @@ -1017,6 +1106,11 @@ class Photo extends Module { public function delete() { + # Functions deletes a photo with all its data and files + # Returns the following: + # (boolean) true = Success + # (boolean) false = Failure + # Check dependencies self::dependencies(isset($this->database, $this->photoIDs)); diff --git a/src/scripts/photo.js b/src/scripts/photo.js index bad5bf6..69e51b0 100644 --- a/src/scripts/photo.js +++ b/src/scripts/photo.js @@ -35,20 +35,27 @@ photo.load = function(photoID, albumID) { api.post('Photo::get', params, function(data) { + if (data==='Warning: Photo private!') { + lychee.content.show(); + lychee.goto(''); + return false; + } + if (data==='Warning: Wrong password!') { checkPasswd = function() { - if (password.value!=='') photo.load(photoID, albumID); - else setTimeout(checkPasswd, 250); + if (password.value!=='') photo.load(photoID, albumID); + else setTimeout(checkPasswd, 250); }; checkPasswd(); return false; } photo.json = data; + if (!visible.photo()) view.photo.show(); view.photo.init(); - lychee.imageview.show(); + setTimeout(function() { lychee.content.show(); //photo.preloadNext(photoID, albumID);