apiv2

package
v1.11.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 72 Imported by: 0

Documentation

Overview

Package apiv2 provides API endpoints for the application.

Package apiv2 provides API endpoints for the application.

Package apiv2 provides API endpoints for the application.

Package apiv2 provides API endpoints for the application.

Index

Constants

View Source
const LegacyCalendarPath = "/api/download_ics/:year/:term/:slug/events.ics"

LegacyCalendarPath is where the calendar feed was first served, by v1.

View Source
const RealtimePath = "/api/v2/realtime"

RealtimePath is the realtime socket, GET /api/v2/realtime?stream=<id>. It pushes the stream's RealtimeEvents, protojson encoded, one per text frame.

Served beside the gateway rather than through it, since gRPC-gateway cannot serve a websocket and MaxConnectionAge rules out gRPC streaming. It must be excluded from the gzip middleware, which would wrap the connection the upgrade has to hijack.

Variables

View Source
var ErrNoCredentials = errors.New("no credentials presented")

ErrNoCredentials means nothing was presented to authenticate with, as opposed to something presented and rejected. On endpoints serving anonymous callers the first answers normally and the second is an expired token that needs a 401 to refresh.

Functions

func MetricsHandler added in v1.7.10

func MetricsHandler() http.Handler

MetricsHandler serves the Prometheus exposition format for everything registered on the default registry, the gRPC server metrics included.

Types

type API

API is the grpc server for the v2 api. It implements the API's services, which are split for grouping rather than to be deployed apart: one process, one gateway mux, one set of interceptors.

func New

func New(db *gorm.DB, opts ...Option) *API

New creates a new API and assigns the given db and a logger

func (*API) AddBookmark

AddBookmark adds a new bookmark.

func (*API) AddCourseAdmin added in v1.9.0

AddCourseAdmin replaces v1's addAdminToCourse, including promoting a student or external participant to lecturer: without that role the administration pages that require the lecture permission would refuse them.

func (*API) AddStreamReaction added in v1.10.0

func (a *API) AddStreamReaction(ctx context.Context, req *protobuf.AddStreamReactionRequest) (*emptypb.Empty, error)

AddStreamReaction records the caller's reaction, replacing v1's addReaction, and tells the stream's viewers. A viewer has one reaction per stream; reacting again replaces it.

func (*API) ApproveChatMessage added in v1.10.0

ApproveChatMessage publishes a message that awaited approval to every viewer.

func (*API) CheckPasswordResetKey added in v1.9.0

func (a *API) CheckPasswordResetKey(ctx context.Context, req *protobuf.PasswordResetKeyRequest) (*emptypb.Empty, error)

CheckPasswordResetKey says whether a key still opens the set-password page; the page asks before showing the form, as the template redirected home instead.

func (*API) CloseChatPoll added in v1.10.0

CloseChatPoll closes the running poll and shows everyone the result.

func (*API) CopyCourse added in v1.9.0

CopyCourse replaces v1's copyCourse: the course's settings, every lecture and the administrators, into a new course in another semester.

func (*API) CopyLecture added in v1.9.0

CopyLecture replaces v1's copyStream. The policy has checked the source course; this checks the caller administers the target too, answering 404 as authorizeCourseAdmin does so the status cannot tell a missing course from someone else's.

v1's move deleted the wrong lecture: it reset the ID of the stream it then copied, so after CreateStream filled in the copy's ID, deleting "the original" deleted the copy. It also went on to delete after a failed create. Here the original's ID is taken first, and a failed create stops before anything is deleted.

func (*API) CreateCourse added in v1.9.0

CreateCourse replaces v1's createCourse, with the defaults the old form sent. Gated on the lecture permission by its policy.

func (*API) CreateFirstUser added in v1.9.0

func (a *API) CreateFirstUser(ctx context.Context, req *protobuf.CreateFirstUserRequest) (*emptypb.Empty, error)

CreateFirstUser creates the administrator of a fresh deployment, the one account that can exist before anyone can sign in. It serves anonymous callers for exactly as long as the users table is empty; getFrontendConfig reports that same state.

func (*API) CreateInfoPage added in v1.8.0

func (a *API) CreateInfoPage(ctx context.Context, req *protobuf.CreateInfoPageRequest) (*protobuf.InfoPage, error)

CreateInfoPage creates a page reachable at /{slug} immediately, without a redeploy.

func (*API) CreateIntegration added in v1.8.1

func (*API) CreateLectureHallAdmin added in v1.9.0

func (a *API) CreateLectureHallAdmin(ctx context.Context, req *protobuf.CreateLectureHallAdminRequest) (*protobuf.LectureHallAdmin, error)

CreateLectureHallAdmin creates a lecture hall the scheduler can assign lectures to.

func (*API) CreateLectureSections added in v1.9.0

CreateLectureSections replaces v1's createVideoSectionBatch. v1 bound the sections whole, stream_id included, so a request could add sections to any lecture; here they are the lecture's whatever is sent.

func (*API) CreateLectures added in v1.9.0

CreateLectures replaces v1's createLecture and, for uploads, its createVOD. The course-admin policy has checked the caller administers the course.

Differences from v1, each deliberate:

  • A VOD upload is what createVOD made, the call the old page used: a lecture waiting for its recording. v1's createLecture `vodup` branch handed a file that did not exist yet to the LRZ upload script and so always failed.
  • Only a livestream gets a stream key; ingest finds a lecture by it, and nothing is ever streamed into an upload or a premiere.
  • Each premiere of a series gets its own file, named by its own start. v1 named every one after the first start, so a series shared one file.
  • The lectures are created in one insert, all or none, rather than by saving the course with its streams appended.
  • v1 also kicked the workers after an ad-hoc lecture, but called NotifyWorkers without running the function it returns, so the minutely cron always did it; it still does.

Creating a lecture in a hall is left to any course administrator, as in v1, where the create form offered the hall to lecturers too; only changing an existing lecture's hall needs a server administrator (mayChangeLectureHall).

func (*API) CreateNotification added in v1.9.0

CreateNotification broadcasts a notification to users matching its target group.

func (*API) CreateServerNotification added in v1.9.0

