Skip to content

Commit

Permalink
Merge pull request #24 from girardinsamuel/2.0
Browse files Browse the repository at this point in the history
Add revoke and refresh token features and refactor to remove dependencies
  • Loading branch information
girardinsamuel authored Mar 23, 2022
2 parents 674ede8 + 013a8ad commit b0cd173
Show file tree
Hide file tree
Showing 17 changed files with 345 additions and 255 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test Application
name: Test Application

on: [push, pull_request]

Expand All @@ -10,9 +10,9 @@ jobs:
python-version: ["3.7", "3.8", "3.9", "3.10"]
name: Python ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
name: Lint
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pythonpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: "3.x"
- name: Install dependencies
Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ DRIVERS = {

`redirect` can be a route name or a path.

## Configuration of your OAuth app:

Then you should create an OAuth App on your provider dashboard. Here are some links:

- GitHub:
- GitLab:
- BitBucket (Atlassian): you must first [create a workspace](https://bitbucket.org/account/workspaces/) and then in `Settings` add an `OAuth consumer` here https://bitbucket.org/{your-workspace-slug}/workspace/settings/api
- ...


## Usage

To authenticate users using an OAuth provider, you will need two routes: one for redirecting the user to the OAuth provider, and another for receiving the callback from the provider after authentication.
Expand Down Expand Up @@ -150,6 +160,27 @@ Some OAuth providers support optional parameters. To include those in the redire
return OAuth.driver("github").with_data({"key": "value"})
```

### Refresh token

Some OAuth providers support refreshing token (GitLab, BitBucket and Google at least). For that
you need a `refresh_token` obtained when calling `user()`:

```python
new_user = OAuth.driver("gitlab").refresh(user.refresh_token)
new_user.token #== is a new token
```

### Revoke token programmatically

Some OAuth providers support revoking token programmatically. For that
you need to pass the token to the `revoke()` method:

```python
revoked = OAuth.driver("gitlab").revoke(token)
```

It returned a boolean to tell if it was successful or not.

## Contributing

Please read the [Contributing Documentation](CONTRIBUTING.md) here.
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
masonite>=4.0<5.0
masonite-orm
requests-oauthlib
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version="1.1.3",
version="1.2.0",
packages=[
"masonite.oauth",
"masonite.oauth.config",
Expand Down Expand Up @@ -63,7 +63,7 @@
# your project is installed. For an analysis of "install_requires" vs pip's
# requirements files see:
# https://packaging.python.org/en/latest/requirements.html
install_requires=["masonite>=4.0<5.0", "requests-oauthlib"],
install_requires=["masonite>=4.0<5.0"],
# List additional groups of dependencies here (e.g. development
# dependencies). You can install these using the following syntax,
# for example:
Expand Down
6 changes: 5 additions & 1 deletion src/masonite/oauth/OAuth.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ def set_configuration(self, config):
return self

def driver(self, name):
return self.drivers[name].set_options(self.get_config_options(name))
try:
selected_driver = self.drivers[name]
except KeyError:
raise Exception(f"The driver {name} has not been registered as an OAuth driver.")
return selected_driver.set_options(self.get_config_options(name))

def get_config_options(self, driver=None):
if driver is None:
Expand Down
18 changes: 18 additions & 0 deletions src/masonite/oauth/OAuthFacade.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from .drivers.BaseDriver import BaseDriver

class OAuth:
def add_driver(name: str, driver: "BaseDriver"):
"""Register a new driver for OAuth2."""
...
def set_configuration(config: dict) -> OAuth:
"""Set configuration for OAuth2."""
...
def driver(name: str) -> "BaseDriver":
"""Get OAuth2 instance for given driver."""
...
def get_config_options(driver: str = None) -> dict:
"""Get configuration options for a given driver or the default driver."""
...
12 changes: 12 additions & 0 deletions src/masonite/oauth/OAuthUser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,27 @@ def __init__(self):
self.email = None
self.avatar = None
self.token = None
self.refresh_token = None
self.expires_in = None

def set_token(self, token):
self.token = token
return self

def set_refresh_token(self, token):
self.refresh_token = token
return self

def set_expires_in(self, expires_in):
self.expires_in = expires_in
return self

def build(self, raw_data):
self.id = raw_data.get("id", None)
self.name = raw_data.get("name", None)
self.nickname = raw_data.get("nickname", None)
self.email = raw_data.get("email", None)
self.avatar = raw_data.get("avatar", None)
self.refresh_token = raw_data.get("refresh_token", None)
self.expires_in = raw_data.get("expires_in", None)
return self
42 changes: 8 additions & 34 deletions src/masonite/oauth/drivers/AppleDriver.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .BaseDriver import BaseDriver
from ..OAuthUser import OAuthUser


class AppleDriver(BaseDriver):
Expand All @@ -12,36 +11,11 @@ def get_auth_url(self):
def get_token_url(self):
return "https://appleid.apple.com/auth/token"

def user(self):
user_data, token = super().user()
user = (
OAuthUser()
.set_token(token)
.build(
{
"id": user_data["sub"],
"nickname": user_data["nickname"],
"name": user_data["name"],
"email": user_data["email"],
"avatar": user_data["picture"],
}
)
)
return user

def user_from_token(self, token):
user_data = super().user_from_token(token)
user = (
OAuthUser()
.set_token(token)
.build(
{
"id": user_data["sub"],
"nickname": user_data["nickname"],
"name": user_data["name"],
"email": user_data["email"],
"avatar": user_data["picture"],
}
)
)
return user
def map_user_data(self, data):
return {
"id": data["sub"],
"nickname": data["nickname"],
"name": data["name"],
"email": data["email"],
"avatar": data["picture"],
}
Loading

0 comments on commit b0cd173

Please sign in to comment.