Skip to content

preferred language #810

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

Merged
merged 3 commits into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
review comments #1
  • Loading branch information
kziemianek committed Apr 24, 2018
commit 31c838a6fca00c3969b398b2da538db0dc4d5e3e
2 changes: 1 addition & 1 deletion app/dashboard/migrations/0051_profile_pref_lang_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='profile',
name='pref_lang_code',
field=models.CharField(default='en', max_length=10),
field=models.CharField(default='en', max_length=2),
preserve_default=False,
),
]
1 change: 1 addition & 0 deletions app/dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ class Profile(SuperModel):
email = models.CharField(max_length=255, blank=True, db_index=True)
github_access_token = models.CharField(max_length=255, blank=True, db_index=True)
pref_lang_code = models.CharField(max_length=10)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should limit the choices to LANGUAGES and we can probably set the max_length to 2.

pref_lang_code = models.CharField(max_length=2, choices=settings.LANGUAGES)
suppress_leaderboard = models.BooleanField(
default=False,
help_text='If this option is chosen, we will remove your profile information from the leaderboard',
Expand Down
151 changes: 151 additions & 0 deletions app/github/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# -*- coding: utf-8 -*-
"""Handle github views.

Copyright (C) 2018 Gitcoin Core

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

"""

from __future__ import print_function, unicode_literals

import logging
import time

from django.conf import settings
from django.http import Http404
from django.shortcuts import redirect
from django.utils import timezone
from django.utils.translation import LANGUAGE_SESSION_KEY
from django.views.decorators.http import require_GET

from app.utils import get_location_from_ip
from dashboard.models import Profile, UserAction
from github.utils import (
get_auth_url, get_github_primary_email, get_github_user_data, get_github_user_token, revoke_token,
)
from ipware.ip import get_real_ip


@require_GET
def github_callback(request):
"""Handle the Github authentication callback."""
# Get request parameters to handle authentication and the redirect.
code = request.GET.get('code', None)
redirect_uri = request.GET.get('redirect_uri')

if not code or not redirect_uri:
raise Http404

# Get OAuth token and github user data.
access_token = get_github_user_token(code)
github_user_data = get_github_user_data(access_token)
handle = github_user_data.get('login')
ip_address = '24.210.224.38' if settings.DEBUG else get_real_ip(request)
geolocation_data = {}

if ip_address:
geolocation_data = get_location_from_ip(ip_address)

if handle:
# Create or update the Profile with the github user data.
user_profile, _ = Profile.objects.update_or_create(
handle=handle,
defaults={
'data': github_user_data or {},
'email': get_github_primary_email(access_token),
'github_access_token': access_token
})

# Update the user's session with handle, email info, preffered language.
session_data = {
'handle': user_profile.handle,
'email': user_profile.email,
'access_token': user_profile.github_access_token,
'profile_id': user_profile.pk,
'name': user_profile.data.get('name', None),
'access_token_last_validated': timezone.now().isoformat()
}

if user_profile.pref_lang_code:
session_data[LANGUAGE_SESSION_KEY] = user_profile.pref_lang_code

for k, v in session_data.items():

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

W291 trailing whitespace

request.session[k] = v

# record a useraction for this
UserAction.objects.create(
profile=user_profile,
action='Login',
metadata={},
ip_address=ip_address,
location_data=geolocation_data)

response = redirect(redirect_uri)
response.set_cookie('last_github_auth_mutation', int(time.time()))
return response


@require_GET
def github_authentication(request):
"""Handle Github authentication."""
redirect_uri = request.GET.get('redirect_uri', '/')

if not request.session.get('access_token'):
return redirect(get_auth_url(redirect_uri))

# Alert local developer that Github integration needs configured.
if settings.ENV == 'local' and (not settings.GITHUB_CLIENT_ID or settings.GITHUB_CLIENT_ID == 'TODO'):
logging.info('GITHUB_CLIENT_ID is not set. Github integration is disabled!')

response = redirect(redirect_uri)
response.set_cookie('last_github_auth_mutation', int(time.time()))
return response


def github_logout(request):
"""Handle Github logout."""
access_token = request.session.pop('access_token', '')
handle = request.session.pop('handle', '')
redirect_uri = request.GET.get('redirect_uri', '/')
geolocation_data = {}
ip_address = '24.210.224.38' if settings.DEBUG else get_real_ip(request)

if ip_address:
geolocation_data = get_location_from_ip(ip_address)

if access_token:
revoke_token(access_token)
request.session.pop('access_token_last_validated')

try:
# If the profile exists, clear the github access token.
profile = Profile.objects.get(handle=handle)
profile.github_access_token = ''
profile.save()

# record a useraction for this
UserAction.objects.create(
profile=profile,
action='Logout',
metadata={},
ip_address=ip_address,
location_data=geolocation_data)
except Profile.DoesNotExist:
pass

request.session.modified = True
response = redirect(redirect_uri)
response.set_cookie('last_github_auth_mutation', int(time.time()))
return response
23 changes: 15 additions & 8 deletions app/marketing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import json

from django.conf import settings
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required
from django.core.validators import validate_email
Expand All @@ -29,7 +30,7 @@
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils import timezone, translation
from django.utils.translation import LANGUAGE_SESSION_KEY
from django.utils.translation import LANGUAGE_SESSION_KEY, check_for_language

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

F401 'django.utils.translation.check_for_language' imported but unused

from django.utils.translation import gettext_lazy as _

from app.utils import sync_profile
Expand Down Expand Up @@ -600,12 +601,17 @@ def email_settings(request, key):
es = es.first()
profile_id = request.session.get('profile_id')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note... This is changing and will soon be: profile = request.user.profile

profile = Profile.objects.get(pk=profile_id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to check if profile_id is None here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if it's possible... can user without profile change preferences ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An anonymous user can still hit the https://gitcoin.co/email/settings/ endpoint at the moment. We'll want to either restrict the view from being accessed without auth or handle when profile_id = request.session.get('profile_id') is None 😢

Copy link
Contributor Author

@kziemianek kziemianek Apr 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preferred_language selection will be available only if profile_id is present in session data, is it fine ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kziemianek 👍 Works for me! Realistically, we'll restrict this view from being accessed by users that haven't authenticated, so that should work!

if request.POST and request.POST.get('preferred_language', False):
preferred_language = request.POST.get('preferred_language')
profile.pref_lang_code = preferred_language
profile.save()
request.session[LANGUAGE_SESSION_KEY] = preferred_language
translation.activate(preferred_language)
preferred_language = request.POST.get('preferred_language')
validation_passed = True
if preferred_language:
if preferred_language not in [i[0] for i in settings.LANGUAGES]:
msg = _('Unknown language')
validation_passed = False
if validation_passed:
profile.pref_lang_code = preferred_language
profile.save()
request.session[LANGUAGE_SESSION_KEY] = preferred_language
translation.activate(preferred_language)

if request.POST and request.POST.get('submit')::
level = request.POST.get('level')
Expand Down Expand Up @@ -644,7 +650,8 @@ def email_settings(request, key):
'msg': msg,
'navs': settings_navs,
'available_languages': ['en', 'pl'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed per the comment below.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can drop this now that you're doing: {% get_available_languages as LANGUAGES %} and {% get_language_info_list for LANGUAGES as langs %}

'preferred_language': profile.pref_lang_code
'preferred_language': profile.pref_lang_code,
'logged_in' : False if request.session.get('profile_id') is None else True

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E203 whitespace before ':'

}
return TemplateResponse(request, 'settings/email.html', context)

Expand Down
Loading