CreateServerNotification creates a banner shown site-wide between start and expires.

func (*API) CreateToken added in v1.9.0

func (a *API) CreateToken(ctx context.Context, req *protobuf.CreateTokenRequest) (*protobuf.TokenSecret, error)

CreateToken issues a token and returns its secret. The secret is not stored anywhere the server can show it back: model.Token keeps only the value itself, so this response is the only time it is ever readable again.

func (*API) CreateUser added in v1.8.0

func (a *API) CreateUser(ctx context.Context, req *protobuf.CreateUserRequest) (*protobuf.UserSummary, error)

CreateUser creates a lecturer account and emails an invitation to set a password.

func (*API) DecideIntegrationAuthorization added in v1.10.0

DecideIntegrationAuthorization records the user's answer and says where to send the browser. Approving is the one step here that hands a credential to a third party, so it is a deliberate request that the page makes with a bearer token:

  • A cookie is attached by the browser to a request any page can trigger, so a cookie-authenticated caller is refused. A bearer token has to be set by script of this origin, and a foreign page cannot do that without a CORS preflight, which the API never grants. (The server-rendered form relied on SameSite defaults for this.)
  • The page that calls it is served with frame-ancestors 'none', so it cannot be clicked through from a framing page; see serveIntegrationAuthorization.

func (*API) DeleteBookmark

func (a *API) DeleteBookmark(ctx context.Context, req *protobuf.DeleteBookmarkRequest) (*emptypb.Empty, error)

DeleteBookmark deletes a bookmark.

func (*API) DeleteChatMessage added in v1.10.0

func (a *API) DeleteChatMessage(ctx context.Context, req *protobuf.DeleteChatMessageRequest) (*emptypb.Empty, error)

DeleteChatMessage removes a message, and its replies, for everyone.

func (*API) DeleteCourse added in v1.9.0

func (a *API) DeleteCourse(ctx context.Context, req *protobuf.DeleteCourseRequest) (*emptypb.Empty, error)

DeleteCourse replaces v1's deleteCourse.

func (*API) DeleteInfoPage added in v1.8.0

func (a *API) DeleteInfoPage(ctx context.Context, req *protobuf.DeleteInfoPageRequest) (*emptypb.Empty, error)

DeleteInfoPage deletes an info page; its route stops resolving immediately.

func (*API) DeleteLectureAttachment added in v1.9.0

func (a *API) DeleteLectureAttachment(ctx context.Context, req *protobuf.DeleteLectureAttachmentRequest) (*emptypb.Empty, error)

DeleteLectureAttachment replaces v1's deleteAttachment, which took the file ID alone: any course's administrators could delete any file, a recording or another lecture's thumbnail included. Here it must be one of the lecture's attachments; the custom thumbnail has deleteLectureThumbnail.

func (*API) DeleteLectureHallAdmin added in v1.9.0

func (a *API) DeleteLectureHallAdmin(ctx context.Context, req *protobuf.DeleteLectureHallAdminRequest) (*emptypb.Empty, error)

DeleteLectureHallAdmin deletes a lecture hall. Its streams keep playing but lose the hall association, matching the v1 handler's DeleteLectureHall dao call.

func (*API) DeleteLectureSection added in v1.9.0

func (a *API) DeleteLectureSection(ctx context.Context, req *protobuf.DeleteLectureSectionRequest) (*emptypb.Empty, error)

DeleteLectureSection replaces v1's deleteVideoSection, asking a worker to delete the thumbnail as it did. v1 answered 500 when the thumbnail's file row could not be read, after the section was already gone; that is only logged here.

func (*API) DeleteLectureSeries added in v1.9.0

func (a *API) DeleteLectureSeries(ctx context.Context, req *protobuf.DeleteLectureSeriesRequest) (*emptypb.Empty, error)

DeleteLectureSeries replaces v1's deleteLectureSeries, audited the same way and narrowed to the course as UpdateLectureSeries is.

func (*API) DeleteLectureThumbnail added in v1.9.0

func (a *API) DeleteLectureThumbnail(ctx context.Context, req *protobuf.DeleteLectureThumbnailRequest) (*emptypb.Empty, error)

DeleteLectureThumbnail deletes the custom thumbnail. v1 had no endpoint of its own: the old page sent the thumbnail's file ID to deleteAttachment, which this narrows to attachments.

custom_thumbnail_enabled is left alone, as v1's upload and delete left it: nothing sets it, and the player shows a custom thumbnail whenever there is one.

func (*API) DeleteLectures added in v1.9.0

func (a *API) DeleteLectures(ctx context.Context, req *protobuf.DeleteLecturesRequest) (*emptypb.Empty, error)

DeleteLectures replaces v1's deleteLectures. As there, nothing is deleted unless every lecture is the course's, and each deletion is audited; a foreign or missing lecture answers 404 rather than v1's 403, as courseLecture does everywhere else.

func (*API) DeleteMaintenanceEmailFailure added in v1.8.1

func (a *API) DeleteMaintenanceEmailFailure(ctx context.Context, req *protobuf.DeleteMaintenanceEmailFailureRequest) (*emptypb.Empty, error)

DeleteMaintenanceEmailFailure dismisses a failed email. It is not retried afterwards.

func (*API) DeleteMaintenanceTranscodingFailure added in v1.8.1

func (a *API) DeleteMaintenanceTranscodingFailure(ctx context.Context, req *protobuf.DeleteMaintenanceTranscodingFailureRequest) (*emptypb.Empty, error)

DeleteMaintenanceTranscodingFailure dismisses a recorded failure. It does not retry the transcode; a stream stuck this way is fixed the way it always has been.

func (*API) DeleteNotification added in v1.9.0

func (a *API) DeleteNotification(ctx context.Context, req *protobuf.DeleteNotificationRequest) (*emptypb.Empty, error)

DeleteNotification deletes a notification; it stops showing to users immediately.

func (*API) DeleteRunner added in v1.8.0

func (a *API) DeleteRunner(ctx context.Context, req *protobuf.DeleteRunnerRequest) (*emptypb.Empty, error)

