diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..36d8451c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +/postgres-data +/node_modules +/public/build +.git diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..961ce2ae --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +DATABASE_URL="postgresql://postgres:postgres@localhost:5433/postgres" +# See docs/bartender.md how to configure job submission +BARTENDER_API_URL=http://localhost:8000 +BARTENDER_PRIVATE_KEY=private_key.pem +# See docs/auth.md#session how generate a better secret +SESSION_SECRET= +# For social login see docs/auth.md diff --git a/.eslintrc.js b/.eslintrc.js index 0ccf82dc..25e928ad 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,4 @@ -/** @type {import('@types/eslint').Linter.BaseConfig} */ +/** @type {import('eslint').Linter.Config} */ module.exports = { root: true, extends: [ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6994d546..000f502c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,11 @@ jobs: cache: "npm" - run: npm ci - run: npm run build --if-present + - name: Generate RSA key pair + run: | + openssl genpkey -algorithm RSA -out private_key.pem \ + -pkeyopt rsa_keygen_bits:2048 + openssl rsa -pubout -in private_key.pem -out public_key.pem - run: npm test -- --coverage - run: npm run typecheck - run: npx prettier --check . diff --git a/.gitignore b/.gitignore index 81235d52..bd245827 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,12 @@ node_modules /sessions /coverage + +/prisma/dev.db + +/private_key.pem +/public_key.pem + +Caddyfile + +postgres-data diff --git a/Dockerfile b/Dockerfile index 30cb8b29..8bfdbee8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ FROM base as deps WORKDIR /myapp -ADD package.json ./ +ADD package.json package-lock.json tsconfig.json ./ RUN npm install --production=false # Setup production node_modules @@ -18,8 +18,8 @@ FROM base as production-deps WORKDIR /myapp COPY --from=deps /myapp/node_modules /myapp/node_modules -ADD package.json ./ -RUN npm prune --production +ADD package.json package-lock.json ./ +RUN npm prune --production # Build the app FROM base as build @@ -29,6 +29,7 @@ WORKDIR /myapp COPY --from=deps /myapp/node_modules /myapp/node_modules ADD . . +RUN npx prisma generate RUN npm run build # Finally, build the production image with minimal footprint @@ -43,6 +44,7 @@ WORKDIR /myapp COPY --from=production-deps /myapp/node_modules /myapp/node_modules +COPY --from=build /myapp/node_modules/.prisma /myapp/node_modules/.prisma COPY --from=build /myapp/build /myapp/build COPY --from=build /myapp/public /myapp/public COPY --from=build /myapp/package.json /myapp/package.json diff --git a/README.md b/README.md index 1ec8c4fd..30ef4aec 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,17 @@ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7990850.svg)](https://doi.org/10.5281/zenodo.7990850) [![fair-software.eu](https://img.shields.io/badge/fair--software.eu-%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8B-yellow)](https://fair-software.eu) +[Haddock3](https://github.com/haddocking/haddock3) (High Ambiguity Driven protein-protein DOCKing) is a an information-driven flexible docking approach for the modeling of biomolecular complexes. This software wraps the the haddock3 command line tool in a web application. The web application makes it easy to make a configuration file, run it and show the results. + Uses -- [bartender](https://github.com/i-VRESSE/bartender) for user and job management. +- [bartender](https://github.com/i-VRESSE/bartender) for job execution. - [workflow-builder](https://github.com/i-VRESSE/workflow-builder) to construct a Haddock3 workflow config file. - [haddock3](https://github.com/haddocking/haddock3) to compute ```mermaid sequenceDiagram - Web app->>+Bartender: Login + Web app->>+Web app: Login Web app->>+Builder: Construct workflow config Builder->>+Bartender: Submit job Bartender->>+haddock3: Run @@ -20,175 +22,119 @@ sequenceDiagram Web app->>+Bartender: Result of job ``` -- [Remix Docs](https://remix.run/docs) - -## Development +## Setup -From your terminal: +The web app is written in [Node.js](https://nodejs.org/) to install dependencies run: -```sh -npm run dev +```shell +npm install ``` -This starts your app in development mode, rebuilding assets on file changes. +Configuration of the web application is done via `.env` file or environment variables. +For configuration of authentication & authorization see [docs/auth.md](docs/auth.md). +For configuration of job submission see [docs/bartender.md#configuration](docs/bartender.md#configuration). +Use [.env.example](../.env.example) as a template: -To format according to [prettier](https://prettier.io) run - -```sh -npm run format +```shell +cp .env.example .env +# Edit .env file ``` -It's recommended to install an editor plugin (like the [VSCode Prettier plugin](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)) to get auto-formatting on save. - -To lint according [eslint](https://eslint.org) run +Create rsa key pair for signing & verifying JWT tokens for bartender web service with: -```sh -npm run lint +```shell +openssl genpkey -algorithm RSA -out private_key.pem \ + -pkeyopt rsa_keygen_bits:2048 +openssl rsa -pubout -in private_key.pem -out public_key.pem ``` -To check the Typescript types run +## Bartender web service -```sh -npm run typecheck -``` +The bartender web service should be running if you want to submit jobs. +See [docs/bartender.md](docs/bartender.md) how to set it up. -To run unit tests (`app/**/*.test.ts`) with [Vitest](https://vitest.dev) use +## Development + +You need to have a PostgreSQL database running. The easiest way is to use Docker: ```sh -# In watch mode -npm run test -# or in single run mode with coverage -npm run test -- run --coverage +npm run docker:dev ``` -## Deployment +(Stores data in `./postgres-data`) +(You can get a psql shell with `npm run psql:dev`) +(On CTRL-C the database is stopped. To remove container use `docker system prune`) -First, build your app for production: +The database can be initialized with ```sh -npm run build +npm run setup +# This will generate prisma client, create tables and insert seed data ``` -Then run the app in production mode: - -```sh -npm start -``` +(You can reset database with `npx prisma migrate reset`.) -Now you'll need to pick a host to deploy it to. +The database setup should be run only once for a fresh database. +Whenever you change the `prisma/schema.prisma` file you need to -### DIY +1. Use [prisma migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate) to generate a migration and to update the database. +2. Run `npx prisma generate` to generate the prisma client. -If you're familiar with deploying node applications, the built-in Remix app server is production-ready. +Start [remix](https://remix.run) development server from your terminal with: -Make sure to deploy the output of `remix build` +```sh +npm run dev +``` -- `build/` -- `public/build/` +This will refresh & rebuild assets on file changes. -### Docker +## Other development commands -The web application can be run inside a Docker container. +To format according to [prettier](https://prettier.io) run -Requirements: +```sh +npm run format +``` -1. [bartender repo](https://github.com/i-VRESSE/bartender) to be cloned in `../bartender` directory. -2. bartender repo should have [.env file](https://github.com/i-VRESSE/bartender/blob/main/docs/configuration.md#environment-variables) -3. bartender repo should have a [config.yaml file](https://github.com/i-VRESSE/bartender/blob/main/docs/configuration.md#configuration-file) +It's recommended to install an editor plugin (like the [VSCode Prettier plugin](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)) to get auto-formatting on save. -Build with +To lint according [eslint](https://eslint.org) run ```sh -docker compose build +npm run lint ``` -Run with +To check the Typescript types run ```sh -docker compose up +npm run typecheck ``` -Web application running at http://localhost:8080 . - -Create super user with +To run unit tests (`app/**/*.test.ts`) with [Vitest](https://vitest.dev) use ```sh -# First register user in web application -docker compose exec bartender bartender super +# In watch mode +npm run test +# or in single run mode with coverage +npm run test -- run --coverage ``` -## Sessions - -Making the login session secure requires a session secret. -The session secret can be configured by setting the `SESSION_SECRET` environment variable. -If not set, a hardcoded secret is used, which should not be used in production. - -The data of the login sessions in stored in the `./sessions` directory. - -## Bartender web service client - -This web app uses a client to consume the bartender web service. +## Deployment -The client can be (re-)generated with +First, build your app for production: -```shell -npm run generate-client +```sh +npm run build ``` -(This command requires that the bartender webservice is running at http://localhost:8000) - -## Bartender web service configuration - -### Bartender - -The web application needs to know where the [Bartender web service](https://github.com/i-VRESSE/bartender) is running. -Configure bartender location with `BARTENDER_API_URL` environment variable. +Then run the app in production mode: ```sh -export BARTENDER_API_URL='http://127.0.0.1:8000' npm start ``` -### Social login - -To enable GitHub or Orcid or EGI Check-in login the bartender web service needs following environment variables. - -```shell -BARTENDER_GITHUB_REDIRECT_URL="http://localhost:3000/auth/github/callback" -BARTENDER_ORCIDSANDBOX_REDIRECT_URL="http://localhost:3000/auth/orcidsandbox/callback" -BARTENDER_ORCID_REDIRECT_URL="http://localhost:3000/auth/orcid/callback" -BARTENDER_EGI_REDIRECT_URL="http://localhost:3000/auth/egi/callback" -``` - -Where `http://localhost:3000` is the URL where the Remix run app is running. +The web application can be run inside a Docker container together with all its dependent containers, see [docs/docker.md](docs/docker.md). -## Haddock3 application +## Stack -This web app expects that the following application is registered in bartender web service. - -```yaml -applications: - haddock3: - command: haddock3 $config - config: workflow.cfg - allowed_roles: - - easy - - expert - - guru -``` - -This allows the archive generated with the workflow builder to be submitted. - -The user can only submit jobs when he/she has any of these allowed roles. -A super user should assign a role to the user at http://localhost:3000/admin/users. -A super user can be made through the admin page or by running `bartender super ` on the server - -## Catalogs - -This repo has a copy (`./app/catalogs/*.yaml`) of the [haddock3 workflow build catalogs](https://github.com/i-VRESSE/workflow-builder/tree/main/packages/haddock3_catalog/public/catalog). - -To fetch the latest catalogs run - -```shell -npm run catalogs -``` +The tech stack is explained in [docs/stack.md](docs/stack.md). diff --git a/app/auth.server.ts b/app/auth.server.ts new file mode 100644 index 00000000..81a3c053 --- /dev/null +++ b/app/auth.server.ts @@ -0,0 +1,322 @@ +import { Authenticator, type StrategyVerifyCallback } from "remix-auth"; +import { type GitHubEmails, GitHubStrategy } from "remix-auth-github"; +import { FormStrategy } from "remix-auth-form"; +import { + type OAuth2Profile, + OAuth2Strategy, + type OAuth2StrategyVerifyParams, +} from "remix-auth-oauth2"; +import { + type KeycloakExtraParams, + KeycloakStrategy, + type KeycloakProfile, +} from "remix-auth-keycloak"; +import { json } from "@remix-run/node"; + +import { sessionStorage } from "./session.server"; +import { + type TokenLessUser, + getUserById, + isSubmitAllowed, + localLogin, + oauthregister, +} from "./models/user.server"; +import { email, object, parse, string } from "valibot"; + +// Create an instance of the authenticator, pass a generic with what +// strategies will return and will store in the session +export const authenticator = new Authenticator(sessionStorage, { + throwOnError: true, +}); + +const CredentialsSchema = object({ + email: string([email()]), + password: string(), +}); + +// Tell the Authenticator to use the form strategy +authenticator.use( + new FormStrategy(async ({ form }) => { + const { email, password } = parse( + CredentialsSchema, + Object.fromEntries(form) + ); + const user = await localLogin(email, password); + return user.id; + }), + "user-pass" +); + +/** + * The super class GitHubStrategy returns emails that are not verified. + * This subclass filters out unverified emails. + */ +class GitHubStrategyWithVerifiedEmail extends GitHubStrategy { + // From https://github.com/sergiodxa/remix-auth-github/blob/75cedd281b58523c5d3db5f7bbe92218cb733c46/src/index.ts#L197 + protected async userEmails(accessToken: string): Promise { + // url & agent are private to super class so we have to copy them here + const userEmailsURL = "https://api.github.com/user/emails"; + const userAgent = "Haddock3WebApp"; + const response = await fetch(userEmailsURL, { + headers: { + Accept: "application/vnd.github.v3+json", + Authorization: `token ${accessToken}`, + "User-Agent": userAgent, + }, + }); + + const data: { + email: string; + verified: boolean; + primary: boolean; + visibility: string; + }[] = await response.json(); + const emails: GitHubEmails = data + .filter((e) => e.verified) + .map(({ email }) => ({ value: email })); + return emails; + } +} + +if ( + process.env.HADDOCK3WEBAPP_GITHUB_CLIENT_ID && + process.env.HADDOCK3WEBAPP_GITHUB_CLIENT_SECRET +) { + const gitHubStrategy = new GitHubStrategyWithVerifiedEmail( + { + clientID: process.env.HADDOCK3WEBAPP_GITHUB_CLIENT_ID, + clientSecret: process.env.HADDOCK3WEBAPP_GITHUB_CLIENT_SECRET, + callbackURL: + process.env.HADDOCK3WEBAPP_GITHUB_CALLBACK_URL || + "http://localhost:3000/auth/github/callback", + userAgent: "Haddock3WebApp", + }, + async ({ profile }) => { + // TODO store users display name in database for more personal greeting + const primaryEmail = profile.emails[0].value; + const photo = profile.photos[0].value ?? undefined; + const userId = await oauthregister(primaryEmail, photo); + return userId; + } + ); + + authenticator.use(gitHubStrategy); +} + +if ( + process.env.HADDOCK3WEBAPP_ORCID_CLIENT_ID && + process.env.HADDOCK3WEBAPP_ORCID_CLIENT_SECRET +) { + interface OrcidOptions { + clientID: string; + clientSecret: string; + callbackURL: string; + isSandBox: boolean; + } + + class OrcidStrategy extends OAuth2Strategy { + name = "orcid"; + private profileEndpoint: string; + private emailsEndpoint: string; + constructor( + options: OrcidOptions, + verify: StrategyVerifyCallback< + User, + OAuth2StrategyVerifyParams + > + ) { + const domain = options.isSandBox ? "sandbox.orcid.org" : "orcid.org"; + const AUTHORIZE_ENDPOINT = `https://${domain}/oauth/authorize`; + const ACCESS_TOKEN_ENDPOINT = `https://${domain}/oauth/token`; + const PROFILE_ENDPOINT = `https://${domain}/oauth/userinfo`; + const EMAILS_ENDPOINT = `https://pub.${domain}/v3.0/{id}/email`; + super( + { + clientID: options.clientID, + clientSecret: options.clientSecret, + callbackURL: options.callbackURL, + authorizationURL: AUTHORIZE_ENDPOINT, + tokenURL: ACCESS_TOKEN_ENDPOINT, + }, + verify + ); + this.profileEndpoint = PROFILE_ENDPOINT; + this.emailsEndpoint = EMAILS_ENDPOINT; + } + + protected authorizationParams() { + return new URLSearchParams({ + scope: "openid", + }); + } + + protected async userEmails(orcid: string) { + const emailsResponse = await fetch( + this.emailsEndpoint.replace("{id}", orcid), + { + headers: { + Accept: "application/orcid+json", + }, + } + ); + const emails: { email: { email: string }[] } = + await emailsResponse.json(); + if (!emails.email) { + throw new Error("No public email found."); + } + return emails.email.map((e) => ({ value: e.email })); + } + + protected async userProfile(accessToken: string): Promise { + const headers = { + Authorization: `Bearer ${accessToken}`, + }; + const profileResponse = await fetch(this.profileEndpoint, { headers }); + const profile = await profileResponse.json(); + const emails = await this.userEmails(profile.sub); + // TODO store Orcid id into database + return { + ...profile, + emails, + }; + } + } + + const orcidStrategy = new OrcidStrategy( + { + clientID: process.env.HADDOCK3WEBAPP_ORCID_CLIENT_ID, + clientSecret: process.env.HADDOCK3WEBAPP_ORCID_CLIENT_SECRET, + callbackURL: + process.env.HADDOCK3WEBAPP_ORCID_CALLBACK_URL || + "http://localhost:3000/auth/orcid/callback", + isSandBox: !!process.env.HADDOCK3WEBAPP_ORCID_SANDBOX, + }, + async ({ profile }) => { + const primaryEmail = profile.emails![0].value; + const photo = profile.photos ? profile.photos![0].value : undefined; + const userId = await oauthregister(primaryEmail, photo); + return userId; + } + ); + + authenticator.use(orcidStrategy); +} + +if ( + process.env.HADDOCK3WEBAPP_EGI_CLIENT_ID && + process.env.HADDOCK3WEBAPP_EGI_CLIENT_SECRET +) { + interface EgiOptions { + clientID: string; + clientSecret: string; + callbackURL: string; + environment: "production" | "development" | "demo"; + } + + class EgiStrategy extends KeycloakStrategy { + name = "egi"; + + constructor( + options: EgiOptions, + verify: StrategyVerifyCallback< + User, + OAuth2StrategyVerifyParams + > + ) { + const domain = { + production: "aai.egi.eu/auth", + development: "aai-dev.egi.eu/auth", + demo: "aai-demoegi.eu/auth", + }[options.environment]; + super( + { + clientID: options.clientID, + clientSecret: options.clientSecret, + callbackURL: options.callbackURL, + domain, + realm: "egi", + useSSL: true, + }, + verify + ); + } + } + + const egiStrategy = new EgiStrategy( + { + clientID: process.env.HADDOCK3WEBAPP_EGI_CLIENT_ID, + clientSecret: process.env.HADDOCK3WEBAPP_EGI_CLIENT_SECRET, + callbackURL: + process.env.HADDOCK3WEBAPP_EGI_CALLBACK_URL || + "http://localhost:3000/auth/egi/callback", + environment: + (process.env.HADDOCK3WEBAPP_EGI_ENVIRONMENT as + | "development" + | "production" + | "demo") || "production", + }, + async ({ profile }) => { + const primaryEmail = profile.emails![0].value; + if (!profile._json.email_verified) { + throw new Error("Email not verified"); + } + const photo = profile.photos ? profile.photos![0].value : undefined; + const userId = await oauthregister(primaryEmail, photo); + // TODO store egi fields like orcid, eduperson or voperson into database + // in far future could be used to submit job on GRID with users credentials + return userId; + } + ); + + authenticator.use(egiStrategy); +} + +export async function mustBeAuthenticated(request: Request) { + const userId = await authenticator.isAuthenticated(request); + if (userId === null) { + throw json({ error: "Unauthorized" }, { status: 401 }); + } + return userId; +} + +export async function getOptionalUser(request: Request) { + const userId = await authenticator.isAuthenticated(request); + if (userId === null) { + return null; + } + return await getUserById(userId); +} + +export async function getUser(request: Request) { + const user = await getOptionalUser(request); + if (!user) { + throw json({ error: "Unauthorized" }, { status: 401 }); + } + return user; +} + +export async function getOptionalClientUser( + request: Request +): Promise { + const user = await getOptionalUser(request); + if (!user) { + return null; + } + const { bartenderToken, bartenderTokenExpiresAt, ...tokenLessUser } = user; + return tokenLessUser; +} + +export async function mustBeAdmin(request: Request) { + const user = await getUser(request); + if (!user.isAdmin) { + throw json("Forbidden, not admin", { status: 403 }); + } +} + +export async function mustBeAllowedToSubmit(request: Request) { + const user = await getUser(request); + if (!isSubmitAllowed(user.preferredExpertiseLevel ?? "")) { + throw json({ error: "Submit not allowed" }, { status: 403 }); + } + return user; +} diff --git a/app/auth.ts b/app/auth.ts new file mode 100644 index 00000000..70f9da53 --- /dev/null +++ b/app/auth.ts @@ -0,0 +1,62 @@ +import { useMemo } from "react"; +import { useMatches } from "@remix-run/react"; + +import type { TokenLessUser } from "./models/user.server"; + +/** + * This base hook is used in other hooks to quickly search for specific data + * across all loader data using useMatches. + * @param {string} id The route id + * @returns {JSON|undefined} The router data or undefined if not found + */ +export function useMatchesData( + id: string +): Record | undefined { + const matchingRoutes = useMatches(); + const route = useMemo( + () => matchingRoutes.find((route) => route.id === id), + [matchingRoutes, id] + ); + return route?.data; +} + +function isUser(user: any): user is TokenLessUser { + return user && typeof user === "object" && typeof user.email === "string"; +} + +export function useOptionalUser() { + const data = useMatchesData("root"); + if (!data || !isUser(data.user)) { + return undefined; + } + return data.user; +} + +export function useUser() { + const maybeUser = useOptionalUser(); + if (!maybeUser) { + throw new Error( + "No user found in root loader, but user is required by useUser. If user is optional, try useOptionalUser instead." + ); + } + return maybeUser; +} + +export function useIsAdmin(): boolean { + const user = useOptionalUser(); + return user?.isAdmin ?? false; +} + +export function useIsLoggedIn(): boolean { + return !!useOptionalUser(); +} + +export function availableSocialLogins() { + return Object.keys(process.env) + .filter( + (key) => key.startsWith("HADDOCK3WEBAPP_") && key.endsWith("_CLIENT_ID") + ) + .map((key) => + key.replace("HADDOCK3WEBAPP_", "").replace("_CLIENT_ID", "").toLowerCase() + ); +} diff --git a/app/bartender-client/.openapi-generator/FILES b/app/bartender-client/.openapi-generator/FILES index bcd56ff4..ff495456 100644 --- a/app/bartender-client/.openapi-generator/FILES +++ b/app/bartender-client/.openapi-generator/FILES @@ -1,26 +1,15 @@ apis/ApplicationApi.ts -apis/AuthApi.ts apis/DefaultApi.ts apis/JobApi.ts -apis/RolesApi.ts -apis/UsersApi.ts +apis/UserApi.ts apis/index.ts index.ts models/ApplicatonConfiguration.ts -models/BearerResponse.ts -models/Detail.ts models/DirectoryItem.ts -models/ErrorModel.ts models/HTTPValidationError.ts models/JobModelDTO.ts models/LocationInner.ts -models/OAuth2AuthorizeResponse.ts -models/OAuthAccountName.ts -models/UserAsListItem.ts -models/UserCreate.ts -models/UserProfileInputDTO.ts -models/UserRead.ts -models/UserUpdate.ts +models/User.ts models/ValidationError.ts models/index.ts runtime.ts diff --git a/app/bartender-client/apis/ApplicationApi.ts b/app/bartender-client/apis/ApplicationApi.ts index fe18d65e..d8b5be0e 100644 --- a/app/bartender-client/apis/ApplicationApi.ts +++ b/app/bartender-client/apis/ApplicationApi.ts @@ -156,14 +156,6 @@ export class ApplicationApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -172,6 +164,10 @@ export class ApplicationApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const consumes: runtime.Consume[] = [ { contentType: "multipart/form-data" }, ]; diff --git a/app/bartender-client/apis/AuthApi.ts b/app/bartender-client/apis/AuthApi.ts deleted file mode 100644 index b0ab9b40..00000000 --- a/app/bartender-client/apis/AuthApi.ts +++ /dev/null @@ -1,1300 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import * as runtime from "../runtime"; -import type { - BearerResponse, - ErrorModel, - HTTPValidationError, - OAuth2AuthorizeResponse, - UserCreate, - UserRead, -} from "../models"; -import { - BearerResponseFromJSON, - BearerResponseToJSON, - ErrorModelFromJSON, - ErrorModelToJSON, - HTTPValidationErrorFromJSON, - HTTPValidationErrorToJSON, - OAuth2AuthorizeResponseFromJSON, - OAuth2AuthorizeResponseToJSON, - UserCreateFromJSON, - UserCreateToJSON, - UserReadFromJSON, - UserReadToJSON, -} from "../models"; - -export interface AuthLocalLoginRequest { - username: string; - password: string; - grantType?: string; - scope?: string; - clientId?: string; - clientSecret?: string; -} - -export interface OauthAssociateEGICheckInAuthorizeRequest { - scopes?: Array; -} - -export interface OauthAssociateEGICheckInCallbackRequest { - code?: string; - codeVerifier?: string; - state?: string; - error?: string; -} - -export interface OauthAssociateGithubAuthorizeRequest { - scopes?: Array; -} - -export interface OauthAssociateGithubCallbackRequest { - code?: string; - codeVerifier?: string; - state?: string; - error?: string; -} - -export interface OauthAssociateOrcidOrgAuthorizeRequest { - scopes?: Array; -} - -export interface OauthAssociateOrcidOrgCallbackRequest { - code?: string; - codeVerifier?: string; - state?: string; - error?: string; -} - -export interface OauthAssociateSandboxOrcidOrgAuthorizeRequest { - scopes?: Array; -} - -export interface OauthAssociateSandboxOrcidOrgCallbackRequest { - code?: string; - codeVerifier?: string; - state?: string; - error?: string; -} - -export interface OauthEGICheckInRemoteAuthorizeRequest { - scopes?: Array; -} - -export interface OauthEGICheckInRemoteCallbackRequest { - code?: string; - codeVerifier?: string; - state?: string; - error?: string; -} - -export interface OauthGithubRemoteAuthorizeRequest { - scopes?: Array; -} - -export interface OauthGithubRemoteCallbackRequest { - code?: string; - codeVerifier?: string; - state?: string; - error?: string; -} - -export interface OauthOrcidOrgRemoteAuthorizeRequest { - scopes?: Array; -} - -export interface OauthOrcidOrgRemoteCallbackRequest { - code?: string; - codeVerifier?: string; - state?: string; - error?: string; -} - -export interface OauthSandboxOrcidOrgRemoteAuthorizeRequest { - scopes?: Array; -} - -export interface OauthSandboxOrcidOrgRemoteCallbackRequest { - code?: string; - codeVerifier?: string; - state?: string; - error?: string; -} - -export interface RegisterRegisterRequest { - userCreate: UserCreate; -} - -/** - * - */ -export class AuthApi extends runtime.BaseAPI { - /** - * Auth:Local.Login - */ - async authLocalLoginRaw( - requestParameters: AuthLocalLoginRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - if ( - requestParameters.username === null || - requestParameters.username === undefined - ) { - throw new runtime.RequiredError( - "username", - "Required parameter requestParameters.username was null or undefined when calling authLocalLogin." - ); - } - - if ( - requestParameters.password === null || - requestParameters.password === undefined - ) { - throw new runtime.RequiredError( - "password", - "Required parameter requestParameters.password was null or undefined when calling authLocalLogin." - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - const consumes: runtime.Consume[] = [ - { contentType: "application/x-www-form-urlencoded" }, - ]; - // @ts-ignore: canConsumeForm may be unused - const canConsumeForm = runtime.canConsumeForm(consumes); - - let formParams: { append(param: string, value: any): any }; - let useForm = false; - if (useForm) { - formParams = new FormData(); - } else { - formParams = new URLSearchParams(); - } - - if (requestParameters.grantType !== undefined) { - formParams.append("grant_type", requestParameters.grantType as any); - } - - if (requestParameters.username !== undefined) { - formParams.append("username", requestParameters.username as any); - } - - if (requestParameters.password !== undefined) { - formParams.append("password", requestParameters.password as any); - } - - if (requestParameters.scope !== undefined) { - formParams.append("scope", requestParameters.scope as any); - } - - if (requestParameters.clientId !== undefined) { - formParams.append("client_id", requestParameters.clientId as any); - } - - if (requestParameters.clientSecret !== undefined) { - formParams.append("client_secret", requestParameters.clientSecret as any); - } - - const response = await this.request( - { - path: `/auth/jwt/login`, - method: "POST", - headers: headerParameters, - query: queryParameters, - body: formParams, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - BearerResponseFromJSON(jsonValue) - ); - } - - /** - * Auth:Local.Login - */ - async authLocalLogin( - requestParameters: AuthLocalLoginRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.authLocalLoginRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Auth:Local.Logout - */ - async authLocalLogoutRaw( - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/jwt/logout`, - method: "POST", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - if (this.isJsonMime(response.headers.get("content-type"))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } - - /** - * Auth:Local.Logout - */ - async authLocalLogout( - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.authLocalLogoutRaw(initOverrides); - return await response.value(); - } - - /** - * Oauth-Associate:Egi Check-In.Authorize - */ - async oauthAssociateEGICheckInAuthorizeRaw( - requestParameters: OauthAssociateEGICheckInAuthorizeRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.scopes) { - queryParameters["scopes"] = requestParameters.scopes; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/associate/egi/authorize`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - OAuth2AuthorizeResponseFromJSON(jsonValue) - ); - } - - /** - * Oauth-Associate:Egi Check-In.Authorize - */ - async oauthAssociateEGICheckInAuthorize( - requestParameters: OauthAssociateEGICheckInAuthorizeRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthAssociateEGICheckInAuthorizeRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * The response varies based on the authentication backend used. - * Oauth-Associate:Egi Check-In.Callback - */ - async oauthAssociateEGICheckInCallbackRaw( - requestParameters: OauthAssociateEGICheckInCallbackRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.code !== undefined) { - queryParameters["code"] = requestParameters.code; - } - - if (requestParameters.codeVerifier !== undefined) { - queryParameters["code_verifier"] = requestParameters.codeVerifier; - } - - if (requestParameters.state !== undefined) { - queryParameters["state"] = requestParameters.state; - } - - if (requestParameters.error !== undefined) { - queryParameters["error"] = requestParameters.error; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/associate/egi/callback`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * The response varies based on the authentication backend used. - * Oauth-Associate:Egi Check-In.Callback - */ - async oauthAssociateEGICheckInCallback( - requestParameters: OauthAssociateEGICheckInCallbackRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthAssociateEGICheckInCallbackRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Oauth-Associate:Github.Authorize - */ - async oauthAssociateGithubAuthorizeRaw( - requestParameters: OauthAssociateGithubAuthorizeRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.scopes) { - queryParameters["scopes"] = requestParameters.scopes; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/associate/github/authorize`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - OAuth2AuthorizeResponseFromJSON(jsonValue) - ); - } - - /** - * Oauth-Associate:Github.Authorize - */ - async oauthAssociateGithubAuthorize( - requestParameters: OauthAssociateGithubAuthorizeRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthAssociateGithubAuthorizeRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * The response varies based on the authentication backend used. - * Oauth-Associate:Github.Callback - */ - async oauthAssociateGithubCallbackRaw( - requestParameters: OauthAssociateGithubCallbackRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.code !== undefined) { - queryParameters["code"] = requestParameters.code; - } - - if (requestParameters.codeVerifier !== undefined) { - queryParameters["code_verifier"] = requestParameters.codeVerifier; - } - - if (requestParameters.state !== undefined) { - queryParameters["state"] = requestParameters.state; - } - - if (requestParameters.error !== undefined) { - queryParameters["error"] = requestParameters.error; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/associate/github/callback`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * The response varies based on the authentication backend used. - * Oauth-Associate:Github.Callback - */ - async oauthAssociateGithubCallback( - requestParameters: OauthAssociateGithubCallbackRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthAssociateGithubCallbackRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Oauth-Associate:Orcid.Org.Authorize - */ - async oauthAssociateOrcidOrgAuthorizeRaw( - requestParameters: OauthAssociateOrcidOrgAuthorizeRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.scopes) { - queryParameters["scopes"] = requestParameters.scopes; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/associate/orcid/authorize`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - OAuth2AuthorizeResponseFromJSON(jsonValue) - ); - } - - /** - * Oauth-Associate:Orcid.Org.Authorize - */ - async oauthAssociateOrcidOrgAuthorize( - requestParameters: OauthAssociateOrcidOrgAuthorizeRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthAssociateOrcidOrgAuthorizeRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * The response varies based on the authentication backend used. - * Oauth-Associate:Orcid.Org.Callback - */ - async oauthAssociateOrcidOrgCallbackRaw( - requestParameters: OauthAssociateOrcidOrgCallbackRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.code !== undefined) { - queryParameters["code"] = requestParameters.code; - } - - if (requestParameters.codeVerifier !== undefined) { - queryParameters["code_verifier"] = requestParameters.codeVerifier; - } - - if (requestParameters.state !== undefined) { - queryParameters["state"] = requestParameters.state; - } - - if (requestParameters.error !== undefined) { - queryParameters["error"] = requestParameters.error; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/associate/orcid/callback`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * The response varies based on the authentication backend used. - * Oauth-Associate:Orcid.Org.Callback - */ - async oauthAssociateOrcidOrgCallback( - requestParameters: OauthAssociateOrcidOrgCallbackRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthAssociateOrcidOrgCallbackRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Oauth-Associate:Sandbox.Orcid.Org.Authorize - */ - async oauthAssociateSandboxOrcidOrgAuthorizeRaw( - requestParameters: OauthAssociateSandboxOrcidOrgAuthorizeRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.scopes) { - queryParameters["scopes"] = requestParameters.scopes; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/associate/orcidsandbox/authorize`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - OAuth2AuthorizeResponseFromJSON(jsonValue) - ); - } - - /** - * Oauth-Associate:Sandbox.Orcid.Org.Authorize - */ - async oauthAssociateSandboxOrcidOrgAuthorize( - requestParameters: OauthAssociateSandboxOrcidOrgAuthorizeRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthAssociateSandboxOrcidOrgAuthorizeRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * The response varies based on the authentication backend used. - * Oauth-Associate:Sandbox.Orcid.Org.Callback - */ - async oauthAssociateSandboxOrcidOrgCallbackRaw( - requestParameters: OauthAssociateSandboxOrcidOrgCallbackRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.code !== undefined) { - queryParameters["code"] = requestParameters.code; - } - - if (requestParameters.codeVerifier !== undefined) { - queryParameters["code_verifier"] = requestParameters.codeVerifier; - } - - if (requestParameters.state !== undefined) { - queryParameters["state"] = requestParameters.state; - } - - if (requestParameters.error !== undefined) { - queryParameters["error"] = requestParameters.error; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/auth/associate/orcidsandbox/callback`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * The response varies based on the authentication backend used. - * Oauth-Associate:Sandbox.Orcid.Org.Callback - */ - async oauthAssociateSandboxOrcidOrgCallback( - requestParameters: OauthAssociateSandboxOrcidOrgCallbackRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthAssociateSandboxOrcidOrgCallbackRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Oauth:Egi Check-In.Remote.Authorize - */ - async oauthEGICheckInRemoteAuthorizeRaw( - requestParameters: OauthEGICheckInRemoteAuthorizeRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.scopes) { - queryParameters["scopes"] = requestParameters.scopes; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request( - { - path: `/auth/egi/authorize`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - OAuth2AuthorizeResponseFromJSON(jsonValue) - ); - } - - /** - * Oauth:Egi Check-In.Remote.Authorize - */ - async oauthEGICheckInRemoteAuthorize( - requestParameters: OauthEGICheckInRemoteAuthorizeRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthEGICheckInRemoteAuthorizeRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * The response varies based on the authentication backend used. - * Oauth:Egi Check-In.Remote.Callback - */ - async oauthEGICheckInRemoteCallbackRaw( - requestParameters: OauthEGICheckInRemoteCallbackRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.code !== undefined) { - queryParameters["code"] = requestParameters.code; - } - - if (requestParameters.codeVerifier !== undefined) { - queryParameters["code_verifier"] = requestParameters.codeVerifier; - } - - if (requestParameters.state !== undefined) { - queryParameters["state"] = requestParameters.state; - } - - if (requestParameters.error !== undefined) { - queryParameters["error"] = requestParameters.error; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request( - { - path: `/auth/egi/callback`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - if (this.isJsonMime(response.headers.get("content-type"))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } - - /** - * The response varies based on the authentication backend used. - * Oauth:Egi Check-In.Remote.Callback - */ - async oauthEGICheckInRemoteCallback( - requestParameters: OauthEGICheckInRemoteCallbackRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthEGICheckInRemoteCallbackRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Oauth:Github.Remote.Authorize - */ - async oauthGithubRemoteAuthorizeRaw( - requestParameters: OauthGithubRemoteAuthorizeRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.scopes) { - queryParameters["scopes"] = requestParameters.scopes; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request( - { - path: `/auth/github/authorize`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - OAuth2AuthorizeResponseFromJSON(jsonValue) - ); - } - - /** - * Oauth:Github.Remote.Authorize - */ - async oauthGithubRemoteAuthorize( - requestParameters: OauthGithubRemoteAuthorizeRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthGithubRemoteAuthorizeRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * The response varies based on the authentication backend used. - * Oauth:Github.Remote.Callback - */ - async oauthGithubRemoteCallbackRaw( - requestParameters: OauthGithubRemoteCallbackRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.code !== undefined) { - queryParameters["code"] = requestParameters.code; - } - - if (requestParameters.codeVerifier !== undefined) { - queryParameters["code_verifier"] = requestParameters.codeVerifier; - } - - if (requestParameters.state !== undefined) { - queryParameters["state"] = requestParameters.state; - } - - if (requestParameters.error !== undefined) { - queryParameters["error"] = requestParameters.error; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request( - { - path: `/auth/github/callback`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - if (this.isJsonMime(response.headers.get("content-type"))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } - - /** - * The response varies based on the authentication backend used. - * Oauth:Github.Remote.Callback - */ - async oauthGithubRemoteCallback( - requestParameters: OauthGithubRemoteCallbackRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthGithubRemoteCallbackRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Oauth:Orcid.Org.Remote.Authorize - */ - async oauthOrcidOrgRemoteAuthorizeRaw( - requestParameters: OauthOrcidOrgRemoteAuthorizeRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.scopes) { - queryParameters["scopes"] = requestParameters.scopes; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request( - { - path: `/auth/orcid/authorize`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - OAuth2AuthorizeResponseFromJSON(jsonValue) - ); - } - - /** - * Oauth:Orcid.Org.Remote.Authorize - */ - async oauthOrcidOrgRemoteAuthorize( - requestParameters: OauthOrcidOrgRemoteAuthorizeRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthOrcidOrgRemoteAuthorizeRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * The response varies based on the authentication backend used. - * Oauth:Orcid.Org.Remote.Callback - */ - async oauthOrcidOrgRemoteCallbackRaw( - requestParameters: OauthOrcidOrgRemoteCallbackRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.code !== undefined) { - queryParameters["code"] = requestParameters.code; - } - - if (requestParameters.codeVerifier !== undefined) { - queryParameters["code_verifier"] = requestParameters.codeVerifier; - } - - if (requestParameters.state !== undefined) { - queryParameters["state"] = requestParameters.state; - } - - if (requestParameters.error !== undefined) { - queryParameters["error"] = requestParameters.error; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request( - { - path: `/auth/orcid/callback`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - if (this.isJsonMime(response.headers.get("content-type"))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } - - /** - * The response varies based on the authentication backend used. - * Oauth:Orcid.Org.Remote.Callback - */ - async oauthOrcidOrgRemoteCallback( - requestParameters: OauthOrcidOrgRemoteCallbackRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthOrcidOrgRemoteCallbackRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Oauth:Sandbox.Orcid.Org.Remote.Authorize - */ - async oauthSandboxOrcidOrgRemoteAuthorizeRaw( - requestParameters: OauthSandboxOrcidOrgRemoteAuthorizeRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.scopes) { - queryParameters["scopes"] = requestParameters.scopes; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request( - { - path: `/auth/orcidsandbox/authorize`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - OAuth2AuthorizeResponseFromJSON(jsonValue) - ); - } - - /** - * Oauth:Sandbox.Orcid.Org.Remote.Authorize - */ - async oauthSandboxOrcidOrgRemoteAuthorize( - requestParameters: OauthSandboxOrcidOrgRemoteAuthorizeRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthSandboxOrcidOrgRemoteAuthorizeRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * The response varies based on the authentication backend used. - * Oauth:Sandbox.Orcid.Org.Remote.Callback - */ - async oauthSandboxOrcidOrgRemoteCallbackRaw( - requestParameters: OauthSandboxOrcidOrgRemoteCallbackRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - if (requestParameters.code !== undefined) { - queryParameters["code"] = requestParameters.code; - } - - if (requestParameters.codeVerifier !== undefined) { - queryParameters["code_verifier"] = requestParameters.codeVerifier; - } - - if (requestParameters.state !== undefined) { - queryParameters["state"] = requestParameters.state; - } - - if (requestParameters.error !== undefined) { - queryParameters["error"] = requestParameters.error; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - const response = await this.request( - { - path: `/auth/orcidsandbox/callback`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - if (this.isJsonMime(response.headers.get("content-type"))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } - - /** - * The response varies based on the authentication backend used. - * Oauth:Sandbox.Orcid.Org.Remote.Callback - */ - async oauthSandboxOrcidOrgRemoteCallback( - requestParameters: OauthSandboxOrcidOrgRemoteCallbackRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.oauthSandboxOrcidOrgRemoteCallbackRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Register:Register - */ - async registerRegisterRaw( - requestParameters: RegisterRegisterRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - if ( - requestParameters.userCreate === null || - requestParameters.userCreate === undefined - ) { - throw new runtime.RequiredError( - "userCreate", - "Required parameter requestParameters.userCreate was null or undefined when calling registerRegister." - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - headerParameters["Content-Type"] = "application/json"; - - const response = await this.request( - { - path: `/auth/register`, - method: "POST", - headers: headerParameters, - query: queryParameters, - body: UserCreateToJSON(requestParameters.userCreate), - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * Register:Register - */ - async registerRegister( - requestParameters: RegisterRegisterRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.registerRegisterRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } -} diff --git a/app/bartender-client/apis/DefaultApi.ts b/app/bartender-client/apis/DefaultApi.ts index 5cb8df21..db29161c 100644 --- a/app/bartender-client/apis/DefaultApi.ts +++ b/app/bartender-client/apis/DefaultApi.ts @@ -19,7 +19,7 @@ import * as runtime from "../runtime"; */ export class DefaultApi extends runtime.BaseAPI { /** - * Checks the health of a project. It returns 200 if the project is healthy. + * Checks the health of a project. It returns 200 if the project is healthy. Args: session: SQLAlchemy session. * Health Check */ async healthCheckRaw( @@ -47,7 +47,7 @@ export class DefaultApi extends runtime.BaseAPI { } /** - * Checks the health of a project. It returns 200 if the project is healthy. + * Checks the health of a project. It returns 200 if the project is healthy. Args: session: SQLAlchemy session. * Health Check */ async healthCheck( diff --git a/app/bartender-client/apis/JobApi.ts b/app/bartender-client/apis/JobApi.ts index a1dae0a6..b64ea5c5 100644 --- a/app/bartender-client/apis/JobApi.ts +++ b/app/bartender-client/apis/JobApi.ts @@ -101,14 +101,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -117,6 +109,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/{jobid}`.replace( @@ -176,14 +172,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -192,6 +180,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/{jobid}/directories`.replace( @@ -261,14 +253,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -277,6 +261,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/{jobid}/directories/{path}` @@ -349,14 +337,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -365,6 +345,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/{jobid}/archive`.replace( @@ -432,14 +416,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -448,6 +424,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/{jobid}/files/{path}` @@ -510,14 +490,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -526,6 +498,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/{jobid}/stderr`.replace( @@ -583,14 +559,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -599,6 +567,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/{jobid}/stdout`.replace( @@ -678,14 +650,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -694,6 +658,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/{jobid}/archive/{path}` @@ -754,14 +722,6 @@ export class JobApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - if (this.configuration && this.configuration.accessToken) { const token = this.configuration.accessToken; const tokenString = await token("HTTPBearer", []); @@ -770,6 +730,10 @@ export class JobApi extends runtime.BaseAPI { headerParameters["Authorization"] = `Bearer ${tokenString}`; } } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + const response = await this.request( { path: `/api/job/`, diff --git a/app/bartender-client/apis/RolesApi.ts b/app/bartender-client/apis/RolesApi.ts deleted file mode 100644 index 433e4aab..00000000 --- a/app/bartender-client/apis/RolesApi.ts +++ /dev/null @@ -1,254 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import * as runtime from "../runtime"; -import type { HTTPValidationError } from "../models"; -import { - HTTPValidationErrorFromJSON, - HTTPValidationErrorToJSON, -} from "../models"; - -export interface AssignRoleToUserRequest { - roleId: string; - userId: string; -} - -export interface UnassignRoleFromUserRequest { - roleId: string; - userId: string; -} - -/** - * - */ -export class RolesApi extends runtime.BaseAPI { - /** - * Assign role to user. Requires super user powers. Args: role_id: Role id user_id: User id roles: Set of allowed roles super_user: Check if current user is super. user_db: User db. Raises: HTTPException: When user is not found Returns: Roles assigned to user. - * Assign Role To User - */ - async assignRoleToUserRaw( - requestParameters: AssignRoleToUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise>> { - if ( - requestParameters.roleId === null || - requestParameters.roleId === undefined - ) { - throw new runtime.RequiredError( - "roleId", - "Required parameter requestParameters.roleId was null or undefined when calling assignRoleToUser." - ); - } - - if ( - requestParameters.userId === null || - requestParameters.userId === undefined - ) { - throw new runtime.RequiredError( - "userId", - "Required parameter requestParameters.userId was null or undefined when calling assignRoleToUser." - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/api/roles/{role_id}/{user_id}` - .replace( - `{${"role_id"}}`, - encodeURIComponent(String(requestParameters.roleId)) - ) - .replace( - `{${"user_id"}}`, - encodeURIComponent(String(requestParameters.userId)) - ), - method: "PUT", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response); - } - - /** - * Assign role to user. Requires super user powers. Args: role_id: Role id user_id: User id roles: Set of allowed roles super_user: Check if current user is super. user_db: User db. Raises: HTTPException: When user is not found Returns: Roles assigned to user. - * Assign Role To User - */ - async assignRoleToUser( - requestParameters: AssignRoleToUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const response = await this.assignRoleToUserRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * List available roles. Requires logged in user to be a super user. Args: roles: Roles from config. super_user: Checks if current user is super. Returns: List of role names. - * List Roles - */ - async listRolesRaw( - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise>> { - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/api/roles/`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response); - } - - /** - * List available roles. Requires logged in user to be a super user. Args: roles: Roles from config. super_user: Checks if current user is super. Returns: List of role names. - * List Roles - */ - async listRoles( - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const response = await this.listRolesRaw(initOverrides); - return await response.value(); - } - - /** - * Unassign role from user. Requires super user powers. Args: role_id: Role id user_id: User id roles: Set of allowed roles super_user: Check if current user is super. user_db: User db. Raises: HTTPException: When user is not found Returns: Roles assigned to user. - * Unassign Role From User - */ - async unassignRoleFromUserRaw( - requestParameters: UnassignRoleFromUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise>> { - if ( - requestParameters.roleId === null || - requestParameters.roleId === undefined - ) { - throw new runtime.RequiredError( - "roleId", - "Required parameter requestParameters.roleId was null or undefined when calling unassignRoleFromUser." - ); - } - - if ( - requestParameters.userId === null || - requestParameters.userId === undefined - ) { - throw new runtime.RequiredError( - "userId", - "Required parameter requestParameters.userId was null or undefined when calling unassignRoleFromUser." - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/api/roles/{role_id}/{user_id}` - .replace( - `{${"role_id"}}`, - encodeURIComponent(String(requestParameters.roleId)) - ) - .replace( - `{${"user_id"}}`, - encodeURIComponent(String(requestParameters.userId)) - ), - method: "DELETE", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response); - } - - /** - * Unassign role from user. Requires super user powers. Args: role_id: Role id user_id: User id roles: Set of allowed roles super_user: Check if current user is super. user_db: User db. Raises: HTTPException: When user is not found Returns: Roles assigned to user. - * Unassign Role From User - */ - async unassignRoleFromUser( - requestParameters: UnassignRoleFromUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const response = await this.unassignRoleFromUserRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } -} diff --git a/app/bartender-client/apis/UserApi.ts b/app/bartender-client/apis/UserApi.ts new file mode 100644 index 00000000..5d982e0c --- /dev/null +++ b/app/bartender-client/apis/UserApi.ts @@ -0,0 +1,71 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * bartender + * Job middleware for i-VRESSE + * + * The version of the OpenAPI document: 0.2.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from "../runtime"; +import type { User } from "../models"; +import { UserFromJSON, UserToJSON } from "../models"; + +/** + * + */ +export class UserApi extends runtime.BaseAPI { + /** + * Get current user based on API key. Args: user: Current user. Returns: Current logged in user. + * Whoami + */ + async whoamiRaw( + initOverrides?: RequestInit | runtime.InitOverrideFunction + ): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("HTTPBearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = this.configuration.apiKey("token"); // APIKeyQuery authentication + } + + const response = await this.request( + { + path: `/api/whoami`, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + UserFromJSON(jsonValue) + ); + } + + /** + * Get current user based on API key. Args: user: Current user. Returns: Current logged in user. + * Whoami + */ + async whoami( + initOverrides?: RequestInit | runtime.InitOverrideFunction + ): Promise { + const response = await this.whoamiRaw(initOverrides); + return await response.value(); + } +} diff --git a/app/bartender-client/apis/UsersApi.ts b/app/bartender-client/apis/UsersApi.ts deleted file mode 100644 index 89a7fb90..00000000 --- a/app/bartender-client/apis/UsersApi.ts +++ /dev/null @@ -1,502 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import * as runtime from "../runtime"; -import type { - ErrorModel, - HTTPValidationError, - UserAsListItem, - UserProfileInputDTO, - UserRead, - UserUpdate, -} from "../models"; -import { - ErrorModelFromJSON, - ErrorModelToJSON, - HTTPValidationErrorFromJSON, - HTTPValidationErrorToJSON, - UserAsListItemFromJSON, - UserAsListItemToJSON, - UserProfileInputDTOFromJSON, - UserProfileInputDTOToJSON, - UserReadFromJSON, - UserReadToJSON, - UserUpdateFromJSON, - UserUpdateToJSON, -} from "../models"; - -export interface ListUsersRequest { - limit?: number; - offset?: number; -} - -export interface UsersDeleteUserRequest { - id: any; -} - -export interface UsersPatchCurrentUserRequest { - userUpdate: UserUpdate; -} - -export interface UsersPatchUserRequest { - id: any; - userUpdate: UserUpdate; -} - -export interface UsersUserRequest { - id: any; -} - -/** - * - */ -export class UsersApi extends runtime.BaseAPI { - /** - * List of users. Requires super user powers. Args: limit: Number of users to return. Defaults to 50. offset: Offset. Defaults to 0. super_user: Check if current user is super. user_db: User db. Returns: List of users. - * List Users - */ - async listUsersRaw( - requestParameters: ListUsersRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise>> { - const queryParameters: any = {}; - - if (requestParameters.limit !== undefined) { - queryParameters["limit"] = requestParameters.limit; - } - - if (requestParameters.offset !== undefined) { - queryParameters["offset"] = requestParameters.offset; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/api/users/`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - jsonValue.map(UserAsListItemFromJSON) - ); - } - - /** - * List of users. Requires super user powers. Args: limit: Number of users to return. Defaults to 50. offset: Offset. Defaults to 0. super_user: Check if current user is super. user_db: User db. Returns: List of users. - * List Users - */ - async listUsers( - requestParameters: ListUsersRequest = {}, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const response = await this.listUsersRaw(requestParameters, initOverrides); - return await response.value(); - } - - /** - * Retrieve profile of currently logged in user. Args: user: Current active user. Returns: user profile. - * Profile - */ - async profileRaw( - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/api/users/profile`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserProfileInputDTOFromJSON(jsonValue) - ); - } - - /** - * Retrieve profile of currently logged in user. Args: user: Current active user. Returns: user profile. - * Profile - */ - async profile( - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.profileRaw(initOverrides); - return await response.value(); - } - - /** - * Users:Current User - */ - async usersCurrentUserRaw( - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/users/me`, - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * Users:Current User - */ - async usersCurrentUser( - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.usersCurrentUserRaw(initOverrides); - return await response.value(); - } - - /** - * Users:Delete User - */ - async usersDeleteUserRaw( - requestParameters: UsersDeleteUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - if (requestParameters.id === null || requestParameters.id === undefined) { - throw new runtime.RequiredError( - "id", - "Required parameter requestParameters.id was null or undefined when calling usersDeleteUser." - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/users/{id}`.replace( - `{${"id"}}`, - encodeURIComponent(String(requestParameters.id)) - ), - method: "DELETE", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.VoidApiResponse(response); - } - - /** - * Users:Delete User - */ - async usersDeleteUser( - requestParameters: UsersDeleteUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - await this.usersDeleteUserRaw(requestParameters, initOverrides); - } - - /** - * Users:Patch Current User - */ - async usersPatchCurrentUserRaw( - requestParameters: UsersPatchCurrentUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - if ( - requestParameters.userUpdate === null || - requestParameters.userUpdate === undefined - ) { - throw new runtime.RequiredError( - "userUpdate", - "Required parameter requestParameters.userUpdate was null or undefined when calling usersPatchCurrentUser." - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - headerParameters["Content-Type"] = "application/json"; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/users/me`, - method: "PATCH", - headers: headerParameters, - query: queryParameters, - body: UserUpdateToJSON(requestParameters.userUpdate), - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * Users:Patch Current User - */ - async usersPatchCurrentUser( - requestParameters: UsersPatchCurrentUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.usersPatchCurrentUserRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Users:Patch User - */ - async usersPatchUserRaw( - requestParameters: UsersPatchUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - if (requestParameters.id === null || requestParameters.id === undefined) { - throw new runtime.RequiredError( - "id", - "Required parameter requestParameters.id was null or undefined when calling usersPatchUser." - ); - } - - if ( - requestParameters.userUpdate === null || - requestParameters.userUpdate === undefined - ) { - throw new runtime.RequiredError( - "userUpdate", - "Required parameter requestParameters.userUpdate was null or undefined when calling usersPatchUser." - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - headerParameters["Content-Type"] = "application/json"; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/users/{id}`.replace( - `{${"id"}}`, - encodeURIComponent(String(requestParameters.id)) - ), - method: "PATCH", - headers: headerParameters, - query: queryParameters, - body: UserUpdateToJSON(requestParameters.userUpdate), - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * Users:Patch User - */ - async usersPatchUser( - requestParameters: UsersPatchUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.usersPatchUserRaw( - requestParameters, - initOverrides - ); - return await response.value(); - } - - /** - * Users:User - */ - async usersUserRaw( - requestParameters: UsersUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise> { - if (requestParameters.id === null || requestParameters.id === undefined) { - throw new runtime.RequiredError( - "id", - "Required parameter requestParameters.id was null or undefined when calling usersUser." - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.accessToken) { - // oauth required - headerParameters["Authorization"] = await this.configuration.accessToken( - "OAuth2PasswordBearer", - [] - ); - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("HTTPBearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request( - { - path: `/users/{id}`.replace( - `{${"id"}}`, - encodeURIComponent(String(requestParameters.id)) - ), - method: "GET", - headers: headerParameters, - query: queryParameters, - }, - initOverrides - ); - - return new runtime.JSONApiResponse(response, (jsonValue) => - UserReadFromJSON(jsonValue) - ); - } - - /** - * Users:User - */ - async usersUser( - requestParameters: UsersUserRequest, - initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { - const response = await this.usersUserRaw(requestParameters, initOverrides); - return await response.value(); - } -} diff --git a/app/bartender-client/apis/index.ts b/app/bartender-client/apis/index.ts index ca036c6a..e3ef3240 100644 --- a/app/bartender-client/apis/index.ts +++ b/app/bartender-client/apis/index.ts @@ -1,8 +1,6 @@ /* tslint:disable */ /* eslint-disable */ export * from "./ApplicationApi"; -export * from "./AuthApi"; export * from "./DefaultApi"; export * from "./JobApi"; -export * from "./RolesApi"; -export * from "./UsersApi"; +export * from "./UserApi"; diff --git a/app/bartender-client/models/BearerResponse.ts b/app/bartender-client/models/BearerResponse.ts deleted file mode 100644 index abd4e170..00000000 --- a/app/bartender-client/models/BearerResponse.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -/** - * - * @export - * @interface BearerResponse - */ -export interface BearerResponse { - /** - * - * @type {string} - * @memberof BearerResponse - */ - accessToken: string; - /** - * - * @type {string} - * @memberof BearerResponse - */ - tokenType: string; -} - -/** - * Check if a given object implements the BearerResponse interface. - */ -export function instanceOfBearerResponse(value: object): boolean { - let isInstance = true; - isInstance = isInstance && "accessToken" in value; - isInstance = isInstance && "tokenType" in value; - - return isInstance; -} - -export function BearerResponseFromJSON(json: any): BearerResponse { - return BearerResponseFromJSONTyped(json, false); -} - -export function BearerResponseFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): BearerResponse { - if (json === undefined || json === null) { - return json; - } - return { - accessToken: json["access_token"], - tokenType: json["token_type"], - }; -} - -export function BearerResponseToJSON(value?: BearerResponse | null): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - access_token: value.accessToken, - token_type: value.tokenType, - }; -} diff --git a/app/bartender-client/models/Detail.ts b/app/bartender-client/models/Detail.ts deleted file mode 100644 index 8f57f977..00000000 --- a/app/bartender-client/models/Detail.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -/** - * - * @export - * @interface Detail - */ -export interface Detail {} - -/** - * Check if a given object implements the Detail interface. - */ -export function instanceOfDetail(value: object): boolean { - let isInstance = true; - - return isInstance; -} - -export function DetailFromJSON(json: any): Detail { - return DetailFromJSONTyped(json, false); -} - -export function DetailFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): Detail { - return json; -} - -export function DetailToJSON(value?: Detail | null): any { - return value; -} diff --git a/app/bartender-client/models/ErrorModel.ts b/app/bartender-client/models/ErrorModel.ts deleted file mode 100644 index baf70ed4..00000000 --- a/app/bartender-client/models/ErrorModel.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -import type { Detail } from "./Detail"; -import { DetailFromJSON, DetailFromJSONTyped, DetailToJSON } from "./Detail"; - -/** - * - * @export - * @interface ErrorModel - */ -export interface ErrorModel { - /** - * - * @type {Detail} - * @memberof ErrorModel - */ - detail: Detail; -} - -/** - * Check if a given object implements the ErrorModel interface. - */ -export function instanceOfErrorModel(value: object): boolean { - let isInstance = true; - isInstance = isInstance && "detail" in value; - - return isInstance; -} - -export function ErrorModelFromJSON(json: any): ErrorModel { - return ErrorModelFromJSONTyped(json, false); -} - -export function ErrorModelFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): ErrorModel { - if (json === undefined || json === null) { - return json; - } - return { - detail: DetailFromJSON(json["detail"]), - }; -} - -export function ErrorModelToJSON(value?: ErrorModel | null): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - detail: DetailToJSON(value.detail), - }; -} diff --git a/app/bartender-client/models/OAuth2AuthorizeResponse.ts b/app/bartender-client/models/OAuth2AuthorizeResponse.ts deleted file mode 100644 index 76e0b81d..00000000 --- a/app/bartender-client/models/OAuth2AuthorizeResponse.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -/** - * - * @export - * @interface OAuth2AuthorizeResponse - */ -export interface OAuth2AuthorizeResponse { - /** - * - * @type {string} - * @memberof OAuth2AuthorizeResponse - */ - authorizationUrl: string; -} - -/** - * Check if a given object implements the OAuth2AuthorizeResponse interface. - */ -export function instanceOfOAuth2AuthorizeResponse(value: object): boolean { - let isInstance = true; - isInstance = isInstance && "authorizationUrl" in value; - - return isInstance; -} - -export function OAuth2AuthorizeResponseFromJSON( - json: any -): OAuth2AuthorizeResponse { - return OAuth2AuthorizeResponseFromJSONTyped(json, false); -} - -export function OAuth2AuthorizeResponseFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): OAuth2AuthorizeResponse { - if (json === undefined || json === null) { - return json; - } - return { - authorizationUrl: json["authorization_url"], - }; -} - -export function OAuth2AuthorizeResponseToJSON( - value?: OAuth2AuthorizeResponse | null -): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - authorization_url: value.authorizationUrl, - }; -} diff --git a/app/bartender-client/models/OAuthAccountName.ts b/app/bartender-client/models/OAuthAccountName.ts deleted file mode 100644 index d24216e8..00000000 --- a/app/bartender-client/models/OAuthAccountName.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -/** - * DTO for social providers name of a user. - * @export - * @interface OAuthAccountName - */ -export interface OAuthAccountName { - /** - * - * @type {string} - * @memberof OAuthAccountName - */ - oauthName: string; - /** - * - * @type {string} - * @memberof OAuthAccountName - */ - accountId: string; - /** - * - * @type {string} - * @memberof OAuthAccountName - */ - accountEmail: string; -} - -/** - * Check if a given object implements the OAuthAccountName interface. - */ -export function instanceOfOAuthAccountName(value: object): boolean { - let isInstance = true; - isInstance = isInstance && "oauthName" in value; - isInstance = isInstance && "accountId" in value; - isInstance = isInstance && "accountEmail" in value; - - return isInstance; -} - -export function OAuthAccountNameFromJSON(json: any): OAuthAccountName { - return OAuthAccountNameFromJSONTyped(json, false); -} - -export function OAuthAccountNameFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): OAuthAccountName { - if (json === undefined || json === null) { - return json; - } - return { - oauthName: json["oauth_name"], - accountId: json["account_id"], - accountEmail: json["account_email"], - }; -} - -export function OAuthAccountNameToJSON(value?: OAuthAccountName | null): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - oauth_name: value.oauthName, - account_id: value.accountId, - account_email: value.accountEmail, - }; -} diff --git a/app/bartender-client/models/User.ts b/app/bartender-client/models/User.ts new file mode 100644 index 00000000..1aae08c9 --- /dev/null +++ b/app/bartender-client/models/User.ts @@ -0,0 +1,83 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * bartender + * Job middleware for i-VRESSE + * + * The version of the OpenAPI document: 0.2.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from "../runtime"; +/** + * User model. + * @export + * @interface User + */ +export interface User { + /** + * + * @type {string} + * @memberof User + */ + username: string; + /** + * + * @type {Array} + * @memberof User + */ + roles?: Array; + /** + * + * @type {string} + * @memberof User + */ + apikey: string; +} + +/** + * Check if a given object implements the User interface. + */ +export function instanceOfUser(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "username" in value; + isInstance = isInstance && "apikey" in value; + + return isInstance; +} + +export function UserFromJSON(json: any): User { + return UserFromJSONTyped(json, false); +} + +export function UserFromJSONTyped( + json: any, + ignoreDiscriminator: boolean +): User { + if (json === undefined || json === null) { + return json; + } + return { + username: json["username"], + roles: !exists(json, "roles") ? undefined : json["roles"], + apikey: json["apikey"], + }; +} + +export function UserToJSON(value?: User | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + username: value.username, + roles: value.roles, + apikey: value.apikey, + }; +} diff --git a/app/bartender-client/models/UserAsListItem.ts b/app/bartender-client/models/UserAsListItem.ts deleted file mode 100644 index 73b82cff..00000000 --- a/app/bartender-client/models/UserAsListItem.ts +++ /dev/null @@ -1,131 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -import type { OAuthAccountName } from "./OAuthAccountName"; -import { - OAuthAccountNameFromJSON, - OAuthAccountNameFromJSONTyped, - OAuthAccountNameToJSON, -} from "./OAuthAccountName"; - -/** - * DTO for user in a list. - * @export - * @interface UserAsListItem - */ -export interface UserAsListItem { - /** - * - * @type {string} - * @memberof UserAsListItem - */ - email: string; - /** - * - * @type {Array} - * @memberof UserAsListItem - */ - oauthAccounts: Array; - /** - * - * @type {Array} - * @memberof UserAsListItem - */ - roles: Array; - /** - * - * @type {string} - * @memberof UserAsListItem - */ - id: string; - /** - * - * @type {boolean} - * @memberof UserAsListItem - */ - isActive: boolean; - /** - * - * @type {boolean} - * @memberof UserAsListItem - */ - isSuperuser: boolean; - /** - * - * @type {boolean} - * @memberof UserAsListItem - */ - isVerified: boolean; -} - -/** - * Check if a given object implements the UserAsListItem interface. - */ -export function instanceOfUserAsListItem(value: object): boolean { - let isInstance = true; - isInstance = isInstance && "email" in value; - isInstance = isInstance && "oauthAccounts" in value; - isInstance = isInstance && "roles" in value; - isInstance = isInstance && "id" in value; - isInstance = isInstance && "isActive" in value; - isInstance = isInstance && "isSuperuser" in value; - isInstance = isInstance && "isVerified" in value; - - return isInstance; -} - -export function UserAsListItemFromJSON(json: any): UserAsListItem { - return UserAsListItemFromJSONTyped(json, false); -} - -export function UserAsListItemFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): UserAsListItem { - if (json === undefined || json === null) { - return json; - } - return { - email: json["email"], - oauthAccounts: (json["oauth_accounts"] as Array).map( - OAuthAccountNameFromJSON - ), - roles: json["roles"], - id: json["id"], - isActive: json["is_active"], - isSuperuser: json["is_superuser"], - isVerified: json["is_verified"], - }; -} - -export function UserAsListItemToJSON(value?: UserAsListItem | null): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - email: value.email, - oauth_accounts: (value.oauthAccounts as Array).map( - OAuthAccountNameToJSON - ), - roles: value.roles, - id: value.id, - is_active: value.isActive, - is_superuser: value.isSuperuser, - is_verified: value.isVerified, - }; -} diff --git a/app/bartender-client/models/UserCreate.ts b/app/bartender-client/models/UserCreate.ts deleted file mode 100644 index 2293978d..00000000 --- a/app/bartender-client/models/UserCreate.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -/** - * DTO to create user. - * @export - * @interface UserCreate - */ -export interface UserCreate { - /** - * - * @type {string} - * @memberof UserCreate - */ - email: string; - /** - * - * @type {string} - * @memberof UserCreate - */ - password: string; - /** - * - * @type {boolean} - * @memberof UserCreate - */ - isActive?: boolean; - /** - * - * @type {boolean} - * @memberof UserCreate - */ - isSuperuser?: boolean; - /** - * - * @type {boolean} - * @memberof UserCreate - */ - isVerified?: boolean; -} - -/** - * Check if a given object implements the UserCreate interface. - */ -export function instanceOfUserCreate(value: object): boolean { - let isInstance = true; - isInstance = isInstance && "email" in value; - isInstance = isInstance && "password" in value; - - return isInstance; -} - -export function UserCreateFromJSON(json: any): UserCreate { - return UserCreateFromJSONTyped(json, false); -} - -export function UserCreateFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): UserCreate { - if (json === undefined || json === null) { - return json; - } - return { - email: json["email"], - password: json["password"], - isActive: !exists(json, "is_active") ? undefined : json["is_active"], - isSuperuser: !exists(json, "is_superuser") - ? undefined - : json["is_superuser"], - isVerified: !exists(json, "is_verified") ? undefined : json["is_verified"], - }; -} - -export function UserCreateToJSON(value?: UserCreate | null): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - email: value.email, - password: value.password, - is_active: value.isActive, - is_superuser: value.isSuperuser, - is_verified: value.isVerified, - }; -} diff --git a/app/bartender-client/models/UserProfileInputDTO.ts b/app/bartender-client/models/UserProfileInputDTO.ts deleted file mode 100644 index d39909ac..00000000 --- a/app/bartender-client/models/UserProfileInputDTO.ts +++ /dev/null @@ -1,97 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -import type { OAuthAccountName } from "./OAuthAccountName"; -import { - OAuthAccountNameFromJSON, - OAuthAccountNameFromJSONTyped, - OAuthAccountNameToJSON, -} from "./OAuthAccountName"; - -/** - * DTO for profile of current user model. - * @export - * @interface UserProfileInputDTO - */ -export interface UserProfileInputDTO { - /** - * - * @type {string} - * @memberof UserProfileInputDTO - */ - email: string; - /** - * - * @type {Array} - * @memberof UserProfileInputDTO - */ - oauthAccounts: Array; - /** - * - * @type {Array} - * @memberof UserProfileInputDTO - */ - roles: Array; -} - -/** - * Check if a given object implements the UserProfileInputDTO interface. - */ -export function instanceOfUserProfileInputDTO(value: object): boolean { - let isInstance = true; - isInstance = isInstance && "email" in value; - isInstance = isInstance && "oauthAccounts" in value; - isInstance = isInstance && "roles" in value; - - return isInstance; -} - -export function UserProfileInputDTOFromJSON(json: any): UserProfileInputDTO { - return UserProfileInputDTOFromJSONTyped(json, false); -} - -export function UserProfileInputDTOFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): UserProfileInputDTO { - if (json === undefined || json === null) { - return json; - } - return { - email: json["email"], - oauthAccounts: (json["oauth_accounts"] as Array).map( - OAuthAccountNameFromJSON - ), - roles: json["roles"], - }; -} - -export function UserProfileInputDTOToJSON( - value?: UserProfileInputDTO | null -): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - email: value.email, - oauth_accounts: (value.oauthAccounts as Array).map( - OAuthAccountNameToJSON - ), - roles: value.roles, - }; -} diff --git a/app/bartender-client/models/UserRead.ts b/app/bartender-client/models/UserRead.ts deleted file mode 100644 index d76562f7..00000000 --- a/app/bartender-client/models/UserRead.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -/** - * DTO for read user. - * @export - * @interface UserRead - */ -export interface UserRead { - /** - * - * @type {any} - * @memberof UserRead - */ - id?: any | null; - /** - * - * @type {string} - * @memberof UserRead - */ - email: string; - /** - * - * @type {boolean} - * @memberof UserRead - */ - isActive?: boolean; - /** - * - * @type {boolean} - * @memberof UserRead - */ - isSuperuser?: boolean; - /** - * - * @type {boolean} - * @memberof UserRead - */ - isVerified?: boolean; - /** - * - * @type {Array} - * @memberof UserRead - */ - roles: Array; -} - -/** - * Check if a given object implements the UserRead interface. - */ -export function instanceOfUserRead(value: object): boolean { - let isInstance = true; - isInstance = isInstance && "email" in value; - isInstance = isInstance && "roles" in value; - - return isInstance; -} - -export function UserReadFromJSON(json: any): UserRead { - return UserReadFromJSONTyped(json, false); -} - -export function UserReadFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): UserRead { - if (json === undefined || json === null) { - return json; - } - return { - id: !exists(json, "id") ? undefined : json["id"], - email: json["email"], - isActive: !exists(json, "is_active") ? undefined : json["is_active"], - isSuperuser: !exists(json, "is_superuser") - ? undefined - : json["is_superuser"], - isVerified: !exists(json, "is_verified") ? undefined : json["is_verified"], - roles: json["roles"], - }; -} - -export function UserReadToJSON(value?: UserRead | null): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - id: value.id, - email: value.email, - is_active: value.isActive, - is_superuser: value.isSuperuser, - is_verified: value.isVerified, - roles: value.roles, - }; -} diff --git a/app/bartender-client/models/UserUpdate.ts b/app/bartender-client/models/UserUpdate.ts deleted file mode 100644 index 577e86f3..00000000 --- a/app/bartender-client/models/UserUpdate.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * bartender - * Job middleware for i-VRESSE - * - * The version of the OpenAPI document: 0.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { exists, mapValues } from "../runtime"; -/** - * DTO to update user. - * @export - * @interface UserUpdate - */ -export interface UserUpdate { - /** - * - * @type {string} - * @memberof UserUpdate - */ - password?: string; - /** - * - * @type {string} - * @memberof UserUpdate - */ - email?: string; - /** - * - * @type {boolean} - * @memberof UserUpdate - */ - isActive?: boolean; - /** - * - * @type {boolean} - * @memberof UserUpdate - */ - isSuperuser?: boolean; - /** - * - * @type {boolean} - * @memberof UserUpdate - */ - isVerified?: boolean; -} - -/** - * Check if a given object implements the UserUpdate interface. - */ -export function instanceOfUserUpdate(value: object): boolean { - let isInstance = true; - - return isInstance; -} - -export function UserUpdateFromJSON(json: any): UserUpdate { - return UserUpdateFromJSONTyped(json, false); -} - -export function UserUpdateFromJSONTyped( - json: any, - ignoreDiscriminator: boolean -): UserUpdate { - if (json === undefined || json === null) { - return json; - } - return { - password: !exists(json, "password") ? undefined : json["password"], - email: !exists(json, "email") ? undefined : json["email"], - isActive: !exists(json, "is_active") ? undefined : json["is_active"], - isSuperuser: !exists(json, "is_superuser") - ? undefined - : json["is_superuser"], - isVerified: !exists(json, "is_verified") ? undefined : json["is_verified"], - }; -} - -export function UserUpdateToJSON(value?: UserUpdate | null): any { - if (value === undefined) { - return undefined; - } - if (value === null) { - return null; - } - return { - password: value.password, - email: value.email, - is_active: value.isActive, - is_superuser: value.isSuperuser, - is_verified: value.isVerified, - }; -} diff --git a/app/bartender-client/models/index.ts b/app/bartender-client/models/index.ts index 5d507499..90b138a5 100644 --- a/app/bartender-client/models/index.ts +++ b/app/bartender-client/models/index.ts @@ -1,18 +1,9 @@ /* tslint:disable */ /* eslint-disable */ export * from "./ApplicatonConfiguration"; -export * from "./BearerResponse"; -export * from "./Detail"; export * from "./DirectoryItem"; -export * from "./ErrorModel"; export * from "./HTTPValidationError"; export * from "./JobModelDTO"; export * from "./LocationInner"; -export * from "./OAuth2AuthorizeResponse"; -export * from "./OAuthAccountName"; -export * from "./UserAsListItem"; -export * from "./UserCreate"; -export * from "./UserProfileInputDTO"; -export * from "./UserRead"; -export * from "./UserUpdate"; +export * from "./User"; export * from "./ValidationError"; diff --git a/app/bartender_token.server.ts b/app/bartender_token.server.ts new file mode 100644 index 00000000..8146a5bf --- /dev/null +++ b/app/bartender_token.server.ts @@ -0,0 +1,75 @@ +/** + * Functions dealing with access token of bartender web service. + */ +import { readFile } from "fs/promises"; +import { type KeyLike, SignJWT, importPKCS8, decodeJwt } from "jose"; + +import { getUser } from "./auth.server"; +import type { User } from "./models/user.server"; +import { setBartenderToken } from "./models/user.server"; + +const alg = "RS256"; + +export class TokenGenerator { + private privateKeyFilename: string; + private issuer: string; + private lifeSpan: string; + private privateKey: KeyLike | undefined = undefined; + constructor( + privateKeyFilename: string, + issuer = "haddock3-webapp", + lifespan = "8h" + ) { + this.privateKeyFilename = privateKeyFilename; + this.issuer = issuer; + this.lifeSpan = lifespan; + } + + async init() { + if (this.privateKey) { + return; + } + const privateKeyBody = await readFile(this.privateKeyFilename, "utf8"); + const privateKey = await importPKCS8(privateKeyBody, alg); + this.privateKey = privateKey; + } + + async generate(sub: string, email: string) { + if (!this.privateKey) { + throw new Error("private key not initialized"); + } + const jwt = await new SignJWT({ + email: email, + }) + .setIssuer(this.issuer) + .setExpirationTime(this.lifeSpan) + .setIssuedAt() + .setSubject(sub) + .setProtectedHeader({ alg }) + .sign(this.privateKey); + return jwt; + } +} +const privateKeyFilename = + process.env.BARTENDER_PRIVATE_KEY || "private_key.pem"; +const generator = new TokenGenerator(privateKeyFilename); + +export async function getBartenderToken(request: Request) { + const user = await getUser(request); + return getBartenderTokenByUser(user); +} + +export async function getBartenderTokenByUser(user: User) { + // if token expires in less than 2 minutes, refresh it + const leeway = 120; + const nowInSeconds = new Date().getTime() / 1000; + const tokenIsExpired = user.bartenderTokenExpiresAt < nowInSeconds + leeway; + if (tokenIsExpired || !user.bartenderToken) { + await generator.init(); + const token = await generator.generate(user.id, user.email); + const { exp } = decodeJwt(token); + await setBartenderToken(user.id, token, exp!); + return token; + } + return user.bartenderToken; +} diff --git a/app/catalogs/index.server.ts b/app/catalogs/index.server.ts index 1e3d25a2..a66bc92b 100644 --- a/app/catalogs/index.server.ts +++ b/app/catalogs/index.server.ts @@ -3,8 +3,9 @@ import type { ICatalog } from "@i-vresse/wb-core/dist/types"; import easy from "./haddock3.easy.json"; import expert from "./haddock3.expert.json"; import guru from "./haddock3.guru.json"; +import type { ExpertiseLevel } from "@prisma/client"; -export async function getCatalog(level: string) { +export async function getCatalog(level: ExpertiseLevel) { // Tried serverDependenciesToBundle in remix.config.js but it didn't work // Fallback to using dynamic import const { prepareCatalog } = await import("@i-vresse/wb-core/dist/catalog.js"); diff --git a/app/components/ErrorMessages.tsx b/app/components/ErrorMessages.tsx new file mode 100644 index 00000000..ff1c57ea --- /dev/null +++ b/app/components/ErrorMessages.tsx @@ -0,0 +1,26 @@ +import type { FlatErrors } from "valibot"; + +export function ErrorMessages({ + path, + errors, +}: { + path: string; + errors?: FlatErrors; +}) { + if (!errors) return <>; + let issues: [string, ...string[]] | undefined = undefined; + if (path === "root" && errors.root) { + issues = errors.root; + } else if (errors.nested[path] !== undefined) { + issues = errors.nested[path]; + } + if (!issues) return <>; + + return ( +
+ {issues.map((message: string) => ( +

{message}

+ ))} +
+ ); +} diff --git a/app/components/Navbar.tsx b/app/components/Navbar.tsx index 81ea5b0e..c00f7695 100644 --- a/app/components/Navbar.tsx +++ b/app/components/Navbar.tsx @@ -1,14 +1,14 @@ import { Link, NavLink } from "@remix-run/react"; -import { useIsAuthenticated, useIsSuperUser } from "~/session"; +import { useIsAdmin, useIsLoggedIn, useUser } from "~/auth"; const LoggedInButton = () => { - const isSuperUser = useIsSuperUser(); + const user = useUser(); + const isAdmin = useIsAdmin(); return (
    {
  • Profile
  • - {isSuperUser && ( + {isAdmin && (
  • Admin
  • @@ -34,10 +34,10 @@ const LoggedInButton = () => { const LoginButton = () => Login; export const Navbar = () => { - const isAuthenticated = useIsAuthenticated(); + const loggedIn = useIsLoggedIn(); return ( -
    +
    Haddock3 @@ -63,7 +63,7 @@ export const Navbar = () => {
- {isAuthenticated ? : } + {loggedIn ? : }
); diff --git a/app/components/admin/UserTableRow.tsx b/app/components/admin/UserTableRow.tsx index 541725cf..3beb5209 100644 --- a/app/components/admin/UserTableRow.tsx +++ b/app/components/admin/UserTableRow.tsx @@ -1,47 +1,59 @@ -import type { UserAsListItem } from "~/bartender-client"; +import type { User } from "~/models/user.server"; +import type { ExpertiseLevel } from "@prisma/client"; interface IProps { - user: UserAsListItem; - roles: string[]; + user: User; + expertiseLevels: ExpertiseLevel[]; onUpdate: (data: FormData) => void; submitting: boolean; } -export const UserTableRow = ({ user, roles, onUpdate, submitting }: IProps) => { +export const UserTableRow = ({ + user, + expertiseLevels, + onUpdate, + submitting, +}: IProps) => { + const usersExpertiseLevels = user.expertiseLevels; return ( {user.email} { + if (window.confirm("Are you sure?") === false) { + return; + } const data = new FormData(); - data.set("isSuperuser", user.isSuperuser ? "false" : "true"); + data.set("isAdmin", user.isAdmin ? "false" : "true"); onUpdate(data); }} />
    - {roles.map((role) => { + {expertiseLevels.map((expertiseLevel) => { return ( -
  • +