Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.
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
48 changes: 41 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI
name: CI/CD

on: [pull_request, push, workflow_dispatch]

Expand All @@ -10,7 +10,6 @@ jobs:
os: [ubuntu-latest]
python-version: [3.7, 3.8, 3.9, '3.10']
runs-on: ${{ matrix.os }}
# TODO(fedden): We need to discuss these steps: We could just use a test-supabase instance or we could update the docker image and use that for the tests.
steps:
- name: Clone Repository
uses: actions/checkout@v2
Expand All @@ -22,11 +21,46 @@ jobs:
uses: abatilo/actions-poetry@v2.1.4
with:
poetry-version: 1.1.11
- name: Build Docker image
run: make run_infra
- name: Sleep for 5 seconds
run: sleep 5
- name: Run Tests
run: make tests
run: make run_tests
- name: Upload Coverage
uses: codecov/codecov-action@v1

publish:
needs: test
if: ${{ !startsWith(github.event.head_commit.message, 'bump:') && github.ref == 'refs/heads/main' && github.event_name == 'push' }}
runs-on: ubuntu-latest
name: "Bump version, create changelog and publish"
steps:
- name: Clone Repository
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Create bump and changelog
uses: commitizen-tools/commitizen-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: main
changelog_increment_filename: body.md
- name: Release
uses: softprops/action-gh-release@v1
with:
body_path: body.md
tag_name: ${{ env.REVISION }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Set up Poetry
uses: abatilo/actions-poetry@v2.1.4
with:
poetry-version: 1.1.11
# - name: Publish
# env:
# PYPI_USERNAME: __token__
# PYPI_PASSWORD: ${{ secrets.PYPI_TOKEN }}
# run: |
# poetry install
# poetry publish --build -u $PYPI_USERNAME -p $PYPI_PASSWORD
8 changes: 7 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ repos:
]

- repo: https://github.com/ambv/black
rev: 21.11b0
rev: 21.11b1
hooks:
- id: black

Expand All @@ -44,3 +44,9 @@ repos:
hooks:
- id: pyupgrade
args: ["--py37-plus", "--keep-runtime-typing"]

- repo: https://github.com/commitizen-tools/commitizen
rev: v2.20.0
hooks:
- id: commitizen
stages: [commit-msg]
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,25 @@ tests_pre_commit:
poetry run pre-commit run --all-files

tests_only:
poetry run pytest --cov=./ --cov-report=xml -vv
poetry run pytest --cov=./ --cov-report=xml --cov-report=html -vv

run_infra:
cd infra &&\
docker-compose down &&\
docker-compose up -d

run_tests: run_infra tests
clean_infra:
cd infra &&\
docker-compose down &&\
docker system prune -a --volumes -f

run_tests: run_infra sleep tests

build_sync:
poetry run unasync gotrue tests

build_run_tests: build_sync run_tests
echo "Done"

sleep:
sleep 10
19 changes: 12 additions & 7 deletions gotrue/_async/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,10 @@ async def set_auth(self, *, access_token: str) -> Session:
return session

