Приложение ВИШ — расписание РУТ (МИИТ)

Расписание Российского университета транспорта для студентов и сотрудников всех институтов. Расписание своей группы и любого преподавателя на день и на неделю, свободные аудитории МИИТ прямо сейчас, загруженность аудиторий, групп и преподавателей, уведомления об изменениях в расписании и ИИ-помощник по расписанию.

Институты

Приложение РУТ (МИИТ) охватывает пять институтов: ВИШ — Высшая инженерная школа, АГА — Академия гражданской авиации, АДХ — Академия дорожного хозяйства, ПИШ — Передовая инженерная школа «Академия ВСМ» и ИМТК — Институт международных транспортных коммуникаций. Расписание группы и расписание преподавателя ищутся одинаково в любом из них.

Что умеет приложение ВИШ
Разделы
Руководство

Права доступа (RBAC)

Обновлено 28.10.2026

Доступ в ВИШ строится на ролях (RBAC): у каждого аккаунта одна роль, у роли — набор прав, а методы API требуют определённых прав. Ключ API и токен OAuth права только сужают и никогда не расширяют. Сверено со стендом d1 23 октября 2026 года.

Роли

Роль определяет, что человек может в приложении. Встроенные роли:

КодРольКоротко
userПользовательБез дополнительных прав; так начинает каждый
teacherПреподавательЗаметки к занятиям; аккаунт связан с карточкой преподавателя
moderatorМодераторПравит расписание института
managerМенеджерМенеджер учебной программы
programHeadРуководитель программыРуководитель образовательной программы
analystАналитикСмотрит и выгружает сводную аналитику, ничего не меняет (пока только d1)
sales, adsManagerПродажи, Менеджер рекламыМеста, партнёры и рекламные кампании (пока только d1)
inspectorИнспекторВидит всё, ничего не меняет (режим просмотра)
developer, adminРазработчик, АдминистраторВсе права
team, product, colleagueКоманда VISH, Продакт, КоллегаВсе права, как у разработчика: сотрудники VISH, продакт-менеджеры и коллеги из партнёров. Новые права каталога получают сами; право, снятое администратором, не возвращается (пока только d1)
changelog-publisherПубликация «Что нового»Роль бота, которым CI публикует «Что нового»; больше ничего не может

Администраторы могут завести и свои роли. Роль аккаунта и его права — в ответе GET /auth/me (поля role и permissions).

Права

Право — строка вида область:объект:действие. Несколько, которые чаще всего нужны интеграциям:

ПравоЧто разрешает
schedule:note:create, schedule:note:update, schedule:note:deleteЗаметки к занятиям
schedule:lesson:create, schedule:lesson:update, schedule:lesson:deleteПравка расписания
schedule:lesson:notifyУведомить о занятии всех, у кого оно в расписании
analytics:readАналитика: /usage/export/…, /reports/institute, загруженность. Открытия пишутся в журнал аудита
analytics:exportВыгрузка аналитики файлом, например расписание в JSON через POST /exports (пока только d1)
students:readСписки студентов групп
api:keys:self-issueВыпустить API-ключ себе без заявки

Полный список с описаниями отдаёт GET /rbac/permissions — для него нужно право rbac:roles:read. Какие права требует конкретный метод, сказано в его описании в OpenAPI (/documentation).

Кроме прав, аккаунт можно ограничить группами и институтами: тогда даже с правом на правку человек правит только расписание своих групп.

Как проверяется запрос

  1. Кто вы. Ключ из X-Api-Key, иначе токен из Authorization: Bearer. Нет ни того ни другого — открытые методы отвечают как всем, остальные — 401 AUTH_REQUIRED.
  2. Права роли. Читаются заново при каждом запросе: если роль сменили, это действует сразу, а не когда истечёт токен.
  3. Сужение. У ключа права — пересечение того, что отметили при выпуске, и того, что роль даёт сейчас. У токена OAuth прав роли нет вовсе: только чтение из короткого списка методов, которые называет его scope.
  4. Режим просмотра. Аккаунт в режиме просмотра (роль «Инспектор») может только читать: любой изменяющий запрос — 403 VIEW_ONLY, с ключом тоже.
  5. Проверка метода. Нет нужного права — 403 FORBIDDEN, в error.message названы недостающие права.

Что значит 403

error.codeПричинаЧто делать
FORBIDDENУ роли или у ключа нет нужного права; оно названо в сообщенииЗапросить роль с этим правом или выпустить ключ с ним
VIEW_ONLYАккаунт в режиме просмотраИзменения — с другого аккаунта
SESSION_REQUIREDМетод только для человека в приложенииНе вызывать ключом или токеном OAuth
PERSON_REQUIREDМетод только для людей, не для ботов—
OAUTH_SCOPE_INSUFFICIENTТокену OAuth этот метод не разрешёнТолько методы из списка для scope

Опирайтесь на error.code: текст сообщения переводится и может меняться.

Как получить больше прав

  • Роль. В приложении — «Моя роль» (/role, или «Настройки» → «Доступ»): заявка на роль преподавателя или сотрудника. Её рассматривает сотрудник института; решение приходит уведомлением.
  • Ключ. Ключ не может больше, чем ваша роль. Если роль получила новые права, а ключ — нет, перевыпуск их не добавит (права и срок остаются прежними): нужен новый ключ — через заявку или выпуском себе, см. API и ключи доступа.
  • Приложение «Входа через ВИШ». Запрашивайте только те scope, что нужны; список разрешённых задаётся при регистрации.

Какие методы открыты

Открытый метод — тот, у которого в OpenAPI нет требования security. Пример считает такие методы по документу самого стенда:

// Count public and protected operations in the stand's own OpenAPI document.
const API = process.env.VISH_API ?? 'https://d1.vish-app.ru/api/v1'
const DOC = new URL('/documentation/json', API)

const response = await fetch(DOC)
if (!response.ok) throw new Error(`${DOC}: HTTP ${response.status}`)
const openapi = await response.json()

const operations = Object.entries(openapi.paths).flatMap(([path, methods]) =>
	Object.entries(methods).map(([method, operation]) => ({
		line: `${method.toUpperCase()} ${path}`,
		isPublic: !operation.security?.length,
	})),
)
const isPublic = (line) => operations.find((operation) => operation.line === line)?.isPublic

if (isPublic('GET /api/v1/groups') !== true || isPublic('GET /api/v1/auth/me') !== false) {
	throw new Error('unexpected security in the OpenAPI document')
}
const open = operations.filter((operation) => operation.isPublic && operation.line.startsWith('GET '))
console.log(`${operations.length} operations, ${open.length} public GETs, for example:`)
for (const operation of open.slice(0, 8)) console.log(' ', operation.line)

Свои роль и права можно посмотреть так (с ключом в поле «Ключ API»):

Попробовать запрос

Ключ нужен только методам с замком. Он живёт только на этой странице: не сохраняется, уходит лишь заголовком этого запроса и забывается, когда вы её покинете. Где взять ключ

Проверено: 2026-10, PWA aa337c45, platform bff65fce.