DeleteRunner removes a runner's registration. Not a way to stop one: a runner still running re-registers on its next heartbeat.

func (*API) DeleteServerNotification added in v1.9.0

func (a *API) DeleteServerNotification(ctx context.Context, req *protobuf.DeleteServerNotificationRequest) (*emptypb.Empty, error)

DeleteServerNotification deletes a server notification; it stops showing immediately.

func (*API) DeleteToken added in v1.9.0

func (a *API) DeleteToken(ctx context.Context, req *protobuf.DeleteTokenRequest) (*emptypb.Empty, error)

DeleteToken revokes a token; it stops authenticating immediately.

func (*API) DeleteUser added in v1.8.0

func (a *API) DeleteUser(ctx context.Context, req *protobuf.DeleteUserRequest) (*emptypb.Empty, error)

DeleteUser deletes an account.

func (*API) DeleteWorker added in v1.8.1

func (a *API) DeleteWorker(ctx context.Context, req *protobuf.DeleteWorkerRequest) (*emptypb.Empty, error)

DeleteWorker removes a worker's registration. Not a way to stop one: a worker still running re-registers on its next heartbeat.

func (*API) EndStream added in v1.10.0

func (a *API) EndStream(ctx context.Context, req *protobuf.EndStreamRequest) (*emptypb.Empty, error)

EndStream ends a live stream early, replacing v1's GET /api/stream/:id/end. The manager marks the stream not live and ended, and tells the viewers over the realtime hub through its live-state notifier (see runner_manager.WithLiveStateNotifier), so this publishes nothing itself: a second StreamLiveEvent would only repeat it.

v1 took the stream from the URL without comparing it to the course, and ended it whether it was live or not; ending a stream that is not live would still mark it ended and stop a recording that has not started.

func (*API) ExportCourseStats added in v1.9.0

func (a *API) ExportCourseStats(ctx context.Context, req *protobuf.ExportCourseStatsRequest) (*httpbody.HttpBody, error)

ExportCourseStats is GetCourseStats as a downloadable file, replacing v1's exportStats for a course.

func (*API) ExportPersonalData

func (a *API) ExportPersonalData(ctx context.Context, req *emptypb.Empty) (*protobuf.ExportPersonalDataResponse, error)

ExportPersonalData exports the personal data of the current user.

func (*API) ExportServerStats added in v1.9.0

func (a *API) ExportServerStats(ctx context.Context, req *protobuf.ExportServerStatsRequest) (*httpbody.HttpBody, error)

ExportServerStats bundles the same data GetServerStats renders into charts as a single downloadable file, mirroring api/statistics.go's exportStats for its courseID == 0 case.

func (*API) GetActivePoll added in v1.10.0

GetActivePoll returns the stream's running poll, if there is one. Vote counts are the course administrators' alone while it runs, so that the tally does not sway the votes; everyone sees them when the poll closes.

func (*API) GetBookmarks

GetBookmarks retrieves bookmarks by stream ID.

func (*API) GetCourseAdmin added in v1.9.0

func (a *API) GetCourseAdmin(ctx context.Context, req *protobuf.GetCourseAdminRequest) (*protobuf.CourseAdmin, error)

GetCourseAdmin replaces what web.AdminPage rendered into the course settings tab.

func (*API) GetCourseBySlug

GetCourseBySlug retrieves a course by its slug, year, and term.

func (*API) GetCourseByToken added in v1.9.0

func (a *API) GetCourseByToken(ctx context.Context, req *protobuf.CourseTokenRequest) (*protobuf.CourseByToken, error)

GetCourseByToken names the course a token opens, for the page to show before asking.

func (*API) GetCourseStats added in v1.9.0

GetCourseStats is the course statistics page's data. The course-admin policy has checked the caller administers the course, and refused course 0, which the statistics queries would read as every course.

func (*API) GetFrontendConfig added in v1.7.10

func (a *API) GetFrontendConfig(ctx context.Context, req *emptypb.Empty) (*protobuf.GetFrontendConfigResponse, error)

GetFrontendConfig returns what the frontend needs to render its shell: branding, version and footer links. Public, because the shell renders before anyone signs in. Nothing in it is per-user.

func (*API) GetInfoPage added in v1.8.0

GetInfoPage returns an info page as HTML, rendered and sanitised here so that bluemonday stays the only thing deciding what may appear in the document.

func (*API) GetIntegration added in v1.9.0

func (a *API) GetIntegration(ctx context.Context, _ *emptypb.Empty) (*protobuf.GetIntegrationResponse, error)

func (*API) GetIntegrationAuthorization added in v1.10.0

GetIntegrationAuthorization is what the consent page shows. It changes nothing.

func (*API) GetLectureStats added in v1.9.0

GetLectureStats is the lecture statistics page's data, replacing v1's getStats with a `lecture` parameter. The course-admin policy has checked the course; this checks the stream is that course's. v1 did not, and several of the per-lecture queries filter on the stream alone, so any course's administrators could read any lecture's view counts by naming it.

func (*API) GetLectureTranscodingProgress added in v1.9.0

GetLectureTranscodingProgress replaces v1's getTranscodingProgress, which answered one version per request and 100 for a version with no progress row. The row is removed when a version finishes, so the absent versions are left out here, and an empty list means done. A version that failed stays listed, with the reason, until the next upload of it.

Read from the progress table rather than the lecture, whose cached copy can be ten seconds old: this is what the card polls.

func (*API) GetLiveCourses

func (a *API) GetLiveCourses(ctx context.Context, req *emptypb.Empty) (*protobuf.GetLiveCoursesResponse, error)

GetLiveCourses retrieves the currently live courses and their streams.

func (*API) GetLoginOptions added in v1.7.10

func (a *API) GetLoginOptions(ctx context.Context, req *emptypb.Empty) (*protobuf.GetLoginOptionsResponse, error)

GetLoginOptions reports which login methods this deployment offers, so that a client can render the right controls before anyone has authenticated.

func (*API) GetNotifications

func (a *API) GetNotifications(ctx context.Context, req *emptypb.Empty) (*protobuf.GetNotificationsResponse, error)

