Skip to content

Commit

Permalink
Merge pull request openedx#709 from proversity-org/proversity/staging
Browse files Browse the repository at this point in the history
Translations ar and cy
Talenetic SSO
  • Loading branch information
Nico van Niekerk authored Apr 12, 2018
2 parents dadc341 + e7e716e commit 2ba7d68
Show file tree
Hide file tree
Showing 17 changed files with 578 additions and 20 deletions.
Binary file modified conf/locale/ar/LC_MESSAGES/django.mo
Binary file not shown.
275 changes: 274 additions & 1 deletion conf/locale/ar/LC_MESSAGES/django.po

Large diffs are not rendered by default.

Binary file modified conf/locale/cy/LC_MESSAGES/django-partial.mo
Binary file not shown.
4 changes: 3 additions & 1 deletion conf/locale/cy/LC_MESSAGES/django-partial.po
Original file line number Diff line number Diff line change
Expand Up @@ -5125,13 +5125,15 @@ msgstr ""

#: lms/djangoapps/courseware/views/views.py
msgid "Your enrollment: Audit track"
msgstr ""
msgstr "Eich cofrestriad: Lwybr awdit"

#: lms/djangoapps/courseware/views/views.py
msgid ""
"You are enrolled in the audit track for this course. The audit track does "
"not include a certificate."
msgstr ""
"Rydych wedi'ch cofrestru ar y trac awdit ar gyfer y cwrs hwn. Nid yw'r "
"llwybr awdit yn cynnwys tystysgrif."

#: lms/djangoapps/courseware/views/views.py
msgid "Your certificate has been invalidated"
Expand Down
Binary file modified conf/locale/cy/LC_MESSAGES/django.mo
Binary file not shown.
38 changes: 23 additions & 15 deletions conf/locale/cy/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -11390,6 +11390,10 @@ msgstr "Cyfrif"
msgid "Help"
msgstr "Help"

#: openedx/features/course_experience/templates/course_experience/course-home-fragment.html
msgid "Start Course"
msgstr "Cychwyn Cwrs"

#: cms/templates/widgets/sock.html
#: themes/edx.org/cms/templates/widgets/sock.html
msgid "Looking for help with {studio_name}?"
Expand Down Expand Up @@ -12142,12 +12146,6 @@ msgstr "Mewngofnodi gyda {provider_name}"
msgid "External resource"
msgstr "Adnodd allanol"

#. Translators: "points" is the student's achieved score on this LTI unit, and
#. "total_points" is the maximum number of points achievable.
#: lms/templates/lti.html
msgid "{points} / {total_points} points"
msgstr "{points} / {total_points} pwynt"

#. Translators: "total_points" is the maximum number of points achievable on
#. this LTI unit
#: lms/templates/lti.html
Expand Down Expand Up @@ -14844,7 +14842,7 @@ msgstr ""

#: lms/templates/courseware/info.html
msgid "Welcome to {org}'s {course_name}!"
msgstr "Croeso i {course_name} {org}!"
msgstr "Croeso i {course_name} {org}'s!"

#: lms/templates/courseware/info.html
msgid "Resume Course"
Expand Down Expand Up @@ -14880,7 +14878,7 @@ msgid "Handout Navigation"
msgstr "Llywio taflenni"

#: lms/templates/courseware/info.html
#, fuzzy
#: openedx/features/course_experience/templates/course_experience/course-home-fragment.html
msgid "Course Tools"
msgstr "Rolau tîm y cwrs"

Expand Down Expand Up @@ -14981,18 +14979,25 @@ msgid "{earned} of {total} possible points"
msgstr "{earned} o'r {total} pwyntiau sy'n bosib"

#: lms/templates/courseware/progress.html
#, fuzzy
msgid "No problem scores in this section"
msgstr "Dim sgorau sy'n broblem yn yr adran hon"

#: lms/templates/courseware/progress.html
msgid "Problem Scores: "
msgstr "Sgorau'r problemau:"
msgstr "Sgoriau broblem:"

#: lms/templates/courseware/progress.html
#, fuzzy
msgid "Practice Scores: "
msgstr "Sgorau ymarferion:"
msgstr "Sgoriau arfer:"

#: lms/templates/lti.html
msgid "{points} / {total_points} points"
msgstr "{points} / {total_points} pwyntiau"

#: lms/templates/courseware/progress.html
msgid "No problem scores in this section"
msgstr "Dim sgorau sy'n broblem yn yr adran hon"

#: lms/templates/login.html
msgid "First time here? Create an account"
msgstr "Y ttro cyntaf yma? Creu cyfrif"

#: lms/templates/courseware/syllabus.html
msgid "{course.display_number_with_default} Course Info"
Expand Down Expand Up @@ -15723,6 +15728,9 @@ msgstr "Dangos y nodiadau"
msgid "Welcome to {course_name}"
msgstr "Croeso i {course_name}"

msgid "Welcome to {course_title}"
msgstr "Croeso i {course_title}"

