Skip to content

Commit

Permalink
remove redis (#160)
Browse files Browse the repository at this point in the history
* remove redis

* continuing work-in-progress

* move some stuff around

* more wip

* misc clean uip

* Refactor get_user_id_from_session_token into get_user_from_jwt

The function get_user_from_jwt is unimplemented but I have left a
comment stating how it should be implemented. In particular, we ought to
throw an error if the JWT is not associated with a user.

Furthermore, I have replaced every instance of user_id with id.

* Fix circular import with TABLE_NAME

* replace new_token fns with appropriate jwt generation placeholders

* unify oauthuser with normal user model

* Revert "replace new_token fns with appropriate jwt generation placeholders"

We are not using JWT's. We are going to use API keys anyway, which makes
JWTs completely pointless.

This reverts commit b66d8ad.

* remove calls to get_api_key fn that isn't doing anything

* get rid of jwts for good and format stuff

* fix all mypy errors except for weird GitHub id thing

almost done with boilerplate

* fix lints for real by adding new custom exception

* Make email field optional

* some stuff

* model schema changes

* clean up

* clean up some stuff

* Just have type of auth_keys be list[str] for User

No one is going to voluntarily pass in auth_keys=None. We ought to just
make the default value the empty list rather than None, since that is
how it is passed into the constructor in the first place

* Get rid of email-password login.

We are transitioning into using OAuth exclusively.

* Remove frontend pages associated with email/password login

* Fix accidental change of GitHub login URL

* Almost-working everything except User creation in model.py

* Fix OAuth GitHub

* Re-implement parts query

* Lints

* Add /robots route by genericing /parts route

* format

* Actually add robot routers, oops.

* Delete unnecessary items_per_page in robots.py

We moved it to BaseCrud

* actually call the right function oops

* Restore image uploading functionality

* Make OAUTH Keys work

* lints and format

* Remove frontend sidebar/api cruft

We no longer use email/password sign-in on the backend; change the
frontend to reflect that.

* Fix image display in frontend

* Fix user owner display

Involves fixing batch query too.

* dont accidentally delete user id WHEN EDITING ROBOT

* Properly display listing owner information

* Adjust misleading router function names

* fix Your Robots/Your Parts queries

* remove unused Sidebar.tsx imports

* Split up GitHub router's GitHub API calls

This is solely to make it possible to mock them in unit tests.

* format

* Make unit tests work with new auth system/backend

* remove bespoke field_info stuff

It was causing bugs /shrug

* Add lints to tests (and have tests pass them too)

* fix lint

---------

Co-authored-by: Dennis Chen <[email protected]>
  • Loading branch information
codekansas and chennisden authored Jul 24, 2024
1 parent de5029a commit dbaf6fd
Show file tree
Hide file tree
Showing 46 changed files with 843 additions and 1,787 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ jobs:
# -v /tmp/dynamodb:/data
# ports:
# - 8000
# redis-local:
# image: redis
# options: >-
# -p 0:6379
# ports:
# - 6379

steps:
- name: Check out repository
Expand Down
20 changes: 1 addition & 19 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ To get started developing:
1. Clone the repository
2. Install the React dependencies and create a `.env.local` file
3. Install the FastAPI dependencies
4. Start the Redis and DynamoDB databases
4. Start the DynamoDB databases
5. Initialize the test databases
6. Serve the FastAPI application
7. Serve the React frontend
Expand Down Expand Up @@ -61,22 +61,6 @@ To run, **source the same environment variables that you use for FastAPI** and t
DYNAMO_ENDPOINT=http://127.0.0.1:4566 dynamodb-admin
```

### Redis

For Redis, use the `redis` Docker image:

```bash
docker pull redis # If you haven't already
docker run --name store-redis -d -p 6379:6379 redis # Start the container in the background
```

Then, if you need to kill the database, you can run:

```bash
docker kill store-redis || true
docker rm store-redis || true
```

## FastAPI

Create a Python virtual environment using either [uv](https://astral.sh/blog/uv) or [virtualenv](https://virtualenv.pypa.io/en/latest/) with at least Python 3.11. This should look something like this:
Expand Down Expand Up @@ -119,8 +103,6 @@ export ROBOLIST_SMTP_SENDER_EMAIL=
export ROBOLIST_SMTP_PASSWORD=
export ROBOLIST_SMTP_SENDER_NAME=
export ROBOLIST_SMTP_USERNAME=
export ROBOLIST_REDIS_HOST=
export ROBOLIST_REDIS_PASSWORD=
export GITHUB_CLIENT_ID=
export GITHUB_CLIENT_SECRET=
```
Expand Down
15 changes: 5 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,13 @@ start-docker-dynamodb:
@docker rm store-db || true
@docker run --name store-db -d -p 8000:8000 amazon/dynamodb-local

start-docker-redis:
@docker kill store-redis || true
@docker rm store-redis || true
@docker run --name store-redis -d -p 6379:6379 redis

# ------------------------ #
# Code Formatting #
# ------------------------ #

format-backend:
@black store
@ruff format store
@black store tests
@ruff format store tests
.PHONY: format

format-frontend:
Expand All @@ -63,9 +58,9 @@ format: format-backend format-frontend
# ------------------------ #

static-checks-backend:
@black --diff --check store
@ruff check store
@mypy --install-types --non-interactive store
@black --diff --check store tests
@ruff check store tests
@mypy --install-types --non-interactive store tests
.PHONY: lint

static-checks-frontend:
Expand Down
16 changes: 0 additions & 16 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import { AlertQueue, AlertQueueProvider } from "hooks/alerts";
import { AuthenticationProvider } from "hooks/auth";
import { ThemeProvider } from "hooks/theme";
import About from "pages/About";
import ChangeEmail from "pages/ChangeEmail";
import EditPartForm from "pages/EditPartForm";
import EditRobotForm from "pages/EditRobotForm";
import Forgot from "pages/Forgot";
import Home from "pages/Home";
import Login from "pages/Login";
import Logout from "pages/Logout";
Expand All @@ -18,9 +16,6 @@ import NewRobot from "pages/NewRobot";
import NotFound from "pages/NotFound";
import PartDetails from "pages/PartDetails";
import Parts from "pages/Parts";
import Register from "pages/Register";
import RegistrationEmail from "pages/RegistrationEmail";
import ResetPassword from "pages/ResetPassword";
import RobotDetails from "pages/RobotDetails";
import Robots from "pages/Robots";
import TestImages from "pages/TestImages";
Expand All @@ -44,18 +39,7 @@ const App = () => {
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<RegistrationEmail />} />
<Route path="/register/:token" element={<Register />} />
<Route path="/logout" element={<Logout />} />
<Route path="/forgot" element={<Forgot />} />
<Route
path="/reset-password/:token"
element={<ResetPassword />}
/>
<Route
path="/change-email/:token"
element={<ChangeEmail />}
/>
<Route path="/robots/:page" element={<Robots />} />
<Route path="/robots/add" element={<NewRobot />} />
<Route path="/parts/add" element={<NewPart />} />
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/RobotForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ const RobotForm: React.FC<RobotFormProps> = ({
Select a Part
</option>
{parts.map((part, index) => (
<option key={index} value={part.part_id}>
<option key={index} value={part.id}>
{part.name}
</option>
))}
Expand Down
9 changes: 5 additions & 4 deletions frontend/src/components/files/ViewImage.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { BACKEND_URL } from "constants/backend";
import { S3_URL } from "constants/backend";
import React from "react";

interface ImageProps {
imageId: string;
caption: string;
}

const ImageComponent: React.FC<ImageProps> = ({ imageId }) => {
const ImageComponent: React.FC<ImageProps> = ({ imageId, caption }) => {
return (
<div style={{ width: "100%", paddingTop: "100%", position: "relative" }}>
<img
src={new URL("image/" + imageId, BACKEND_URL).toString()}
alt="Robot"
src={new URL("images/" + imageId, S3_URL).toString()}
alt={caption}
className="d-block rounded-lg"
style={{
position: "absolute",
Expand Down
119 changes: 1 addition & 118 deletions frontend/src/components/nav/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import TCButton from "components/files/TCButton";
import { useAlertQueue } from "hooks/alerts";
import { api } from "hooks/api";
import { useAuthentication } from "hooks/auth";
import { FormEvent, useState } from "react";
import { Col, Form, Offcanvas, Row } from "react-bootstrap";
import { Col, Offcanvas, Row } from "react-bootstrap";
import { Link } from "react-router-dom";

interface Props {
Expand All @@ -12,46 +7,6 @@ interface Props {
}

const Sidebar = ({ show, onHide }: Props) => {
const { addAlert } = useAlertQueue();

const auth = useAuthentication();
const auth_api = new api(auth.api);

const [newEmail, setNewEmail] = useState<string>("");
const [changeEmailSuccess, setChangeEmailSuccess] = useState<boolean>(false);
const [oldPassword, setOldPassword] = useState<string>("");
const [newPassword, setNewPassword] = useState<string>("");
const [changePasswordSuccess, setChangePasswordSuccess] =
useState<boolean>(false);

const sendChangeEmail = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
try {
await auth_api.send_change_email(newEmail);
setChangeEmailSuccess(true);
} catch (error) {
if (error instanceof Error) {
addAlert(error.message, "error");
} else {
addAlert("Unexpected error when trying to change email", "error");
}
}
};

const changePassword = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
try {
await auth_api.change_password(oldPassword, newPassword);
setChangePasswordSuccess(true);
} catch (error) {
if (error instanceof Error) {
addAlert(error.message, "error");
} else {
addAlert("Unexpected error when trying to change password", "error");
}
}
};

return (
<Offcanvas show={show} onHide={onHide} placement="end">
<Offcanvas.Header closeButton>
Expand All @@ -65,78 +20,6 @@ const Sidebar = ({ show, onHide }: Props) => {
height: "100%",
}}
>
<Row>
<p>
<strong>Change Email</strong>
</p>
{auth.email == "[email protected]" ? (
<p>
No email address associated with this account. (This is because
you registered via OAuth.)
</p>
) : (
<p>Current email: {auth.email}</p>
)}
{changeEmailSuccess ? (
<p>An email has been sent to your new email address.</p>
) : (
<Form onSubmit={sendChangeEmail}>
<label htmlFor="new-email">New email</label>
<Form.Control
id="new-email"
autoComplete="email"
className="mb-3"
type="text"
onChange={(e) => {
setNewEmail(e.target.value);
}}
value={newEmail}
required
/>
<TCButton type="submit">Change Email</TCButton>
</Form>
)}
</Row>
<Row>
<p>
<strong>Change Password</strong>
</p>
<p>
You may only change your password if you have a previous password.
If not, log out and reset your password.
</p>
{changePasswordSuccess ? (
<p>Your password has been changed.</p>
) : (
<Form onSubmit={changePassword}>
<label htmlFor="old-password">Old password</label>
<Form.Control
id="old-password"
autoComplete="current-password"
className="mb-3"
type="password"
onChange={(e) => {
setOldPassword(e.target.value);
}}
value={oldPassword}
required
/>
<label htmlFor="new-password">New password</label>
<Form.Control
id="new-password"
autoComplete="new-password"
className="mb-3"
type="password"
onChange={(e) => {
setNewPassword(e.target.value);
}}
value={newPassword}
required
/>
<TCButton type="submit">Change Password</TCButton>
</Form>
)}
</Row>
<Row style={{ marginTop: "auto" }} />
<Row>
<Link to="/about">About</Link>
Expand Down
3 changes: 0 additions & 3 deletions frontend/src/components/nav/TopNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ const TopNavbar = () => {
<Nav.Link as={Link} to="/login">
Login
</Nav.Link>
<Nav.Link as={Link} to="/register">
Register
</Nav.Link>
</>
)}
</div>
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/constants/backend.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { AxiosError, isAxiosError } from "axios";

export const BACKEND_URL =
process.env.REACT_APP_BACKEND_URL || "http://localhost:8080";
process.env.REACT_APP_BACKEND_URL || "http://127.0.0.1:8080";

export const S3_URL = process.env.S3_URL || "http://127.0.0.1:4566";

// eslint-disable-next-line
export const humanReadableError = (error: any | undefined) => {
Expand Down
Loading

0 comments on commit dbaf6fd

Please sign in to comment.