GetNotifications retrieves notifications for the current user.

func (*API) GetPinForCourse

GetPinForCourse checks if the user has pinned the course.

func (*API) GetPinnedCourses

func (a *API) GetPinnedCourses(ctx context.Context, req *emptypb.Empty) (*protobuf.GetPinnedCoursesResponse, error)

GetPinnedCourses retrieves the pinned courses for a user.

func (*API) GetProgressBatch

GetProgressBatch returns a batch of watch progresses for a list of streams for the current user

func (*API) GetPublicCourses

GetPublicCourses retrieves the public courses for a given semester.

func (*API) GetSchedule added in v1.9.0

GetSchedule replaces v1's schedule.ics for the administration schedule. v1 read a fixed window from a month ago to three months ahead, so the calendar showed nothing outside it; this reads whatever the calendar is showing. Gated on the lecture permission by its policy.

func (*API) GetSemesters

func (a *API) GetSemesters(ctx context.Context, req *emptypb.Empty) (*protobuf.GetSemestersResponse, error)

GetSemesters retrieves all available semesters and the current semester.

func (*API) GetServerNotifications

func (a *API) GetServerNotifications(ctx context.Context, req *emptypb.Empty) (*protobuf.GetServerNotificationsResponse, error)

GetServerNotifications retrieves current server notifications.

func (*API) GetServerStats added in v1.9.0

func (a *API) GetServerStats(ctx context.Context, _ *emptypb.Empty) (*protobuf.ServerStatsResponse, error)

GetServerStats returns the quick counters and charted activity for the server-wide statistics page. Gated on server.administer by its policy in services.go.

func (*API) GetStream

func (a *API) GetStream(ctx context.Context, req *protobuf.GetStreamRequest) (*protobuf.CourseStream, error)

GetStream returns a stream by its ID including the course and lecture hall

func (*API) GetStreamPlaylist

GetStreamPlaylist returns the playlist for a stream

func (*API) GetStreamSeekHeatmap added in v1.10.0

GetStreamSeekHeatmap returns where viewers jump to, replacing v1's GET /api/seekReport/:id.

func (*API) GetStreamWatch added in v1.10.0

func (a *API) GetStreamWatch(ctx context.Context, req *protobuf.GetStreamWatchRequest) (*protobuf.StreamWatch, error)

GetStreamWatch returns everything the watch page renders in one call, replacing web/watch.go's WatchPage and the template logic around it. Which layout to show is the URL's business and the viewer's saved preference, so v1's redirect to the preferred view is not here: default_layout says what to open with, and the client decides.

func (*API) GetSubtitles

func (a *API) GetSubtitles(ctx context.Context, req *protobuf.GetSubtitlesRequest) (*httpbody.HttpBody, error)

GetSubtitles returns the subtitles for a stream in a specific language

func (*API) GetThumbs

func (a *API) GetThumbs(ctx context.Context, req *protobuf.GetThumbsRequest) (*httpbody.HttpBody, error)

GetThumbs returns the thumbnails for a stream

func (*API) GetUser

func (a *API) GetUser(ctx context.Context, req *emptypb.Empty) (*protobuf.GetUserResponse, error)

GetUser retrieves the current user based on the context. It returns a GetUserResponse or an error if one occurs.

func (*API) GetUserCourses

GetUserCourses retrieves the courses for a user for a given semester.

func (*API) GetVideoSections

GetVideoSections returns a list of video sections for a stream

func (*API) HealthCheck

func (a *API) HealthCheck(ctx context.Context, req *emptypb.Empty) (*protobuf.HealthCheckResponse, error)

HealthCheck returns ok

func (*API) ImportCourseImportCourses added in v1.9.0

func (a *API) ImportCourseImportCourses(ctx context.Context, req *protobuf.CourseImportRequest) (*protobuf.CourseImportResponse, error)

ImportCourseImportCourses creates a course and its streams for each selected course, then emails its main contact an activation (or opt-out) link. A failure importing one course does not stop the others; the response reports each outcome so nothing is silently dropped, unlike the v1 handler this replaces, which concatenated errors into one string and either 500'd every course or reported none at all.

func (*API) InviteCourseParticipants added in v1.9.0

InviteCourseParticipants replaces v1's createUserForCourse, both its single and its batch form. An address without an account gets an external account, enrolled, and the invitation to set a password; one with an account is enrolled and told.

v1 ran a batch in the background, two seconds apart, to pace the mail. The mails are queued and sent at a configured rate by the mail cron now, so this answers once every invitee is handled, with how each went.

func (*API) ListAdministeredCourses added in v1.9.0

func (a *API) ListAdministeredCourses(ctx context.Context, _ *emptypb.Empty) (*protobuf.ListAdministeredCoursesResponse, error)

ListAdministeredCourses replaces the course list web.AdminPage rendered into the administration sidebar, every semester's. Gated on the lecture permission by its policy.

func (*API) ListAllowedStreamReactions added in v1.10.0

ListAllowedStreamReactions returns the emoji a viewer may react with, replacing v1's GET /api/stream/:id/reactions/allowed.

func (*API) ListAudits added in v1.9.0

ListAudits returns one page of the server-wide audit log, newest first. Gated on PermAdministerServer by its policy in services.go.

func (*API) ListChatMessages added in v1.10.0

ListChatMessages returns the stream's chat as the caller may see it: everything for the course's administrators, who moderate it, and otherwise the visible messages plus the caller's own, which they see while those await approval.

func (*API) ListChatUsers added in v1.10.0

ListChatUsers returns who has written in the stream's chat under their own name, for @-mentions.

func (*API) ListCourseAdmins added in v1.9.0

ListCourseAdmins replaces v1's getAdmins.

func (*API) ListCourseIntegrationGrants added in v1.9.0

func (*API) ListCourseLectureHallSettings added in v1.9.0

ListCourseLectureHallSettings replaces v1's lecture-halls-by-id.

func (*API) ListCourseLecturesAdmin added in v1.9.0

ListCourseLecturesAdmin is the lecture management list, replacing v1's GET /api/course/:courseID/lectures. Gated on administering the course.