async def get_session_from_url(
self, *, url: str, store_session: bool = False
self,
*,
url: str,
store_session: bool = False,
) -> Session:
"""Gets the session data from a URL string.

Expand Down Expand Up @@ -406,16 +409,16 @@ async def get_session_from_url(
token_type = query.get("token_type")
if error_description:
raise APIError(error_description[0], 400)
if not access_token:
if not access_token or not access_token[0]:
raise APIError("No access_token detected.", 400)
if not expires_in or expires_in[0]:
if not expires_in or not expires_in[0]:
raise APIError("No expires_in detected.", 400)
if not refresh_token:
if not refresh_token or not refresh_token[0]:
raise APIError("No refresh_token detected.", 400)
if not token_type:
if not token_type or not token_type[0]:
raise APIError("No token_type detected.", 400)
try:
expires_at = round(time.time()) + int(expires_in[0])
expires_at = round(time()) + int(expires_in[0])
except ValueError:
raise APIError("Invalid expires_in.", 400)
response = await self.api.get_user(jwt=access_token[0])
Expand All @@ -431,8 +434,9 @@ async def get_session_from_url(
)
if store_session:
await self._save_session(session=session)
recovery_mode = query.get("type")
self._notify_all_subscribers(event=AuthChangeEvent.SIGNED_IN)
if query.get("type") == "recovery":
if recovery_mode == "recovery":
self._notify_all_subscribers(event=AuthChangeEvent.PASSWORD_RECOVERY)
return session

Expand Down Expand Up @@ -581,6 +585,7 @@ async def _call_refresh_token(
refresh_token=cast(str, refresh_token)
)
await self._save_session(session=response)
self._notify_all_subscribers(event=AuthChangeEvent.TOKEN_REFRESHED)
self._notify_all_subscribers(event=AuthChangeEvent.SIGNED_IN)
return response

Expand Down
21 changes: 14 additions & 7 deletions gotrue/_sync/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,12 @@ def set_auth(self, *, access_token: str) -> Session:
self._save_session(session=session)
return session

def get_session_from_url(self, *, url: str, store_session: bool = False) -> Session:
def get_session_from_url(
self,
*,
url: str,
store_session: bool = False,
) -> Session:
"""Gets the session data from a URL string.

Parameters
Expand Down Expand Up @@ -404,16 +409,16 @@ def get_session_from_url(self, *, url: str, store_session: bool = False) -> Sess
token_type = query.get("token_type")
if error_description:
raise APIError(error_description[0], 400)
if not access_token:
if not access_token or not access_token[0]:
raise APIError("No access_token detected.", 400)
if not expires_in or expires_in[0]:
if not expires_in or not expires_in[0]:
raise APIError("No expires_in detected.", 400)
if not refresh_token:
if not refresh_token or not refresh_token[0]:
raise APIError("No refresh_token detected.", 400)
if not token_type:
if not token_type or not token_type[0]:
raise APIError("No token_type detected.", 400)
try:
expires_at = round(time.time()) + int(expires_in[0])
expires_at = round(time()) + int(expires_in[0])
except ValueError:
raise APIError("Invalid expires_in.", 400)
response = self.api.get_user(jwt=access_token[0])
Expand All @@ -429,8 +434,9 @@ def get_session_from_url(self, *, url: str, store_session: bool = False) -> Sess
)
if store_session:
self._save_session(session=session)
recovery_mode = query.get("type")
self._notify_all_subscribers(event=AuthChangeEvent.SIGNED_IN)
if query.get("type") == "recovery":
if recovery_mode == "recovery":
self._notify_all_subscribers(event=AuthChangeEvent.PASSWORD_RECOVERY)
return session

Expand Down Expand Up @@ -575,6 +581,7 @@ def _call_refresh_token(self, *, refresh_token: Optional[str] = None) -> Session
raise ValueError("No current session and refresh_token not supplied.")
response = self.api.refresh_access_token(refresh_token=cast(str, refresh_token))
self._save_session(session=response)
self._notify_all_subscribers(event=AuthChangeEvent.TOKEN_REFRESHED)
self._notify_all_subscribers(event=AuthChangeEvent.SIGNED_IN)
return response

Expand Down
3 changes: 2 additions & 1 deletion gotrue/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,12 @@ def validator(cls, values: dict) -> dict:


class AuthChangeEvent(str, Enum):
PASSWORD_RECOVERY = "PASSWORD_RECOVERY"
SIGNED_IN = "SIGNED_IN"
SIGNED_OUT = "SIGNED_OUT"
TOKEN_REFRESHED = "TOKEN_REFRESHED"
USER_UPDATED = "USER_UPDATED"
USER_DELETED = "USER_DELETED"
PASSWORD_RECOVERY = "PASSWORD_RECOVERY"


class Subscription(BaseModelFromResponse):
Expand Down
3 changes: 2 additions & 1 deletion infra/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@ services:
- '9000:9000' # web interface
- '1100:1100' # POP3
db:
image: supabase/postgres
image: supabase/postgres:latest
ports:
- '5432:5432'
command: postgres -c config_file=/etc/postgresql/postgresql.conf
volumes:
- ./db:/docker-entrypoint-initdb.d/
environment:
Expand Down
Loading