#: lms/templates/emails/account_creation_and_enroll_emailMessage.txt
msgid ""
"To get started, please visit https://{site_name}. The login information for "
Expand Down
Binary file modified conf/locale/cy/LC_MESSAGES/djangojs.mo
Binary file not shown.
11 changes: 11 additions & 0 deletions conf/locale/cy/LC_MESSAGES/djangojs.po
Original file line number Diff line number Diff line change
Expand Up @@ -8218,6 +8218,17 @@ msgstr "Dangoswch ffyrdd eraill o fewngofnodi neu gofrestru"
msgid "Sign in with Institution/Campus Credentials"
msgstr "Mewngofnodi gyda chymwysterau sefydliad/campws"

#: cms/templates/login.html cms/templates/widgets/header.html
#: themes/red-theme/cms/templates/login.html
msgid "Sign In"
msgstr "Mewngofnodi"

msgid "First time here?"
msgstr "Y tro cyntaf yma?"

msgid "Create an Account."
msgstr "Creu cyfrif."

#: lms/templates/student_account/institution_login.underscore
#: lms/templates/student_account/institution_register.underscore
#: test_root/staticfiles/templates/student_account/institution_login.underscore
Expand Down
Binary file modified conf/locale/cy/LC_MESSAGES/mako.mo
Binary file not shown.
5 changes: 3 additions & 2 deletions conf/locale/cy/LC_MESSAGES/mako.po
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,7 @@ msgstr "Adnodd allanol"
#. "total_points" is the maximum number of points achievable.
#: lms/templates/lti.html
msgid "{points} / {total_points} points"
msgstr "{points} / {total_points} pwynt"
msgstr "{points} / {total_points} pwyntiau"

#. Translators: "total_points" is the maximum number of points achievable on
#. this LTI unit
Expand All @@ -1218,6 +1218,7 @@ msgstr "Rhowch launch_url. Cliciwch ar \"Golygu\", a chwblhau'r meysydd gofynnol
msgid "Feedback on your work from the grader:"
msgstr "Adborth ar eich gwaith gan y graddiwr:"


#: lms/templates/lti_form.html
msgid "Press to Launch"
msgstr "Gwasgwch i lansio"
Expand Down Expand Up @@ -4079,7 +4080,7 @@ msgstr "Llywio taflenni"

#: lms/templates/courseware/info.html
msgid "Course Tools"
msgstr ""
msgstr "Rolau tîm y cwrs"

#: lms/templates/courseware/info.html
msgid "Course Handouts"
Expand Down
Binary file modified conf/locale/cy/LC_MESSAGES/underscore.mo
Binary file not shown.
14 changes: 14 additions & 0 deletions conf/locale/cy/LC_MESSAGES/underscore.po
Original file line number Diff line number Diff line change
Expand Up @@ -3490,3 +3490,17 @@ msgstr ""
#, python-format
msgid " %(username)s "
msgstr ""

#: cms/templates/login.html cms/templates/widgets/header.html
#: themes/red-theme/cms/templates/login.html
msgid "Sign In"
msgstr "Mewngofnodi"

msgid "First time here?"
msgstr "Y tro cyntaf yma?"

msgid "Create an Account."
msgstr "Creu cyfrif."

msgid "SIGN IN"
msgstr "Mewngofnodi"
222 changes: 222 additions & 0 deletions lms/djangoapps/student_account/talenetic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
from six.moves.urllib_parse import urlencode, unquote
import jwt
import json
from django.conf import settings
from student.models import Registration, UserProfile
from social_core.backends.oauth import BaseOAuth2
from django.contrib.auth.models import User
import uuid
import logging
import social_django

log = logging.getLogger(__name__)

class TaleneticOAuth2(BaseOAuth2):
"""
Talenetic OAuth2 authentication backend
"""
settings_dict = settings.CUSTOM_BACKENDS.get('talenetic')
name = 'talenetic-oauth2'
REDIRECT_STATE = False
ID_KEY = 'emailaddress'
STATE_PARAMETER = False
AUTHORIZATION_URL = settings_dict.get('AUTH_URL')
ACCESS_TOKEN_URL = settings_dict.get('ACCESS_TOKEN_URL')
ACCESS_TOKEN_METHOD = 'GET'
REFRESH_TOKEN_URL = settings_dict.get('REFRESH_TOKEN_URL')
REFRESH_TOKEN_METHOD = 'POST'
RESPONSE_TYPE = 'code jwt_token'
REDIRECT_IS_HTTPS = False
REVOKE_TOKEN_URL = settings_dict.get('LOGOUT_URL')
REVOKE_TOKEN_METHOD = 'POST'

def get_scope_argument(self):
return {}