v1 also answered signed playlist and download URLs, a colour and hasStats; the colour is the client's to derive from the state flags, hasStats was always false (the stats were never loaded), and the URLs are the player's business, so only which versions exist is carried here.

func (*API) ListCourseParticipants added in v1.9.0

ListCourseParticipants replaces the invitations table v1 rendered into the page: the external accounts enrolled in the course.

func (*API) ListInfoPages added in v1.8.0

func (a *API) ListInfoPages(ctx context.Context, req *emptypb.Empty) (*protobuf.ListInfoPagesResponse, error)

ListInfoPages lists every info page's slug and title, without its content: enough for a client to know a page exists before asking getInfoPage for it.

func (*API) ListInfoPagesAdmin added in v1.8.0

func (a *API) ListInfoPagesAdmin(ctx context.Context, req *emptypb.Empty) (*protobuf.ListInfoPagesAdminResponse, error)

ListInfoPagesAdmin lists every info page with its raw content, for editing.

func (*API) ListIntegrations added in v1.8.1

func (a *API) ListIntegrations(ctx context.Context, req *emptypb.Empty) (*protobuf.ListIntegrationsResponse, error)

func (*API) ListLectureHallsAdmin added in v1.9.0

func (a *API) ListLectureHallsAdmin(ctx context.Context, req *emptypb.Empty) (*protobuf.ListLectureHallsAdminResponse, error)

ListLectureHallsAdmin lists every lecture hall with its stream sources.

func (*API) ListMaintenanceCronJobs added in v1.8.1

func (a *API) ListMaintenanceCronJobs(ctx context.Context, req *emptypb.Empty) (*protobuf.ListMaintenanceCronJobsResponse, error)

ListMaintenanceCronJobs lists the jobs the scheduler knows by name, for the page to offer as choices before triggering one manually.

func (*API) ListMaintenanceEmailFailures added in v1.8.1

func (a *API) ListMaintenanceEmailFailures(ctx context.Context, req *emptypb.Empty) (*protobuf.ListMaintenanceEmailFailuresResponse, error)

ListMaintenanceEmailFailures lists every email that has exhausted its retries or is still failing, so an administrator can see why and dismiss the ones that are stale.

func (*API) ListMaintenanceTranscodingFailures added in v1.8.1

func (a *API) ListMaintenanceTranscodingFailures(ctx context.Context, req *emptypb.Empty) (*protobuf.ListMaintenanceTranscodingFailuresResponse, error)

ListMaintenanceTranscodingFailures lists every recorded transcoding failure.

func (*API) ListNotificationsAdmin added in v1.9.0

func (a *API) ListNotificationsAdmin(ctx context.Context, req *emptypb.Empty) (*protobuf.ListNotificationsAdminResponse, error)

ListNotificationsAdmin lists every notification ever broadcast, newest first.

Unlike GetNotifications (MetaService), this is not filtered by target: an administrator manages the whole history, not just the ones aimed at them.

func (*API) ListPolls added in v1.10.0

ListPolls returns the stream's closed polls with their results, for the course's administrators.

func (*API) ListRunners added in v1.8.0

func (a *API) ListRunners(ctx context.Context, req *emptypb.Empty) (*protobuf.ListRunnersResponse, error)

ListRunners returns every registered runner. Both endpoints here are gated on PermAdministerServer by their policy in services.go.

func (*API) ListScheduleLectureHalls added in v1.9.0

func (a *API) ListScheduleLectureHalls(ctx context.Context, _ *emptypb.Empty) (*protobuf.ListScheduleLectureHallsResponse, error)

ListScheduleLectureHalls names the halls the schedule can be filtered by. The template rendered the same list into the page for every lecturer; v2's listLectureHallsAdmin carries addresses and needs server.administer.

func (*API) ListServerNotificationsAdmin added in v1.9.0

func (a *API) ListServerNotificationsAdmin(ctx context.Context, req *emptypb.Empty) (*protobuf.ListServerNotificationsAdminResponse, error)

ListServerNotificationsAdmin lists every server notification, past, active and future, for editing. GetServerNotifications (MetaService, public) filters this down to what is currently active; the admin page needs the rest too.

func (*API) ListStaff added in v1.8.0

func (a *API) ListStaff(ctx context.Context, req *emptypb.Empty) (*protobuf.ListUsersResponse, error)

ListStaff returns the administrators and lecturers, with contact details unmasked.

That SearchUsers masks and this does not is inherited from the page they replace, and kept deliberately: what an administrator may see is a policy decision, not a port.

func (*API) ListTokens added in v1.9.0

func (a *API) ListTokens(ctx context.Context, req *emptypb.Empty) (*protobuf.ListTokensResponse, error)

ListTokens lists every issued token's owner, scope and usage. It never returns a token's secret: that is shown once, in the response to createToken, and nowhere else afterwards -- not even to the account that created it.

func (*API) ListWorkers added in v1.8.1

func (a *API) ListWorkers(ctx context.Context, req *emptypb.Empty) (*protobuf.ListWorkersResponse, error)

ListWorkers returns every registered worker, plus the token a new worker authenticates its registration with. Both endpoints here are gated on PermAdministerServer by their policy in services.go.

func (*API) OptInCourseByToken added in v1.9.0

func (a *API) OptInCourseByToken(ctx context.Context, req *protobuf.CourseTokenRequest) (*emptypb.Empty, error)

OptInCourseByToken switches an imported course on: visible to anyone signed in, with recordings, and no longer deleted if it was opted out before.

func (*API) OptOutCourseByToken added in v1.9.0

func (a *API) OptOutCourseByToken(ctx context.Context, req *protobuf.CourseTokenRequest) (*emptypb.Empty, error)

OptOutCourseByToken deletes an imported course the lecturer does not want streamed.

func (*API) PinCourse

PinCourse pins or unpins a course for the user.

func (*API) Proxy

func (a *API) Proxy() func(c *gin.Context)

Proxy returns a gin handler that proxies requests to the grpc gateway server

func (*API) RefreshLectureHallPresetsAdmin added in v1.9.0

