Skip to content

Commit

Permalink
Merge pull request #525 from hotosm/feature/oauth-2
Browse files Browse the repository at this point in the history
Upgrade : Oauth2 Login for OSM
  • Loading branch information
kshitijrajsharma committed Feb 7, 2024
2 parents 6468955 + f0aba75 commit c1b9154
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 51 deletions.
3 changes: 2 additions & 1 deletion core/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@
)

AUTHENTICATION_BACKENDS = (
"social_core.backends.openstreetmap.OpenStreetMapOAuth",
# "social_core.backends.openstreetmap.OpenStreetMapOAuth",
"social_core.backends.openstreetmap_oauth2.OpenStreetMapOAuth2",
"oauth2_provider.backends.OAuth2Backend",
"social_core.backends.email.EmailAuth",
"social_core.backends.username.UsernameAuth",
Expand Down
85 changes: 45 additions & 40 deletions core/settings/contrib.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,58 +8,63 @@
# Extra installed apps
INSTALLED_APPS += (
# any 3rd party apps
'rest_framework',
'rest_framework_gis',
'rest_framework.authtoken',
'social_django',
"rest_framework",
"rest_framework_gis",
"rest_framework.authtoken",
"social_django",
)

# 3rd party specific app settings
OAUTH2_PROVIDER = {
'ACCESS_TOKEN_EXPIRE_SECONDS': 10 * 365 * 24 * 60 * 60,
"ACCESS_TOKEN_EXPIRE_SECONDS": 10 * 365 * 24 * 60 * 60,
}

REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.SearchFilter',
'rest_framework.filters.OrderingFilter'),
'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework.authentication.TokenAuthentication',
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
'rest_framework.authentication.SessionAuthentication',),
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'api.renderers.HOTExportApiRenderer',
"DEFAULT_FILTER_BACKENDS": (
"rest_framework.filters.SearchFilter",
"rest_framework.filters.OrderingFilter",
),
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning',
'DEFAULT_VERSION': '1.0',
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 20
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.TokenAuthentication",
"oauth2_provider.contrib.rest_framework.OAuth2Authentication",
"rest_framework.authentication.SessionAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
"DEFAULT_RENDERER_CLASSES": (
"rest_framework.renderers.JSONRenderer",
"api.renderers.HOTExportApiRenderer",
),
"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.AcceptHeaderVersioning",
"DEFAULT_VERSION": "1.0",
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
"PAGE_SIZE": 20,
}


# OAuth login settings
SOCIAL_AUTH_OPENSTREETMAP_LOGIN_URL = '/osm/login/'
SOCIAL_AUTH_OPENSTREETMAP_KEY = os.getenv('OSM_API_KEY')
SOCIAL_AUTH_OPENSTREETMAP_SECRET = os.getenv('OSM_API_SECRET')
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'
SOCIAL_AUTH_LOGIN_ERROR_URL = '/osm/error'
SOCIAL_AUTH_URL_NAMESPACE = 'osm'
SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ['username', 'first_name', 'email']
SOCIAL_AUTH_OPENSTREETMAP_LOGIN_URL = "/osm/login/"
SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY = os.getenv("OSM_API_KEY")
SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET = os.getenv("OSM_API_SECRET")
SOCIAL_AUTH_LOGIN_REDIRECT_URL = "/"
SOCIAL_AUTH_LOGIN_ERROR_URL = "/osm/error"
SOCIAL_AUTH_URL_NAMESPACE = "osm"
SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ["username", "first_name", "email"]
SOCIAL_AUTH_FORCE_EMAIL_VALIDATION = True
SOCIAL_AUTH_EMAIL_VALIDATION_FUNCTION = 'ui.pipeline.email_validation'
SOCIAL_AUTH_EMAIL_VALIDATION_URL = '/osm/email_verify_sent/'
SOCIAL_AUTH_EMAIL_VALIDATION_FUNCTION = "ui.pipeline.email_validation"
SOCIAL_AUTH_EMAIL_VALIDATION_URL = "/osm/email_verify_sent/"

SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'ui.pipeline.require_email',
'social_core.pipeline.mail.mail_validation',
'social_core.pipeline.social_auth.associate_by_email',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.debug.debug',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details'
"social_core.pipeline.social_auth.social_details",
"social_core.pipeline.social_auth.social_uid",
"social_core.pipeline.social_auth.auth_allowed",
"social_core.pipeline.social_auth.social_user",
"social_core.pipeline.user.get_username",
"ui.pipeline.require_email",
"social_core.pipeline.mail.mail_validation",
"social_core.pipeline.social_auth.associate_by_email",
"social_core.pipeline.user.create_user",
"social_core.pipeline.social_auth.associate_user",
"social_core.pipeline.debug.debug",
"social_core.pipeline.social_auth.load_extra_data",
"social_core.pipeline.user.user_details",
)
2 changes: 1 addition & 1 deletion ops/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Examples of how to backup and restore the database:
psql exports < export_tool_2023-03-06.pgdump
```

8. Modify the OAuth1 application with your hostname's `redirect_uris`
8. Modify the OAuth2 application with your hostname's `redirect_uris`

### Storage and Environment Variables

Expand Down
6 changes: 3 additions & 3 deletions ops/systemd/export_workers.env
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ EMAIL_HOST_USER=<INSECURE_SMTP_USERNAME>
EMAIL_HOST_PASSWORD=<SECURE_SMTP_PASSWORD>
REPLY_TO_EMAIL=<INSECURE_REPLY_EMAIL>

##OAUTH 1 Settings
OSM_API_KEY=<SECURE_OSM_OAUTH1_APP_CONSUMER_KEY>
OSM_API_SECRET=<SECURE_OSM_OAUTH1_APP_CONSUMER_SECRET>
##OAUTH 2 Settings
OSM_API_KEY=<SECURE_OSM_OAUTH2_APP_CONSUMER_KEY>
OSM_API_SECRET=<SECURE_OSM_OAUTH2_APP_CONSUMER_SECRET>

## Workers
WORKER_SECRET_KEY=<SECURE_WORKER_KEY>
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mercantile~=0.10.0
psycopg2
python3-openid==3.2.0
social-auth-app-django==5.4.0
social-auth-core==4.4.2
social-auth-core==4.4.2 ### Upgrade this to include oauth2
pytz
pyyaml>=5.3
raven
Expand Down
1 change: 1 addition & 0 deletions ui/app/actions/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ if (window.OAUTH_CLIENT_ID == null) {
}

const oauthConfig = {
// url: window.EXPORTS_API_URL + "/o/openstreetmap_oauth2",
url: window.EXPORTS_API_URL + "/o/authorize?approval_prompt=auto",
client: window.OAUTH_CLIENT_ID,
redirect: `${window.location.protocol}//${hostname}/authorized`
Expand Down
2 changes: 1 addition & 1 deletion ui/app/components/help/API.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default () =>
<p>User authentication and authorization is a two-step process.</p>
<p>
The Export Tool requires that users log into OpenStreetMap using{" "}
<a href="https://oauth.net/1/">OAuth 1.0a</a> (you don't need to know
<a href="https://oauth.net/2/">OAuth 2.0a</a> (you don't need to know
this). This provides user identity, specifically an OSM username to
associate with exports. You generally don't need to care about this,
except to know that usernames are the same as on OSM.
Expand Down
2 changes: 1 addition & 1 deletion ui/templates/osm/email.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
{% blocktrans %}Please provide a valid email address. This email address will be used to notifiy you when your exports are ready.
A verification link will be sent to the email address you provide.{% endblocktrans %}
<br/><br/>
<form method="post" action="{% url 'osm:complete' 'openstreetmap' %}" id="registerEmail">
<form method="post" action="{% url 'osm:complete' 'openstreetmap-oauth2' %}" id="registerEmail">
{% csrf_token %}
<div class="form-group row" id="form-group-email">
<div class="col-md-12">
Expand Down
7 changes: 4 additions & 3 deletions ui/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ def login(request):
if not request.user.is_authenticated:
# preserve redirects ("next" in request.GET)
return redirect(
reverse("osm:begin", args=["openstreetmap"]) + "?" + request.GET.urlencode()
reverse("osm:begin", args=["openstreetmap-oauth2"])
+ "?"
+ request.GET.urlencode()
)
else:
return redirect("/v3/")
Expand All @@ -48,7 +50,7 @@ def v3(request, *args, **kwargs):
except Application.DoesNotExist:
ui_app = Application.objects.create(
name="OSM Export Tool UI",
redirect_uris="http://localhost/authorized http://localhost:8080/authorized http://localhost:8000/authorized",
redirect_uris="http://localhost/authorized http://127.0.0.1:8000/authorized http://localhost:8080/authorized http://localhost:8000/authorized",
client_type=Application.CLIENT_PUBLIC,
authorization_grant_type=Application.GRANT_IMPLICIT,
skip_authorization=True,
Expand All @@ -70,7 +72,6 @@ def redirect_to_v3(request):
def worker_dashboard(request):
if not request.user.is_superuser:
return HttpResponseForbidden()
# return HttpResponse('test')
return HttpResponseRedirect(f"/{settings.WORKER_SECRET_KEY}/")


Expand Down

0 comments on commit c1b9154

Please sign in to comment.