Skip to content

Commit

Permalink
pass auth headers to /csrf (#16464)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaazzam authored Dec 20, 2024
1 parent 3cd21c6 commit a7033fa
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 14 deletions.
5 changes: 4 additions & 1 deletion src/prefect/server/api/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,13 @@ def create_ui_app(ephemeral: bool) -> FastAPI:
mimetypes.add_type("application/javascript", ".js")

@ui_app.get(f"{stripped_base_url}/ui-settings")
def ui_settings():
def ui_settings() -> dict[str, Any]:
return {
"api_url": prefect.settings.PREFECT_UI_API_URL.value(),
"csrf_enabled": prefect.settings.PREFECT_SERVER_CSRF_PROTECTION_ENABLED.value(),
"auth": "BASIC"
if prefect.settings.PREFECT_SERVER_API_AUTH_STRING.value()
else None,
"flags": [],
}

Expand Down
2 changes: 2 additions & 0 deletions tests/server/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from prefect.server.api.server import create_app
from prefect.settings import (
PREFECT_SERVER_API_AUTH_STRING,
PREFECT_SERVER_CSRF_PROTECTION_ENABLED,
PREFECT_UI_API_URL,
temporary_settings,
Expand All @@ -28,6 +29,7 @@ def test_app_exposes_ui_settings():
assert response.json() == {
"api_url": PREFECT_UI_API_URL.value(),
"csrf_enabled": PREFECT_SERVER_CSRF_PROTECTION_ENABLED.value(),
"auth": "BASIC" if PREFECT_SERVER_API_AUTH_STRING.value() else None,
"flags": [],
}

Expand Down
1 change: 1 addition & 0 deletions ui/src/maps/uiSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const mapSettingsResponseToSettings: MapFunction<SettingsResponse, Settin
return {
apiUrl: source.api_url,
csrfEnabled: source.csrf_enabled,
auth: source.auth,
flags: this.map('FlagResponse', source.flags, 'FeatureFlag').filter(isNotNullish),
}
}
15 changes: 9 additions & 6 deletions ui/src/pages/AppRouterView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import router, { routes as appRoutes } from '@/router'
import { createPrefectApi, prefectApiKey } from '@/utilities/api'
import { canKey } from '@/utilities/permissions'
import { UiSettings } from '@/services/uiSettings'
const { can } = useCreateCan()
const { config } = await useApiConfig()
Expand All @@ -46,15 +47,17 @@
provide(prefectApiKey, api)
provide(workspaceApiKey, api)
provide(workspaceRoutesKey, routes)
api.admin.authCheck().then(authenticated => {
if (!authenticated) {
api.admin.authCheck().then(status_code => {
if (status_code == 401) {
if (router.currentRoute.value.name !== 'login') {
showToast('Authentication failed.', 'error', { timeout: false })
router.push({
name: 'login',
query: { redirect: router.currentRoute.value.fullPath }
})
}
router.push({
name: 'login',
query: { redirect: router.currentRoute.value.fullPath }
})
} else {
api.health.isHealthy().then(healthy => {
if (!healthy) {
Expand Down
19 changes: 13 additions & 6 deletions ui/src/services/adminApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Api } from '@prefecthq/prefect-ui-library'
import { ServerSettings } from '@/models/ServerSettings'
import { UiSettings } from './uiSettings'

export class AdminApi extends Api {
protected override routePrefix = '/admin'
Expand All @@ -11,13 +12,19 @@ export class AdminApi extends Api {
public async getVersion(): Promise<string> {
return await this.get<string>('/version').then(({ data }) => data)
}

public async authCheck(): Promise<boolean> {
public async authCheck(): Promise<number> {
const auth = await UiSettings.get('auth')
if (!auth) {
return 200
}
try {
await this.getVersion()
return true
} catch {
return false
const res = await this.get('/version')
return res.status
} catch (error: any) {
if (error.response) {
return error.response.status
}
return 500
}
}
}
9 changes: 8 additions & 1 deletion ui/src/services/csrfTokenApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@ export class CsrfTokenApi extends Api {

const refresh = async (): Promise<void> => {
try {
const response = await this.get<CsrfTokenResponse>(`/csrf-token?client=${this.clientId}`)

const password = localStorage.getItem('prefect-password')
const response = await this.get<CsrfTokenResponse>(`/csrf-token?client=${this.clientId}`,
{
headers: password ? {
'Authorization': `Basic ${password}`
} : undefined
})
this.csrfToken = mapper.map('CsrfTokenResponse', response.data, 'CsrfToken')

this.ongoingRefresh = null
Expand Down
1 change: 1 addition & 0 deletions ui/src/services/uiSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { FeatureFlag } from '@/utilities/permissions'
export type Settings = {
apiUrl: string,
csrfEnabled: boolean,
auth: string,
flags: FeatureFlag[],
}

Expand Down
1 change: 1 addition & 0 deletions ui/src/types/settingsResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { FlagResponse } from '@/types/flagResponse'
export type SettingsResponse = {
api_url: string,
csrf_enabled: boolean,
auth: string | null,
flags: FlagResponse[],
}

0 comments on commit a7033fa

Please sign in to comment.