CAT-SOOP is a flexible, programmable learning management system based on the Python programming language. https://catsoop.mit.edu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

123 lines
4.4 KiB

  1. # This file is part of CAT-SOOP
  2. # Copyright (c) 2011-2020 by The CAT-SOOP Developers <catsoop-dev@mit.edu>
  3. #
  4. # This program is free software: you can redistribute it and/or modify it under
  5. # the terms of the GNU Affero General Public License as published by the Free
  6. # Software Foundation, either version 3 of the License, or (at your option) any
  7. # later version.
  8. #
  9. # This program is distributed in the hope that it will be useful, but WITHOUT
  10. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  12. # details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. import json
  17. import urllib.parse, urllib.request
  18. def get_logged_in_user(context):
  19. session = context["cs_session_data"]
  20. logintype = context["csm_auth"].get_auth_type_by_name(context, "login")
  21. def generate_token():
  22. return logintype["generate_confirmation_token"](50)
  23. _get_base_url = logintype["_get_base_url"]
  24. # if the session tells us someone is logged in, return their
  25. # information
  26. action = context["cs_form"].get("loginaction", None)
  27. if action == "logout":
  28. context["cs_session_data"] = {}
  29. return {"cs_reload": True}
  30. elif "username" in session:
  31. uname = session["username"]
  32. return {
  33. "username": uname,
  34. "name": session.get("name", uname),
  35. "email": session.get("email", uname),
  36. }
  37. elif action is None:
  38. if context.get("cs_view_without_auth", True):
  39. old_postload = context.get("cs_post_load", None)
  40. def new_postload(context):
  41. if old_postload is not None:
  42. old_postload(context)
  43. if "cs_login_box" in context:
  44. lbox = context["cs_login_box"](context)
  45. else:
  46. lbox = LOGIN_BOX % (
  47. _get_base_url(context),
  48. context["cs_openid_server"],
  49. )
  50. context["cs_content"] = lbox + context["cs_content"]
  51. context["cs_post_load"] = new_postload
  52. return {}
  53. else:
  54. context["cs_handler"] = "passthrough"
  55. context["cs_content_header"] = "Please Log In"
  56. context["cs_content"] = LOGIN_PAGE % (
  57. _get_base_url(context),
  58. context["cs_openid_server"],
  59. )
  60. return {"cs_render_now": True}
  61. elif action == "login":
  62. redir_url = "%s/_auth/openid_connect/callback" % context["cs_url_root"]
  63. scope = context.get("cs_openid_scope", "openid profile email")
  64. state = generate_token()
  65. nonce = generate_token()
  66. get_data = {
  67. "redirect_uri": redir_url,
  68. "state": state,
  69. "nonce": nonce,
  70. "scope": scope,
  71. "client_id": context.get("cs_openid_client_id", None),
  72. "response_type": "code",
  73. }
  74. openid_url = context.get("cs_openid_server", None)
  75. request = urllib.request.Request(
  76. "%s/.well-known/openid-configuration" % openid_url
  77. )
  78. resp = json.loads(urllib.request.urlopen(request).read())
  79. session["_openid_course"] = context["cs_course"]
  80. session["_openid_path"] = context["cs_path_info"]
  81. session["_openid_nonce"] = nonce
  82. session["_openid_state"] = state
  83. session["_openid_config"] = resp
  84. qstring = urllib.parse.urlencode(get_data)
  85. return {"cs_redirect": "%s?%s" % (resp["authorization_endpoint"], qstring)}
  86. else:
  87. raise Exception("Unknown action: %r" % action)
  88. LOGIN_PAGE = """
  89. <div id="catsoop_login_box">
  90. Access to this page requires logging in via OpenID Connect. Please <a
  91. href="%s?loginaction=login">Log In</a> to continue.<br/>Note that this link
  92. will take you to an external site (<tt>%s</tt>) to authenticate, and then you
  93. will be redirected back to this page.
  94. </div>
  95. """
  96. LOGIN_BOX = """
  97. <div class="response" id="catsoop_login_box">
  98. <b><center>You are not logged in.</center></b><br/>
  99. If you are a current student, please <a href="%s?loginaction=login">Log
  100. In</a> for full access to the web site.<br/>Note that this link will take you to
  101. an external site (<tt>%s</tt>) to authenticate, and then you will be redirected
  102. back to this page.
  103. </div>
  104. """