func (a *API) RefreshLectureHallPresetsAdmin(ctx context.Context, req *protobuf.RefreshLectureHallPresetsAdminRequest) (*protobuf.LectureHallAdmin, error)

RefreshLectureHallPresetsAdmin fetches the presets configured on a hall's camera and replaces the stored list with them, matching v1's fetchLHPresets.

func (*API) RegenerateCourseThumbnails added in v1.10.0

func (a *API) RegenerateCourseThumbnails(ctx context.Context, req *protobuf.RegenerateCourseThumbnailsRequest) (*emptypb.Empty, error)

RegenerateCourseThumbnails starts a background job that asks a runner to redo the thumbnail for every available version (combined, camera, presentation) of every recorded lecture in the course. It returns as soon as the jobs are queued, the way GenerateMaintenanceThumbnails does for every course at once.

func (*API) RegisterLegacyCalendar added in v1.10.0

func (a *API) RegisterLegacyCalendar(r gin.IRoutes)

RegisterLegacyCalendar serves the feed at its original address, LegacyCalendarPath. People subscribed their calendars to it and apps poll it for years, so it must keep working. It answers in place rather than redirecting to the v2 address, because some calendar clients do not follow a redirect and would silently end the subscription.

func (*API) RemoveCourseAdmin added in v1.9.0

func (a *API) RemoveCourseAdmin(ctx context.Context, req *protobuf.RemoveCourseAdminRequest) (*protobuf.CourseAdminUser, error)

RemoveCourseAdmin replaces v1's removeAdminFromCourse, which refused to remove the last administrator: nobody but a server administrator could then reach the course.

func (*API) ReportStreamIssue added in v1.10.0

func (a *API) ReportStreamIssue(ctx context.Context, req *protobuf.ReportStreamIssueRequest) (*emptypb.Empty, error)

ReportStreamIssue forwards a viewer's problem report to the alert room, replacing v1's reportStreamIssue. Open to every signed-in viewer who may watch the stream: v1 allowed only the course's administrators, so a student's report was a 403.

func (*API) ReportStreamSeek added in v1.10.0

func (a *API) ReportStreamSeek(ctx context.Context, req *protobuf.ReportStreamSeekRequest) (*emptypb.Empty, error)

ReportStreamSeek counts one seek for the heatmap, replacing v1's POST /api/seekReport/:id. v1 neither checked the viewer could see the stream nor that the position was a number within it.

func (*API) RequestLectureSubtitles added in v1.9.0

func (a *API) RequestLectureSubtitles(ctx context.Context, req *protobuf.RequestLectureSubtitlesRequest) (*emptypb.Empty, error)

RequestLectureSubtitles replaces v1's requestSubtitles, sending the voice service the same request. v1 dialled it per request and answered 500 whatever went wrong; an unconfigured or unreachable voice service is a 503 here.

func (*API) ResetPassword

ResetPassword resets the password for the user with the given username.

func (*API) ResolveChatMessage added in v1.10.0

ResolveChatMessage marks a message, usually a question, as resolved.

func (*API) RetractChatMessage added in v1.10.0

RetractChatMessage hides an approved message again and drops its reactions.

func (*API) RevokeCourseIntegrationGrant added in v1.9.0

func (a *API) RevokeCourseIntegrationGrant(ctx context.Context, req *protobuf.RevokeCourseIntegrationGrantRequest) (*emptypb.Empty, error)

func (*API) RevokeIntegrationKey added in v1.8.1

func (a *API) RevokeIntegrationKey(ctx context.Context, req *protobuf.RevokeIntegrationKeyRequest) (*emptypb.Empty, error)

func (*API) RotateIntegrationKey added in v1.8.1

func (*API) Run

func (a *API) Run(lis net.Listener) error

Run starts the grpc server on port 12544 and the grpc gateway on ::8081/api/v2

func (*API) RunMaintenanceCronJob added in v1.8.1

func (a *API) RunMaintenanceCronJob(ctx context.Context, req *protobuf.RunMaintenanceCronJobRequest) (*emptypb.Empty, error)

RunMaintenanceCronJob executes a registered job immediately. Unlike the v1 route, which silently ignored a name it did not recognize, this refuses one — the page only ever offers names from ListMaintenanceCronJobs, so a mismatch means the scheduler changed underneath an open tab, and the caller should be told rather than shown a false success.

func (*API) Search added in v1.9.0

Search finds courses, lectures and subtitle lines the caller may see.

func (*API) SearchCourseImportSchedule added in v1.9.0

func (a *API) SearchCourseImportSchedule(ctx context.Context, req *protobuf.CourseImportSearchRequest) (*protobuf.CourseImportSearchResponse, error)

SearchCourseImportSchedule fetches the department's room schedule from TUMonline for the given date range, groups it by course and enriches each with its contacts and language, for an administrator to review before importing.

func (*API) SearchStreamSubtitles added in v1.10.0

SearchStreamSubtitles finds lines of one recording's subtitles, replacing v1's /api/search/stream/:id/subtitles. v1 returned Meilisearch's response as it came, ten hits at most.

func (*API) SearchTumOnlineCourses added in v1.9.0

SearchTumOnlineCourses replaces v1's searchCourse. Gated on the lecture permission by its policy.

func (*API) SearchUsers added in v1.8.0

SearchUsers searches every account, with contact details masked.

func (*API) SearchUsersForCourse added in v1.9.0

SearchUsersForCourse replaces v1's searchUserForCourse for finding someone to make an administrator. searchUsers needs users.manage, which a course's lecturers lack; this answers no more than v1 did: name, login and role.

func (*API) SendChatMessage added in v1.10.0

SendChatMessage writes a message in the stream's chat.

func (*API) SetDefaultCameraPresetAdmin added in v1.9.0

func (a *API) SetDefaultCameraPresetAdmin(ctx context.Context, req *protobuf.SetDefaultCameraPresetAdminRequest) (*emptypb.Empty, error)

SetDefaultCameraPresetAdmin marks one preset default for a hall and unsets the others, matching v1's updateLectureHallsDefaultPreset.

func (*API) SetPasswordByResetKey added in v1.9.0

