Skip to content

Commit

Permalink
Keycloak Group Management (#147)
Browse files Browse the repository at this point in the history
* changing permission string to other direction

* fixing group and role creation to match the new design

* moving token verifier into own folder

* renaming keycloak into keycloakRealmManager

* moving roles in permissionValidation

* adding support to add custom groups to keycloak

* storing changes

* finishing adding students to groups

* adding support to get group members

* adding authentication to endpoints
  • Loading branch information
niclasheun authored Feb 14, 2025
1 parent ecc4b95 commit 052cbfd
Show file tree
Hide file tree
Showing 38 changed files with 857 additions and 228 deletions.
4 changes: 2 additions & 2 deletions server/applicationAdministration/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgxpool"
db "github.com/niclasheun/prompt2.0/db/sqlc"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/keycloakTokenVerifier"
"github.com/niclasheun/prompt2.0/permissionValidation"
log "github.com/sirupsen/logrus"
)

func InitApplicationAdministrationModule(routerGroup *gin.RouterGroup, queries db.Queries, conn *pgxpool.Pool) {
setupApplicationRouter(routerGroup, keycloak.KeycloakMiddleware, keycloak.ApplicationMiddleware, checkAccessControlByIDWrapper)
setupApplicationRouter(routerGroup, keycloakTokenVerifier.KeycloakMiddleware, keycloakTokenVerifier.ApplicationMiddleware, checkAccessControlByIDWrapper)
ApplicationServiceSingleton = &ApplicationService{
queries: queries,
conn: conn,
Expand Down
22 changes: 11 additions & 11 deletions server/applicationAdministration/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,28 @@ import (
"github.com/niclasheun/prompt2.0/applicationAdministration/applicationDTO"
"github.com/niclasheun/prompt2.0/coursePhase/coursePhaseParticipation"
"github.com/niclasheun/prompt2.0/coursePhase/coursePhaseParticipation/coursePhaseParticipationDTO"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/mailing"
"github.com/niclasheun/prompt2.0/permissionValidation"
log "github.com/sirupsen/logrus"
)

func setupApplicationRouter(router *gin.RouterGroup, authMiddleware func() gin.HandlerFunc, applicationMiddleware func() gin.HandlerFunc, permissionIDMiddleware func(allowedRoles ...string) gin.HandlerFunc) {
application := router.Group("/applications", authMiddleware())

// Application Form Endpoints
application.GET("/:coursePhaseID/form", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getApplicationForm)
application.PUT("/:coursePhaseID/form", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateApplicationForm)
application.GET("/:coursePhaseID/score", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), getAdditionalScores)
application.POST("/:coursePhaseID/score", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), uploadAdditionalScore)
application.PUT("/:coursePhaseID/assessment", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateApplicationsStatus)
application.GET("/:coursePhaseID/form", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getApplicationForm)
application.PUT("/:coursePhaseID/form", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateApplicationForm)
application.GET("/:coursePhaseID/score", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), getAdditionalScores)
application.POST("/:coursePhaseID/score", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), uploadAdditionalScore)
application.PUT("/:coursePhaseID/assessment", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateApplicationsStatus)

application.POST("/:coursePhaseID", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), postApplicationManual)
application.DELETE("/:coursePhaseID", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), deleteApplications)
application.POST("/:coursePhaseID", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), postApplicationManual)
application.DELETE("/:coursePhaseID", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), deleteApplications)

application.GET("/:coursePhaseID/:coursePhaseParticipationID", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getApplicationByCPPID)
application.PUT("/:coursePhaseID/:coursePhaseParticipationID/assessment", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateApplicationAssessment)
application.GET("/:coursePhaseID/:coursePhaseParticipationID", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getApplicationByCPPID)
application.PUT("/:coursePhaseID/:coursePhaseParticipationID/assessment", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateApplicationAssessment)

application.GET("/:coursePhaseID/participations", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getAllApplicationParticipations)
application.GET("/:coursePhaseID/participations", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getAllApplicationParticipations)

// Apply Endpoints - No Authentication needed
apply := router.Group("/apply")
Expand Down
4 changes: 2 additions & 2 deletions server/course/courseParticipation/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import (
"github.com/gin-gonic/gin"
"github.com/jackc/pgx/v5/pgxpool"
db "github.com/niclasheun/prompt2.0/db/sqlc"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/keycloakTokenVerifier"
"github.com/niclasheun/prompt2.0/permissionValidation"
)

