feat: close profile (#978)

This commit is contained in:
lalka2018 2023-12-02 20:21:16 +03:00 committed by GitHub
parent 04eb724cd5
commit 1e7fdeff27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 598 additions and 142 deletions

View file

@ -25,6 +25,9 @@ class Notes implements Handler
assert($noteOwner instanceof User); assert($noteOwner instanceof User);
if(!$noteOwner->getPrivacyPermission("notes.read", $this->user)) if(!$noteOwner->getPrivacyPermission("notes.read", $this->user))
$reject(160, "You don't have permission to access this note"); $reject(160, "You don't have permission to access this note");
if(!$note->canBeViewedBy($this->user))
$reject(15, "Access to note denied");
$resolve([ $resolve([
"title" => $note->getName(), "title" => $note->getName(),

View file

@ -46,7 +46,7 @@ class Search implements Handler
break; 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); $results = array_slice(iterator_to_array($res), 0, 5);

View file

@ -27,6 +27,9 @@ class Wall implements Handler
if($post->getSuggestionType() != 0) if($post->getSuggestionType() != 0)
$reject(25, "Can't get suggested post"); $reject(25, "Can't get suggested post");
if(!$post->canBeViewedBy($this->user))
$reject(12, "Access denied");
$res = (object) []; $res = (object) [];
$res->id = $post->getId(); $res->id = $post->getId();
$res->wall = $post->getTargetWall(); $res->wall = $post->getTargetWall();

View file

@ -13,19 +13,23 @@ final class Friends extends VKAPIRequestHandler
$users = new UsersRepo; $users = new UsersRepo;
$this->requireUser(); $this->requireUser();
if ($user_id == 0) { if ($user_id == 0) {
$user_id = $this->getUser()->getId(); $user_id = $this->getUser()->getId();
} }
if (is_null($users->get($user_id))) { $user = $users->get($user_id);
$this->fail(100, "One of the parameters specified was missing or invalid");
}
foreach($users->get($user_id)->getFriends($offset, $count) as $friend) { if(!$user || $user->isDeleted())
$friends[$i] = $friend->getId(); $this->fail(100, "Invalid user");
$i++;
} 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; $response = $friends;

View file

@ -19,6 +19,17 @@ final class Gifts extends VKAPIRequestHandler
if(!$user || $user->isDeleted()) if(!$user || $user->isDeleted())
$this->fail(177, "Invalid user"); $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 = []; $gift_item = [];
$userGifts = array_slice(iterator_to_array($user->getGifts(1, $count, false)), $offset); $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()) if(!$user || $user->isDeleted())
$this->fail(177, "Invalid user"); $this->fail(177, "Invalid user");
if(!$user->canBeViewedBy($this->getUser()))
$this->fail(15, "Access denied");
$gift = (new GiftsRepo)->get($gift_id); $gift = (new GiftsRepo)->get($gift_id);
if(!$gift) if(!$gift)

View file

@ -19,9 +19,12 @@ final class Groups extends VKAPIRequestHandler
$users = new UsersRepo; $users = new UsersRepo;
$user = $users->get($user_id); $user = $users->get($user_id);
if(is_null($user)) if(is_null($user) || $user->isDeleted())
$this->fail(15, "Access denied"); $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) foreach($user->getClubs($offset, $filter == "admin", $count, true) as $club)
$clbs[] = $club; $clbs[] = $club;
@ -400,9 +403,15 @@ final class Groups extends VKAPIRequestHandler
]; ];
foreach($filds as $fild) { foreach($filds as $fild) {
$canView = $member->canBeViewedBy($this->getUser());
switch($fild) { switch($fild) {
case "bdate": 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; break;
case "can_post": case "can_post":
$arr->items[$i]->can_post = $club->canBeModifiedBy($member); $arr->items[$i]->can_post = $club->canBeModifiedBy($member);
@ -423,6 +432,11 @@ final class Groups extends VKAPIRequestHandler
$arr->items[$i]->connections = 1; $arr->items[$i]->connections = 1;
break; break;
case "contacts": case "contacts":
if(!$canView) {
$arr->items[$i]->contacts = "secret@gmail.com";
break;
}
$arr->items[$i]->contacts = $member->getContactEmail(); $arr->items[$i]->contacts = $member->getContactEmail();
break; break;
case "country": case "country":
@ -438,15 +452,30 @@ final class Groups extends VKAPIRequestHandler
$arr->items[$i]->has_mobile = false; $arr->items[$i]->has_mobile = false;
break; break;
case "last_seen": case "last_seen":
if(!$canView) {
$arr->items[$i]->last_seen = 0;
break;
}
$arr->items[$i]->last_seen = $member->getOnline()->timestamp(); $arr->items[$i]->last_seen = $member->getOnline()->timestamp();
break; break;
case "lists": case "lists":
$arr->items[$i]->lists = ""; $arr->items[$i]->lists = "";
break; break;
case "online": case "online":
if(!$canView) {
$arr->items[$i]->online = false;
break;
}
$arr->items[$i]->online = $member->isOnline(); $arr->items[$i]->online = $member->isOnline();
break; break;
case "online_mobile": 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"; $arr->items[$i]->online_mobile = $member->getOnlinePlatform() == "android" || $member->getOnlinePlatform() == "iphone" || $member->getOnlinePlatform() == "mobile";
break; break;
case "photo_100": case "photo_100":
@ -477,12 +506,27 @@ final class Groups extends VKAPIRequestHandler
$arr->items[$i]->schools = 0; $arr->items[$i]->schools = 0;
break; break;
case "sex": case "sex":
if(!$canView) {
$arr->items[$i]->sex = -1;
break;
}
$arr->items[$i]->sex = $member->isFemale() ? 1 : 2; $arr->items[$i]->sex = $member->isFemale() ? 1 : 2;
break; break;
case "site": case "site":
if(!$canView) {
$arr->items[$i]->site = NULL;
break;
}
$arr->items[$i]->site = $member->getWebsite(); $arr->items[$i]->site = $member->getWebsite();
break; break;
case "status": case "status":
if(!$canView) {
$arr->items[$i]->status = "r";
break;
}
$arr->items[$i]->status = $member->getStatus(); $arr->items[$i]->status = $member->getStatus();
break; break;
case "universities": case "universities":

View file

@ -44,7 +44,7 @@ final class Likes extends VKAPIRequestHandler
if(is_null($postable) || $postable->isDeleted()) if(is_null($postable) || $postable->isDeleted())
$this->fail(100, "One of the parameters specified was missing or invalid: object not found"); $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"); $this->fail(2, "Access to postable denied");
} }
@ -89,7 +89,7 @@ final class Likes extends VKAPIRequestHandler
if(is_null($postable) || $postable->isDeleted()) if(is_null($postable) || $postable->isDeleted())
$this->fail(100, "One of the parameters specified was missing or invalid: object not found"); $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"); $this->fail(2, "Access to postable denied");
} }
@ -111,7 +111,7 @@ final class Likes extends VKAPIRequestHandler
if(is_null($user) || $user->isDeleted()) if(is_null($user) || $user->isDeleted())
$this->fail(100, "One of the parameters specified was missing or invalid: user not found"); $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"); $this->fail(1984, "Access denied: you can't see this user");
} }
@ -181,6 +181,9 @@ final class Likes extends VKAPIRequestHandler
if(!$object || $object->isDeleted()) if(!$object || $object->isDeleted())
$this->fail(56, "Invalid postable"); $this->fail(56, "Invalid postable");
if(!$object->canBeViewedBy($this->getUser()))
$this->fail(665, "Access to postable denied");
$res = (object)[ $res = (object)[
"count" => $object->getLikesCount(), "count" => $object->getLikesCount(),
"items" => [] "items" => []

View file

@ -51,7 +51,8 @@ final class Newsfeed extends VKAPIRequestHandler
{ {
$this->requireUser(); $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) if($this->getUser()->getNsfwTolerance() === User::NSFW_INTOLERANT)
$queryBase .= " AND `nsfw` = 0"; $queryBase .= " AND `nsfw` = 0";

View file

@ -40,6 +40,9 @@ final class Notes extends VKAPIRequestHandler
if($note->getOwner()->isDeleted()) if($note->getOwner()->isDeleted())
$this->fail(403, "Owner is deleted"); $this->fail(403, "Owner is deleted");
if(!$note->canBeViewedBy($this->getUser()))
$this->fail(15, "Access denied");
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser())) if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
$this->fail(43, "No access"); $this->fail(43, "No access");
@ -153,7 +156,10 @@ final class Notes extends VKAPIRequestHandler
$this->fail(15, "Invalid user"); $this->fail(15, "Invalid user");
if(!$user->getPrivacyPermission('notes.read', $this->getUser())) 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)) { if(empty($note_ids)) {
$notes = array_slice(iterator_to_array((new NotesRepo)->getUserNotes($user, 1, $count + $offset, $sort == 0 ? "ASC" : "DESC")), $offset); $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())) if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
$this->fail(40, "Access denied: this user chose to hide his notes"); $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(); return $note->toVkApiStruct();
} }
@ -224,6 +233,9 @@ final class Notes extends VKAPIRequestHandler
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser())) if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
$this->fail(14, "No access"); $this->fail(14, "No access");
if(!$note->canBeViewedBy($this->getUser()))
$this->fail(15, "Access to note denied");
$arr = (object) [ $arr = (object) [
"count" => $note->getCommentsCount(), "count" => $note->getCommentsCount(),

View file

@ -304,7 +304,6 @@ final class Photos extends VKAPIRequestHandler
if(!$user || $user->isDeleted()) if(!$user || $user->isDeleted())
$this->fail(2, "Invalid user"); $this->fail(2, "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."); $this->fail(21, "This user chose to hide his albums.");
@ -363,26 +362,21 @@ final class Photos extends VKAPIRequestHandler
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $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"); $this->fail(21, "Select user_id or group_id");
}
if($user_id > 0) { if($user_id > 0) {
$us = (new UsersRepo)->get($user_id); $us = (new UsersRepo)->get($user_id);
if(!$us || $us->isDeleted()) { if(!$us || $us->isDeleted())
$this->fail(21, "Invalid user"); $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."); $this->fail(21, "This user chose to hide his albums.");
}
return (new Albums)->getUserAlbumsCount($us); return (new Albums)->getUserAlbumsCount($us);
} }
if($group_id > 0) if($group_id > 0) {
{
$cl = (new Clubs)->get($group_id); $cl = (new Clubs)->get($group_id);
if(!$cl) { if(!$cl) {
$this->fail(21, "Invalid club"); $this->fail(21, "Invalid club");
@ -404,17 +398,11 @@ final class Photos extends VKAPIRequestHandler
$ph = explode("_", $phota); $ph = explode("_", $phota);
$photo = (new PhotosRepo)->getByOwnerAndVID((int)$ph[0], (int)$ph[1]); $photo = (new PhotosRepo)->getByOwnerAndVID((int)$ph[0], (int)$ph[1]);
if(!$photo || $photo->isDeleted()) { if(!$photo || $photo->isDeleted())
$this->fail(21, "Invalid photo"); $this->fail(21, "Invalid photo");
}
if($photo->getOwner()->isDeleted()) { if(!$photo->canBeViewedBy($this->getUser()))
$this->fail(21, "Owner of this photo is deleted"); $this->fail(15, "Access denied");
}
if(!$photo->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) {
$this->fail(21, "This user chose to hide his photos.");
}
$res[] = $photo->toVkApiStruct($photo_sizes, $extended); $res[] = $photo->toVkApiStruct($photo_sizes, $extended);
} }
@ -434,9 +422,9 @@ final class Photos extends VKAPIRequestHandler
if(!$album || $album->isDeleted()) if(!$album || $album->isDeleted())
$this->fail(21, "Invalid album"); $this->fail(21, "Invalid album");
if(!$album->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) if(!$album->canBeViewedBy($this->getUser()))
$this->fail(21, "This user chose to hide his albums."); $this->fail(15, "Access denied");
$photos = array_slice(iterator_to_array($album->getPhotos(1, $count + $offset)), $offset); $photos = array_slice(iterator_to_array($album->getPhotos(1, $count + $offset)), $offset);
$res["count"] = sizeof($photos); $res["count"] = sizeof($photos);
@ -458,7 +446,7 @@ final class Photos extends VKAPIRequestHandler
$id = explode("_", $photo); $id = explode("_", $photo);
$phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]); $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); $res["items"][] = $phot->toVkApiStruct($photo_sizes, $extended);
} }
} }
@ -474,13 +462,11 @@ final class Photos extends VKAPIRequestHandler
$album = (new Albums)->get($album_id); $album = (new Albums)->get($album_id);
if(!$album || $album->canBeModifiedBy($this->getUser())) { if(!$album || $album->canBeModifiedBy($this->getUser()))
$this->fail(21, "Invalid album"); $this->fail(21, "Invalid album");
}
if($album->isDeleted()) { if($album->isDeleted())
$this->fail(22, "Album already deleted"); $this->fail(22, "Album already deleted");
}
$album->delete(); $album->delete();
@ -494,13 +480,11 @@ final class Photos extends VKAPIRequestHandler
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id);
if(!$photo) { if(!$photo)
$this->fail(21, "Invalid photo"); $this->fail(21, "Invalid photo");
}
if($photo->isDeleted()) { if($photo->isDeleted())
$this->fail(21, "Photo is deleted"); $this->fail(21, "Photo is deleted");
}
if(!empty($caption)) { if(!empty($caption)) {
$photo->setDescription($caption); $photo->setDescription($caption);
@ -518,17 +502,14 @@ final class Photos extends VKAPIRequestHandler
if(empty($photos)) { if(empty($photos)) {
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); $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"); $this->fail(21, "You can't delete another's photo");
}
if(!$photo) { if(!$photo)
$this->fail(21, "Invalid photo"); $this->fail(21, "Invalid photo");
}
if($photo->isDeleted()) { if($photo->isDeleted())
$this->fail(21, "Photo already deleted"); $this->fail(21, "Photo is already deleted");
}
$photo->delete(); $photo->delete();
} else { } else {
@ -540,17 +521,14 @@ final class Photos extends VKAPIRequestHandler
$phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]); $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"); $this->fail(21, "You can't delete another's photo");
}
if(!$phot) { if(!$phot)
$this->fail(21, "Invalid photo"); $this->fail(21, "Invalid photo");
}
if($phot->isDeleted()) { if($phot->isDeleted())
$this->fail(21, "Photo already deleted"); $this->fail(21, "Photo already deleted");
}
$phot->delete(); $phot->delete();
} }
@ -570,17 +548,11 @@ final class Photos extends VKAPIRequestHandler
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
$comment = (new CommentsRepo)->get($comment_id); $comment = (new CommentsRepo)->get($comment_id);
if(!$comment) { if(!$comment)
$this->fail(21, "Invalid comment"); $this->fail(21, "Invalid comment");
}
if(!$comment->canBeModifiedBy($this->getUser())) { if(!$comment->canBeModifiedBy($this->getUser()))
$this->fail(21, "Forbidden"); $this->fail(21, "Access denied");
}
if($comment->isDeleted()) {
$this->fail(4, "Comment already deleted");
}
$comment->delete(); $comment->delete();
@ -592,20 +564,16 @@ final class Photos extends VKAPIRequestHandler
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
if(empty($message) && empty($attachments)) { if(empty($message) && empty($attachments))
$this->fail(100, "Required parameter 'message' missing."); $this->fail(100, "Required parameter 'message' missing.");
}
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id);
if(!$photo->getAlbum()->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { if(!$photo || $photo->isDeleted())
$this->fail(21, "This user chose to hide his albums."); $this->fail(180, "Invalid photo");
}
if(!$photo) if(!$photo->canBeViewedBy($this->getUser()))
$this->fail(180, "Photo not found"); $this->fail(15, "Access to photo denied");
if($photo->isDeleted())
$this->fail(189, "Photo is deleted");
$comment = new Comment; $comment = new Comment;
$comment->setOwner($this->getUser()->getId()); $comment->setOwner($this->getUser()->getId());
@ -666,22 +634,21 @@ final class Photos extends VKAPIRequestHandler
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
if($owner_id < 0) { if($owner_id < 0)
$this->fail(4, "This method doesn't works with clubs"); $this->fail(4, "This method doesn't works with clubs");
}
$user = (new UsersRepo)->get($owner_id); $user = (new UsersRepo)->get($owner_id);
if(!$user) { if(!$user)
$this->fail(4, "Invalid 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."); $this->fail(21, "This user chose to hide his albums.");
}
$photos = array_slice(iterator_to_array((new PhotosRepo)->getEveryUserPhoto($user, 1, $count + $offset)), $offset); $photos = array_slice(iterator_to_array((new PhotosRepo)->getEveryUserPhoto($user, 1, $count + $offset)), $offset);
$res = []; $res = [
"items" => [],
];
foreach($photos as $photo) { foreach($photos as $photo) {
if(!$photo || $photo->isDeleted()) continue; if(!$photo || $photo->isDeleted()) continue;
@ -699,17 +666,11 @@ final class Photos extends VKAPIRequestHandler
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id);
$comms = array_slice(iterator_to_array($photo->getComments(1, $offset + $count)), $offset); $comms = array_slice(iterator_to_array($photo->getComments(1, $offset + $count)), $offset);
if(!$photo) { if(!$photo || $photo->isDeleted())
$this->fail(4, "Invalid photo"); $this->fail(4, "Invalid photo");
}
if(!$photo->getAlbum()->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { if(!$photo->canBeViewedBy($this->getUser()))
$this->fail(21, "This user chose to hide his photos."); $this->fail(21, "Access denied");
}
if($photo->isDeleted()) {
$this->fail(4, "Photo is deleted");
}
$res = [ $res = [
"count" => sizeof($comms), "count" => sizeof($comms),
@ -727,4 +688,4 @@ final class Photos extends VKAPIRequestHandler
return $res; return $res;
} }
} }

View file

@ -16,6 +16,10 @@ final class Status extends VKAPIRequestHandler
$this->fail(501, "Group statuses are not implemented"); $this->fail(501, "Group statuses are not implemented");
else { else {
$user = (new UsersRepo)->get($user_id); $user = (new UsersRepo)->get($user_id);
if(!$user || $user->isDeleted() || !$user->canBeViewedBy($this->getUser()))
$this->fail(15, "Invalid user");
$audioStatus = $user->getCurrentAudioStatus(); $audioStatus = $user->getCurrentAudioStatus();
if($audioStatus) { if($audioStatus) {
return [ return [

View file

@ -50,13 +50,13 @@ final class Users extends VKAPIRequestHandler
"id" => $usr->getId(), "id" => $usr->getId(),
"first_name" => $usr->getFirstName(true), "first_name" => $usr->getFirstName(true),
"last_name" => $usr->getLastName(true), "last_name" => $usr->getLastName(true),
"is_closed" => false, "is_closed" => $usr->isClosed(),
"can_access_closed" => true, "can_access_closed" => (bool)$usr->canBeViewedBy($this->getUser()),
]; ];
$flds = explode(',', $fields); $flds = explode(',', $fields);
$canView = $usr->canBeViewedBy($this->getUser());
foreach($flds as $field) { foreach($flds as $field) {
switch($field) { switch($field) {
case "verified": case "verified":
$response[$i]->verified = intval($usr->isVerified()); $response[$i]->verified = intval($usr->isVerified());
@ -150,36 +150,91 @@ final class Users extends VKAPIRequestHandler
]; ];
} }
case "music": case "music":
if(!$canView) {
$response[$i]->music = "secret";
break;
}
$response[$i]->music = $usr->getFavoriteMusic(); $response[$i]->music = $usr->getFavoriteMusic();
break; break;
case "movies": case "movies":
if(!$canView) {
$response[$i]->movies = "secret";
break;
}
$response[$i]->movies = $usr->getFavoriteFilms(); $response[$i]->movies = $usr->getFavoriteFilms();
break; break;
case "tv": case "tv":
if(!$canView) {
$response[$i]->tv = "secret";
break;
}
$response[$i]->tv = $usr->getFavoriteShows(); $response[$i]->tv = $usr->getFavoriteShows();
break; break;
case "books": case "books":
if(!$canView) {
$response[$i]->books = "secret";
break;
}
$response[$i]->books = $usr->getFavoriteBooks(); $response[$i]->books = $usr->getFavoriteBooks();
break; break;
case "city": case "city":
if(!$canView) {
$response[$i]->city = "Воскресенск";
break;
}
$response[$i]->city = $usr->getCity(); $response[$i]->city = $usr->getCity();
break; break;
case "interests": case "interests":
if(!$canView) {
$response[$i]->interests = "secret";
break;
}
$response[$i]->interests = $usr->getInterests(); $response[$i]->interests = $usr->getInterests();
break; break;
case "quotes": case "quotes":
$response[$i]->interests = $usr->getFavoriteQuote(); if(!$canView) {
$response[$i]->quotes = "secret";
break;
}
$response[$i]->quotes = $usr->getFavoriteQuote();
break; break;
case "email": case "email":
$response[$i]->interests = $usr->getEmail(); if(!$canView) {
$response[$i]->email = "secret@gmail.com";
break;
}
$response[$i]->email = $usr->getContactEmail();
break; break;
case "telegram": case "telegram":
$response[$i]->interests = $usr->getTelegram(); if(!$canView) {
$response[$i]->telegram = "@secret";
break;
}
$response[$i]->telegram = $usr->getTelegram();
break; break;
case "about": case "about":
$response[$i]->interests = $usr->getDescription(); if(!$canView) {
$response[$i]->about = "secret";
break;
}
$response[$i]->about = $usr->getDescription();
break; break;
case "rating": case "rating":
if(!$canView) {
$response[$i]->rating = 22;
break;
}
$response[$i]->rating = $usr->getRating(); $response[$i]->rating = $usr->getRating();
break; break;
case "counters": case "counters":
@ -214,6 +269,14 @@ final class Users extends VKAPIRequestHandler
$this->requireUser(); $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) foreach($users->get($user_id)->getFollowers($offset, $count) as $follower)
$followers[] = $follower->getId(); $followers[] = $follower->getId();
@ -306,6 +369,7 @@ final class Users extends VKAPIRequestHandler
"fav_shows" => !empty($fav_shows) ? $fav_shows : NULL, "fav_shows" => !empty($fav_shows) ? $fav_shows : NULL,
"fav_books" => !empty($fav_books) ? $fav_books : NULL, "fav_books" => !empty($fav_books) ? $fav_books : NULL,
"fav_quotes" => !empty($fav_quotes) ? $fav_quotes : NULL, "fav_quotes" => !empty($fav_quotes) ? $fav_quotes : NULL,
"doNotSearchPrivate" => true,
]; ];
$find = $users->find($q, $parameters, $sortg); $find = $users->find($q, $parameters, $sortg);

View file

@ -36,14 +36,16 @@ final class Video extends VKAPIRequestHandler
]; ];
} else { } else {
if ($owner_id > 0) if ($owner_id > 0)
$user = (new UsersRepo)->get($owner_id); $user = (new UsersRepo)->get($owner_id);
else else
$this->fail(1, "Not implemented"); $this->fail(1, "Not implemented");
if(!$user->getPrivacyPermission('videos.read', $this->getUser())) { if(!$user || $user->isDeleted())
$this->fail(20, "Access denied: this user chose to hide his videos"); $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); $videos = (new VideosRepo)->getByUser($user, $offset + 1, $count);
$videosCount = (new VideosRepo)->getUserVideosCount($user); $videosCount = (new VideosRepo)->getUserVideosCount($user);

View file

@ -39,6 +39,9 @@ final class Wall extends VKAPIRequestHandler
if ($owner_id > 0) if ($owner_id > 0)
if(!$wallOnwer || $wallOnwer->isDeleted()) if(!$wallOnwer || $wallOnwer->isDeleted())
$this->fail(18, "User was deleted or banned"); $this->fail(18, "User was deleted or banned");
if(!$wallOnwer->canBeViewedBy($this->getUser()))
$this->fail(15, "Access denied");
else else
if(!$wallOnwer) if(!$wallOnwer)
$this->fail(15, "Access denied: wall is disabled"); // Don't search for logic here pls $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(), "first_name" => $user->getFirstName(),
"id" => $user->getId(), "id" => $user->getId(),
"last_name" => $user->getLastName(), "last_name" => $user->getLastName(),
"can_access_closed" => false, "can_access_closed" => (bool)$user->canBeViewedBy($this->getUser()),
"is_closed" => false, "is_closed" => $user->isClosed(),
"sex" => $user->isFemale() ? 1 : ($user->isNeutral() ? 0 : 2), "sex" => $user->isFemale() ? 1 : ($user->isNeutral() ? 0 : 2),
"screen_name" => $user->getShortCode(), "screen_name" => $user->getShortCode(),
"photo_50" => $user->getAvatarUrl(), "photo_50" => $user->getAvatarUrl(),
@ -289,7 +292,11 @@ final class Wall extends VKAPIRequestHandler
foreach($psts as $pst) { foreach($psts as $pst) {
$id = explode("_", $pst); $id = explode("_", $pst);
$post = (new PostsRepo)->getPostById(intval($id[0]), intval($id[1])); $post = (new PostsRepo)->getPostById(intval($id[0]), intval($id[1]));
if($post && !$post->isDeleted()) { 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(); $from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId();
$attachments = []; $attachments = [];
$repost = []; // чел высрал семь сигарет 😳 помянем 🕯 $repost = []; // чел высрал семь сигарет 😳 помянем 🕯
@ -440,8 +447,8 @@ final class Wall extends VKAPIRequestHandler
"first_name" => $user->getFirstName(), "first_name" => $user->getFirstName(),
"id" => $user->getId(), "id" => $user->getId(),
"last_name" => $user->getLastName(), "last_name" => $user->getLastName(),
"can_access_closed" => false, "can_access_closed" => (bool)$user->canBeViewedBy($this->getUser()),
"is_closed" => false, "is_closed" => $user->isClosed(),
"sex" => $user->isFemale() ? 1 : 2, "sex" => $user->isFemale() ? 1 : 2,
"screen_name" => $user->getShortCode(), "screen_name" => $user->getShortCode(),
"photo_50" => $user->getAvatarUrl(), "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)) $wallOwner = ($owner_id > 0 ? (new UsersRepo)->get($owner_id) : (new ClubsRepo)->get($owner_id * -1))
?? $this->fail(18, "User was deleted or banned"); ?? $this->fail(18, "User was deleted or banned");
if($owner_id > 0) 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) else if($owner_id < 0)
if($wallOwner->canBeModifiedBy($this->getUser())) if($wallOwner->canBeModifiedBy($this->getUser()))
$canPost = true; $canPost = true;
@ -696,6 +703,9 @@ final class Wall extends VKAPIRequestHandler
$post = (new PostsRepo)->getPostById((int) $postArray[1], (int) $postArray[2]); $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 || $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 = new Post;
$nPost->setOwner($this->user->getId()); $nPost->setOwner($this->user->getId());
@ -734,6 +744,9 @@ final class Wall extends VKAPIRequestHandler
$post = (new PostsRepo)->getPostById($owner_id, $post_id); $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 || $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"); $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); # один хуй айди всех комментов общий $comment = (new CommentsRepo)->get($comment_id); # один хуй айди всех комментов общий
if(!$comment || $comment->isDeleted()) if(!$comment || $comment->isDeleted())
$this->fail(100, "Invalid comment"); $this->fail(100, "Invalid comment");
if(!$comment->canBeViewedBy($this->getUser()))
$this->fail(15, "Access denied");
$profiles = []; $profiles = [];
@ -886,6 +902,9 @@ final class Wall extends VKAPIRequestHandler
$post = (new PostsRepo)->getPostById($owner_id, $post_id); $post = (new PostsRepo)->getPostById($owner_id, $post_id);
if(!$post || $post->isDeleted()) $this->fail(100, "Invalid post"); if(!$post || $post->isDeleted()) $this->fail(100, "Invalid post");
if(!$post->canBeViewedBy($this->getUser()))
$this->fail(15, "Access denied");
if($post->getTargetWall() < 0) if($post->getTargetWall() < 0)
$club = (new ClubsRepo)->get(abs($post->getTargetWall())); $club = (new ClubsRepo)->get(abs($post->getTargetWall()));

View file

@ -67,6 +67,21 @@ class Album extends MediaCollection
return $this->has($photo); 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 function toVkApiStruct(?User $user = NULL, bool $need_covers = false, bool $photo_sizes = false): object
{ {
$res = (object) []; $res = (object) [];

View file

@ -399,6 +399,11 @@ class Club extends RowModel
$this->save(); $this->save();
} }
function canBeViewedBy(?User $user = NULL)
{
return is_null($this->getBanReason());
}
function getAlert(): ?string function getAlert(): ?string
{ {
return $this->getRecord()->alert; return $this->getRecord()->alert;

View file

@ -94,6 +94,15 @@ class Comment extends Post
{ {
return "/wall" . $this->getTarget()->getPrettyId() . "#_comment" . $this->getId(); 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() function toNotifApiStruct()
{ {

View file

@ -118,6 +118,15 @@ class Note extends Postable
{ {
return $this->getRecord()->source; 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 function toVkApiStruct(): object
{ {

View file

@ -328,6 +328,19 @@ class Photo extends Media
return $res; 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 static function fastMake(int $owner, string $description = "", array $file, ?Album $album = NULL, bool $anon = false): Photo
{ {

View file

@ -278,6 +278,17 @@ class Poll extends Attachable
return $poll; 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 function save(?bool $log = false): void
{ {

View file

@ -248,6 +248,15 @@ class Post extends Postable
$this->unwire(); $this->unwire();
$this->save(); $this->save();
} }
function canBeViewedBy(?User $user = NULL): bool
{
if($this->isDeleted()) {
return false;
}
return $this->getWallOwner()->canBeViewedBy($user);
}
function getSuggestionType() function getSuggestionType()
{ {

View file

@ -4,9 +4,13 @@ use openvk\Web\Models\Entities\User;
trait TOwnable 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; return true;
} }

View file

@ -508,6 +508,9 @@ class User extends RowModel
else if($user->getId() === $this->getId()) else if($user->getId() === $this->getId())
return true; return true;
if($permission != "messages.write" && !$this->canBeViewedBy($user))
return false;
switch($permStatus) { switch($permStatus) {
case User::PRIVACY_ONLY_FRIENDS: case User::PRIVACY_ONLY_FRIENDS:
return $this->getSubscriptionStatus($user) === User::SUBSCRIPTION_MUTUAL; return $this->getSubscriptionStatus($user) === User::SUBSCRIPTION_MUTUAL;
@ -1260,13 +1263,60 @@ class User extends RowModel
} }
return $response; 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() function getRealId()
{ {
return $this->getId(); return $this->getId();
} }
function toVkApiStruct(): object function toVkApiStruct(?User $user = NULL): object
{ {
$res = (object) []; $res = (object) [];
@ -1280,6 +1330,12 @@ class User extends RowModel
$res->photo_id = !is_null($this->getAvatarPhoto()) ? $this->getAvatarPhoto()->getPrettyId() : NULL; $res->photo_id = !is_null($this->getAvatarPhoto()) ? $this->getAvatarPhoto()->getPrettyId() : NULL;
# TODO: Perenesti syuda vsyo ostalnoyie # TODO: Perenesti syuda vsyo ostalnoyie
$res->is_closed = $this->isClosed();
if(!is_null($user)) {
$res->can_access_closed = (bool)$this->canBeViewedBy($user);
}
return $res; return $res;
} }

View file

@ -224,7 +224,21 @@ class Video extends Media
return $video; 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() function toNotifApiStruct()
{ {
$fromYoutube = $this->getType() == Video::TYPE_EMBED; $fromYoutube = $this->getType() == Video::TYPE_EMBED;

View file

@ -128,6 +128,9 @@ class Users
case "doNotSearchMe": case "doNotSearchMe":
$result->where("id !=", $paramValue); $result->where("id !=", $paramValue);
break; break;
case "doNotSearchPrivate":
$result->where("profile_type", 0);
break;
} }
} }
} }

View file

@ -43,6 +43,10 @@ final class CommentPresenter extends OpenVKPresenter
$entity = $repo->get($eId); $entity = $repo->get($eId);
if(!$entity) $this->notFound(); if(!$entity) $this->notFound();
if(!$entity->canBeViewedBy($this->user->identity)) {
$this->flashFail("err", tr("error"), tr("forbidden"));
}
if($entity instanceof Topic && $entity->isClosed()) if($entity instanceof Topic && $entity->isClosed())
$this->notFound(); $this->notFound();

View file

@ -20,9 +20,12 @@ final class GiftsPresenter extends OpenVKPresenter
$this->assertUserLoggedIn(); $this->assertUserLoggedIn();
$user = $this->users->get($user); $user = $this->users->get($user);
if(!$user) if(!$user || $user->isDeleted())
$this->notFound(); $this->notFound();
if(!$user->canBeViewedBy($this->user->identity ?? NULL))
$this->flashFail("err", tr("forbidden"), tr("forbidden_comment"));
$this->template->user = $user; $this->template->user = $user;
$this->template->page = $page = (int) ($this->queryParam("p") ?? 1); $this->template->page = $page = (int) ($this->queryParam("p") ?? 1);
$this->template->count = $user->getGiftCount(); $this->template->count = $user->getGiftCount();
@ -52,6 +55,9 @@ final class GiftsPresenter extends OpenVKPresenter
if(!$user || !$cat) if(!$user || !$cat)
$this->flashFail("err", tr("error_when_gifting"), tr("error_user_not_exists")); $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); $this->template->page = $page = (int) ($this->queryParam("p") ?? 1);
$gifts = $cat->getGifts($page, null, $this->template->count); $gifts = $cat->getGifts($page, null, $this->template->count);
@ -72,6 +78,9 @@ final class GiftsPresenter extends OpenVKPresenter
if(!$gift->canUse($this->user->identity)) if(!$gift->canUse($this->user->identity))
$this->flashFail("err", tr("error_when_gifting"), tr("error_no_more_gifts")); $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(); $coinsLeft = $this->user->identity->getCoins() - $gift->getPrice();
if($coinsLeft < 0) if($coinsLeft < 0)
$this->flashFail("err", tr("error_when_gifting"), tr("error_no_money")); $this->flashFail("err", tr("error_when_gifting"), tr("error_no_money"));

View file

@ -40,6 +40,8 @@ final class NotesPresenter extends OpenVKPresenter
$this->notFound(); $this->notFound();
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->user->identity ?? NULL)) if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->user->identity ?? NULL))
$this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); $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->cCount = $note->getCommentsCount();
$this->template->cPage = (int) ($this->queryParam("p") ?? 1); $this->template->cPage = (int) ($this->queryParam("p") ?? 1);

View file

@ -136,6 +136,9 @@ final class PhotosPresenter extends OpenVKPresenter
if(!$album) $this->notFound(); if(!$album) $this->notFound();
if($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted()) if($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted())
$this->notFound(); $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 */) { if($owner > 0 /* bc we currently don't have perms for clubs */) {
$ownerObject = (new Users)->get($owner); $ownerObject = (new Users)->get($owner);
@ -158,7 +161,8 @@ final class PhotosPresenter extends OpenVKPresenter
{ {
$photo = $this->photos->getByOwnerAndVID($ownerId, $photoId); $photo = $this->photos->getByOwnerAndVID($ownerId, $photoId);
if(!$photo || $photo->isDeleted()) $this->notFound(); 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(!is_null($this->queryParam("from"))) {
if(preg_match("%^album([0-9]++)$%", $this->queryParam("from"), $matches) === 1) { if(preg_match("%^album([0-9]++)$%", $this->queryParam("from"), $matches) === 1) {
$album = $this->albums->get((int) $matches[1]); $album = $this->albums->get((int) $matches[1]);

View file

@ -97,6 +97,7 @@ final class SearchPresenter extends OpenVKPresenter
"before" => $this->queryParam("datebefore") != "" ? strtotime($this->queryParam("datebefore")) : NULL, "before" => $this->queryParam("datebefore") != "" ? strtotime($this->queryParam("datebefore")) : NULL,
"after" => $this->queryParam("dateafter") != "" ? strtotime($this->queryParam("dateafter")) : NULL, "after" => $this->queryParam("dateafter") != "" ? strtotime($this->queryParam("dateafter")) : NULL,
"gender" => $this->queryParam("gender") != "" && $this->queryParam("gender") != 2 ? $this->queryParam("gender") : NULL, "gender" => $this->queryParam("gender") != "" && $this->queryParam("gender") != 2 ? $this->queryParam("gender") : NULL,
"doNotSearchPrivate" => true,
"only_performers" => $this->queryParam("only_performers") == "on" ? "1" : NULL, "only_performers" => $this->queryParam("only_performers") == "on" ? "1" : NULL,
"with_lyrics" => $this->queryParam("with_lyrics") == "on" ? true : NULL, "with_lyrics" => $this->queryParam("with_lyrics") == "on" ? true : NULL,
]; ];

View file

@ -29,10 +29,14 @@ final class UserPresenter extends OpenVKPresenter
function renderView(int $id): void function renderView(int $id): void
{ {
$user = $this->users->get($id); $user = $this->users->get($id);
if(!$user || $user->isDeleted()) { if(!$user || $user->isDeleted() || !$user->canBeViewedBy($this->user->identity)) {
if(!is_null($user) && $user->isDeactivated()) { if(!is_null($user) && $user->isDeactivated()) {
$this->template->_template = "User/deactivated.xml"; $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; $this->template->user = $user;
} else { } else {
$this->template->_template = "User/deleted.xml"; $this->template->_template = "User/deleted.xml";
@ -464,6 +468,10 @@ final class UserPresenter extends OpenVKPresenter
$input = $this->postParam(str_replace(".", "_", $setting)); $input = $this->postParam(str_replace(".", "_", $setting));
$user->setPrivacySetting($setting, min(3, (int)abs((int)$input ?? $user->getPrivacySetting($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") { } else if($_GET['act'] === "finance.top-up") {
$token = $this->postParam("key0") . $this->postParam("key1") . $this->postParam("key2") . $this->postParam("key3"); $token = $this->postParam("key0") . $this->postParam("key1") . $this->postParam("key2") . $this->postParam("key3");
$voucher = (new Vouchers)->getByToken($token); $voucher = (new Vouchers)->getByToken($token);

View file

@ -39,11 +39,12 @@ final class VideosPresenter extends OpenVKPresenter
function renderView(int $owner, int $vId): void function renderView(int $owner, int $vId): void
{ {
$user = $this->users->get($owner); $user = $this->users->get($owner);
$video = $this->videos->getByOwnerAndVID($owner, $vId);
if(!$user) $this->notFound(); if(!$user) $this->notFound();
if(!$video || $video->isDeleted()) $this->notFound();
if(!$user->getPrivacyPermission('videos.read', $this->user->identity ?? NULL)) if(!$user->getPrivacyPermission('videos.read', $this->user->identity ?? NULL))
$this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); $this->flashFail("err", tr("forbidden"), tr("forbidden_comment"));
if($this->videos->getByOwnerAndVID($owner, $vId)->isDeleted()) $this->notFound();
$this->template->user = $user; $this->template->user = $user;
$this->template->video = $this->videos->getByOwnerAndVID($owner, $vId); $this->template->video = $this->videos->getByOwnerAndVID($owner, $vId);

View file

@ -46,7 +46,7 @@ final class WallPresenter extends OpenVKPresenter
function renderWall(int $user, bool $embedded = false): void function renderWall(int $user, bool $embedded = false): void
{ {
$owner = ($user < 0 ? (new Clubs) : (new Users))->get(abs($user)); $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")); $this->flashFail("err", tr("error"), tr("forbidden"));
if(is_null($this->user)) { if(is_null($this->user)) {
@ -114,7 +114,7 @@ final class WallPresenter extends OpenVKPresenter
if(is_null($this->user)) { if(is_null($this->user)) {
$canPost = false; $canPost = false;
} else if($user > 0) { } else if($user > 0) {
if(!$owner->isBanned()) if(!$owner->isBanned() && $owner->canBeViewedBy($this->user->identity))
$canPost = $owner->getPrivacyPermission("wall.write", $this->user->identity); $canPost = $owner->getPrivacyPermission("wall.write", $this->user->identity);
else else
$this->flashFail("err", tr("error"), tr("forbidden")); $this->flashFail("err", tr("error"), tr("forbidden"));
@ -190,8 +190,9 @@ final class WallPresenter extends OpenVKPresenter
$page = (int) ($_GET["p"] ?? 1); $page = (int) ($_GET["p"] ?? 1);
$pPage = min((int) ($_GET["posts"] ?? OPENVK_DEFAULT_PER_PAGE), 50); $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) if($this->user->identity->getNsfwTolerance() === User::NSFW_INTOLERANT)
$queryBase .= " AND `nsfw` = 0"; $queryBase .= " AND `nsfw` = 0";
@ -430,22 +431,25 @@ final class WallPresenter extends OpenVKPresenter
$post = $this->posts->getPostById($wall, $post_id); $post = $this->posts->getPostById($wall, $post_id);
if(!$post || $post->isDeleted()) if(!$post || $post->isDeleted())
$this->notFound(); $this->notFound();
if(!$post->canBeViewedBy($this->user->identity))
$this->flashFail("err", tr("error"), tr("forbidden"));
$this->logPostView($post, $wall); $this->logPostView($post, $wall);
$this->template->post = $post; $this->template->post = $post;
if ($post->getTargetWall() > 0) { if ($post->getTargetWall() > 0) {
$this->template->wallOwner = (new Users)->get($post->getTargetWall()); $this->template->wallOwner = (new Users)->get($post->getTargetWall());
$this->template->isWallOfGroup = false; $this->template->isWallOfGroup = false;
if($this->template->wallOwner->isBanned()) if($this->template->wallOwner->isBanned())
$this->flashFail("err", tr("error"), tr("forbidden")); $this->flashFail("err", tr("error"), tr("forbidden"));
} else { } else {
$this->template->wallOwner = (new Clubs)->get(abs($post->getTargetWall())); $this->template->wallOwner = (new Clubs)->get(abs($post->getTargetWall()));
$this->template->isWallOfGroup = true; $this->template->isWallOfGroup = true;
if ($this->template->wallOwner->isBanned()) if ($this->template->wallOwner->isBanned())
$this->flashFail("err", tr("error"), tr("forbidden")); $this->flashFail("err", tr("error"), tr("forbidden"));
} }
$this->template->cCount = $post->getCommentsCount(); $this->template->cCount = $post->getCommentsCount();
$this->template->cPage = (int) ($_GET["p"] ?? 1); $this->template->cPage = (int) ($_GET["p"] ?? 1);
$this->template->comments = iterator_to_array($post->getComments($this->template->cPage)); $this->template->comments = iterator_to_array($post->getComments($this->template->cPage));

View file

@ -189,7 +189,7 @@
</div> </div>
{elseif $type == "posts"} {elseif $type == "posts"}
<div n:foreach="$data as $dat" class="content"> <div n:foreach="$data as $dat" class="content">
{if !$dat || $dat->getTargetWall() < 0 && $dat->getWallOwner()->isHideFromGlobalFeedEnabled()} {if !$dat || $dat->getTargetWall() < 0 && $dat->getWallOwner()->isHideFromGlobalFeedEnabled() || !$dat->canBeViewedBy($thisUser)}
{_closed_group_post}. {_closed_group_post}.
{else} {else}
{include "../components/post.xml", post => $dat, commentSection => true, onWallOf => true} {include "../components/post.xml", post => $dat, commentSection => true, onWallOf => true}

View file

@ -266,8 +266,6 @@
<select name="page.read" style="width: 164px;"> <select name="page.read" style="width: 164px;">
<option value="3" {if $user->getPrivacySetting('page.read') == 3}selected{/if}>{_privacy_value_anybody_dative}</option> <option value="3" {if $user->getPrivacySetting('page.read') == 3}selected{/if}>{_privacy_value_anybody_dative}</option>
<option value="2" {if $user->getPrivacySetting('page.read') == 2}selected{/if}>{_privacy_value_users}</option> <option value="2" {if $user->getPrivacySetting('page.read') == 2}selected{/if}>{_privacy_value_users}</option>
<option value="1" {if $user->getPrivacySetting('page.read') == 1}selected{/if}>{_privacy_value_friends_dative}</option>
<option value="0" {if $user->getPrivacySetting('page.read') == 0}selected{/if}>{_privacy_value_only_me_dative}</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -397,6 +395,17 @@
</select> </select>
</td> </td>
</tr> </tr>
<tr>
<td width="120" valign="top">
<span class="nobold">{_profile_type}</span>
</td>
<td>
<select name="profile_type", style="width: 164px;">
<option value="0" {if $user->getProfileType() == 0}selected{/if}>{_profile_type_open}</option>
<option value="1" {if $user->getProfileType() == 1}selected{/if}>{_profile_type_closed}</option>
</select>
</td>
</tr>
<tr> <tr>
<td> <td>

View file

@ -0,0 +1,96 @@
{extends "../@layout.xml"}
{block title}{$user->getCanonicalName()}{/block}
{block header}
{$user->getCanonicalName()}
<img n:if="$user->isVerified()"
class="name-checkmark"
src="/assets/packages/static/openvk/img/checkmark.png"
/>
{/block}
{block content}
<div class="left_small_block">
<div>
<img src="{$user->getAvatarUrl('normal')}"
alt="{$user->getCanonicalName()}"
style="width: 100%; image-rendering: -webkit-optimize-contrast;" />
</div>
<div id="profile_links" n:if="isset($thisUser)">
<a style="width: 194px;" n:if="$user->getPrivacyPermission('messages.write', $thisUser)" href="/im?sel={$user->getId()}" class="profile_link">{_send_message}</a>
{var $subStatus = $user->getSubscriptionStatus($thisUser)}
{if $subStatus === 0}
<form action="/setSub/user" method="post" class="profile_link_form" id="addToFriends">
<input type="hidden" name="act" value="add" />
<input type="hidden" name="id" value="{$user->getId()}" />
<input type="hidden" name="hash" value="{$csrfToken}" />
<input type="submit" class="profile_link" value="{_friends_add}" style="width: 194px;" />
</form>
{elseif $subStatus === 1}
<form action="/setSub/user" method="post" class="profile_link_form" id="addToFriends">
<input type="hidden" name="act" value="add" />
<input type="hidden" name="id" value="{$user->getId()}" />
<input type="hidden" name="hash" value="{$csrfToken}" />
<input type="submit" class="profile_link" value="{_friends_accept}" style="width: 194px;" />
</form>
{elseif $subStatus === 2}
<form action="/setSub/user" method="post" class="profile_link_form" id="addToFriends">
<input type="hidden" name="act" value="rem" />
<input type="hidden" name="id" value="{$user->getId()}" />
<input type="hidden" name="hash" value="{$csrfToken}" />
<input type="submit" class="profile_link" value="{_friends_reject}" style="width: 194px;" />
</form>
{/if}
<a class="profile_link" style="display:block;width:96%;" href="javascript:reportUser()">{_report}</a>
<script>
function reportUser() {
uReportMsgTxt = "Вы собираетесь пожаловаться на данного пользователя.";
uReportMsgTxt += "<br/>Что именно вам кажется недопустимым в этом материале?";
uReportMsgTxt += "<br/><br/><b>Причина жалобы</b>: <input type='text' id='uReportMsgInput' placeholder='Причина' />"
MessageBox("Пожаловаться?", uReportMsgTxt, ["Подтвердить", "Отмена"], [
(function() {
res = document.querySelector("#uReportMsgInput").value;
xhr = new XMLHttpRequest();
xhr.open("GET", "/report/" + {$user->getId()} + "?reason=" + res + "&type=user", true);
xhr.onload = (function() {
if(xhr.responseText.indexOf("reason") === -1)
MessageBox("Ошибка", "Не удалось подать жалобу...", ["OK"], [Function.noop]);
else
MessageBox("Операция успешна", "Скоро её рассмотрят модераторы", ["OK"], [Function.noop]);
});
xhr.send(null);
}),
Function.noop
]);
}
</script>
</div>
</div>
<div class="right_big_block">
<div class="page_info">
<div class="accountInfo clearFix">
<div class="profileName">
<h2>{$user->getFullName()}</h2>
<div class="page_status" style="color: #AAA;">{_closed_page}</div>
</div>
</div>
<div class="msg msg_yellow" style="width: 93%;margin-top: 10px;">
{var $m = $user->isFemale() ? "f" : "m"}
{tr("limited_access_to_page_$m", $user->getFirstName())}
{if isset($thisUser)}
{if $subStatus != 2}
<br /><br />
{_you_can_add}
<a href="javascript:addToFriends.submit()">{tr("add_to_friends_$m")}</a>
{/if}
{else}
<br /><br />
{tr("register_to_access_page_$m")}
{/if}
</div>
</div>
</div>
{/block}

View file

@ -10,7 +10,6 @@
</a> </a>
{/if} {/if}
{elseif $attachment instanceof \openvk\Web\Models\Entities\Video} {elseif $attachment instanceof \openvk\Web\Models\Entities\Video}
{if !$attachment->isDeleted()}
{if $attachment->getType() === 0} {if $attachment->getType() === 0}
<div class="bsdn media" data-name="{$attachment->getName()}" data-author="{$attachment->getOwner()->getCanonicalName()}"> <div class="bsdn media" data-name="{$attachment->getName()}" data-author="{$attachment->getOwner()->getCanonicalName()}">
<video class="media" src="{$attachment->getURL()}"></video> <video class="media" src="{$attachment->getURL()}"></video>
@ -28,10 +27,6 @@
<img src="/assets/packages/static/openvk/img/videoico.png" /> <img src="/assets/packages/static/openvk/img/videoico.png" />
<a href="/video{$attachment->getPrettyId()}" id="videoOpen" data-id="{$attachment->getId()}">{$attachment->getName()}</a> <a href="/video{$attachment->getPrettyId()}" id="videoOpen" data-id="{$attachment->getId()}">{$attachment->getName()}</a>
</div> </div>
{else}
<span style="color:gray;">{_video_is_deleted}</span>
{/if}
{elseif $attachment instanceof \openvk\Web\Models\Entities\Poll} {elseif $attachment instanceof \openvk\Web\Models\Entities\Poll}
{presenter "openvk!Poll->view", $attachment->getId()} {presenter "openvk!Poll->view", $attachment->getId()}
{elseif $attachment instanceof \openvk\Web\Models\Entities\Note} {elseif $attachment instanceof \openvk\Web\Models\Entities\Note}

View file

@ -1013,6 +1013,11 @@ table.User {
background-color: #f5e9ec; background-color: #f5e9ec;
} }
.msg.msg_yellow {
border-color:#D4BC4C;
background-color:#F9F6E7;
}
.edit_link { .edit_link {
color: #c5c5c5; color: #c5c5c5;
font-family: verdana, arial, sans-serif; font-family: verdana, arial, sans-serif;

View file

@ -0,0 +1 @@
ALTER TABLE `profiles` ADD `profile_type` TINYINT(1) NOT NULL DEFAULT '0' AFTER `client_name`;

View file

@ -163,6 +163,18 @@
"before" = "before"; "before" = "before";
"forever" = "forever"; "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 */ /* Wall */
"feed" = "News"; "feed" = "News";
@ -653,6 +665,10 @@
"privacy_value_only_me_dative" = "Only me"; "privacy_value_only_me_dative" = "Only me";
"privacy_value_nobody" = "Nobody"; "privacy_value_nobody" = "Nobody";
"profile_type" = "Profile type";
"profile_type_open" = "Open";
"profile_type_closed" = "Closed";
"your_email_address" = "Your Email address"; "your_email_address" = "Your Email address";
"your_page_address" = "Your address page"; "your_page_address" = "Your address page";
"page_address" = "Address page"; "page_address" = "Address page";

View file

@ -140,6 +140,22 @@
"updated_at" = "Обновлено $1"; "updated_at" = "Обновлено $1";
"user_banned" = "К сожалению, нам пришлось заблокировать страницу пользователя <b>$1</b>."; "user_banned" = "К сожалению, нам пришлось заблокировать страницу пользователя <b>$1</b>.";
"user_banned_comment" = "Комментарий модератора:"; "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" = "Подтверждённая страница"; "verified_page" = "Подтверждённая страница";
"user_is_blocked" = "Пользователь заблокирован"; "user_is_blocked" = "Пользователь заблокирован";
"before" = "до"; "before" = "до";
@ -625,6 +641,9 @@
"privacy_value_only_me" = "Только я"; "privacy_value_only_me" = "Только я";
"privacy_value_only_me_dative" = "Только мне"; "privacy_value_only_me_dative" = "Только мне";
"privacy_value_nobody" = "Никто"; "privacy_value_nobody" = "Никто";
"profile_type" = "Тип профиля";
"profile_type_open" = "Открытый";
"profile_type_closed" = "Закрытый";
"your_email_address" = "Адрес Вашей электронной почты"; "your_email_address" = "Адрес Вашей электронной почты";
"your_page_address" = "Адрес Вашей страницы"; "your_page_address" = "Адрес Вашей страницы";
"page_address" = "Адрес страницы"; "page_address" = "Адрес страницы";