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

User login #196

Merged
merged 85 commits into from Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
3d3afff
wip
Jan 25, 2024
2a8ab79
user login changes
Jan 29, 2024
8e799b8
missing file
Jan 29, 2024
7ba0906
missing file
Jan 29, 2024
e4c5577
missing file
Jan 29, 2024
e237ede
Merge branch 'dev' of https://github.com/Police-Data-Accessibility-Pr…
Feb 1, 2024
18cec79
add user put test
Feb 1, 2024
e6293ef
Dev -> Main (#202)
mbodeantor Feb 7, 2024
3044b35
Merge remote-tracking branch 'origin/main' into user_login
joshuagraber Feb 7, 2024
ffea309
chore(deps): bump design-system 2.3.0 -> 2.4.0
joshuagraber Feb 7, 2024
5a8cda4
Merge branch 'user_login' of https://github.com/Police-Data-Accessibi…
Feb 9, 2024
8ab0390
chore(deps): bump design-system -> 2.4.1
joshuagraber Feb 12, 2024
c087b6f
feat(pages): Add login page
joshuagraber Feb 12, 2024
fce00c0
feat(pages): add shell of password page
joshuagraber Feb 12, 2024
a813bbb
feat(router): add new pages to router
joshuagraber Feb 12, 2024
dda07db
reset password, role check for edit permissions
Feb 15, 2024
8d9cb79
Merge branch 'user_login' of https://github.com/Police-Data-Accessibi…
Feb 15, 2024
75f5531
missing file
Feb 15, 2024
c11d49f
fixed tests
Feb 16, 2024
895841b
fixed tests
Feb 16, 2024
20d8cda
don't insert search log on test
Feb 16, 2024
5f16d4b
move login to own endpoint
Feb 19, 2024
abbeea9
session token
Feb 20, 2024
cbb7459
refresh session tokens
Feb 22, 2024
3db5e9a
style(pages): miscellaneous code cleanup
joshuagraber Feb 23, 2024
5dbace4
chore(deps): bump vue, add pinia
joshuagraber Feb 23, 2024
03b9797
chore(deps): add jwt-decode
joshuagraber Feb 23, 2024
3c492d9
chore(deps): add lodash
joshuagraber Feb 23, 2024
3a12b2a
refresh test and fix
Feb 23, 2024
ab097e8
Merge branch 'user_login' of github.com:Police-Data-Accessibility-Pro…
joshuagraber Feb 23, 2024
65ea58e
chore(deps): add persist state plugin for pinia
joshuagraber Feb 23, 2024
5cb220b
feat(state): add pinia store for auth
joshuagraber Feb 23, 2024
5cab8bd
feat(components): add AuthWrapper component
joshuagraber Feb 23, 2024
6cd2039
refactor(pages): update login page
joshuagraber Feb 23, 2024
e636d5f
refactor(router): push to login rather than update route
joshuagraber Feb 23, 2024
a12e5b9
docs(README): update client docs
joshuagraber Feb 23, 2024
e55e7af
unit tests
Feb 23, 2024
c34c435
chore(deps): pinia testing
joshuagraber Feb 23, 2024
f589994
test(pages): update tests and snapshots
joshuagraber Feb 23, 2024
0ddd257
Merge branch 'user_login' of github.com:Police-Data-Accessibility-Pro…
joshuagraber Feb 23, 2024
788618d
test(util): add test for parseJwt
joshuagraber Feb 23, 2024
6f57ce1
test(components): add test for AuthWrapper
joshuagraber Feb 23, 2024
a84a6cf
fix(router): public route logic conflicting
joshuagraber Feb 23, 2024
94ce64b
chore(router): cleanup: remove unnecessary check
joshuagraber Feb 23, 2024
09c0b65
fix(store): update logout patch
joshuagraber Feb 23, 2024
5f13ba5
fix(store): one more update to logout
joshuagraber Feb 23, 2024
f6cf8f7
feat(stores): create user store
joshuagraber Feb 26, 2024
a277f12
feat(pages): build change password route
joshuagraber Feb 26, 2024
aea7fb0
feat(pages): add password reset route
joshuagraber Feb 26, 2024
240ed05
refactor(store): log user back in on pw change
joshuagraber Feb 26, 2024
9eb023b
fix(stores): status code logic
joshuagraber Feb 26, 2024
821bbee
PR feedback changes
Feb 26, 2024
9b4f03e
Merge branch 'user_login' of https://github.com/Police-Data-Accessibi…
Feb 26, 2024
0e5c517
refactor: miscellaneous updates
joshuagraber Feb 26, 2024
c3d9e31
PR feedback changes
Feb 26, 2024
d0282fd
Merge branch 'user_login' of https://github.com/Police-Data-Accessibi…
Feb 26, 2024
76c6037
chore(local): standardize port for dev server
joshuagraber Feb 26, 2024
04e6948
refactor: update password reset
joshuagraber Feb 26, 2024
9148ca0
docs(README): update client notes
joshuagraber Feb 26, 2024
b08b714
refactor(pages): update log in per feedback
joshuagraber Feb 26, 2024
09409a3
test fix
Feb 27, 2024
15f4358
test(components): update AuthWrapper test
joshuagraber Feb 27, 2024
e55ac63
test(pages): add LogIn tests
joshuagraber Feb 27, 2024
0813d92
Merge branch 'user_login' of github.com:Police-Data-Accessibility-Pro…
joshuagraber Feb 27, 2024
e5a9fd9
chore(cleanup): remove stray log
joshuagraber Feb 27, 2024
750b5b5
test(pages): update login snapshots
joshuagraber Feb 28, 2024
1937b8b
fix(ci): indentation in test.yml
joshuagraber Feb 28, 2024
2238c94
Merge remote-tracking branch 'origin/dev' into user_login
joshuagraber Feb 28, 2024
d206a9e
test fix
Feb 28, 2024
d510eab
cleanup
Feb 28, 2024
2055435
resolve conflict
Feb 28, 2024
5eaf59c
Update pull.yaml
mbodeantor Feb 28, 2024
8f6de15
Update login_queries.py
mbodeantor Feb 28, 2024
1ac0d69
Update pull.yaml
mbodeantor Feb 28, 2024
970af9d
Update pull.yaml
mbodeantor Feb 28, 2024
293f4ce
test(pages): update login test -> coverage 100%
joshuagraber Mar 1, 2024
522370f
test(pages): add ChangePassword test
joshuagraber Mar 1, 2024
ad5f991
test(pages): misc updates to login and change password tests
joshuagraber Mar 1, 2024
5ae00de
test(pages): add tests for ResetPassword
joshuagraber Mar 1, 2024
b43d372
update login queries
joshuagraber Mar 4, 2024
98e2b67
test(components): search results card -> 100% coverage
joshuagraber Mar 4, 2024
15a266a
test(pages): miscellaneous updates to static view
joshuagraber Mar 4, 2024
fa5e17a
ci(pull): update env setting in API test
joshuagraber Mar 6, 2024
3fab966
Merge remote-tracking branch 'origin/dev' into user_login
joshuagraber Mar 7, 2024
bc15f61
docs(README): add local client base url
joshuagraber Mar 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/pull.yaml
Expand Up @@ -12,7 +12,7 @@ jobs:
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
Expand All @@ -30,6 +30,8 @@ jobs:
- uses: psf/black@stable

test_api:
env:
SECRET_KEY: ${{ secrets.SECRET_KEY }}
name: Test API
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -127,4 +129,4 @@ jobs:
cache-dependency-path: 'client/package-lock.json'
- run: npm ci
- name: Build app
run: npm run build
run: npm run build
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Expand Up @@ -19,5 +19,4 @@ jobs:
- name: Run tests
env:
VUE_APP_PDAP_API_KEY: ${{ secrets.VUE_APP_PDAP_API_KEY }}

run: python regular_api_checks.py
16 changes: 11 additions & 5 deletions README.md
Expand Up @@ -47,22 +47,24 @@ pip install -r requirements.txt

### 5. Add environment secrets

Either add a `.env` file to your local root directory or manually export these secrets: `DO_DATABASE_URL` and `VITE_VUE_APP_BASE_URL`.
Either add a `.env` file to your local root directory or manually export these secrets: `DO_DATABASE_URL` and `VITE_VUE_API_BASE_URL`.

Reach out to contact@pdap.io or make noise in Discord if you'd like access to these keys.

```
# .env

DO_DATABASE_URL="postgres://data_sources_app:<password>@db-postgresql-nyc3-38355-do-user-8463429-0.c.db.ondigitalocean.com:25060/defaultdb"
VITE_VUE_APP_BASE_URL="http://localhost:5000"
VITE_VUE_API_BASE_URL="http://localhost:5000"
VITE_VUE_APP_BASE_URL="http://localhost:8888"
```

```
# shell

export DO_DATABASE_URL=postgres://data_sources_app:<password>@db-postgresql-nyc3-38355-do-user-8463429-0.c.db.ondigitalocean.com:25060/defaultdb
export VITE_VUE_APP_BASE_URL="http://localhost:5000"
export VITE_VUE_API_BASE_URL="http://localhost:5000"
export VITE_VUE_APP_BASE_URL="http://localhost:8888"
```

### 6. Allow your IP address
Expand Down Expand Up @@ -108,14 +110,18 @@ pip install pytest
pytest

```

## Linting
Linting is enforced with black on PR creation. You can use black to automatically reformat your files before commiting them, this will allow your PR to pass this check. Any files that require reformatting will be listed on any failed checks on the PR.
```
black app_test.py
```

## Other helpful commands for the client app
## Client App

A few things to know:

- We use Vue3. This allows for using either the options or composition APIs. Feel free to use whichever you are most fluent in.
- We use `pinia` for state management. This works much better with the composition API than with options, so it is recommended to use the composition API if you need data from one of the `pinia` stores.

### Compiles and minifies for production
```
Expand Down
29 changes: 29 additions & 0 deletions app.py
Expand Up @@ -2,6 +2,11 @@
from flask_restful import Api
from flask_cors import CORS
from resources.User import User
from resources.Login import Login
from resources.RefreshSession import RefreshSession
from resources.ApiKey import ApiKey
from resources.RequestResetPassword import RequestResetPassword
from resources.ResetPassword import ResetPassword
from resources.QuickSearch import QuickSearch
from resources.DataSources import DataSources
from resources.DataSources import DataSourceById
Expand All @@ -19,6 +24,29 @@
api.add_resource(
User, "/user", resource_class_kwargs={"psycopg2_connection": psycopg2_connection}
)
api.add_resource(
Login, "/login", resource_class_kwargs={"psycopg2_connection": psycopg2_connection}
)
api.add_resource(
RefreshSession,
"/refresh-session",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
ApiKey,
"/api_key",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
RequestResetPassword,
"/request-reset-password",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
ResetPassword,
"/reset-password",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
QuickSearch,
"/quick-search/<search>/<location>",
Expand Down Expand Up @@ -50,5 +78,6 @@
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)


if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0")
96 changes: 95 additions & 1 deletion app_test.py
Expand Up @@ -14,14 +14,28 @@
data_source_by_id_results,
DATA_SOURCES_APPROVED_COLUMNS,
)

