summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/handlers.py14
-rw-r--r--server/user_session.py58
2 files changed, 63 insertions, 9 deletions
diff --git a/server/handlers.py b/server/handlers.py
index 93818f0..5df7161 100644
--- a/server/handlers.py
+++ b/server/handlers.py
@@ -284,11 +284,19 @@ class GetUserStat(CodeqService):
class SamlLogin(CodeqService):
def process(self, request):
- data = request.data.get('data')
- if data is None:
+ js = request.data
+ saml_data = js.get('saml_data')
+ gui_lang = js.get('gui_lang', 'en')
+ if saml_data is None:
request.reply({'code': 1, 'message': 'SAML user data not specified'})
else:
- request.reply({'code': 0, 'message': 'OK'}) # TODO: implement login using SAML credentials
+ session = request.session
+ try:
+ name, email, date_joined, last_login = session.saml_login_or_signup(saml_data, gui_lang)
+ except Exception as e:
+ request.reply({'code': 2, 'message': 'SAML login failed: ' + str(e)})
+ else:
+ request.reply({'code': 0, 'message': 'OK', 'name': name, 'email': email, 'joined': date_joined.isoformat(), 'last-login': last_login.isoformat(), 'settings': session.get_settings()})
# maps actions to their handlers
diff --git a/server/user_session.py b/server/user_session.py
index b5cdd61..739da9a 100644
--- a/server/user_session.py
+++ b/server/user_session.py
@@ -86,7 +86,10 @@ class UserSession(object):
finally:
cur.close()
finally:
- conn.commit()
+ try:
+ conn.commit()
+ except:
+ pass
db.return_connection(conn)
def signup(self, username, name, email, password, lang):
@@ -110,8 +113,45 @@ class UserSession(object):
self.settings = {'gui_lang': lang}
finally:
cur.close()
- finally:
conn.commit()
+ finally:
+ db.return_connection(conn)
+
+ def saml_login_or_signup(self, saml_data, gui_lang):
+ uuid = saml_data.get('schacUUID')
+ if uuid is None:
+ raise AuthenticationFailed('SAML data does not contain schacUUID')
+ name = saml_data.get('displayName')
+ email = saml_data.get('mail')
+ with self._access_lock:
+ now = datetime.datetime.utcnow()
+ conn = db.get_connection()
+ try:
+ cur = conn.cursor()
+ try:
+ cur.execute('update codeq_user set name = %s, email = %s, saml_data = %s, last_login = %s where username = %s and saml_data is not null returning id, gui_lang, date_joined, robot_address', (name, email, psycopg2.extras.Json(saml_data), str(now), uuid))
+ row = cur.fetchone()
+ if row:
+ self.uid = row[0]
+ self.username = uuid
+ self.settings = {'gui_lang': row[1], 'robot_address': row[3]}
+ return name, email, row[2], now
+ else:
+ cur.execute('insert into codeq_user (username, name, email, is_admin, is_active, date_joined, last_login, gui_lang, saml_data) values (%s, %s, %s, %s, %s, %s, %s, %s, %s) returning id', (uuid, name, email, False, True, str(now), str(now), gui_lang, psycopg2.extras.Json(saml_data)))
+ row = cur.fetchone()
+ if row is None:
+ raise SignupFailed('Sign-up failed')
+ self.uid = row[0]
+ self.username = uuid
+ self.settings = {'gui_lang': gui_lang, 'robot_address': None}
+ return name, email, now, now
+ finally:
+ cur.close()
+ finally:
+ try:
+ conn.commit()
+ except:
+ pass
db.return_connection(conn)
def destroy(self):
@@ -150,8 +190,8 @@ class UserSession(object):
cur.execute("update codeq_user set gui_lang = %s, robot_address = %s where id = %s", (self.settings['gui_lang'], self.settings['robot_address'], self.uid))
finally:
cur.close()
- finally:
conn.commit()
+ finally:
db.return_connection(conn)
def load_language_session(self, problem_id):
@@ -178,7 +218,10 @@ class UserSession(object):
finally:
cur.close()
finally:
- conn.commit()
+ try:
+ conn.commit()
+ except:
+ pass
db.return_connection(conn)
def end_language_session(self):
@@ -209,7 +252,10 @@ class UserSession(object):
finally:
cur.close()
finally:
- conn.commit()
+ try:
+ conn.commit()
+ except:
+ pass
db.return_connection(conn)
def update_solution(self, problem_id, trace, solution):
@@ -257,8 +303,8 @@ class UserSession(object):
raise PasswordChangeFailed('Password change failed')
finally:
cur.close()
- finally:
conn.commit()
+ finally:
db.return_connection(conn)
def get_stat(self):