def auth_complete(self, *args, **kwargs):
"""Completes login process, must return user instance"""
self.process_error(self.data)
state = self.validate_state()
access_url = "{}?uid={}".format(self.access_token_url(), self._get_uid())
response = self.request_access_token(
access_url,
data=self._get_creds(),
headers=self._get_creds(),
auth=self.auth_complete_credentials(),
method=self.ACCESS_TOKEN_METHOD
)
self.process_error(response)
return self.do_auth(response['jwt_token'], response=response,
*args, **kwargs)


def do_auth(self, jwt_token, *args, **kwargs):
data = self.user_data(jwt_token, *args, **kwargs)
response = kwargs.get('response') or {}
response.update(data or {})
if 'access_token' not in response:
response['access_token'] = jwt_token
kwargs.update({'response': response, 'backend': self})
return self.strategy.authenticate(*args, **kwargs)


def _get_uid(self):
if 'uid' in self.data:
return self.data['uid']
else:
return None


def auth_params(self, state=None):
client_id, client_secret = self.get_key_and_secret()

uri = self.get_redirect_uri(state)
if self.REDIRECT_IS_HTTPS:
uri = uri.replace('http://', 'https://')

params = {
'urlredirect': uri,
'clientId': client_id,
'secretkey': client_secret
}
return params


def get_user_id(self, details, response):
return details.get('email')


def user_data(self, access_token, *args, **kwargs):
"""Loads user data from service"""
return self.get_user_details(kwargs.get('response'))


def get_user_details(self, response):
response = self._fill_fields(response)
self._set_uid_to_profile(self._get_uid(), response.get('emailaddress'))
return {'username': response.get('username'),
'email': response.get('emailaddress'),
'fullname': response.get('firstname'),
'first_name': response.get('firstname')}


def _fill_fields(self, data):
# a little util to fill in missing data for later consumption
if data.get('firstname') is None:
data['firstname'] = data.get('emailaddress').split('@')[0]
if data.get('username') is None:
data['username'] = data.get('emailaddress').split('@')[0]

return data


def _get_creds(self):
client_id, client_secret = self.get_key_and_secret()
return {
'secretkey': client_secret,
'clientId': client_id
}


def auth_headers(self):
return {'Accept': 'application/json'}


def pipeline(self, pipeline, pipeline_index=0, *args, **kwargs):
"""
This is a special override of the pipeline method.
This will grab the user from the actual ran pipeline and
add the incoming uid as a uid field to the meta field on the user profile
"""

# due to some of the usernames that will come in from the SSO containing a .fullstop
# the user can not be found and then the oauth tries
# to make a new one and breaks as the email exists,
# this is to set the user if it exists forcefully for the rest of oauth to work properly.
if kwargs.get('user') is None:
try:
user = User.objects.get(email=kwargs.get('response').get('emailaddress'))
kwargs['user'] = user
except User.DoesNotExist:
pass

out = self.run_pipeline(pipeline, pipeline_index, *args, **kwargs)
if not isinstance(out, dict):
return out

user = out.get('user')

if user:
user.social_user = out.get('social')
user.is_new = out.get('is_new')

return user


def _set_uid_to_profile(self, uid, emailaddress):
"""
This function calls for the existing user by emailaddress,
if the user is found we save the requested uid to the user profile
because we need it to logout.
"""
try:
user = User.objects.get(email=emailaddress)
user_profile = user.profile
new_meta = {'talenetic-uid': uid}
if len(user_profile.meta) > 0:
previous_meta = json.loads(user_profile.meta)

mixed_dicts =\
(previous_meta.items() + new_meta.items())
new_meta =\
{key: value for (key, value) in mixed_dicts}

user_profile.meta = json.dumps(new_meta)
user_profile.save()
except Exception as e:
log.error("Could not save uid to user profile or something else: {}".format(e.message))


def auth_url(self):
"""Return redirect url"""
params = self.auth_params()
params = urlencode(params)
if not self.REDIRECT_STATE:
# redirect_uri matching is strictly enforced, so match the
# providers value exactly.
params = unquote(params)
return '{0}?{1}'.format(self.authorization_url(), params)


def revoke_token_url(self, token, uid):
social_user = social_django.models.DjangoStorage.user.get_social_auth(provider=self.name, uid=uid)
profile = social_user.user.profile
meta_data = json.loads(profile.meta)
url = "{}?uid={}".format(self.REVOKE_TOKEN_URL, meta_data.get('talenetic-uid'))
return url


def revoke_token_params(self, token, uid):
return {}


def revoke_token_headers(self, token, uid):
return self._get_creds()


def process_revoke_token_response(self, response):
return response.status_code == 200


def revoke_token(self, token, uid):
if self.REVOKE_TOKEN_URL:
url = self.revoke_token_url(token, uid)
params = self.revoke_token_params(token, uid)
headers = self.revoke_token_headers(token, uid)
data = urlencode(params) if self.REVOKE_TOKEN_METHOD != 'GET' \
else None
response = self.request(url, params=params, headers=headers,
data=data, method=self.REVOKE_TOKEN_METHOD)
return self.process_revoke_token_response(response)
Loading

0 comments on commit 2ba7d68

Please sign in to comment.