mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 17:34:10 +03:00
Send credentials on open_project
(#9468)
- Close https://github.com/enso-org/cloud-v2/issues/1038 - Send credentials for libs to use, when opening projects against the Cloud (Remote) backend. # Important Notes None
This commit is contained in:
parent
11e1e9efa0
commit
4c7c20ad08
@ -37,6 +37,8 @@ import * as detect from 'enso-common/src/detect'
|
||||
|
||||
import type * as loggerProvider from '#/providers/LoggerProvider'
|
||||
|
||||
import * as dateTime from '#/utilities/dateTime'
|
||||
|
||||
import * as service from '#/authentication/service'
|
||||
|
||||
// =================
|
||||
@ -48,6 +50,8 @@ import * as service from '#/authentication/service'
|
||||
* This provider alone requires a string because it is not a standard provider, and thus has no
|
||||
* constant defined in the AWS Amplify library. */
|
||||
const GITHUB_PROVIDER = 'Github'
|
||||
/** One second, in milliseconds. */
|
||||
const SEC_MS = 1_000
|
||||
|
||||
// ================
|
||||
// === UserInfo ===
|
||||
@ -376,7 +380,7 @@ export interface UserSession {
|
||||
/** URL to refresh the access token. */
|
||||
readonly refreshUrl: string
|
||||
/** Time when the access token will expire, date and time in ISO 8601 format (UTC timezone). */
|
||||
readonly expireAt: string
|
||||
readonly expireAt: dateTime.Rfc3339DateTime
|
||||
/** Cognito app integration client id.. */
|
||||
readonly clientId: string
|
||||
}
|
||||
@ -393,11 +397,7 @@ function parseUserSession(session: cognito.CognitoUserSession, clientId: string)
|
||||
} else {
|
||||
const expirationTimestamp = session.getAccessToken().getExpiration()
|
||||
|
||||
const expireAt = (() => {
|
||||
const date = new Date(0)
|
||||
date.setUTCSeconds(expirationTimestamp)
|
||||
return date.toISOString()
|
||||
})()
|
||||
const expireAt = dateTime.toRfc3339(new Date(expirationTimestamp * SEC_MS))
|
||||
|
||||
return {
|
||||
email,
|
||||
|
@ -13,6 +13,7 @@ import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
|
||||
import * as authProvider from '#/providers/AuthProvider'
|
||||
import * as backendProvider from '#/providers/BackendProvider'
|
||||
import * as modalProvider from '#/providers/ModalProvider'
|
||||
import * as sessionProvider from '#/providers/SessionProvider'
|
||||
import * as textProvider from '#/providers/TextProvider'
|
||||
|
||||
import type * as assetEvent from '#/events/assetEvent'
|
||||
@ -82,6 +83,7 @@ export default function ProjectIcon(props: ProjectIconProps) {
|
||||
const { keyProp: key, item, setItem, assetEvents, doOpenManually } = props
|
||||
const { doCloseEditor, doOpenEditor } = props
|
||||
const { backend } = backendProvider.useBackend()
|
||||
const { session } = sessionProvider.useSession()
|
||||
const { user } = authProvider.useNonPartialUserSession()
|
||||
const { unsetModal } = modalProvider.useSetModal()
|
||||
const toastAndLog = toastAndLogHooks.useToastAndLog()
|
||||
@ -145,7 +147,11 @@ export default function ProjectIcon(props: ProjectIconProps) {
|
||||
}
|
||||
await backend.openProject(
|
||||
item.id,
|
||||
{ executeAsync: shouldRunInBackground, parentId: item.parentId },
|
||||
{
|
||||
executeAsync: shouldRunInBackground,
|
||||
parentId: item.parentId,
|
||||
cognitoCredentials: session,
|
||||
},
|
||||
item.title
|
||||
)
|
||||
}
|
||||
@ -165,7 +171,11 @@ export default function ProjectIcon(props: ProjectIconProps) {
|
||||
case backendModule.BackendType.local: {
|
||||
await backend.openProject(
|
||||
item.id,
|
||||
{ executeAsync: shouldRunInBackground, parentId: item.parentId },
|
||||
{
|
||||
executeAsync: shouldRunInBackground,
|
||||
parentId: item.parentId,
|
||||
cognitoCredentials: null,
|
||||
},
|
||||
item.title
|
||||
)
|
||||
setState(oldState =>
|
||||
@ -188,6 +198,7 @@ export default function ProjectIcon(props: ProjectIconProps) {
|
||||
backend,
|
||||
item,
|
||||
closeProjectAbortController,
|
||||
session,
|
||||
toastAndLog,
|
||||
/* should never change */ setState,
|
||||
/* should never change */ setItem,
|
||||
|
@ -360,6 +360,15 @@ export interface Version {
|
||||
readonly version_type: VersionType
|
||||
}
|
||||
|
||||
/** Credentials that need to be passed to libraries to give them access to the Cloud API. */
|
||||
export interface CognitoCredentials {
|
||||
readonly accessToken: string
|
||||
readonly refreshToken: string
|
||||
readonly refreshUrl: string
|
||||
readonly clientId: string
|
||||
readonly expireAt: dateTime.Rfc3339DateTime
|
||||
}
|
||||
|
||||
/** Subscription plans. */
|
||||
export enum Plan {
|
||||
solo = 'solo',
|
||||
@ -958,6 +967,8 @@ export interface UpdateProjectRequestBody {
|
||||
/** HTTP request body for the "open project" endpoint. */
|
||||
export interface OpenProjectRequestBody {
|
||||
readonly executeAsync: boolean
|
||||
/** MUST be present on Remote backend; NOT REQUIRED on Local backend. */
|
||||
readonly cognitoCredentials: CognitoCredentials | null
|
||||
/** Only used by the Local backend. */
|
||||
readonly parentId: DirectoryId
|
||||
}
|
||||
|
@ -601,13 +601,29 @@ export default class RemoteBackend extends Backend {
|
||||
): Promise<void> {
|
||||
const body = object.omit(bodyRaw, 'parentId')
|
||||
const path = remoteBackendPaths.openProjectPath(projectId)
|
||||
const response = await this.post(path, body)
|
||||
if (body.cognitoCredentials == null) {
|
||||
return this.throw(null, 'openProjectMissingCredentialsBackendError', title)
|
||||
} else {
|
||||
const credentials = body.cognitoCredentials
|
||||
const exactCredentials: backendModule.CognitoCredentials = {
|
||||
accessToken: credentials.accessToken,
|
||||
clientId: credentials.clientId,
|
||||
expireAt: credentials.expireAt,
|
||||
refreshToken: credentials.refreshToken,
|
||||
refreshUrl: credentials.refreshUrl,
|
||||
}
|
||||
const filteredBody: Omit<backendModule.OpenProjectRequestBody, 'parentId'> = {
|
||||
...body,
|
||||
cognitoCredentials: exactCredentials,
|
||||
}
|
||||
const response = await this.post(path, filteredBody)
|
||||
if (!responseIsSuccessful(response)) {
|
||||
return await this.throw(response, 'openProjectBackendError', title)
|
||||
return this.throw(response, 'openProjectBackendError', title)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the name or AMI of a project.
|
||||
* @throws An error if a non-successful status code (not 200-299) was received. */
|
||||
|
@ -93,6 +93,7 @@
|
||||
"closeProjectBackendError": "Could not close project '$0'.",
|
||||
"getProjectDetailsBackendError": "Could not get details of project '$0'.",
|
||||
"openProjectBackendError": "Could not open project '$0'.",
|
||||
"openProjectMissingCredentialsBackendError": "Could not open project '$0': Missing credentials.",
|
||||
"updateProjectBackendError": "Could not update project '$0'.",
|
||||
"checkResourcesBackendError": "Could not get resource usage for project '$0'.",
|
||||
"listFilesBackendError": "Could not list files.",
|
||||
|
@ -69,6 +69,7 @@ interface PlaceholderOverrides {
|
||||
readonly closeProjectBackendError: [string]
|
||||
readonly getProjectDetailsBackendError: [string]
|
||||
readonly openProjectBackendError: [string]
|
||||
readonly openProjectMissingCredentialsBackendError: [string]
|
||||
readonly updateProjectBackendError: [string]
|
||||
readonly checkResourcesBackendError: [string]
|
||||
readonly uploadFileWithNameBackendError: [string]
|
||||
|
Loading…
Reference in New Issue
Block a user