func (a *API) SetPasswordByResetKey(ctx context.Context, req *protobuf.SetPasswordByResetKeyRequest) (*emptypb.Empty, error)

SetPasswordByResetKey sets the password of the user the key was mailed to and spends the key.

func (*API) StartChatPoll added in v1.10.0

StartChatPoll starts a poll, when none is running.

func (*API) SwitchCameraPreset added in v1.9.0

func (a *API) SwitchCameraPreset(ctx context.Context, req *protobuf.SwitchCameraPresetRequest) (*emptypb.Empty, error)

SwitchCameraPreset points the camera of a live stream's lecture hall at a preset, replacing v1's switchPreset. The course-admin policy has already checked the course; this checks that the stream is that course's, and takes the hall from the stream rather than the request. v1 took both from the URL and checked neither, so any course's administrators could move any room's camera.

func (*API) TakeCameraPresetSnapshotAdmin added in v1.9.0

func (a *API) TakeCameraPresetSnapshotAdmin(ctx context.Context, req *protobuf.TakeCameraPresetSnapshotAdminRequest) (*protobuf.CameraPresetAdmin, error)

TakeCameraPresetSnapshotAdmin moves the camera to the preset, waits for it to arrive, and photographs it, matching v1's takeSnapshot.

func (*API) ToggleChatReaction added in v1.10.0

ToggleChatReaction adds the caller's reaction to a message, or removes it when they have reacted with that emoji already.

func (*API) UpdateBookmark

UpdateBookmark updates an existing bookmark.

func (*API) UpdateCourseLectureHallSettings added in v1.9.0

UpdateCourseLectureHallSettings replaces v1's presets POST. As there, what is sent replaces every hall's settings. Unlike there, a hall must be one the course has lectures in and a preset one of that hall's: v1 stored whatever it was sent.

func (*API) UpdateCourseSettings added in v1.9.0

func (a *API) UpdateCourseSettings(ctx context.Context, req *protobuf.UpdateCourseSettingsRequest) (*protobuf.CourseAdmin, error)

UpdateCourseSettings replaces web.UpdateCourse, the settings tab's form post. Only the fields present change; v1's form sent every one of them, unticked boxes as off.

v1's form also carried the "reload from TUMOnline" buttons, but their labels no longer matched what the handler compared against, so they saved the settings instead. They are left out here rather than ported broken.

func (*API) UpdateInfoPage added in v1.8.0

func (a *API) UpdateInfoPage(ctx context.Context, req *protobuf.UpdateInfoPageRequest) (*protobuf.InfoPage, error)

UpdateInfoPage replaces an info page's slug, title and content.

func (*API) UpdateLecture added in v1.9.0

func (a *API) UpdateLecture(ctx context.Context, req *protobuf.UpdateLectureRequest) (*emptypb.Empty, error)

UpdateLecture replaces v1's renameLecture, updateDescription, updateLectureTime, setLectureHall for one lecture, and the stream chat and visibility toggles. The course-admin policy has checked the course; courseLecture checks the lecture is that course's, which v1 did not.

Everything is validated before anything is written, so a bad hall or time leaves the lecture as it was.

Renames, description changes and new times reach everyone watching over the realtime socket, as v1 pushed the first two over its own.

func (*API) UpdateLectureHallAdmin added in v1.9.0

func (a *API) UpdateLectureHallAdmin(ctx context.Context, req *protobuf.UpdateLectureHallAdminRequest) (*protobuf.LectureHallAdmin, error)

UpdateLectureHallAdmin replaces a lecture hall's name, stream protocol and sources.

func (*API) UpdateLectureSection added in v1.9.0

func (a *API) UpdateLectureSection(ctx context.Context, req *protobuf.UpdateLectureSectionRequest) (*emptypb.Empty, error)

UpdateLectureSection replaces v1's updateVideoSection, which wrote through gorm's Updates and so silently kept the old value for anything set to zero: a section could not be moved to the start of the hour, nor of the lecture. v1 also kept the thumbnail of the old start; a moved section has its thumbnail made again.

func (*API) UpdateLectureSeries added in v1.9.0

func (a *API) UpdateLectureSeries(ctx context.Context, req *protobuf.UpdateLectureSeriesRequest) (*emptypb.Empty, error)

UpdateLectureSeries replaces v1's updateLectureSeries, which copied a lecture's already-saved name and description to its series. This takes the values instead, and also sets the hall and chat, which the old page had to send per lecture.

Narrowed to the course: v1 matched on the series identifier alone, which a copied lecture carries into its new course.

func (*API) UpdateLectureSeriesTime added in v1.9.0

func (a *API) UpdateLectureSeriesTime(ctx context.Context, req *protobuf.UpdateLectureSeriesTimeRequest) (*emptypb.Empty, error)

UpdateLectureSeriesTime replaces v1's updateLectureTime followed by updateLectureSeriesTime, the two calls the old page made in turn: the lecture takes the new times and the rest of its series their time of day and duration, each keeping its date. In one transaction rather than two requests, and narrowed to the course as UpdateLectureSeries is.

func (*API) UpdateLecturesLectureHall added in v1.9.0

func (a *API) UpdateLecturesLectureHall(ctx context.Context, req *protobuf.UpdateLecturesLectureHallRequest) (*emptypb.Empty, error)

UpdateLecturesLectureHall replaces v1's setLectureHall for the lectures selected on the course page. Server administrators only, as for the hall in UpdateLecture.

Nothing is written unless every lecture is the course's, and an unknown hall is the request's mistake rather than a missing resource: the lectures are what the path names.

func (*API) UpdateProgress

func (a *API) UpdateProgress(ctx context.Context, req *protobuf.UpdateProgressRequest) (*protobuf.StreamProgress, error)

UpdateProgress updates the watch progress for a stream

func (*API) UpdateServerNotification added in v1.9.0

UpdateServerNotification replaces a server notification's text, severity and active window.

func (*API) UpdateUserRole added in v1.8.0

func (a *API) UpdateUserRole(ctx context.Context, req *protobuf.UpdateUserRoleRequest) (*protobuf.UserSummary, error)

UpdateUserRole sets an account's role.