from middleware.user_queries import (
user_post_results,
user_check_email,
)
from middleware.login_queries import (
login_results,
create_session_token,
token_results,
is_admin,
)
from middleware.archives_queries import (
archives_get_results,
archives_get_query,
archives_put_broken_as_of_results,
archives_put_last_cached_results,
ARCHIVES_GET_COLUMNS,
)
from middleware.reset_token_queries import (
check_reset_token,
add_reset_token,
delete_reset_token,
)
from app_test_data import (
DATA_SOURCES_ROWS,
DATA_SOURCE_QUERY_RESULTS,
Expand Down Expand Up @@ -125,6 +139,86 @@ def test_data_source_by_id_approved(session):
assert not response


def test_user_post_query(session):
curs = session.cursor()
user_post_results(curs, "unit_test", "unit_test")

email_check = curs.execute(
f"SELECT email FROM users WHERE email = 'unit_test'"
).fetchone()[0]

assert email_check == "unit_test"


def test_login_query(session):
curs = session.cursor()
user_data = login_results(curs, "test")

assert user_data["password_digest"]


def test_create_session_token_results(session):
curs = session.cursor()
token = create_session_token(curs, 1, "test")

curs = session.cursor()
new_token = token_results(curs, token)

assert new_token["email"]


def test_is_admin(session):
curs = session.cursor()
admin = is_admin(curs, "mbodenator@gmail.com")

assert admin


def test_not_admin(session):
curs = session.cursor()
admin = is_admin(curs, "test")

assert not admin


def test_user_check_email(session):
curs = session.cursor()
user_data = user_check_email(curs, "test")
print(user_data)

assert user_data["id"]


def test_check_reset_token(session):
curs = session.cursor()
reset_token = check_reset_token(curs, "test")
print(reset_token)

assert reset_token["id"]


def test_add_reset_token(session):
curs = session.cursor()
add_reset_token(curs, "unit_test", "unit_test")

email_check = curs.execute(
f"SELECT email FROM reset_tokens WHERE email = 'unit_test'"
).fetchone()[0]

assert email_check == "unit_test"


def test_delete_reset_token(session):
curs = session.cursor()
delete_reset_token(curs, "test", "test")

email_check = curs.execute(
f"SELECT email FROM reset_tokens WHERE email = 'test'"
).fetchone()

assert not email_check


def test_archives_get_results(session):
response = archives_get_results(conn=session)

Expand Down