Documentation
¶
Index ¶
- Constants
- Variables
- func AdminCourseJson(c *model.Course, lhs []model.LectureHall, u *model.User) []gin.H
- func AdminOfCourse(c *gin.Context)
- func AdminToken(daoWrapper dao.DaoWrapper) gin.HandlerFunc
- func CourseListContains(courses []model.Course, courseId uint) bool
- func CreateAccessToken(user uint, samlSubjectID *string) (string, error)
- func ErrorHandler(c *gin.Context)
- func GetCacheItem(key string) (interface{}, bool)
- func InitBranding()
- func InitContext(daoWrapper dao.DaoWrapper) gin.HandlerFunc
- func InitCourse(wrapper dao.DaoWrapper) gin.HandlerFunc
- func InitCronService()
- func InitStream(wrapper dao.DaoWrapper) gin.HandlerFunc
- func InitStreamRealtime() realtime.SubscriptionMiddleware
- func LoadConfig()
- func LoggedIn(c *gin.Context)
- func MaskEmail(email string) (masked string, err error)
- func MaskLogin(login string) (masked string)
- func OwnerOfCourse(c *gin.Context)
- func RenderErrorPage(c *gin.Context, status int, message string)
- func RequirePermission(p model.Permission) gin.HandlerFunc
- func SearchCourses(q string, filter string) *meilisearch.SearchResponse
- func SetCacheItem(key string, value interface{}, ttl time.Duration)
- func SetSignedPlaylists(s *model.Stream, user *model.User, allowDownloading bool) error
- func SetTemplateExecutor(e TemplateExecutor)
- func StartSession(c *gin.Context, data *SessionData)
- func Truncate(input string, length int) string
- func TruncateHtml(buf []byte, maxlen int, ellipsis string) ([]byte, error)
- func UploadLRZ(file string) error
- type Branding
- type CanonicalURL
- type Config
- type CronService
- type DebugTemplateExecutor
- type ErrorPageData
- type ExportDataEntry
- type ExportStatsContainer
- type JWTClaims
- type JWTPlaylistClaims
- type MailConfig
- type Mailer
- type MeiliCourse
- type MeiliExporter
- type MeiliSearchInterface
- type MeiliStream
- type MeiliSubtitles
- type ReleaseTemplateExecutor
- type RequestError
- type SessionData
- type TUMLiveContext
- type TemplateExecutor
Constants ¶
const ( PageNotFoundErrMsg = "This page does not exist." CourseNotFoundErrMsg = "We couldn't find the course you were looking for." StreamNotFoundErrMsg = "We couldn't find the stream you were looking for." ForbiddenGenericErrMsg = "You don't have permissions to access this resource. " + "Please reach out if this seems wrong :)" ForbiddenStreamAccess = "You don't have permissions to access this stream. " + "Please make sure to use the correct login." ForbiddenCourseAccess = "You don't have permissions to access this course. " + "Please make sure to use the correct login." )
const ( CSVSep = "," CSVLb = "\n\r" )
const AccessTokenTTL = time.Minute * 15
AccessTokenTTL is how long a bearer access token stays valid. Clients hold them in memory and re-mint from the session cookie, so they are far shorter-lived.
const SessionTTL = time.Hour * 24 * 7
SessionTTL is how long a browser session cookie stays valid.
Variables ¶
var ( ErrUnbalancedTags = errors.New("unbalanced tags") TagExpr = regexp.MustCompile("<(/?)([A-Za-z0-9]+).*?>") EntityExpr = regexp.MustCompile("&#?[A-Za-z0-9]+;") )
var CookieSecure = false
CookieSecure sets whether to use secure cookies or not, defaults to false in dev mode, true in production
var ErrMeiliNotConfigured = errors.New("meilisearch is not configured")
var VersionTag = "development"
VersionTag is the build's version, set from main via ldflags, "development" when unstamped. Here rather than in web so the v2 API need not import the frontend it is replacing.
Functions ¶
func AdminCourseJson ¶
AdminCourseJson is the JSON representation of a courses streams for the admin panel
func AdminOfCourse ¶
AdminOfCourse checks if the user is an admin of the course or admin. If not, aborts with status Forbidden.
func AdminToken ¶
func AdminToken(daoWrapper dao.DaoWrapper) gin.HandlerFunc
func CourseListContains ¶
CourseListContains checks whether courses contain a course with a given courseId
func CreateAccessToken ¶ added in v1.7.10
CreateAccessToken mints a short-lived `Authorization: Bearer` credential for the v2 API, signed with the same key and claims as a session cookie.
func ErrorHandler ¶
func GetCacheItem ¶
GetCacheItem returns the value of the key if it exists in the cache. (nil, err) otherwise
func InitBranding ¶
func InitBranding()
InitBranding initializes the global branding configuration variable `BrandingCfg`. If the config file doesn't exist it will be set to the result of `getDefaultBranding()`.
func InitContext ¶
func InitContext(daoWrapper dao.DaoWrapper) gin.HandlerFunc
func InitCourse ¶
func InitCourse(wrapper dao.DaoWrapper) gin.HandlerFunc
func InitStream ¶
func InitStream(wrapper dao.DaoWrapper) gin.HandlerFunc
func InitStreamRealtime ¶
func InitStreamRealtime() realtime.SubscriptionMiddleware
func LoadConfig ¶
func LoadConfig()
func LoggedIn ¶
LoggedIn is a middleware that checks if the user is logged in and redirects to the login page if not
func OwnerOfCourse ¶
func RenderErrorPage ¶
RenderErrorPage renders the error page with the given error code and message. the gin context is always aborted after this function is called.
func RequirePermission ¶ added in v1.7.10
func RequirePermission(p model.Permission) gin.HandlerFunc
RequirePermission aborts with Forbidden unless the caller holds the permission. A route group states the capability it needs rather than the role that has it, so moving a capability between roles is a change to model.rolePermissions alone.
func SearchCourses ¶
func SearchCourses(q string, filter string) *meilisearch.SearchResponse
func SetCacheItem ¶
SetCacheItem adds the key and value to the cache with the given expiration time.
func SetSignedPlaylists ¶
SetSignedPlaylists adds a signed jwt to all available playlist urls that indicates that the user is allowed to consume the playlist. The method assumes that the user has been pre-authorized and doesn't check for permissions.
func SetTemplateExecutor ¶
func SetTemplateExecutor(e TemplateExecutor)
SetTemplateExecutor sets the templates and template executor for the middlewares to execute error pages
func StartSession ¶
func StartSession(c *gin.Context, data *SessionData)
func TruncateHtml ¶
TruncateHtml will truncate a given byte slice to a maximum of maxlen visible characters and optionally append ellipsis. HTML tags are automatically closed generating valid truncated HTML. Based on: https://github.com/mborgerson/GoTruncateHtml
Types ¶
type CanonicalURL ¶
type CanonicalURL struct {
// contains filtered or unexported fields
}
func NewCanonicalURL ¶
func NewCanonicalURL(url string) CanonicalURL
func (CanonicalURL) Course ¶
func (c CanonicalURL) Course(year int, term string, slug string) string
func (CanonicalURL) Info ¶
func (c CanonicalURL) Info(version string) string
func (CanonicalURL) Login ¶
func (c CanonicalURL) Login() string
func (CanonicalURL) Root ¶
func (c CanonicalURL) Root() string
type Config ¶
type Config struct {
Lrz struct {
Name string `yaml:"name"`
Email string `yaml:"email"`
Phone string `yaml:"phone"`
UploadURL string `yaml:"uploadUrl"`
SubDir string `yaml:"subDir"`
} `yaml:"lrz"`
Mail MailConfig `yaml:"mail"`
Db struct {
User string `yaml:"user"`
Password string `yaml:"password"`
Database string `yaml:"database"`
Host string `yaml:"host"`
Port uint `yaml:"port"`
} `yaml:"db"`
Campus struct {
Base string `yaml:"base"`
Tokens []string `yaml:"tokens"`
CampusProxy *struct {
Host string `yaml:"host"`
Scheme string `yaml:"scheme"`
} `yaml:"campusProxy"`
RelevantOrgs *[]string `yaml:"relevantOrgs"`
} `yaml:"campus"`
Ldap struct {
URL string `yaml:"url"`
User string `yaml:"user"`
Password string `yaml:"password"`
BaseDn string `yaml:"baseDn"`
UserDn string `yaml:"userDn"`
UseForLogin bool `yaml:"useForLogin"`
} `yaml:"ldap"`
Saml *struct {
IdpMetadataURL string `yaml:"idpMetadataURL"`
Cert string `yaml:"cert"`
Privkey string `yaml:"privkey"`
EntityID string `yaml:"entityID"`
RootURLs []string `yaml:"rootURL"`
IdpName string `yaml:"idpName"`
IdpColor string `yaml:"idpColor"`
} `yaml:"saml"`
Paths struct {
Static string `yaml:"static"`
Mass string `yaml:"mass"`
Branding string `yaml:"branding"`
} `yaml:"paths"`
Auths struct {
SmpUser string `yaml:"smpUser"` // todo, do we need this? Should this be in the lecture_halls table?
SmpPassword string `yaml:"smpPassword"`
PwrCrtlAuth string `yaml:"pwrCrtlAuth"`
CamAuth string `yaml:"camAuth"`
CamAuthSony string `yaml:"camAuthSony"`
} `yaml:"auths"`
Alerts *struct {
Matrix *struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
Homeserver string `yaml:"homeserver"`
LogRoomID string `yaml:"logRoomID"`
AlertRoomID string `yaml:"alertRoomId"`
} `yaml:"matrix"`
} `yaml:"alerts"`
VoiceService *struct {
Host string `yaml:"host"`
Port string `yaml:"port"`
AuthToken string `yaml:"authToken"`
}
IngestBase string `yaml:"ingestBase"`
WebUrl string `yaml:"webUrl"`
WorkerToken string `yaml:"workerToken"` // used for workers to join the worker pool
JWTKey *string `yaml:"jwtKey"`
Meili *struct {
Host string `yaml:"host"`
ApiKey string `yaml:"apiKey"`
} `yaml:"meili"`
// MetricsPort is the port the Prometheus endpoint listens on, separate from the
// web port so the metrics are not exposed to the internet. Empty disables it.
MetricsPort string `yaml:"metricsPort"`
VodURLTemplate string `yaml:"vodURLTemplate"`
CanonicalURL string `yaml:"canonicalURL"`
WikiURL string `yaml:"wikiURL"`
RtmpProxyURL string `yaml:"rtmpProxyURL"`
RtmpProxyService string `yaml:"rtmpProxyService"`
}
func (Config) GetJWTKey ¶
func (Config) GetJWTKey() *rsa.PrivateKey
func (Config) GetMeiliClient ¶
func (c Config) GetMeiliClient() (meilisearch.ServiceManager, error)
type CronService ¶
type CronService struct {
// contains filtered or unexported fields
}
var Cron *CronService
Cron is the global CronService
func (*CronService) AddFunc ¶
func (c *CronService) AddFunc(name string, fn func(), spec string) error
AddFunc creates a cronJob fn running at the interval specified by spec. The job can be referenced by name.
func (*CronService) ListCronJobs ¶
func (c *CronService) ListCronJobs() []string
ListCronJobs returns a []string with the names of all cronjobs
func (*CronService) RunJob ¶
func (c *CronService) RunJob(name string)
RunJob executes the cronJob identified by name even when it's not due. Invalid names are ignored silently.
type DebugTemplateExecutor ¶
type DebugTemplateExecutor struct {
Patterns []string
}
func (DebugTemplateExecutor) ExecuteTemplate ¶
func (e DebugTemplateExecutor) ExecuteTemplate(w io.Writer, name string, data interface{}) error
type ErrorPageData ¶
ErrorPageData is the required data for the error page
type ExportDataEntry ¶
type ExportStatsContainer ¶
type ExportStatsContainer struct {
// contains filtered or unexported fields
}
func (ExportStatsContainer) AddDataEntry ¶
func (e ExportStatsContainer) AddDataEntry(entry *ExportDataEntry) ExportStatsContainer
func (ExportStatsContainer) ExportCsv ¶
func (e ExportStatsContainer) ExportCsv() string
func (ExportStatsContainer) ExportJson ¶
func (e ExportStatsContainer) ExportJson() []gin.H
type JWTClaims ¶
type JWTClaims struct {
*jwt.RegisteredClaims
UserID uint
SamlSubjectID *string // identifier of the SAML session (if any)
}
JWTClaims are the claims contained in a session
type JWTPlaylistClaims ¶
type MailConfig ¶
type Mailer ¶
type Mailer struct {
Dao dao.DaoWrapper
MaxMailsPerMinute int
}
type MeiliCourse ¶
type MeiliCourse struct {
ID uint `json:"ID"`
Name string `json:"name"`
Slug string `json:"slug"`
Year int `json:"year"`
TeachingTerm string `json:"semester"`
Visibility string `json:"visibility"`
}
func ToMeiliCourses ¶
func ToMeiliCourses(cs []model.Course) []MeiliCourse
ToMeiliCourses converts slice of model.Course to slice of MeiliCourse
type MeiliExporter ¶
type MeiliExporter struct {
// contains filtered or unexported fields
}
func NewMeiliExporter ¶
func NewMeiliExporter(d dao.DaoWrapper) *MeiliExporter
func (*MeiliExporter) Export ¶
func (m *MeiliExporter) Export()
Export exports all relevant search data to MeiliSearch Instance
func (*MeiliExporter) SetIndexSettings ¶
func (m *MeiliExporter) SetIndexSettings()
type MeiliSearchInterface ¶
type MeiliSearchInterface interface {
SearchSubtitles(q string, streamID uint) *meilisearch.SearchResponse
Search(q string, limit int64, searchType int, courseFilter string, streamFilter string, subtitleFilter string) *meilisearch.MultiSearchResponse
}
func NewMeiliSearchFunctions ¶
func NewMeiliSearchFunctions() MeiliSearchInterface
type MeiliStream ¶
type MeiliStream struct {
ID uint `json:"ID"`
Name string `json:"name"`
Description string `json:"description"`
CourseName string `json:"courseName"`
Year int `json:"year"`
TeachingTerm string `json:"semester"`
CourseID uint `json:"courseID"`
Private uint `json:"private"`
Visibility string `json:"visibility"` // corresponds to the visibility of the course
}
func ToMeiliStreams ¶
func ToMeiliStreams(streams []model.Stream, daoWrapper dao.DaoWrapper) ([]MeiliStream, error)
ToMeiliStreams converts slice of model.Stream to slice of MeiliStream
type MeiliSubtitles ¶
type MeiliSubtitles struct {
ID string `json:"ID"` // meili id: streamID + timestamp
StreamID uint `json:"streamID"`
Timestamp int64 `json:"timestamp"`
TextPrev string `json:"textPrev"` // the previous subtitle line
Text string `json:"text"`
TextNext string `json:"textNext"` // the next subtitle line
}
type ReleaseTemplateExecutor ¶
func (ReleaseTemplateExecutor) ExecuteTemplate ¶
func (e ReleaseTemplateExecutor) ExecuteTemplate(w io.Writer, name string, data interface{}) error
type RequestError ¶
func (RequestError) Error ¶
func (r RequestError) Error() string
func (RequestError) ToResponse ¶
func (r RequestError) ToResponse() gin.H
type SessionData ¶
type TUMLiveContext ¶
type TUMLiveContext struct {
User *model.User
Course *model.Course
Stream *model.Stream
SamlSubjectID *string
}
func (*TUMLiveContext) UserIsAdmin ¶
func (c *TUMLiveContext) UserIsAdmin() bool