func InitCourseParticipationModule(routerGroup *gin.RouterGroup, queries db.Queries, conn *pgxpool.Pool) {
setupCourseParticipationRouter(routerGroup, keycloak.KeycloakMiddleware, checkAccessControlByIDWrapper)
setupCourseParticipationRouter(routerGroup, keycloakTokenVerifier.KeycloakMiddleware, checkAccessControlByIDWrapper)
CourseParticipationServiceSingleton = &CourseParticipationService{
queries: queries,
conn: conn,
Expand Down
6 changes: 3 additions & 3 deletions server/course/courseParticipation/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/niclasheun/prompt2.0/course/courseParticipation/courseParticipationDTO"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/permissionValidation"
)

func setupCourseParticipationRouter(router *gin.RouterGroup, authMiddleware func() gin.HandlerFunc, permissionIDMiddleware func(allowedRoles ...string) gin.HandlerFunc) {
// incoming path should be /course/:uuid/
courseParticipation := router.Group("/courses/:uuid/participations", authMiddleware())
courseParticipation.GET("", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getCourseParticipationsForCourse)
courseParticipation.POST("/enroll", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), createCourseParticipation)
courseParticipation.GET("/self", getOwnCourseParticipation)
courseParticipation.GET("", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getCourseParticipationsForCourse)
courseParticipation.POST("/enroll", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), createCourseParticipation)
}

func getOwnCourseParticipation(c *gin.Context) {
Expand Down
7 changes: 4 additions & 3 deletions server/course/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import (
"github.com/gin-gonic/gin"
"github.com/jackc/pgx/v5/pgxpool"
db "github.com/niclasheun/prompt2.0/db/sqlc"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/keycloakRealmManager"
"github.com/niclasheun/prompt2.0/keycloakTokenVerifier"
"github.com/niclasheun/prompt2.0/permissionValidation"
)

func InitCourseModule(routerGroup *gin.RouterGroup, queries db.Queries, conn *pgxpool.Pool) {

setupCourseRouter(routerGroup, keycloak.KeycloakMiddleware, permissionValidation.CheckAccessControlByRole, checkAccessControlByIDWrapper)
setupCourseRouter(routerGroup, keycloakTokenVerifier.KeycloakMiddleware, permissionValidation.CheckAccessControlByRole, checkAccessControlByIDWrapper)
CourseServiceSingleton = &CourseService{
queries: queries,
conn: conn,
createCourseGroupsAndRoles: keycloak.CreateCourseGroupsAndRoles,
createCourseGroupsAndRoles: keycloakRealmManager.CreateCourseGroupsAndRoles,
}

// possibly more setup tasks
Expand Down
21 changes: 11 additions & 10 deletions server/course/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,25 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/niclasheun/prompt2.0/course/courseDTO"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/permissionValidation"
log "github.com/sirupsen/logrus"
)

// Id Middleware for all routes with a course id
// Role middleware for all without id -> possible additional filtering in subroutes required
func setupCourseRouter(router *gin.RouterGroup, authMiddleware func() gin.HandlerFunc, permissionRoleMiddleware, permissionIDMiddleware func(allowedRoles ...string) gin.HandlerFunc) {
course := router.Group("/courses", authMiddleware())
course.GET("/", permissionRoleMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor, permissionValidation.CourseStudent), getAllCourses)
course.GET("/:uuid", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getCourseByID)
course.POST("/", permissionRoleMiddleware(permissionValidation.PromptAdmin, permissionValidation.PromptLecturer), createCourse)
course.PUT("/:uuid/phase_graph", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateCoursePhaseOrder)
course.GET("/:uuid/phase_graph", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getCoursePhaseGraph)
course.GET("/:uuid/meta_graph", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getMetaDataGraph)
course.PUT("/:uuid/meta_graph", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateMetaDataGraph)
course.PUT("/:uuid", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateCourseData)
course.GET("/self", getOwnCourses)
course.GET("/", permissionRoleMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor, keycloak.CourseStudent), getAllCourses)
course.GET("/:uuid", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getCourseByID)
course.POST("/", permissionRoleMiddleware(keycloak.PromptAdmin, keycloak.PromptLecturer), createCourse)
course.PUT("/:uuid/phase_graph", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateCoursePhaseOrder)
course.GET("/:uuid/phase_graph", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getCoursePhaseGraph)
course.GET("/:uuid/meta_graph", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getMetaDataGraph)
course.PUT("/:uuid/meta_graph", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateMetaDataGraph)
course.PUT("/:uuid", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateCourseData)
course.DELETE("/:uuid", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), deleteCourse)

course.DELETE("/:uuid", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), deleteCourse)
}

func getOwnCourses(c *gin.Context) {
Expand Down
4 changes: 2 additions & 2 deletions server/course/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/niclasheun/prompt2.0/course/courseDTO"
"github.com/niclasheun/prompt2.0/coursePhase/coursePhaseDTO"
db "github.com/niclasheun/prompt2.0/db/sqlc"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/permissionValidation"
log "github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -42,7 +42,7 @@ func GetAllCourses(ctx context.Context, userRoles map[string]bool) ([]courseDTO.
var courses []db.Course
var err error
// Get all active courses the user is allowed to see
if userRoles[keycloak.PromptAdmin] {
if userRoles[permissionValidation.PromptAdmin] {
// get all courses
courses, err = CourseServiceSingleton.queries.GetAllActiveCoursesAdmin(ctxWithTimeout)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions server/course/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
"github.com/niclasheun/prompt2.0/coursePhase"
"github.com/niclasheun/prompt2.0/coursePhase/coursePhaseDTO"
db "github.com/niclasheun/prompt2.0/db/sqlc"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/meta"
"github.com/niclasheun/prompt2.0/permissionValidation"
"github.com/niclasheun/prompt2.0/testutils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -60,7 +60,7 @@ func (suite *CourseServiceTestSuite) TearDownSuite() {
}

func (suite *CourseServiceTestSuite) TestGetAllCourses() {
courses, err := GetAllCourses(suite.ctx, map[string]bool{keycloak.PromptAdmin: true})
courses, err := GetAllCourses(suite.ctx, map[string]bool{permissionValidation.PromptAdmin: true})
assert.NoError(suite.T(), err)
assert.Equal(suite.T(), len(courses), 10, "Expected all courses")

Expand Down
4 changes: 2 additions & 2 deletions server/coursePhase/coursePhaseParticipation/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import (
"github.com/gin-gonic/gin"
"github.com/jackc/pgx/v5/pgxpool"
db "github.com/niclasheun/prompt2.0/db/sqlc"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/keycloakTokenVerifier"
"github.com/niclasheun/prompt2.0/permissionValidation"
)

func InitCoursePhaseParticipationModule(routerGroup *gin.RouterGroup, queries db.Queries, conn *pgxpool.Pool) {
setupCoursePhaseParticipationRouter(routerGroup, keycloak.KeycloakMiddleware, checkAccessControlByIDWrapper)
setupCoursePhaseParticipationRouter(routerGroup, keycloakTokenVerifier.KeycloakMiddleware, checkAccessControlByIDWrapper)
CoursePhaseParticipationServiceSingleton = &CoursePhaseParticipationService{
queries: queries,
conn: conn,
Expand Down
14 changes: 7 additions & 7 deletions server/coursePhase/coursePhaseParticipation/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/niclasheun/prompt2.0/coursePhase/coursePhaseParticipation/coursePhaseParticipationDTO"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/permissionValidation"
)

func setupCoursePhaseParticipationRouter(routerGroup *gin.RouterGroup, authMiddleware func() gin.HandlerFunc, permissionIDMiddleware func(allowedRoles ...string) gin.HandlerFunc) {
courseParticipation := routerGroup.Group("/course_phases/:uuid/participations", authMiddleware())
courseParticipation.GET("/self", permissionIDMiddleware(keycloak.CourseStudent), getOwnCoursePhaseParticipation)
courseParticipation.GET("", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getParticipationsForCoursePhase)
courseParticipation.POST("", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), createCoursePhaseParticipation)
courseParticipation.GET("/:participation_uuid", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor), getParticipation)
courseParticipation.PUT("/:participation_uuid", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateCoursePhaseParticipation)
courseParticipation.GET("/self", permissionIDMiddleware(permissionValidation.CourseStudent), getOwnCoursePhaseParticipation)
courseParticipation.GET("", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getParticipationsForCoursePhase)
courseParticipation.POST("", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), createCoursePhaseParticipation)
courseParticipation.GET("/:participation_uuid", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor), getParticipation)
courseParticipation.PUT("/:participation_uuid", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateCoursePhaseParticipation)
// allow to modify multiple at once
courseParticipation.PUT("", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateBatchCoursePhaseParticipation)
courseParticipation.PUT("", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateBatchCoursePhaseParticipation)
}

func getOwnCoursePhaseParticipation(c *gin.Context) {
Expand Down
4 changes: 2 additions & 2 deletions server/coursePhase/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import (
"github.com/gin-gonic/gin"
"github.com/jackc/pgx/v5/pgxpool"
db "github.com/niclasheun/prompt2.0/db/sqlc"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/keycloakTokenVerifier"
"github.com/niclasheun/prompt2.0/permissionValidation"
)

func InitCoursePhaseModule(routerGroup *gin.RouterGroup, queries db.Queries, conn *pgxpool.Pool) {

setupCoursePhaseRouter(routerGroup, keycloak.KeycloakMiddleware, checkAccessControlByIDWrapper, checkAccessControlByCourseIDWrapper)
setupCoursePhaseRouter(routerGroup, keycloakTokenVerifier.KeycloakMiddleware, checkAccessControlByIDWrapper, checkAccessControlByCourseIDWrapper)
CoursePhaseServiceSingleton = &CoursePhaseService{
queries: queries,
conn: conn,
Expand Down
16 changes: 8 additions & 8 deletions server/coursePhase/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/niclasheun/prompt2.0/coursePhase/coursePhaseDTO"
"github.com/niclasheun/prompt2.0/keycloak"
"github.com/niclasheun/prompt2.0/meta"
"github.com/niclasheun/prompt2.0/permissionValidation"
log "github.com/sirupsen/logrus"
)

func setupCoursePhaseRouter(router *gin.RouterGroup, authMiddleware func() gin.HandlerFunc, permissionIDMiddleware, permissionCourseIDMiddleware func(allowedRoles ...string) gin.HandlerFunc) {
coursePhase := router.Group("/course_phases", authMiddleware())
coursePhase.GET("/:uuid", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer, keycloak.CourseEditor, keycloak.CourseStudent), getCoursePhaseByID)
coursePhase.GET("/:uuid", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer, permissionValidation.CourseEditor, permissionValidation.CourseStudent), getCoursePhaseByID)
// getting the course ID here to do correct rights management
coursePhase.POST("/course/:courseID", permissionCourseIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), createCoursePhase)
coursePhase.PUT("/:uuid", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), updateCoursePhase)
coursePhase.DELETE("/:uuid", permissionIDMiddleware(keycloak.PromptAdmin, keycloak.CourseLecturer), deleteCoursePhase)
coursePhase.POST("/course/:courseID", permissionCourseIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), createCoursePhase)
coursePhase.PUT("/:uuid", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), updateCoursePhase)
coursePhase.DELETE("/:uuid", permissionIDMiddleware(permissionValidation.PromptAdmin, permissionValidation.CourseLecturer), deleteCoursePhase)
}

func createCoursePhase(c *gin.Context) {
Expand Down Expand Up @@ -130,9 +130,9 @@ func deleteCoursePhase(c *gin.Context) {
}

func hasRestrictedDataAccess(userRolesMap map[string]bool, courseTokenIdentifier string) bool {
return userRolesMap[keycloak.PromptAdmin] ||
userRolesMap[fmt.Sprintf("%s-%s", courseTokenIdentifier, keycloak.CourseLecturer)] ||
userRolesMap[fmt.Sprintf("%s-%s", courseTokenIdentifier, keycloak.CourseEditor)]
return userRolesMap[permissionValidation.PromptAdmin] ||
userRolesMap[fmt.Sprintf("%s-%s", courseTokenIdentifier, permissionValidation.CourseLecturer)] ||
userRolesMap[fmt.Sprintf("%s-%s", courseTokenIdentifier, permissionValidation.CourseEditor)]
}

func handleError(c *gin.Context, statusCode int, err error) {
Expand Down
11 changes: 10 additions & 1 deletion server/db/query/students.sql
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,13 @@ WHERE (first_name || ' ' || last_name) ILIKE '%' || $1 || '%'
OR last_name ILIKE '%' || $1 || '%'
OR email ILIKE '%' || $1 || '%'
OR matriculation_number ILIKE '%' || $1 || '%'
OR university_login ILIKE '%' || $1 || '%';
OR university_login ILIKE '%' || $1 || '%';

-- name: GetStudentEmails :many
SELECT id, email
FROM student
WHERE id = ANY($1::uuid[]);

-- name: GetStudentsByEmail :many
SELECT * FROM student
WHERE email = ANY($1::text[]);
Loading

0 comments on commit 052cbfd

Please sign in to comment.