Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/793 - non existent pages + private workspace #862

Merged
merged 5 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion applications/osb-portal/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
import Box from "@mui/material/Box";
import { UserInfo } from "./types/user";
import SampleIframePage from "./pages/SampleIframePage";
import NotFoundPage from "./pages/NotFoundPage";

declare module "@mui/styles/defaultTheme" {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
Expand Down Expand Up @@ -75,7 +76,7 @@ export const App = (props: AppProps) => {
return (
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<OSBErrorBoundary>
<OSBErrorBoundary error={props.error} >
<CssBaseline />
<AboutDialog />
{!props.error && (
Expand Down Expand Up @@ -171,6 +172,7 @@ export const App = (props: AppProps) => {
/>
}
/>
<Route path="*" element={<NotFoundPage />} />
</Routes>
</Box>
</Router>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import DialogContent from "@mui/material/DialogContent";
import DialogTitle from "@mui/material/DialogTitle";
import Button from "@mui/material/Button";

interface OSBErrorBoundaryProps {
error?: any;
}

interface OwnState {
eventId: string;
hasError: string;
Expand All @@ -23,9 +27,12 @@ const ERROR_MESSAGES: any = {
// 404
"NOT FOUND":
"Oops. This resource could not be found. Please check the URL you are trying to access and try again.",
// User 404
"USER_NOT_FOUND":
"Oops. This user could not be found. Please check the URL you are trying to access and try again.",
};

class OSBErrorBoundary extends React.Component<{}, OwnState> {
class OSBErrorBoundary extends React.Component<OSBErrorBoundaryProps, OwnState> {
public state: OwnState = {
eventId: null,
hasError: null,
Expand All @@ -46,7 +53,9 @@ class OSBErrorBoundary extends React.Component<{}, OwnState> {

let message =
"Oops. Something went wrong. Please report this error to us.";
if (error.status && error.status < 500) {
if (window.location.pathname.startsWith("/user/")) {
message = ERROR_MESSAGES["USER_NOT_FOUND"];
} else if (error.status && error.status < 500) {
message = ERROR_MESSAGES[error.statusText] || error.statusText;
} else {
Sentry.captureException(error);
Expand All @@ -55,6 +64,13 @@ class OSBErrorBoundary extends React.Component<{}, OwnState> {
});
}

static getDerivedStateFromProps(nextProps: any, prevState: any) {
if (nextProps.error) {
return { ...prevState, hasError: 'true', message: nextProps.error };
}
return { ...prevState };
}

render() {
if (this.state.hasError) {
// render fallback UI
Expand Down
43 changes: 43 additions & 0 deletions applications/osb-portal/src/pages/NotFoundPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import { Alert, Button, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material'
import { getCleanPath } from '../utils'

const NotFoundPage = () => {
const [message, setMessage] = React.useState("")
const pathParts = getCleanPath(window.location.pathname)
React.useEffect(() => {
setMessage("This path doesn't exist")
}, [pathParts])
return (
<>
<Dialog open={true}>
<DialogTitle id="alert-dialog-title" title="Error" />
<DialogContent>
<Alert severity="error" key={1}>
<div className="errorAlertDiv" key={"div-1"}>
{message}
</div>
</Alert>
</DialogContent>
<DialogActions>
<Button
onClick={() => window.history.back()}
>
Go back
</Button>
<Button
variant="outlined"
color="primary"
onClick={() => window.open("/", "_self")}
>
Return to homepage
</Button>
</DialogActions>
</Dialog>
</>
)


}

export default NotFoundPage
3 changes: 2 additions & 1 deletion applications/osb-portal/src/pages/UserPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ export const UserPage = (props: any) => {
React.useEffect(() => {
getUser(userName).then((u) => {
setUser(u);

}).catch((e) => {
setError(e);
});
}, [userName, props.workspacesCounter]);

Expand Down
8 changes: 8 additions & 0 deletions applications/osb-portal/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,12 @@ export function getNotebooksNamedServerLink() {
return null;
}
return `//${OSBAllApplications.jupyter.subdomain}.${getBaseDomain()}/hub/home`
}

export function getCleanPath(path: string) {
const pathParts = path.split("/")
if (pathParts[pathParts.length - 1] === "") {
pathParts.pop()
}
return pathParts
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ def clone(self, workspace_id):

def is_authorized(self, workspace):
current_user_id = keycloak_user_id()
if not current_user_id:
return False
return workspace and (workspace.publicable or
(workspace.user_id and workspace.user_id == current_user_id) or
(get_auth_client().user_has_realm_role(user_id=current_user_id, role="administrator")))
Expand Down Expand Up @@ -299,6 +301,8 @@ def to_dao(cls, d: dict) -> TWorkspaceEntity:
def get(self, id_):

workspace: Workspace = super().get(id_)
if not self.is_authorized(workspace):
raise NotAuthorized()

if any(wr.status == ResourceStatus.P for wr in workspace.resources):
fake_path = f"Importing resources"
Expand Down
Loading