Documentation
¶
Overview ¶
Package db is glabs-web's MongoDB layer. It owns the connection and the collection access; everything above it works with the decoded documents.
Index ¶
- Variables
- type DB
- func (db *DB) CountUsers(ctx context.Context) (int64, error)
- func (db *DB) CourseOf(ctx context.Context, owner, name string) (*StoredCourse, error)
- func (db *DB) CoursesOf(ctx context.Context, owner string) ([]*StoredCourse, error)
- func (db *DB) DeleteCourse(ctx context.Context, owner, name string) error
- func (db *DB) DeleteUserGitLabToken(ctx context.Context, owner string) error
- func (db *DB) Disconnect(ctx context.Context) error
- func (db *DB) EnsureCourseIndexes(ctx context.Context) error
- func (db *DB) EnsureUserIndexes(ctx context.Context) error
- func (db *DB) EnsureUserSecretIndexes(ctx context.Context) error
- func (db *DB) GetUserByEmail(ctx context.Context, email string) (*model.User, error)
- func (db *DB) GetUserSecret(ctx context.Context, owner string) (*UserSecret, error)
- func (db *DB) SaveCourse(ctx context.Context, course *StoredCourse) error
- func (db *DB) SaveUser(ctx context.Context, user *model.User) error
- func (db *DB) SaveUserGitLabToken(ctx context.Context, owner string, sealed secrets.SealedValue, ...) error
- type StoredCourse
- type UserSecret
Constants ¶
This section is empty.
Variables ¶
var ErrCourseNotFound = errors.New("course not found")
ErrCourseNotFound is returned when a course does not exist for the given owner. It deliberately does not distinguish "does not exist" from "belongs to someone else": to one user, another user's course simply is not there.
Functions ¶
This section is empty.
Types ¶
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
func Connect ¶
Connect opens the connection and verifies it with a ping, so a bad URI fails at startup rather than on the first query.
UseLocalTimeZone decodes the UTC that Mongo stores back into time.Local, which main sets to Europe/Berlin — so timestamps read out in the zone they were written in.
func (*DB) CountUsers ¶
CountUsers reports how many users exist, so seeding can run only on an empty allowlist.
func (*DB) CourseOf ¶ added in v3.2.0
CourseOf returns one course owned by the given user, or ErrCourseNotFound.
func (*DB) CoursesOf ¶ added in v3.2.0
CoursesOf returns the courses owned by the given user, sorted by name.
func (*DB) DeleteCourse ¶ added in v3.2.0
DeleteCourse removes a course owned by the given user. Deleting a course that does not exist for that owner is ErrCourseNotFound, not a silent success — so a delete of another user's course reports "not found" rather than pretending it worked.
func (*DB) DeleteUserGitLabToken ¶ added in v3.3.0
DeleteUserGitLabToken removes only the GitLab PAT from a user's secrets.
func (*DB) EnsureCourseIndexes ¶ added in v3.2.0
EnsureCourseIndexes makes (owner, name) unique — a user has at most one course of a given name, and the pair is how every query is keyed.
func (*DB) EnsureUserIndexes ¶
EnsureUserIndexes makes the email unique. Called once at startup.
func (*DB) EnsureUserSecretIndexes ¶ added in v3.3.0
EnsureUserSecretIndexes makes owner unique — one secrets document per user.
func (*DB) GetUserByEmail ¶
GetUserByEmail returns the user with the given email, or nil if there is none. The auth middleware treats nil as "not on the allowlist" — a 403 — so a missing user must be nil, nil rather than an error.
func (*DB) GetUserSecret ¶ added in v3.3.0
GetUserSecret returns the stored secrets for a user, or nil when none exist.
func (*DB) SaveCourse ¶ added in v3.2.0
func (db *DB) SaveCourse(ctx context.Context, course *StoredCourse) error
SaveCourse inserts or replaces a course for its owner. The owner and name on the document are the key; a document can never be written under a different owner than the one on it.
func (*DB) SaveUserGitLabToken ¶ added in v3.3.0
func (db *DB) SaveUserGitLabToken(ctx context.Context, owner string, sealed secrets.SealedValue, updatedAt time.Time) error
SaveUserGitLabToken upserts the sealed GitLab PAT for a user, touching only the gitlab fields so it never clobbers other secrets on the document.
type StoredCourse ¶ added in v3.2.0
type StoredCourse struct {
Owner string `bson:"owner"`
Name string `bson:"name"`
Source *config.CourseSource `bson:"source"`
RawYAML []byte `bson:"rawYAML,omitempty"`
ImportedAt time.Time `bson:"importedAt"`
UpdatedAt time.Time `bson:"updatedAt"`
}
StoredCourse is a course as saved by one user. Ownership is strict: a course belongs to the user who imported it, and no other user can see or touch it.
RawYAML is kept verbatim alongside the parsed Source so a download can return exactly what was uploaded — comments and key order and all — as long as the course has not been edited through the web. Re-encoding Source would lose them.
type UserSecret ¶ added in v3.3.0
type UserSecret struct {
Owner string `bson:"owner"`
GitLab *secrets.SealedValue `bson:"gitlab,omitempty"`
GitLabUpdatedAt *time.Time `bson:"gitlabUpdatedAt,omitempty"`
}
UserSecret holds a user's encrypted per-user secrets, keyed by the owner's email — here, the GitLab personal access token. The value is AES-256-GCM sealed; the plaintext never touches the database. This document is never exposed over GraphQL, only a "set / when" status is.