Социальная сеть своими руками

Социальная сеть своими руками

Сегодня расскажу про создание простой социальной сети на Node.js и MongoDB. В основе будет использован декларативный фреймворк Evado, который обеспечивает готовую инфраструктуру многопользовательского приложения.

Итак, первым делом устанавливаем и запускаем шаблон приложения, как описано в инструкции. Далее переходим в веб-интерфейс и создаем метаданные нашей социальной сети.

Создание метаданных

Переходим в модуль Студия и создаем класс Аватар (avatar) для графического отображения пользователя. Добавляем атрибут Файл (file) с типом Файл. На вкладке Поведения создаем поведение c типом Файл. Поведение обеспечивает дополнительный функционал класса. В данном случае - это работа с файлами (загрузка, отображение, скачивание).

Создаем класс Участник (member), который будет представлять пользователей нашей социальной сети. Добавляем атрибут Пользователь (user) с типом Пользователь для связи участника с системным аккаунтом. Добавляем строковый атрибут Имя (name). Добавляем ссылочный атрибут Аватар (avatar) на класс Аватар.

Метаданные социальной сети
Метаданные социальной сети
Метаданные социальной сети

Далее создаем класс Друг (friend), который будет представлять дружбу между двумя участниками социальной сети. Добавляем ссылочный атрибут Инициатор (initiator) на класс Участник для того, кто создал дружбу. Добавляем ссылочный атрибут Приглашенный (invitee) на класс Участник для того, кто был приглашен дружить. Кроме этого добавляем служебный атрибут Дата создания (_createdAt), который отображает время создания дружбы.

Приглашение дружить

Для дружбы в нашей социальной сети необходимо, чтобы один из участников оправил приглашение другому, который его подтвердит. Создаем класс Приглашение (invitation). Добавляем ссылочные атрибуты Отправитель (sender) и Получатель (recipient) на класс Участник. Для атрибута Получатель добавляем валидатор RecipientValidator, который проверяет не существует ли уже приглашение для этих участников или не являются ли друзьями отправитель и получатель:

Для сопроводительного сообщения приглашения добавляем текстовый атрибут Текст (text). Кроме того, добавляем два служебных атрибута - Дата создания (_createdAt) и Состояние (_state).

Переходим на вкладку Состояния и создаем состояние Ожидание (pending). Ставим флажки По умолчанию и Только для чтения. В этом состоянии приглашение будет находиться сразу после создания. Далее создаем состояние Принято (accepted), в котором находится приглашение после одобрения приглашенным участником. И, наконец, добавляем состояние Отказано (declined), для случая, когда участник отверг приглашение.

Переходы состояний для класса Приглашение
Переходы состояний для класса Приглашение
Переходы состояний для класса Приглашение

На вкладке Переходы отображаются возможные изменения состояний. Создаем переход Принять (accept) с начальными состояниями Ожидание, Отказано и конечным состоянием Принято. Создаем переход Отказать (decline) из начального состояния Ожидание в конечное - Отказано. Для каждого из переходов укажем условие, что только участник, являющийся получателем приглашение может выполнить переход:

{"recipient":"$user.meta.base.member"}.

После принятия приглашения необходимо создать объект класса Друг, а после отказа - отправить уведомление. Для этого необходимо создать пользовательское поведение InvitationBehavior и подключить его на вкладке Поведения:

Обратные ссылки

Обратные ссылки не хранятся в объекте, а вычисляются на основе заданного отношения. Переходим в класс Аватар и добавляем атрибут Владелец (owner) как обратную ссылку на класс Участник и атрибут Аватар. Таким образом мы находим участника из аватара, которому он принадлежит.

Атрибут обратная ссылка вычисляет значение из отношения
Атрибут обратная ссылка вычисляет значение из отношения
Атрибут обратная ссылка вычисляет значение из отношения

Далее переходим в класс Участник и добавляем обратную ссылку Друзья (friends) на класс Друг. Заметим, что однозначно определить ссылочный атрибут нельзя, так как участник может быть как инициатором дружбы, так и приглашенным. Для такого случая напишем свой фильтр друзей и укажем его в отношении:

Для отображения поступивших участнику приглашений добавляем обратную ссылку Входящие приглашения (incomingInvitations) на класс Приглашение и атрибут Получатель. А для приглашений, которые отправил участник, создадим обратную ссылку Исходящие приглашения (outgoingInvitations) на класс Приглашение и атрибут Отправитель.

Вычисляемые атрибуты

При просмотре участника социальной сети необходимо видеть в каких отношениях он состоит с текущим пользователем. Для этого создадим вычисляемый атрибут Статус дружбы (friendStatus) и укажем источником значения FriendStatusExpression:

Представления классов

Представления переопределяют параметры класса для отображения объектов в различных случаях (например, в списке, в форме редактирования и т.п.).

Переходим в класс Участник и создаем представление Публичный список (publicList), в котором добавляем только атрибуты Имя и Аватар. Теперь при запросе списка участников в данном представлении будет возвращаться только указанная информация.

Представление Публичный список класса Участник
Представление Публичный список класса Участник
Представление Публичный список класса Участник

Создаем представление Публичный просмотр (publicView) для просмотра участника другими пользователями. Добавляем атрибуты Имя, Аватар, Статус дружбы и Друзья. Чтобы пользователь не мог изменить данные объекта в публичных представлениях, ставим у них флажок Только для чтения.

Экспортируем созданные метаданные в приложение кнопкой на верхней панели.

Утилиты

Утилиты определяют дополнительный функционал доступный для пользователей системы.

Создадим утилиту, которая отправляет приглашение от текущего пользователя просматриваемому участнику. Метод isActive проверяет доступность утилиты - не являетесь ли вы уже друзьями или не имеется ли уже приглашение. Метод execute создает объект приглашения, назначая отправителем текущего пользователя, а получателем - просматриваемого участника.

Подключение утилиты происходит в файле конфигурации приложения:

  • Class - местоположение утилиты в приложении;
  • name - название утилиты;
  • enabled - включена или выключена;
  • css - класс стилей используемый для кнопки утилиты;
  • frontClass - управляющий клиентский класс (на стороне браузера);
  • actions - действия с объектом, при которых утилита доступна;
  • targetClass - класс метаданных.

Теперь при открытии формы участника социальной сети, если он не является вашим другом, появится кнопка запуска утилиты:

Создание приглашения через утилиту
Создание приглашения через утилиту
Создание приглашения через утилиту

Права доступа

Система безопасности фреймворка Evado основана на ролевом доступе. Пользователю может быть назначены одна или несколько ролей. Каждая роль может иметь разрешения доступа к некоторому функционалу. Каждое разрешение может иметь правило, ограничивающее его применение в момент проверки.

Переходим в модуль Администрирование в меню Безопасность - Роли и создаем роль Участник (member). Для того, чтобы эта роль назначалась по умолчанию для зарегистрированных пользователей добавляем в конфигурацию (config/default.js):

auth: { defaultAssignments: ['member'] }

На вкладке Разрешения добавляем следующие разрешения:

  • moduleOffice для доступа к модулю Офис;
  • moduleApiBaseUpload для загрузки файлов, определенных в метаданных;
  • utilityInviteFriend для доступа к утилите создания приглашения.

Далее переходим в меню Разрешения метаданных. Первым делом создаем разрешение позволяющее участнику читать объекты классов Аватар, Друг и представлений Публичный список, Публичный просмотр класса Участник.

В разрешениях метаданных иерархия доступа определяется структурой сущностей. Например, предоставление чтения для класса автоматически дает такое же право для всех его представлений и т.п.

Создаем разрешение участнику читать и изменять приглашения, которые он получает. Для этого добавляем правило Получатель (recipient), проверяющее, что атрибут Получатель у объекта Приглашения равен текущему пользователю.

Создаем разрешение на все действия с объектами классов Аватар и Приглашение, созданные участником. Для проверки авторства подключаем правило Создатель (creator).

Для того, чтобы изменения вступили в силу перезапускаем безопасность кнопкой на верхней панели.

Итог

Готовое приложение социальной сети доступно для запуска, изучения и модификации.