Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Course and user endpoints for API v2 #1429

Merged
merged 16 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions api/courses.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (r coursesRoutes) getLive(c *gin.Context) {
}
// only show "enrolled" streams to users which are enrolled or admins
if courseForLiveStream.Visibility == "enrolled" {
if !isUserAllowedToWatchPrivateCourse(courseForLiveStream, tumLiveContext.User) {
if !tumLiveContext.User.IsAllowedToWatchPrivateCourse(courseForLiveStream) {
continue
}
}
Expand Down Expand Up @@ -405,18 +405,6 @@ func (r coursesRoutes) getCourseBySlug(c *gin.Context) {
c.JSON(http.StatusOK, courseDTO)
}

func isUserAllowedToWatchPrivateCourse(course model.Course, user *model.User) bool {
if user != nil {
for _, c := range user.Courses {
if c.ID == course.ID {
return true
}
}
return user.IsEligibleToWatchCourse(course)
}
return false
}

func (r coursesRoutes) createVOD(c *gin.Context) {
logger.Info("createVOD")
var req createVODReq
Expand Down
31 changes: 31 additions & 0 deletions api_v2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# GOCAST API V2
carlobortolan marked this conversation as resolved.
Show resolved Hide resolved

This API is designed to be a user-friendly and easy-to-use interface for third party services. It provides access to all non-administrative features of the GoCast platform via gRPC methods and exposes a REST API proxy for easy access.

In the future, this API might be extended to include more features and endpoints and replace the current REST API.

## Documentation

You can find the docs for the new API [here](https://tum.live/api/v2/docs).

You can generate the code documentation using `godoc` and find it at [http://localhost:6060/pkg/github.com/TUM-Dev/gocast](`http://localhost:6060/pkg/github.com/TUM-Dev/gocast`).

## File structure

All proto messages can be found in `api_v2.proto`.
The actual endpoints are implemented in `<./endpoint.go>.go`, custom erros in `./errors` and helper functions such as parsers, custom database queries, etc. in `./helpers`.

## Config

Install protobuf by running `./api_v2/installBuf.sh`.

To generate the files in `./protobuf`, run:
`./api_v2/generate.sh`.

## Running the server

To build and start the new API, start GoCast as usual with:
`go run ./cmd/tumlive/tumlive.go`.

The gRPC server will be running on port 12544 and the API proxy on [localhost:8081/api/v2](http://localhost:8081/api/v2/status).<br>
The docs can be found at [http://localhost:8081/api/v2/docs](http://localhost:8081/api/v2/docs).
19 changes: 19 additions & 0 deletions api_v2/buf.gen.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: v1
plugins:
- name: go
out: protobuf
opt:
- paths=source_relative
- name: go-grpc
out: protobuf
opt:
- paths=source_relative
- name: grpc-gateway
out: protobuf
opt:
- paths=source_relative
- allow_repeated_fields_in_body=true
- name: openapiv2
out: docs
opt:
- allow_repeated_fields_in_body=true
2 changes: 2 additions & 0 deletions api_v2/buf.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Generated by buf. DO NOT EDIT.
version: v1
8 changes: 8 additions & 0 deletions api_v2/buf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: v1
deps: []
lint:
use:
- DEFAULT
breaking:
use:
- FILE
45 changes: 45 additions & 0 deletions api_v2/errors/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Package errors provides helper functions for handling errors with specific HTTP status codes.
package errors

import (
"fmt"
"log/slog"
"net/http"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// WithStatus creates a new error with a specific HTTP status code and a given error message.
// It maps the HTTP status code to a corresponding gRPC status code.
// If the HTTP status code is not recognized, it logs a warning and uses gRPC's Unknown code.
// It returns a gRPC error with the mapped gRPC status code and the original error message.
func WithStatus(httpStatus int, err error) error {
var code codes.Code
switch httpStatus {
case http.StatusNotFound:
code = codes.NotFound
case http.StatusUnauthorized:
code = codes.Unauthenticated
case http.StatusForbidden:
code = codes.PermissionDenied
case http.StatusBadRequest:
code = codes.InvalidArgument
case http.StatusConflict:
code = codes.AlreadyExists
case http.StatusTooManyRequests:
code = codes.ResourceExhausted
case http.StatusNotImplemented:
code = codes.Unimplemented
case http.StatusServiceUnavailable:
code = codes.Unavailable
case http.StatusGatewayTimeout:
code = codes.DeadlineExceeded
case http.StatusInternalServerError:
code = codes.Unknown // default to 500
default:
slog.Warn("Unknown HTTP status code: ", "httpStatus", fmt.Sprintf("%d", httpStatus))
code = codes.Unknown
}
return status.Error(code, err.Error())
}
26 changes: 26 additions & 0 deletions api_v2/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

# needs buf: https://docs.buf.build/installation#github-releases
BASEDIR=$(dirname "$0")
echo making sure that this script is run from $BASEDIR
pushd $BASEDIR > /dev/null

echo updating the generated files
export PATH="$PATH:$(go env GOPATH)/bin"
buf dep update || exit 1
buf generate || exit 1

echo making sure that all artifacts we don\'t need are cleaned up
rm -f google/api/*.go
rm -f google/api/*.swagger.json

echo making sure that all artifacts we don\'t need are cleaned up
rm -rf docs/google docs/protoc-gen-openapiv2 protobuf/google protobuf/protoc-gen-openapiv2

echo maing sure that the generated files are formatted
go fmt server/*.go || exit 1
goimports -w server/*.go || exit 1
buf format -w --path server || exit 1

# clean up the stack
popd > /dev/null
31 changes: 31 additions & 0 deletions api_v2/google/api/annotations.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2015 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.api;

import "google/api/http.proto";
import "google/protobuf/descriptor.proto";

option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
option java_multiple_files = true;
option java_outer_classname = "AnnotationsProto";
option java_package = "com.google.api";
option objc_class_prefix = "GAPI";

extend google.protobuf.MethodOptions {
// See `HttpRule`.
HttpRule http = 72295728;
}
Loading
Loading