From 1e7fdeff272adc58bff5d5eeb499ab3825a2929d Mon Sep 17 00:00:00 2001 From: lalka2018 <99399973+lalka2016@users.noreply.github.com> Date: Sat, 2 Dec 2023 20:21:16 +0300 Subject: [PATCH] feat: close profile (#978) --- ServiceAPI/Notes.php | 3 + ServiceAPI/Search.php | 2 +- ServiceAPI/Wall.php | 3 + VKAPI/Handlers/Friends.php | 24 ++-- VKAPI/Handlers/Gifts.php | 14 +++ VKAPI/Handlers/Groups.php | 48 ++++++- VKAPI/Handlers/Likes.php | 9 +- VKAPI/Handlers/Newsfeed.php | 3 +- VKAPI/Handlers/Notes.php | 14 ++- VKAPI/Handlers/Photos.php | 119 ++++++------------ VKAPI/Handlers/Status.php | 4 + VKAPI/Handlers/Users.php | 80 ++++++++++-- VKAPI/Handlers/Video.php | 12 +- VKAPI/Handlers/Wall.php | 31 ++++- Web/Models/Entities/Album.php | 15 +++ Web/Models/Entities/Club.php | 5 + Web/Models/Entities/Comment.php | 9 ++ Web/Models/Entities/Note.php | 9 ++ Web/Models/Entities/Photo.php | 13 ++ Web/Models/Entities/Poll.php | 11 ++ Web/Models/Entities/Post.php | 9 ++ Web/Models/Entities/Traits/TOwnable.php | 8 +- Web/Models/Entities/User.php | 58 ++++++++- Web/Models/Entities/Video.php | 14 +++ Web/Models/Repositories/Users.php | 3 + Web/Presenters/CommentPresenter.php | 4 + Web/Presenters/GiftsPresenter.php | 11 +- Web/Presenters/NotesPresenter.php | 2 + Web/Presenters/PhotosPresenter.php | 6 +- Web/Presenters/SearchPresenter.php | 1 + Web/Presenters/UserPresenter.php | 10 +- Web/Presenters/VideosPresenter.php | 5 +- Web/Presenters/WallPresenter.php | 24 ++-- Web/Presenters/templates/Search/Index.xml | 2 +- Web/Presenters/templates/User/Settings.xml | 13 +- Web/Presenters/templates/User/private.xml | 96 ++++++++++++++ .../templates/components/attachment.xml | 5 - Web/static/css/main.css | 5 + install/sqls/000XX-close-profiles.sql | 1 + locales/en.strings | 16 +++ locales/ru.strings | 19 +++ 41 files changed, 598 insertions(+), 142 deletions(-) create mode 100644 Web/Presenters/templates/User/private.xml create mode 100644 install/sqls/000XX-close-profiles.sql diff --git a/ServiceAPI/Notes.php b/ServiceAPI/Notes.php index 456cfaee..ea76267e 100644 --- a/ServiceAPI/Notes.php +++ b/ServiceAPI/Notes.php @@ -25,6 +25,9 @@ class Notes implements Handler assert($noteOwner instanceof User); if(!$noteOwner->getPrivacyPermission("notes.read", $this->user)) $reject(160, "You don't have permission to access this note"); + + if(!$note->canBeViewedBy($this->user)) + $reject(15, "Access to note denied"); $resolve([ "title" => $note->getName(), diff --git a/ServiceAPI/Search.php b/ServiceAPI/Search.php index 46def4f4..de0f9d2c 100644 --- a/ServiceAPI/Search.php +++ b/ServiceAPI/Search.php @@ -46,7 +46,7 @@ class Search implements Handler break; } - $res = $repo->find($query, ["doNotSearchMe" => $this->user->getId()], $sort); + $res = $repo->find($query, ["doNotSearchMe" => $this->user->getId(), "doNotSearchPrivate" => true,], $sort); $results = array_slice(iterator_to_array($res), 0, 5); diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index d01922b8..c7a8362c 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -27,6 +27,9 @@ class Wall implements Handler if($post->getSuggestionType() != 0) $reject(25, "Can't get suggested post"); + if(!$post->canBeViewedBy($this->user)) + $reject(12, "Access denied"); + $res = (object) []; $res->id = $post->getId(); $res->wall = $post->getTargetWall(); diff --git a/VKAPI/Handlers/Friends.php b/VKAPI/Handlers/Friends.php index 59cf5679..56af8d11 100644 --- a/VKAPI/Handlers/Friends.php +++ b/VKAPI/Handlers/Friends.php @@ -13,19 +13,23 @@ final class Friends extends VKAPIRequestHandler $users = new UsersRepo; $this->requireUser(); - - if ($user_id == 0) { + + if ($user_id == 0) { $user_id = $this->getUser()->getId(); } - - if (is_null($users->get($user_id))) { - $this->fail(100, "One of the parameters specified was missing or invalid"); - } + + $user = $users->get($user_id); - foreach($users->get($user_id)->getFriends($offset, $count) as $friend) { - $friends[$i] = $friend->getId(); - $i++; - } + if(!$user || $user->isDeleted()) + $this->fail(100, "Invalid user"); + + if(!$user->getPrivacyPermission("friends.read", $this->getUser())) + $this->fail(15, "Access denied: this user chose to hide his friends."); + + foreach($user->getFriends($offset, $count) as $friend) { + $friends[$i] = $friend->getId(); + $i++; + } $response = $friends; diff --git a/VKAPI/Handlers/Gifts.php b/VKAPI/Handlers/Gifts.php index 2702924d..dd6fa07a 100644 --- a/VKAPI/Handlers/Gifts.php +++ b/VKAPI/Handlers/Gifts.php @@ -19,6 +19,17 @@ final class Gifts extends VKAPIRequestHandler if(!$user || $user->isDeleted()) $this->fail(177, "Invalid user"); + if(!$user->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + + /* + if(!$user->getPrivacyPermission('gifts.read', $this->getUser())) + $this->fail(15, "Access denied: this user chose to hide his gifts");*/ + + + if(!$user->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + $gift_item = []; $userGifts = array_slice(iterator_to_array($user->getGifts(1, $count, false)), $offset); @@ -62,6 +73,9 @@ final class Gifts extends VKAPIRequestHandler if(!$user || $user->isDeleted()) $this->fail(177, "Invalid user"); + if(!$user->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + $gift = (new GiftsRepo)->get($gift_id); if(!$gift) diff --git a/VKAPI/Handlers/Groups.php b/VKAPI/Handlers/Groups.php index 5dc47316..ffa4fedd 100644 --- a/VKAPI/Handlers/Groups.php +++ b/VKAPI/Handlers/Groups.php @@ -19,9 +19,12 @@ final class Groups extends VKAPIRequestHandler $users = new UsersRepo; $user = $users->get($user_id); - if(is_null($user)) + if(is_null($user) || $user->isDeleted()) $this->fail(15, "Access denied"); + if(!$user->getPrivacyPermission('groups.read', $this->getUser())) + $this->fail(15, "Access denied: this user chose to hide his groups."); + foreach($user->getClubs($offset, $filter == "admin", $count, true) as $club) $clbs[] = $club; @@ -400,9 +403,15 @@ final class Groups extends VKAPIRequestHandler ]; foreach($filds as $fild) { + $canView = $member->canBeViewedBy($this->getUser()); switch($fild) { case "bdate": - $arr->items[$i]->bdate = $member->getBirthday()->format('%e.%m.%Y'); + if(!$canView) { + $arr->items[$i]->bdate = "01.01.1970"; + break; + } + + $arr->items[$i]->bdate = $member->getBirthday() ? $member->getBirthday()->format('%e.%m.%Y') : NULL; break; case "can_post": $arr->items[$i]->can_post = $club->canBeModifiedBy($member); @@ -423,6 +432,11 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->connections = 1; break; case "contacts": + if(!$canView) { + $arr->items[$i]->contacts = "secret@gmail.com"; + break; + } + $arr->items[$i]->contacts = $member->getContactEmail(); break; case "country": @@ -438,15 +452,30 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->has_mobile = false; break; case "last_seen": + if(!$canView) { + $arr->items[$i]->last_seen = 0; + break; + } + $arr->items[$i]->last_seen = $member->getOnline()->timestamp(); break; case "lists": $arr->items[$i]->lists = ""; break; case "online": + if(!$canView) { + $arr->items[$i]->online = false; + break; + } + $arr->items[$i]->online = $member->isOnline(); break; case "online_mobile": + if(!$canView) { + $arr->items[$i]->online_mobile = false; + break; + } + $arr->items[$i]->online_mobile = $member->getOnlinePlatform() == "android" || $member->getOnlinePlatform() == "iphone" || $member->getOnlinePlatform() == "mobile"; break; case "photo_100": @@ -477,12 +506,27 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->schools = 0; break; case "sex": + if(!$canView) { + $arr->items[$i]->sex = -1; + break; + } + $arr->items[$i]->sex = $member->isFemale() ? 1 : 2; break; case "site": + if(!$canView) { + $arr->items[$i]->site = NULL; + break; + } + $arr->items[$i]->site = $member->getWebsite(); break; case "status": + if(!$canView) { + $arr->items[$i]->status = "r"; + break; + } + $arr->items[$i]->status = $member->getStatus(); break; case "universities": diff --git a/VKAPI/Handlers/Likes.php b/VKAPI/Handlers/Likes.php index fab127f2..8b478a3b 100644 --- a/VKAPI/Handlers/Likes.php +++ b/VKAPI/Handlers/Likes.php @@ -44,7 +44,7 @@ final class Likes extends VKAPIRequestHandler if(is_null($postable) || $postable->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid: object not found"); - if(method_exists($postable, "canBeViewedBy") && !$postable->canBeViewedBy($this->getUser() ?? NULL)) { + if(!$postable->canBeViewedBy($this->getUser() ?? NULL)) { $this->fail(2, "Access to postable denied"); } @@ -89,7 +89,7 @@ final class Likes extends VKAPIRequestHandler if(is_null($postable) || $postable->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid: object not found"); - if(method_exists($postable, "canBeViewedBy") && !$postable->canBeViewedBy($this->getUser() ?? NULL)) { + if(!$postable->canBeViewedBy($this->getUser() ?? NULL)) { $this->fail(2, "Access to postable denied"); } @@ -111,7 +111,7 @@ final class Likes extends VKAPIRequestHandler if(is_null($user) || $user->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid: user not found"); - if(method_exists($user, "canBeViewedBy") && !$user->canBeViewedBy($this->getUser())) { + if(!$user->canBeViewedBy($this->getUser())) { $this->fail(1984, "Access denied: you can't see this user"); } @@ -181,6 +181,9 @@ final class Likes extends VKAPIRequestHandler if(!$object || $object->isDeleted()) $this->fail(56, "Invalid postable"); + if(!$object->canBeViewedBy($this->getUser())) + $this->fail(665, "Access to postable denied"); + $res = (object)[ "count" => $object->getLikesCount(), "items" => [] diff --git a/VKAPI/Handlers/Newsfeed.php b/VKAPI/Handlers/Newsfeed.php index 4833e7be..64ee1862 100644 --- a/VKAPI/Handlers/Newsfeed.php +++ b/VKAPI/Handlers/Newsfeed.php @@ -51,7 +51,8 @@ final class Newsfeed extends VKAPIRequestHandler { $this->requireUser(); - $queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND `posts`.`deleted` = 0 AND `posts`.`suggested` = 0"; + $queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) LEFT JOIN `profiles` ON LEAST(`posts`.`wall`, 0) = 0 AND `profiles`.`id` = ABS(`posts`.`wall`)"; + $queryBase .= "WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND (`profiles`.`profile_type` = 0 OR `profiles`.`first_name` IS NULL) AND `posts`.`deleted` = 0 AND `posts`.`suggested` = 0"; if($this->getUser()->getNsfwTolerance() === User::NSFW_INTOLERANT) $queryBase .= " AND `nsfw` = 0"; diff --git a/VKAPI/Handlers/Notes.php b/VKAPI/Handlers/Notes.php index 9f0e6eab..620877c9 100644 --- a/VKAPI/Handlers/Notes.php +++ b/VKAPI/Handlers/Notes.php @@ -40,6 +40,9 @@ final class Notes extends VKAPIRequestHandler if($note->getOwner()->isDeleted()) $this->fail(403, "Owner is deleted"); + if(!$note->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser())) $this->fail(43, "No access"); @@ -153,7 +156,10 @@ final class Notes extends VKAPIRequestHandler $this->fail(15, "Invalid user"); if(!$user->getPrivacyPermission('notes.read', $this->getUser())) - $this->fail(43, "Access denied: this user chose to hide his notes"); + $this->fail(15, "Access denied: this user chose to hide his notes"); + + if(!$user->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); if(empty($note_ids)) { $notes = array_slice(iterator_to_array((new NotesRepo)->getUserNotes($user, 1, $count + $offset, $sort == 0 ? "ASC" : "DESC")), $offset); @@ -204,6 +210,9 @@ final class Notes extends VKAPIRequestHandler if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser())) $this->fail(40, "Access denied: this user chose to hide his notes"); + if(!$note->canBeViewedBy($this->getUser())) + $this->fail(15, "Access to note denied"); + return $note->toVkApiStruct(); } @@ -224,6 +233,9 @@ final class Notes extends VKAPIRequestHandler if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser())) $this->fail(14, "No access"); + + if(!$note->canBeViewedBy($this->getUser())) + $this->fail(15, "Access to note denied"); $arr = (object) [ "count" => $note->getCommentsCount(), diff --git a/VKAPI/Handlers/Photos.php b/VKAPI/Handlers/Photos.php index bb1a22f0..d06ecde3 100644 --- a/VKAPI/Handlers/Photos.php +++ b/VKAPI/Handlers/Photos.php @@ -304,7 +304,6 @@ final class Photos extends VKAPIRequestHandler if(!$user || $user->isDeleted()) $this->fail(2, "Invalid user"); - if(!$user->getPrivacyPermission('photos.read', $this->getUser())) $this->fail(21, "This user chose to hide his albums."); @@ -363,26 +362,21 @@ final class Photos extends VKAPIRequestHandler $this->requireUser(); $this->willExecuteWriteAction(); - if($user_id == 0 && $group_id == 0 || $user_id > 0 && $group_id > 0) { + if($user_id == 0 && $group_id == 0 || $user_id > 0 && $group_id > 0) $this->fail(21, "Select user_id or group_id"); - } if($user_id > 0) { - $us = (new UsersRepo)->get($user_id); - if(!$us || $us->isDeleted()) { + if(!$us || $us->isDeleted()) $this->fail(21, "Invalid user"); - } - if(!$us->getPrivacyPermission('photos.read', $this->getUser())) { + if(!$us->getPrivacyPermission('photos.read', $this->getUser())) $this->fail(21, "This user chose to hide his albums."); - } return (new Albums)->getUserAlbumsCount($us); } - if($group_id > 0) - { + if($group_id > 0) { $cl = (new Clubs)->get($group_id); if(!$cl) { $this->fail(21, "Invalid club"); @@ -404,17 +398,11 @@ final class Photos extends VKAPIRequestHandler $ph = explode("_", $phota); $photo = (new PhotosRepo)->getByOwnerAndVID((int)$ph[0], (int)$ph[1]); - if(!$photo || $photo->isDeleted()) { + if(!$photo || $photo->isDeleted()) $this->fail(21, "Invalid photo"); - } - if($photo->getOwner()->isDeleted()) { - $this->fail(21, "Owner of this photo is deleted"); - } - - if(!$photo->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { - $this->fail(21, "This user chose to hide his photos."); - } + if(!$photo->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); $res[] = $photo->toVkApiStruct($photo_sizes, $extended); } @@ -434,9 +422,9 @@ final class Photos extends VKAPIRequestHandler if(!$album || $album->isDeleted()) $this->fail(21, "Invalid album"); - - if(!$album->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) - $this->fail(21, "This user chose to hide his albums."); + + if(!$album->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); $photos = array_slice(iterator_to_array($album->getPhotos(1, $count + $offset)), $offset); $res["count"] = sizeof($photos); @@ -458,7 +446,7 @@ final class Photos extends VKAPIRequestHandler $id = explode("_", $photo); $phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]); - if($phot && !$phot->isDeleted()) { + if($phot && !$phot->isDeleted() && $phot->canBeViewedBy($this->getUser())) { $res["items"][] = $phot->toVkApiStruct($photo_sizes, $extended); } } @@ -474,13 +462,11 @@ final class Photos extends VKAPIRequestHandler $album = (new Albums)->get($album_id); - if(!$album || $album->canBeModifiedBy($this->getUser())) { + if(!$album || $album->canBeModifiedBy($this->getUser())) $this->fail(21, "Invalid album"); - } - if($album->isDeleted()) { + if($album->isDeleted()) $this->fail(22, "Album already deleted"); - } $album->delete(); @@ -494,13 +480,11 @@ final class Photos extends VKAPIRequestHandler $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); - if(!$photo) { + if(!$photo) $this->fail(21, "Invalid photo"); - } - if($photo->isDeleted()) { + if($photo->isDeleted()) $this->fail(21, "Photo is deleted"); - } if(!empty($caption)) { $photo->setDescription($caption); @@ -518,17 +502,14 @@ final class Photos extends VKAPIRequestHandler if(empty($photos)) { $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); - if($this->getUser()->getId() !== $photo->getOwner()->getId()) { + if($this->getUser()->getId() !== $photo->getOwner()->getId()) $this->fail(21, "You can't delete another's photo"); - } - if(!$photo) { + if(!$photo) $this->fail(21, "Invalid photo"); - } - if($photo->isDeleted()) { - $this->fail(21, "Photo already deleted"); - } + if($photo->isDeleted()) + $this->fail(21, "Photo is already deleted"); $photo->delete(); } else { @@ -540,17 +521,14 @@ final class Photos extends VKAPIRequestHandler $phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]); - if($this->getUser()->getId() !== $phot->getOwner()->getId()) { + if($this->getUser()->getId() !== $phot->getOwner()->getId()) $this->fail(21, "You can't delete another's photo"); - } - if(!$phot) { + if(!$phot) $this->fail(21, "Invalid photo"); - } - if($phot->isDeleted()) { + if($phot->isDeleted()) $this->fail(21, "Photo already deleted"); - } $phot->delete(); } @@ -570,17 +548,11 @@ final class Photos extends VKAPIRequestHandler $this->willExecuteWriteAction(); $comment = (new CommentsRepo)->get($comment_id); - if(!$comment) { + if(!$comment) $this->fail(21, "Invalid comment"); - } - if(!$comment->canBeModifiedBy($this->getUser())) { - $this->fail(21, "Forbidden"); - } - - if($comment->isDeleted()) { - $this->fail(4, "Comment already deleted"); - } + if(!$comment->canBeModifiedBy($this->getUser())) + $this->fail(21, "Access denied"); $comment->delete(); @@ -592,20 +564,16 @@ final class Photos extends VKAPIRequestHandler $this->requireUser(); $this->willExecuteWriteAction(); - if(empty($message) && empty($attachments)) { + if(empty($message) && empty($attachments)) $this->fail(100, "Required parameter 'message' missing."); - } $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); - if(!$photo->getAlbum()->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { - $this->fail(21, "This user chose to hide his albums."); - } + if(!$photo || $photo->isDeleted()) + $this->fail(180, "Invalid photo"); - if(!$photo) - $this->fail(180, "Photo not found"); - if($photo->isDeleted()) - $this->fail(189, "Photo is deleted"); + if(!$photo->canBeViewedBy($this->getUser())) + $this->fail(15, "Access to photo denied"); $comment = new Comment; $comment->setOwner($this->getUser()->getId()); @@ -666,22 +634,21 @@ final class Photos extends VKAPIRequestHandler $this->requireUser(); $this->willExecuteWriteAction(); - if($owner_id < 0) { + if($owner_id < 0) $this->fail(4, "This method doesn't works with clubs"); - } $user = (new UsersRepo)->get($owner_id); - if(!$user) { + if(!$user) $this->fail(4, "Invalid user"); - } - if(!$user->getPrivacyPermission('photos.read', $this->getUser())) { + if(!$user->getPrivacyPermission('photos.read', $this->getUser())) $this->fail(21, "This user chose to hide his albums."); - } $photos = array_slice(iterator_to_array((new PhotosRepo)->getEveryUserPhoto($user, 1, $count + $offset)), $offset); - $res = []; + $res = [ + "items" => [], + ]; foreach($photos as $photo) { if(!$photo || $photo->isDeleted()) continue; @@ -699,17 +666,11 @@ final class Photos extends VKAPIRequestHandler $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); $comms = array_slice(iterator_to_array($photo->getComments(1, $offset + $count)), $offset); - if(!$photo) { + if(!$photo || $photo->isDeleted()) $this->fail(4, "Invalid photo"); - } - if(!$photo->getAlbum()->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { - $this->fail(21, "This user chose to hide his photos."); - } - - if($photo->isDeleted()) { - $this->fail(4, "Photo is deleted"); - } + if(!$photo->canBeViewedBy($this->getUser())) + $this->fail(21, "Access denied"); $res = [ "count" => sizeof($comms), @@ -727,4 +688,4 @@ final class Photos extends VKAPIRequestHandler return $res; } -} \ No newline at end of file +} diff --git a/VKAPI/Handlers/Status.php b/VKAPI/Handlers/Status.php index a1b104a2..5234a7fc 100644 --- a/VKAPI/Handlers/Status.php +++ b/VKAPI/Handlers/Status.php @@ -16,6 +16,10 @@ final class Status extends VKAPIRequestHandler $this->fail(501, "Group statuses are not implemented"); else { $user = (new UsersRepo)->get($user_id); + + if(!$user || $user->isDeleted() || !$user->canBeViewedBy($this->getUser())) + $this->fail(15, "Invalid user"); + $audioStatus = $user->getCurrentAudioStatus(); if($audioStatus) { return [ diff --git a/VKAPI/Handlers/Users.php b/VKAPI/Handlers/Users.php index 6c31e9be..961d0c5f 100644 --- a/VKAPI/Handlers/Users.php +++ b/VKAPI/Handlers/Users.php @@ -50,13 +50,13 @@ final class Users extends VKAPIRequestHandler "id" => $usr->getId(), "first_name" => $usr->getFirstName(true), "last_name" => $usr->getLastName(true), - "is_closed" => false, - "can_access_closed" => true, + "is_closed" => $usr->isClosed(), + "can_access_closed" => (bool)$usr->canBeViewedBy($this->getUser()), ]; $flds = explode(',', $fields); - - foreach($flds as $field) { + $canView = $usr->canBeViewedBy($this->getUser()); + foreach($flds as $field) { switch($field) { case "verified": $response[$i]->verified = intval($usr->isVerified()); @@ -150,36 +150,91 @@ final class Users extends VKAPIRequestHandler ]; } case "music": + if(!$canView) { + $response[$i]->music = "secret"; + break; + } + $response[$i]->music = $usr->getFavoriteMusic(); break; case "movies": + if(!$canView) { + $response[$i]->movies = "secret"; + break; + } + $response[$i]->movies = $usr->getFavoriteFilms(); break; case "tv": + if(!$canView) { + $response[$i]->tv = "secret"; + break; + } + $response[$i]->tv = $usr->getFavoriteShows(); break; case "books": + if(!$canView) { + $response[$i]->books = "secret"; + break; + } + $response[$i]->books = $usr->getFavoriteBooks(); break; case "city": + if(!$canView) { + $response[$i]->city = "Воскресенск"; + break; + } + $response[$i]->city = $usr->getCity(); break; case "interests": + if(!$canView) { + $response[$i]->interests = "secret"; + break; + } + $response[$i]->interests = $usr->getInterests(); break; case "quotes": - $response[$i]->interests = $usr->getFavoriteQuote(); + if(!$canView) { + $response[$i]->quotes = "secret"; + break; + } + + $response[$i]->quotes = $usr->getFavoriteQuote(); break; case "email": - $response[$i]->interests = $usr->getEmail(); + if(!$canView) { + $response[$i]->email = "secret@gmail.com"; + break; + } + + $response[$i]->email = $usr->getContactEmail(); break; case "telegram": - $response[$i]->interests = $usr->getTelegram(); + if(!$canView) { + $response[$i]->telegram = "@secret"; + break; + } + + $response[$i]->telegram = $usr->getTelegram(); break; case "about": - $response[$i]->interests = $usr->getDescription(); + if(!$canView) { + $response[$i]->about = "secret"; + break; + } + + $response[$i]->about = $usr->getDescription(); break; case "rating": + if(!$canView) { + $response[$i]->rating = 22; + break; + } + $response[$i]->rating = $usr->getRating(); break; case "counters": @@ -214,6 +269,14 @@ final class Users extends VKAPIRequestHandler $this->requireUser(); + $user = $users->get($user_id); + + if(!$user || $user->isDeleted()) + $this->fail(14, "Invalid user"); + + if(!$user->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + foreach($users->get($user_id)->getFollowers($offset, $count) as $follower) $followers[] = $follower->getId(); @@ -306,6 +369,7 @@ final class Users extends VKAPIRequestHandler "fav_shows" => !empty($fav_shows) ? $fav_shows : NULL, "fav_books" => !empty($fav_books) ? $fav_books : NULL, "fav_quotes" => !empty($fav_quotes) ? $fav_quotes : NULL, + "doNotSearchPrivate" => true, ]; $find = $users->find($q, $parameters, $sortg); diff --git a/VKAPI/Handlers/Video.php b/VKAPI/Handlers/Video.php index 5d0967c7..f468686d 100755 --- a/VKAPI/Handlers/Video.php +++ b/VKAPI/Handlers/Video.php @@ -36,14 +36,16 @@ final class Video extends VKAPIRequestHandler ]; } else { if ($owner_id > 0) - $user = (new UsersRepo)->get($owner_id); + $user = (new UsersRepo)->get($owner_id); else $this->fail(1, "Not implemented"); - if(!$user->getPrivacyPermission('videos.read', $this->getUser())) { - $this->fail(20, "Access denied: this user chose to hide his videos"); - } - + if(!$user || $user->isDeleted()) + $this->fail(14, "Invalid user"); + + if(!$user->getPrivacyPermission('videos.read', $this->getUser())) + $this->fail(21, "This user chose to hide his videos."); + $videos = (new VideosRepo)->getByUser($user, $offset + 1, $count); $videosCount = (new VideosRepo)->getUserVideosCount($user); diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 84cf1a19..3cbc7648 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -39,6 +39,9 @@ final class Wall extends VKAPIRequestHandler if ($owner_id > 0) if(!$wallOnwer || $wallOnwer->isDeleted()) $this->fail(18, "User was deleted or banned"); + + if(!$wallOnwer->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); else if(!$wallOnwer) $this->fail(15, "Access denied: wall is disabled"); // Don't search for logic here pls @@ -234,8 +237,8 @@ final class Wall extends VKAPIRequestHandler "first_name" => $user->getFirstName(), "id" => $user->getId(), "last_name" => $user->getLastName(), - "can_access_closed" => false, - "is_closed" => false, + "can_access_closed" => (bool)$user->canBeViewedBy($this->getUser()), + "is_closed" => $user->isClosed(), "sex" => $user->isFemale() ? 1 : ($user->isNeutral() ? 0 : 2), "screen_name" => $user->getShortCode(), "photo_50" => $user->getAvatarUrl(), @@ -289,7 +292,11 @@ final class Wall extends VKAPIRequestHandler foreach($psts as $pst) { $id = explode("_", $pst); $post = (new PostsRepo)->getPostById(intval($id[0]), intval($id[1])); + if($post && !$post->isDeleted()) { + if(!$post->canBeViewedBy($this->getUser())) + continue; + $from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId(); $attachments = []; $repost = []; // чел высрал семь сигарет 😳 помянем 🕯 @@ -440,8 +447,8 @@ final class Wall extends VKAPIRequestHandler "first_name" => $user->getFirstName(), "id" => $user->getId(), "last_name" => $user->getLastName(), - "can_access_closed" => false, - "is_closed" => false, + "can_access_closed" => (bool)$user->canBeViewedBy($this->getUser()), + "is_closed" => $user->isClosed(), "sex" => $user->isFemale() ? 1 : 2, "screen_name" => $user->getShortCode(), "photo_50" => $user->getAvatarUrl(), @@ -495,7 +502,7 @@ final class Wall extends VKAPIRequestHandler $wallOwner = ($owner_id > 0 ? (new UsersRepo)->get($owner_id) : (new ClubsRepo)->get($owner_id * -1)) ?? $this->fail(18, "User was deleted or banned"); if($owner_id > 0) - $canPost = $wallOwner->getPrivacyPermission("wall.write", $this->getUser()); + $canPost = $wallOwner->getPrivacyPermission("wall.write", $this->getUser()) && $wallOwner->canBeViewedBy($this->getUser()); else if($owner_id < 0) if($wallOwner->canBeModifiedBy($this->getUser())) $canPost = true; @@ -696,6 +703,9 @@ final class Wall extends VKAPIRequestHandler $post = (new PostsRepo)->getPostById((int) $postArray[1], (int) $postArray[2]); if(!$post || $post->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid"); + if(!$post->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + $nPost = new Post; $nPost->setOwner($this->user->getId()); @@ -734,6 +744,9 @@ final class Wall extends VKAPIRequestHandler $post = (new PostsRepo)->getPostById($owner_id, $post_id); if(!$post || $post->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid"); + + if(!$post->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); $comments = (new CommentsRepo)->getCommentsByTarget($post, $offset+1, $count, $sort == "desc" ? "DESC" : "ASC"); @@ -817,8 +830,11 @@ final class Wall extends VKAPIRequestHandler $comment = (new CommentsRepo)->get($comment_id); # один хуй айди всех комментов общий - if(!$comment || $comment->isDeleted()) + if(!$comment || $comment->isDeleted()) $this->fail(100, "Invalid comment"); + + if(!$comment->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); $profiles = []; @@ -886,6 +902,9 @@ final class Wall extends VKAPIRequestHandler $post = (new PostsRepo)->getPostById($owner_id, $post_id); if(!$post || $post->isDeleted()) $this->fail(100, "Invalid post"); + if(!$post->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + if($post->getTargetWall() < 0) $club = (new ClubsRepo)->get(abs($post->getTargetWall())); diff --git a/Web/Models/Entities/Album.php b/Web/Models/Entities/Album.php index 150cc625..dccd4e63 100644 --- a/Web/Models/Entities/Album.php +++ b/Web/Models/Entities/Album.php @@ -67,6 +67,21 @@ class Album extends MediaCollection return $this->has($photo); } + function canBeViewedBy(?User $user = NULL): bool + { + if($this->isDeleted()) { + return false; + } + + $owner = $this->getOwner(); + + if(get_class($owner) == "openvk\\Web\\Models\\Entities\\User") { + return $owner->canBeViewedBy($user) && $owner->getPrivacyPermission('photos.read', $user); + } else { + return $owner->canBeViewedBy($user); + } + } + function toVkApiStruct(?User $user = NULL, bool $need_covers = false, bool $photo_sizes = false): object { $res = (object) []; diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php index 5324efb6..a46eb573 100644 --- a/Web/Models/Entities/Club.php +++ b/Web/Models/Entities/Club.php @@ -399,6 +399,11 @@ class Club extends RowModel $this->save(); } + function canBeViewedBy(?User $user = NULL) + { + return is_null($this->getBanReason()); + } + function getAlert(): ?string { return $this->getRecord()->alert; diff --git a/Web/Models/Entities/Comment.php b/Web/Models/Entities/Comment.php index a553443e..24fb2c1b 100644 --- a/Web/Models/Entities/Comment.php +++ b/Web/Models/Entities/Comment.php @@ -94,6 +94,15 @@ class Comment extends Post { return "/wall" . $this->getTarget()->getPrettyId() . "#_comment" . $this->getId(); } + + function canBeViewedBy(?User $user = NULL): bool + { + if($this->isDeleted() || $this->getTarget()->isDeleted()) { + return false; + } + + return $this->getTarget()->canBeViewedBy($user); + } function toNotifApiStruct() { diff --git a/Web/Models/Entities/Note.php b/Web/Models/Entities/Note.php index bdc34307..33ac6b04 100644 --- a/Web/Models/Entities/Note.php +++ b/Web/Models/Entities/Note.php @@ -118,6 +118,15 @@ class Note extends Postable { return $this->getRecord()->source; } + + function canBeViewedBy(?User $user = NULL): bool + { + if($this->isDeleted() || $this->getOwner()->isDeleted()) { + return false; + } + + return $this->getOwner()->getPrivacyPermission('notes.read', $user) && $this->getOwner()->canBeViewedBy($user); + } function toVkApiStruct(): object { diff --git a/Web/Models/Entities/Photo.php b/Web/Models/Entities/Photo.php index 72d371ad..4cba7734 100644 --- a/Web/Models/Entities/Photo.php +++ b/Web/Models/Entities/Photo.php @@ -328,6 +328,19 @@ class Photo extends Media return $res; } + + function canBeViewedBy(?User $user = NULL): bool + { + if($this->isDeleted() || $this->getOwner()->isDeleted()) { + return false; + } + + if(!is_null($this->getAlbum())) { + return $this->getAlbum()->canBeViewedBy($user); + } else { + return $this->getOwner()->canBeViewedBy($user); + } + } static function fastMake(int $owner, string $description = "", array $file, ?Album $album = NULL, bool $anon = false): Photo { diff --git a/Web/Models/Entities/Poll.php b/Web/Models/Entities/Poll.php index dc4b7d32..60a39bc5 100644 --- a/Web/Models/Entities/Poll.php +++ b/Web/Models/Entities/Poll.php @@ -278,6 +278,17 @@ class Poll extends Attachable return $poll; } + + function canBeViewedBy(?User $user = NULL): bool + { + # waiting for #935 :( + /*if(!is_null($this->getAttachedPost())) { + return $this->getAttachedPost()->canBeViewedBy($user); + } else {*/ + return true; + #} + + } function save(?bool $log = false): void { diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index 48a2191f..51b42c07 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -248,6 +248,15 @@ class Post extends Postable $this->unwire(); $this->save(); } + + function canBeViewedBy(?User $user = NULL): bool + { + if($this->isDeleted()) { + return false; + } + + return $this->getWallOwner()->canBeViewedBy($user); + } function getSuggestionType() { diff --git a/Web/Models/Entities/Traits/TOwnable.php b/Web/Models/Entities/Traits/TOwnable.php index 08e5fde3..90182ddf 100644 --- a/Web/Models/Entities/Traits/TOwnable.php +++ b/Web/Models/Entities/Traits/TOwnable.php @@ -4,9 +4,13 @@ use openvk\Web\Models\Entities\User; trait TOwnable { - function canBeViewedBy(?User $user): bool + function canBeViewedBy(?User $user = NULL): bool { - // TODO implement normal check in master + # TODO: #950 + if($this->isDeleted()) { + return false; + } + return true; } diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index 05de73ee..4f1fbff1 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -508,6 +508,9 @@ class User extends RowModel else if($user->getId() === $this->getId()) return true; + if($permission != "messages.write" && !$this->canBeViewedBy($user)) + return false; + switch($permStatus) { case User::PRIVACY_ONLY_FRIENDS: return $this->getSubscriptionStatus($user) === User::SUBSCRIPTION_MUTUAL; @@ -1260,13 +1263,60 @@ class User extends RowModel } return $response; } + + function getProfileType(): int + { + # 0 — открытый профиль, 1 — закрытый + return $this->getRecord()->profile_type; + } + function canBeViewedBy(?User $user = NULL): bool + { + if(!is_null($user)) { + if($this->getId() == $user->getId()) { + return true; + } + + if($user->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL)) { + return true; + } + + if($this->getProfileType() == 0) { + return true; + } else { + if($user->getSubscriptionStatus($this) == User::SUBSCRIPTION_MUTUAL) { + return true; + } else { + return false; + } + } + + } else { + if($this->getProfileType() == 0) { + if($this->getPrivacySetting("page.read") == 3) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + return true; + } + + function isClosed() + { + return (bool) $this->getProfileType(); + } + function getRealId() { return $this->getId(); } - function toVkApiStruct(): object + function toVkApiStruct(?User $user = NULL): object { $res = (object) []; @@ -1280,6 +1330,12 @@ class User extends RowModel $res->photo_id = !is_null($this->getAvatarPhoto()) ? $this->getAvatarPhoto()->getPrettyId() : NULL; # TODO: Perenesti syuda vsyo ostalnoyie + $res->is_closed = $this->isClosed(); + + if(!is_null($user)) { + $res->can_access_closed = (bool)$this->canBeViewedBy($user); + } + return $res; } diff --git a/Web/Models/Entities/Video.php b/Web/Models/Entities/Video.php index fa54392e..2c1c0b05 100644 --- a/Web/Models/Entities/Video.php +++ b/Web/Models/Entities/Video.php @@ -224,7 +224,21 @@ class Video extends Media return $video; } + + function canBeViewedBy(?User $user = NULL): bool + { + if($this->isDeleted() || $this->getOwner()->isDeleted()) { + return false; + } + if(get_class($this->getOwner()) == "openvk\\Web\\Models\\Entities\\User") { + return $this->getOwner()->canBeViewedBy($user) && $this->getOwner()->getPrivacyPermission('videos.read', $user); + } else { + # Groups doesn't have videos but ok + return $this->getOwner()->canBeViewedBy($user); + } + } + function toNotifApiStruct() { $fromYoutube = $this->getType() == Video::TYPE_EMBED; diff --git a/Web/Models/Repositories/Users.php b/Web/Models/Repositories/Users.php index de0d341d..d2f4500e 100644 --- a/Web/Models/Repositories/Users.php +++ b/Web/Models/Repositories/Users.php @@ -128,6 +128,9 @@ class Users case "doNotSearchMe": $result->where("id !=", $paramValue); break; + case "doNotSearchPrivate": + $result->where("profile_type", 0); + break; } } } diff --git a/Web/Presenters/CommentPresenter.php b/Web/Presenters/CommentPresenter.php index 86ccb126..4170cdb3 100644 --- a/Web/Presenters/CommentPresenter.php +++ b/Web/Presenters/CommentPresenter.php @@ -43,6 +43,10 @@ final class CommentPresenter extends OpenVKPresenter $entity = $repo->get($eId); if(!$entity) $this->notFound(); + if(!$entity->canBeViewedBy($this->user->identity)) { + $this->flashFail("err", tr("error"), tr("forbidden")); + } + if($entity instanceof Topic && $entity->isClosed()) $this->notFound(); diff --git a/Web/Presenters/GiftsPresenter.php b/Web/Presenters/GiftsPresenter.php index 39359add..6e85a29d 100644 --- a/Web/Presenters/GiftsPresenter.php +++ b/Web/Presenters/GiftsPresenter.php @@ -20,9 +20,12 @@ final class GiftsPresenter extends OpenVKPresenter $this->assertUserLoggedIn(); $user = $this->users->get($user); - if(!$user) + if(!$user || $user->isDeleted()) $this->notFound(); + if(!$user->canBeViewedBy($this->user->identity ?? NULL)) + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + $this->template->user = $user; $this->template->page = $page = (int) ($this->queryParam("p") ?? 1); $this->template->count = $user->getGiftCount(); @@ -52,6 +55,9 @@ final class GiftsPresenter extends OpenVKPresenter if(!$user || !$cat) $this->flashFail("err", tr("error_when_gifting"), tr("error_user_not_exists")); + if(!$user->canBeViewedBy($this->user->identity)) + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + $this->template->page = $page = (int) ($this->queryParam("p") ?? 1); $gifts = $cat->getGifts($page, null, $this->template->count); @@ -72,6 +78,9 @@ final class GiftsPresenter extends OpenVKPresenter if(!$gift->canUse($this->user->identity)) $this->flashFail("err", tr("error_when_gifting"), tr("error_no_more_gifts")); + if(!$user->canBeViewedBy($this->user->identity ?? NULL)) + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + $coinsLeft = $this->user->identity->getCoins() - $gift->getPrice(); if($coinsLeft < 0) $this->flashFail("err", tr("error_when_gifting"), tr("error_no_money")); diff --git a/Web/Presenters/NotesPresenter.php b/Web/Presenters/NotesPresenter.php index 4b71c8b1..67105fe3 100644 --- a/Web/Presenters/NotesPresenter.php +++ b/Web/Presenters/NotesPresenter.php @@ -40,6 +40,8 @@ final class NotesPresenter extends OpenVKPresenter $this->notFound(); if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->user->identity ?? NULL)) $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + if(!$note->canBeViewedBy($this->user->identity)) + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); $this->template->cCount = $note->getCommentsCount(); $this->template->cPage = (int) ($this->queryParam("p") ?? 1); diff --git a/Web/Presenters/PhotosPresenter.php b/Web/Presenters/PhotosPresenter.php index aeb8ba1e..09130c60 100644 --- a/Web/Presenters/PhotosPresenter.php +++ b/Web/Presenters/PhotosPresenter.php @@ -136,6 +136,9 @@ final class PhotosPresenter extends OpenVKPresenter if(!$album) $this->notFound(); if($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted()) $this->notFound(); + + if(!$album->canBeViewedBy($this->user->identity)) + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); if($owner > 0 /* bc we currently don't have perms for clubs */) { $ownerObject = (new Users)->get($owner); @@ -158,7 +161,8 @@ final class PhotosPresenter extends OpenVKPresenter { $photo = $this->photos->getByOwnerAndVID($ownerId, $photoId); if(!$photo || $photo->isDeleted()) $this->notFound(); - + if(!$photo->canBeViewedBy($this->user->identity)) + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); if(!is_null($this->queryParam("from"))) { if(preg_match("%^album([0-9]++)$%", $this->queryParam("from"), $matches) === 1) { $album = $this->albums->get((int) $matches[1]); diff --git a/Web/Presenters/SearchPresenter.php b/Web/Presenters/SearchPresenter.php index d80c06c3..02394503 100644 --- a/Web/Presenters/SearchPresenter.php +++ b/Web/Presenters/SearchPresenter.php @@ -97,6 +97,7 @@ final class SearchPresenter extends OpenVKPresenter "before" => $this->queryParam("datebefore") != "" ? strtotime($this->queryParam("datebefore")) : NULL, "after" => $this->queryParam("dateafter") != "" ? strtotime($this->queryParam("dateafter")) : NULL, "gender" => $this->queryParam("gender") != "" && $this->queryParam("gender") != 2 ? $this->queryParam("gender") : NULL, + "doNotSearchPrivate" => true, "only_performers" => $this->queryParam("only_performers") == "on" ? "1" : NULL, "with_lyrics" => $this->queryParam("with_lyrics") == "on" ? true : NULL, ]; diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php index 870e4ab2..3785e47b 100644 --- a/Web/Presenters/UserPresenter.php +++ b/Web/Presenters/UserPresenter.php @@ -29,10 +29,14 @@ final class UserPresenter extends OpenVKPresenter function renderView(int $id): void { $user = $this->users->get($id); - if(!$user || $user->isDeleted()) { + if(!$user || $user->isDeleted() || !$user->canBeViewedBy($this->user->identity)) { if(!is_null($user) && $user->isDeactivated()) { $this->template->_template = "User/deactivated.xml"; + $this->template->user = $user; + } else if(!$user->canBeViewedBy($this->user->identity)) { + $this->template->_template = "User/private.xml"; + $this->template->user = $user; } else { $this->template->_template = "User/deleted.xml"; @@ -464,6 +468,10 @@ final class UserPresenter extends OpenVKPresenter $input = $this->postParam(str_replace(".", "_", $setting)); $user->setPrivacySetting($setting, min(3, (int)abs((int)$input ?? $user->getPrivacySetting($setting)))); } + + $prof = $this->postParam("profile_type") == 1 || $this->postParam("profile_type") == 0 ? (int)$this->postParam("profile_type") : 0; + $user->setProfile_type($prof); + } else if($_GET['act'] === "finance.top-up") { $token = $this->postParam("key0") . $this->postParam("key1") . $this->postParam("key2") . $this->postParam("key3"); $voucher = (new Vouchers)->getByToken($token); diff --git a/Web/Presenters/VideosPresenter.php b/Web/Presenters/VideosPresenter.php index 6f92891c..625f4877 100644 --- a/Web/Presenters/VideosPresenter.php +++ b/Web/Presenters/VideosPresenter.php @@ -39,11 +39,12 @@ final class VideosPresenter extends OpenVKPresenter function renderView(int $owner, int $vId): void { $user = $this->users->get($owner); + $video = $this->videos->getByOwnerAndVID($owner, $vId); + if(!$user) $this->notFound(); + if(!$video || $video->isDeleted()) $this->notFound(); if(!$user->getPrivacyPermission('videos.read', $this->user->identity ?? NULL)) $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - - if($this->videos->getByOwnerAndVID($owner, $vId)->isDeleted()) $this->notFound(); $this->template->user = $user; $this->template->video = $this->videos->getByOwnerAndVID($owner, $vId); diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index d0f17d56..b29968d0 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -46,7 +46,7 @@ final class WallPresenter extends OpenVKPresenter function renderWall(int $user, bool $embedded = false): void { $owner = ($user < 0 ? (new Clubs) : (new Users))->get(abs($user)); - if ($owner->isBanned()) + if ($owner->isBanned() || !$owner->canBeViewedBy($this->user->identity)) $this->flashFail("err", tr("error"), tr("forbidden")); if(is_null($this->user)) { @@ -114,7 +114,7 @@ final class WallPresenter extends OpenVKPresenter if(is_null($this->user)) { $canPost = false; } else if($user > 0) { - if(!$owner->isBanned()) + if(!$owner->isBanned() && $owner->canBeViewedBy($this->user->identity)) $canPost = $owner->getPrivacyPermission("wall.write", $this->user->identity); else $this->flashFail("err", tr("error"), tr("forbidden")); @@ -190,8 +190,9 @@ final class WallPresenter extends OpenVKPresenter $page = (int) ($_GET["p"] ?? 1); $pPage = min((int) ($_GET["posts"] ?? OPENVK_DEFAULT_PER_PAGE), 50); - - $queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND `posts`.`deleted` = 0 AND `posts`.`suggested` = 0"; + + $queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) LEFT JOIN `profiles` ON LEAST(`posts`.`wall`, 0) = 0 AND `profiles`.`id` = ABS(`posts`.`wall`)"; + $queryBase .= "WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND (`profiles`.`profile_type` = 0 OR `profiles`.`first_name` IS NULL) AND `posts`.`deleted` = 0 AND `posts`.`suggested` = 0"; if($this->user->identity->getNsfwTolerance() === User::NSFW_INTOLERANT) $queryBase .= " AND `nsfw` = 0"; @@ -430,22 +431,25 @@ final class WallPresenter extends OpenVKPresenter $post = $this->posts->getPostById($wall, $post_id); if(!$post || $post->isDeleted()) $this->notFound(); + + if(!$post->canBeViewedBy($this->user->identity)) + $this->flashFail("err", tr("error"), tr("forbidden")); $this->logPostView($post, $wall); $this->template->post = $post; if ($post->getTargetWall() > 0) { - $this->template->wallOwner = (new Users)->get($post->getTargetWall()); - $this->template->isWallOfGroup = false; + $this->template->wallOwner = (new Users)->get($post->getTargetWall()); + $this->template->isWallOfGroup = false; if($this->template->wallOwner->isBanned()) $this->flashFail("err", tr("error"), tr("forbidden")); - } else { - $this->template->wallOwner = (new Clubs)->get(abs($post->getTargetWall())); - $this->template->isWallOfGroup = true; + } else { + $this->template->wallOwner = (new Clubs)->get(abs($post->getTargetWall())); + $this->template->isWallOfGroup = true; if ($this->template->wallOwner->isBanned()) $this->flashFail("err", tr("error"), tr("forbidden")); - } + } $this->template->cCount = $post->getCommentsCount(); $this->template->cPage = (int) ($_GET["p"] ?? 1); $this->template->comments = iterator_to_array($post->getComments($this->template->cPage)); diff --git a/Web/Presenters/templates/Search/Index.xml b/Web/Presenters/templates/Search/Index.xml index f8c8c173..b17e125f 100644 --- a/Web/Presenters/templates/Search/Index.xml +++ b/Web/Presenters/templates/Search/Index.xml @@ -189,7 +189,7 @@ {elseif $type == "posts"}
- {if !$dat || $dat->getTargetWall() < 0 && $dat->getWallOwner()->isHideFromGlobalFeedEnabled()} + {if !$dat || $dat->getTargetWall() < 0 && $dat->getWallOwner()->isHideFromGlobalFeedEnabled() || !$dat->canBeViewedBy($thisUser)} {_closed_group_post}. {else} {include "../components/post.xml", post => $dat, commentSection => true, onWallOf => true} diff --git a/Web/Presenters/templates/User/Settings.xml b/Web/Presenters/templates/User/Settings.xml index 6fb9322f..d34993e8 100644 --- a/Web/Presenters/templates/User/Settings.xml +++ b/Web/Presenters/templates/User/Settings.xml @@ -266,8 +266,6 @@ @@ -397,6 +395,17 @@ + + + {_profile_type} + + + + + diff --git a/Web/Presenters/templates/User/private.xml b/Web/Presenters/templates/User/private.xml new file mode 100644 index 00000000..a2520a07 --- /dev/null +++ b/Web/Presenters/templates/User/private.xml @@ -0,0 +1,96 @@ +{extends "../@layout.xml"} +{block title}{$user->getCanonicalName()}{/block} + +{block header} + {$user->getCanonicalName()} + +{/block} + +{block content} +
+
+ {$user->getCanonicalName()} +
+ +
+ +
+
+
+
+

{$user->getFullName()}

+
{_closed_page}
+
+
+
+ {var $m = $user->isFemale() ? "f" : "m"} + {tr("limited_access_to_page_$m", $user->getFirstName())} + + {if isset($thisUser)} + {if $subStatus != 2} +

+ {_you_can_add} + {tr("add_to_friends_$m")} + {/if} + {else} +

+ {tr("register_to_access_page_$m")} + {/if} +
+
+
+{/block} \ No newline at end of file diff --git a/Web/Presenters/templates/components/attachment.xml b/Web/Presenters/templates/components/attachment.xml index fbc36ede..5a656a74 100644 --- a/Web/Presenters/templates/components/attachment.xml +++ b/Web/Presenters/templates/components/attachment.xml @@ -10,7 +10,6 @@ {/if} {elseif $attachment instanceof \openvk\Web\Models\Entities\Video} - {if !$attachment->isDeleted()} {if $attachment->getType() === 0}
@@ -28,10 +27,6 @@ {$attachment->getName()}
- - {else} - {_video_is_deleted} - {/if} {elseif $attachment instanceof \openvk\Web\Models\Entities\Poll} {presenter "openvk!Poll->view", $attachment->getId()} {elseif $attachment instanceof \openvk\Web\Models\Entities\Note} diff --git a/Web/static/css/main.css b/Web/static/css/main.css index 0e8b06d9..84184b04 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -1013,6 +1013,11 @@ table.User { background-color: #f5e9ec; } +.msg.msg_yellow { + border-color:#D4BC4C; + background-color:#F9F6E7; +} + .edit_link { color: #c5c5c5; font-family: verdana, arial, sans-serif; diff --git a/install/sqls/000XX-close-profiles.sql b/install/sqls/000XX-close-profiles.sql new file mode 100644 index 00000000..480692e2 --- /dev/null +++ b/install/sqls/000XX-close-profiles.sql @@ -0,0 +1 @@ +ALTER TABLE `profiles` ADD `profile_type` TINYINT(1) NOT NULL DEFAULT '0' AFTER `client_name`; diff --git a/locales/en.strings b/locales/en.strings index ad80db1f..cca4d9b1 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -163,6 +163,18 @@ "before" = "before"; "forever" = "forever"; +"closed_page" = "Closed page"; + +"limited_access_to_page_m" = "$1 limited access to his page."; +"limited_access_to_page_f" = "$1 limited access to her page."; + +"you_can_add" = "You can"; +"add_to_friends_m" = "add him to friends."; +"add_to_friends_f" = "add her to friends."; + +"register_to_access_page_m" = "Sign up to get access to his page."; +"register_to_access_page_f" = "Sign up to get access to her page."; + /* Wall */ "feed" = "News"; @@ -653,6 +665,10 @@ "privacy_value_only_me_dative" = "Only me"; "privacy_value_nobody" = "Nobody"; +"profile_type" = "Profile type"; +"profile_type_open" = "Open"; +"profile_type_closed" = "Closed"; + "your_email_address" = "Your Email address"; "your_page_address" = "Your address page"; "page_address" = "Address page"; diff --git a/locales/ru.strings b/locales/ru.strings index f06eefe1..712de62f 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -140,6 +140,22 @@ "updated_at" = "Обновлено $1"; "user_banned" = "К сожалению, нам пришлось заблокировать страницу пользователя $1."; "user_banned_comment" = "Комментарий модератора:"; + +"closed_page" = "Закрытая страница"; + +"limited_access_to_page_m" = "$1 ограничил доступ к своей странице."; +"limited_access_to_page_f" = "$1 ограничила доступ к своей странице."; + +"you_can_add" = "Вы можете"; +"add_to_friends_m" = "добавить его в друзья."; +"add_to_friends_f" = "добавить её в друзья."; + +"register_to_access_page_m" = "Зарегистрируйтесь, чтобы получить доступ к его странице."; +"register_to_access_page_f" = "Зарегистрируйтесь, чтобы получить доступ к её странице."; + +"private_profile_warning" = "Этот профиль закрытый, но вы имеете к нему доступ, потому что вы — администратор."; +"private_profile_warning_desc" = "Пожалуйста, уважайте право на личную жизнь и не злоупотребляйте этой возможностью."; + "verified_page" = "Подтверждённая страница"; "user_is_blocked" = "Пользователь заблокирован"; "before" = "до"; @@ -625,6 +641,9 @@ "privacy_value_only_me" = "Только я"; "privacy_value_only_me_dative" = "Только мне"; "privacy_value_nobody" = "Никто"; +"profile_type" = "Тип профиля"; +"profile_type_open" = "Открытый"; +"profile_type_closed" = "Закрытый"; "your_email_address" = "Адрес Вашей электронной почты"; "your_page_address" = "Адрес Вашей страницы"; "page_address" = "Адрес страницы";