(opts *Opts)
| 184 | } |
| 185 | |
| 186 | func craftMiddleware(opts *Opts) []middleware.Middleware { |
| 187 | middlewares := []middleware.Middleware{ |
| 188 | recovery.Recovery( |
| 189 | recovery.WithHandler(func(_ context.Context, req, err interface{}) error { |
| 190 | sentry.CaptureMessage(fmt.Sprintf("%v", err)) |
| 191 | return errors.InternalServer("internal error", "there was an internal error") |
| 192 | }), |
| 193 | ), |
| 194 | logging.Server(opts.Logger), |
| 195 | } |
| 196 | |
| 197 | logHelper := log.NewHelper(opts.Logger) |
| 198 | |
| 199 | // User authentication |
| 200 | middlewares = append(middlewares, |
| 201 | usercontext.Prometheus(), |
| 202 | // If we require a logged in user we |
| 203 | selector.Server( |
| 204 | // 1 - Extract the currentUser/API token from the JWT |
| 205 | // NOTE: this works because both currentUser and API tokens JWT use the same signing method and secret |
| 206 | jwtMiddleware.Server(func(_ *jwt.Token) (interface{}, error) { |
| 207 | return []byte(opts.AuthConfig.GeneratedJwsHmacSecret), nil |
| 208 | }, |
| 209 | jwtMiddleware.WithSigningMethod(user.SigningMethod), |
| 210 | ), |
| 211 | // 2.a - Set its API token and organization as alternative to the user |
| 212 | usercontext.WithCurrentAPITokenAndOrgMiddleware(opts.APITokenUseCase, opts.OrganizationUseCase, logHelper), |
| 213 | // 2.b - Update API Token last usage |
| 214 | usercontext.WithAPITokenUsageUpdater(opts.APITokenUseCase, logHelper), |
| 215 | // 2.c - Set its user |
| 216 | usercontext.WithCurrentUserMiddleware(opts.UserUseCase, logHelper), |
| 217 | // Store all memberships in the context |
| 218 | usercontext.WithCurrentMembershipsMiddleware(opts.MembershipUseCase, opts.MembershipsCache), |
| 219 | // Operation authorization forward |
| 220 | usercontext.WithOperationAuthorizationMiddleware(opts.OperationAuthConfig, logHelper), |
| 221 | selector.Server( |
| 222 | // 2.d- Set its organization |
| 223 | usercontext.WithCurrentOrganizationMiddleware(opts.UserUseCase, opts.OrganizationUseCase, logHelper), |
| 224 | // 2.e- Block all operations on suspended orgs |
| 225 | usercontext.WithSuspensionMiddleware(), |
| 226 | // 3 - Check user/token authorization |
| 227 | authzMiddleware.WithAuthzMiddleware(opts.AuthzUseCase, logHelper), |
| 228 | ).Match(requireAllButOrganizationOperationsMatcher()).Build(), |
| 229 | // 4 - Make sure the account is fully functional |
| 230 | selector.Server( |
| 231 | usercontext.CheckUserHasAccess(opts.AuthConfig.AllowList, opts.UserUseCase), |
| 232 | ).Match(allowListEnabled()).Build(), |
| 233 | selector.Server( |
| 234 | usercontext.ValidateCASBackend(opts.CASBackendUseCase), |
| 235 | ).Match(requireFullyConfiguredOrgMatcher()).Build(), |
| 236 | ).Match(requireCurrentUserMatcher()).Build(), |
| 237 | ) |
| 238 | |
| 239 | // attestation branch |
| 240 | middlewares = append(middlewares, |
| 241 | // if we require a robot account |
| 242 | selector.Server( |
| 243 | // 1 - Extract information from the JWT by using the claims |
no test coverage detected