Skip to content

Commit

Permalink
Merge pull request #80 from eurofurence/issue-33-more-groups-implemen…
Browse files Browse the repository at this point in the history
…tation

further implementation
  • Loading branch information
Jumpy-Squirrel authored Sep 2, 2024
2 parents e5b3aff + d7e4494 commit 2f2888a
Show file tree
Hide file tree
Showing 71 changed files with 882 additions and 962 deletions.
1 change: 1 addition & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- 'main'
- 'issue-33-more-groups-implementation'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
28 changes: 22 additions & 6 deletions api/openapi-spec/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,25 @@ paths:
description: |-
Obtain a list of all or selected groups, including their members.
Admin or Api Key authorization: can see all groups.
Admin or Api Key authorization: can see all groups if the "show"
query parameter is set to "all".
User authorization will only show groups visible to the current user, and only allows
"show" value "public".
Normal users: can only see groups visible to them. If public groups are enabled in configuration,
this means all groups that are public, not full, and from which the user wasn't banned. Not all fields
will be filled.
Note: both admins and normal users can always use the findMyGroup operation to get the group they are in.
operationId: listGroups
parameters:
- name: show
in: query
description: set to "all" to request admin access rather than normal visibility rules. If permissions aren't sufficient, will result in a 403. Set to "public" to request only groups with flag "public".
schema:
type: string
example: public
default: public
- name: member_ids
in: query
description: a comma separated list of badge numbers. The result will be limited to all groups that contain at least one of these badge numbers as members. Only admins can set this parameter, it is ignored for normal attendees to avoid leaking information.
Expand All @@ -94,7 +104,7 @@ paths:
example: 2
- name: max_size
in: query
description: list only groups that currently have at most this many members (optional, defaults to -1 which means no limitation)
description: list only groups that currently have at most this many members (optional, defaults to 0 which means no limitation)
schema:
type: integer
example: 4
Expand Down Expand Up @@ -179,13 +189,13 @@ paths:
schema:
$ref: '#/components/schemas/Error'
'403':
description: You do not have permission to create a group (maybe not registered or not in valid status for creating a group?)
description: You do not have permission to create a group (not a valid registration? not in valid status for creating a group?)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: No such attendee (when setting owner id).
description: No such attendee (when setting owner id - admin only).
content:
application/json:
schema:
Expand Down Expand Up @@ -237,7 +247,7 @@ paths:
schema:
$ref: '#/components/schemas/Error'
'403':
description: You do not have permission to see this (maybe not a valid registration?)
description: You do not have permission to see this (maybe not a valid registration? status not attending?)
content:
application/json:
schema:
Expand Down Expand Up @@ -335,7 +345,7 @@ paths:
$ref: '#/components/schemas/Group'
required: true
responses:
'200':
'204':
description: Successful operation
headers:
Location:
Expand Down Expand Up @@ -425,6 +435,12 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: Group still contains members other than the owner. Must remove them first to ensure proper notifications.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: An unexpected error occurred. This includes database errors. A best effort attempt is made to return details in the body.
content:
Expand Down
2 changes: 1 addition & 1 deletion cmd/reg-room-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"github.com/urfave/cli/v2"

"github.com/eurofurence/reg-room-service/internal/web/app"
"github.com/eurofurence/reg-room-service/internal/application/app"
)

var (
Expand Down
39 changes: 29 additions & 10 deletions docs/config.example.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
server:
port: 8081
go_live:
public:
start_iso_datetime: 1995-06-30T11:11:11+02:00
booking_code: Kaiser-Wilhelm-Koog
staff:
start_iso_datetime: 1995-06-29T11:11:11+02:00
booking_code: Dithmarschen
group: staff
service:
attendee_service_url: 'http://localhost:9091' # no trailing slash
max_group_size: 6
group_flags:
- public
room_flags:
- handicapped
- final
server:
port: 9094
database:
use: 'mysql' # or inmemory
username: 'demouser'
password: 'demopw'
database: 'tcp(localhost:3306)/dbname'
parameters:
- 'charset=utf8mb4'
- 'collation=utf8mb4_general_ci'
- 'parseTime=True'
- 'timeout=30s' # connection timeout
security:
cors:
disable: false
Expand All @@ -28,3 +36,14 @@ security:
cKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbc
mwIDAQAB
-----END PUBLIC KEY-----
logging:
style: ecs
severity: INFO
go_live:
public:
start_iso_datetime: 1995-06-30T11:11:11+02:00
booking_code: Kaiser-Wilhelm-Koog
staff:
start_iso_datetime: 1995-06-29T11:11:11+02:00
booking_code: Dithmarschen
group: staff
15 changes: 15 additions & 0 deletions internal/api/v1/apimodel.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
package modelsv1

import "time"

var _ = time.Now

type Error struct {
// The time at which the error occurred.
Timestamp time.Time `json:"timestamp"`
// An internal trace id assigned to the error. Used to find logs associated with errors across our services. Display to the user as something to communicate to us with inquiries about the error.
Requestid string `json:"requestid"`
// A keyed description of the error. We do not write human readable text here because the user interface will be multi language. At this time, there are these values: - auth.unauthorized (token missing completely or invalid) - auth.forbidden (permissions missing)
Message string `json:"message"`
// Optional additional details about the error. If available, will usually contain English language technobabble.
Details map[string][]string `json:"details,omitempty"`
}

type Group struct {
// The internal primary key of the group, in the form of a UUID. Only set when reading groups, completely ignored when you send a group to us.
ID string `yaml:"id" json:"id"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"context"
aulogging "github.com/StephanHCB/go-autumn-logging"
auzerolog "github.com/StephanHCB/go-autumn-logging-zerolog"
"github.com/eurofurence/reg-room-service/internal/config"
"github.com/eurofurence/reg-room-service/internal/application/common"
"github.com/eurofurence/reg-room-service/internal/application/server"
"github.com/eurofurence/reg-room-service/internal/repository/config"
"github.com/eurofurence/reg-room-service/internal/repository/database/dbrepo"
"github.com/eurofurence/reg-room-service/internal/repository/downstreams/attendeeservice"
"github.com/eurofurence/reg-room-service/internal/web/common"
"github.com/eurofurence/reg-room-service/internal/web/server"
"github.com/rs/zerolog"
)

Expand Down
93 changes: 93 additions & 0 deletions internal/application/common/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package common

import (
"context"
"github.com/golang-jwt/jwt/v4"
)

type (
CtxKeyIDToken struct{}
CtxKeyAccessToken struct{}
CtxKeyAPIKey struct{}
CtxKeyClaims struct{}

CtxKeyRequestID struct{}
CtxKeyRequestURL struct{}

// TODO Remove after legacy system was replaced with 2FA
// See reference https://github.com/eurofurence/reg-payment-service/issues/57
CtxKeyAdminHeader struct{}
)

type CustomClaims struct {
EMail string `json:"email"`
EMailVerified bool `json:"email_verified"`
Groups []string `json:"groups,omitempty"`
Name string `json:"name"`
}

type AllClaims struct {
jwt.RegisteredClaims
CustomClaims
}

const RequestIDKey = "RequestIDKey"

// GetRequestID extracts the request ID from the context.
//
// It originally comes from a header with the request, or is rolled while processing
// the request.
func GetRequestID(ctx context.Context) string {
if reqID, ok := ctx.Value(RequestIDKey).(string); ok {
return reqID
}

return "ffffffff"
}

// GetClaims extracts all jwt token claims from the context.
func GetClaims(ctx context.Context) *AllClaims {
claims := ctx.Value(CtxKeyClaims{})
if claims == nil {
return nil
}

allClaims, ok := claims.(*AllClaims)
if !ok {
return nil
}

return allClaims
}

// GetGroups extracts the groups from the jwt token that came with the request
// or from the groups retrieved from userinfo, if using authorization token.
//
// In either case the list is filtered by relevant groups (if reg-auth-service is configured).
func GetGroups(ctx context.Context) []string {
claims := GetClaims(ctx)
if claims == nil || claims.Groups == nil {
return []string{}
}
return claims.Groups
}

// HasGroup checks that the user has a group.
func HasGroup(ctx context.Context, group string) bool {
for _, grp := range GetGroups(ctx) {
if grp == group {
return true
}
}
return false
}

// GetSubject extracts the subject field from the jwt token or the userinfo response, if using
// an authorization token.
func GetSubject(ctx context.Context) string {
claims := GetClaims(ctx)
if claims == nil {
return ""
}
return claims.Subject
}
Loading

0 comments on commit 2f2888a

Please sign in to comment.