func (*API) UpdateUserSettings

UpdateUserSettings updates the profile settings for the current user.

func (*API) VotePoll added in v1.10.0

VotePoll records the caller's vote in the stream's running poll. A vote is final.

type CamService added in v1.9.0

type CamService interface {
	For(address string, cameraType model.CameraType) (camera.Cam, error)
}

CamService hands out a controller for one camera. Declared here rather than taken from pkg/camera so the tests can stand in a fake; *camera.Service satisfies it.

The same interface exists in pkg/runner_manager for the same reason.

type CourseRequest added in v1.8.0

type CourseRequest interface {
	GetCourseId() uint32
}

CourseRequest is the request of an RPC that acts on one course.

type Option added in v1.9.0

type Option func(*API)

Option configures an API beyond what it needs to exist. What is optional here is what the API can serve without: an API with no camera service still answers every endpoint that does not touch a camera.

func WithCamService added in v1.9.0

func WithCamService(cams CamService) Option

WithCamService gives the API access to the lecture hall cameras. Without it the endpoints that reach a camera refuse; everything else works, which is what keeps the camera out of the tests that do not care about it.

func WithMassStorage added in v1.9.0

func WithMassStorage(dir string) Option

WithMassStorage sets where uploaded attachments and thumbnails are written, the same directory v1 writes them to.

func WithPresetImageDir added in v1.9.0

func WithPresetImageDir(dir string) Option

WithPresetImageDir sets where a preset's snapshot is written. In production this is the static directory the images are then served from, so a snapshot taken here appears under /public.

func WithRealtimeHub added in v1.10.0

func WithRealtimeHub(hub realtimehub.Hub) Option

WithRealtimeHub shares the hub the realtime socket reads from with the producers that publish to it from outside this package.

func WithSearch added in v1.9.0

func WithSearch(s Search) Option

WithSearch gives the API its search. Without one, searching answers 503.

func WithSectionImages added in v1.9.0

func WithSectionImages(s SectionImages) Option

WithSectionImages lets the section endpoints have thumbnails made. Without it the sections are still saved, they just get no thumbnail.

func WithStreamEnder added in v1.10.0

func WithStreamEnder(s StreamEnder) Option

WithStreamEnder gives the API the means to end a live stream. Without one, endStream answers 503.

func WithSubtitleGenerator added in v1.9.0

func WithSubtitleGenerator(client pb.SubtitleGeneratorClient, authToken string) Option

WithSubtitleGenerator connects requestLectureSubtitles to the voice service. Without it the endpoint answers 503, the voice service being an optional deployment.

func WithSubtitleSearch added in v1.10.0

func WithSubtitleSearch(m tools.MeiliSearchInterface) Option

WithSubtitleSearch gives the API its Meilisearch for searching inside one recording's subtitles. Without one, that search answers 503.

func WithTUMOnline added in v1.9.0

func WithTUMOnline(t TUMOnline) Option

WithTUMOnline gives the API access to TUMOnline. Without it the course search refuses and a new course is created without its lectures and enrolments.

func WithThumbnails added in v1.10.0

func WithThumbnails(t Thumbnails) Option

WithThumbnails lets RegenerateCourseThumbnails reach a runner. Without it the RPC answers 503.

func WithUploads added in v1.11.0

func WithUploads(u Uploads) Option

WithUploads lets uploading a lecture's recording reach a runner. Without it the upload answers 503.

type Search interface {
	Search(ctx context.Context, user *model.User, query string, limit int64, scope search.SearchScope) (search.SearchHits, error)
}

Search is what the search RPC runs on; search.SearchCatalog in production, which carries v1's filters so both APIs find the same things.

type SectionImages added in v1.9.0

type SectionImages interface {
	// Generate makes the thumbnails of sections from the recording at playlistURL,
	// which must be signed. It blocks until the job is handed off.
	Generate(streamID uint, playlistURL string, course model.Course, sections []model.VideoSection) error
	// Delete asks a worker to delete a section thumbnail's file.
	Delete(path string) error
}

SectionImages generates and deletes the thumbnails of a lecture's sections. The generation goes to a runner or else a worker, and the worker half only exists in api/, so it is handed in; api.SectionImages satisfies it.

type StreamEnder added in v1.10.0

type StreamEnder interface {
	EndStream(ctx context.Context, streamID uint, discardVoD bool) error
}

StreamEnder stops a live stream where it is being recorded. *runner_manager.Manager satisfies it.

type StreamRequest

type StreamRequest interface {
	GetStreamId() uint32
}

type TUMOnline added in v1.9.0

type TUMOnline interface {
	SearchCourses(q string, limit int64) ([]search.PrefetchedCourse, error)
	// SyncCourse starts fetching and returns; the work outlives the request.
	SyncCourse(course model.Course)
}

TUMOnline is what course creation needs of TUMOnline: its course list to fill a new course in from, and the lectures and enrolments to fetch once one exists. Declared here so the tests can stand in a fake; tum.Catalog satisfies it.

type Thumbnails added in v1.10.0

type Thumbnails interface {
	// Regenerate asks a runner to redo the thumbnail for one version of one VOD.
	// playlistURL must be signed.
	Regenerate(streamID uint, version model.StreamVersion, playlistURL string) error
}

Thumbnails regenerates one VOD's large thumbnail. Only a runner understands the versions PlaylistUrl, PlaylistUrlCAM and PlaylistUrlPRES stand for, so the worker half that SectionImages has has no equivalent here. See WithThumbnails.

type UploadTarget added in v1.11.0

type UploadTarget struct {
	Host string
	Port int
	// Token is single use and tells the runner which lecture the file belongs to.
	Token string
}

UploadTarget is where a runner takes one upload.

type Uploads added in v1.11.0

type Uploads interface {
	// Reserve picks a runner and returns where to send the file for the given version of
	// the stream. The runner learns which stream and version through the token.
	Reserve(ctx context.Context, streamID uint, version model.StreamVersion) (UploadTarget, error)
}

Uploads reserves a runner for a lecture's uploaded recording. Only a runner converts uploads, so without one (see WithUploads) uploading answers 503.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL