Skip to content
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

To do fixes #1818 #1974

Merged
2 changes: 2 additions & 0 deletions .github/workflows/python-flake8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ on:
branches:
- develop
- stable
- GSOC2023-NilupulManodya
pull_request:
branches:
- develop
- stable
- GSOC2023-NilupulManodya

jobs:
lint:
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*.pyc
*.swp
*.patch
idp.subject.*
*~
mslib/mss_config.py
mslib/performance/data/
Expand Down
18 changes: 9 additions & 9 deletions docs/conf_sso_test_msscolab.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Configuration MSS Colab Server with Testing IDP for SSO
Configuration MSS Colab Server with Testing IdP for SSO
=======================================================
Testing IDP (`mslib/idp`) is designed specifically for testing the Single Sign-On (SSO) process using PySAML2.

nilupulmanodya marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -27,11 +27,11 @@ Before getting started, you should correctly activate the environments, set the
Generate Keys, Certificates, and backend_saml files
---------------------------------------------------

This involves generating both .key files and .crt files for both the Identity provider and mscolab server and backend_saml.yaml file.
This involves generating both `.key` files and `.crt` files for both the Identity provider and mscolab server and `backend_saml.yaml` file.

Before running the command make sure to set
`USE_SAML2 = False`
In some cases, if you set `USE_SAML2 = True` without certificates, this will not execute. So, make sure to set `USE_SAML2 = False` before executing the command.
If you set `USE_SAML2 = True` without keys and certificates, this will not execute. So, make sure to set `USE_SAML2 = False` before executing the command.

Then you can generate files, simply by running,

Expand All @@ -42,7 +42,7 @@ Then you can generate files, simply by running,
Enable USE_SAML2
----------------

To enable saml2 based login (identity provider-based login), set `USE_SAML2 = True` in the `mslib/mscolab/conf.py` file of the MSS Colab server.
To enable SAML2-based login (identity provider-based login), set `USE_SAML2 = True` in the `mslib/mscolab/conf.py` file of the MSS Colab server.

nilupulmanodya marked this conversation as resolved.
Show resolved Hide resolved
After setting the `USE_SAML2`, the next step is to add the `CONFIGURED_IDPS` dictionary. This dictionary should include keys for each enabled Identity Provider, represented by `idp_identity_name`, and their corresponding `idp_name`. Once this dictionary is set up, it should be used to update various functionalities of the mscolab server, such as the SAML2Client config .yml file, ensuring proper integration with the enabled IDPs.

Expand All @@ -52,15 +52,15 @@ Generate metadata files

This involves generating necessary metadata files for both the identity provider and the service provider. You can generate them by simply running the appropriate command.

Before executing this, you should set `USE_SAML2=True` as described in the third step(USE_SAML2).
Before executing this, you should set `USE_SAML2=True` as described in the third step(Enable USE_SAML2).

`$ python mslib/mscolab/mscolab.py sso_conf --init_sso_metadata`

nilupulmanodya marked this conversation as resolved.
Show resolved Hide resolved

Start Identity provider
-----------------------

Once you setted certificates and metada files you can start mscolab server and local identity provider. To start local identity provider, simpy execute
Once you set certificates and metada files you can start mscolab server and local identity provider. To start local identity provider, simply execute

`$ python mslib/idp/idp.py idp_conf`

nilupulmanodya marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -70,7 +70,7 @@ Start the mscolab Server

Before Starting the mscolab server, make sure to do necessary database migrations.

When this is the first time you setup a mscolab server, you have to initialize the database by
When this is the first time you setup a mscolab server, you have to initialize the database by

`$ python mslib/mscolab/mscolab.py db --init`

nilupulmanodya marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -79,14 +79,14 @@ When this is the first time you setup a mscolab server, you have to initialize t

https://mss.readthedocs.io/en/stable/mscolab.html#data-base-migration

When migrations done, you can start mscolab server by.
When migrations finished, you can start mscolab server using the following command:
`$ python mslib/mscolab/mscolab.py start`


Testing Single Sign-On (SSO) process
------------------------------------

* Once you have successfully launched the server and identity provider, you can begin testing the Single Sign-On (SSO) process.
* Start MSS PyQT application `$ python mslib/msui/msui.py`.
* Start MSS PyQt application `$ python mslib/msui/msui.py`.
* Login with identity provider through Qt Client application.
nilupulmanodya marked this conversation as resolved.
Show resolved Hide resolved
* To log in to the mscolab server through the identity provider, you can use the credentials specified in the ``PASSWD`` section of the ``MSS/mslib/idp/idp.py`` file. Look for the relevant section in the file to find the necessary login credentials.
10 changes: 8 additions & 2 deletions mslib/auth_client_sp/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,17 @@ def get_id(self):
return self.id



with app.app_context():
db.create_all()


@login_manager.user_loader
def load_user(user_id):
""" since the user_id is just the primary key of our user table,
use it in the query for the user """
return User.query.get(int(user_id))


with open("mslib/auth_client_sp/saml2_backend.yaml", encoding="utf-8") as fobj:
yaml_data = yaml.safe_load(fobj)

Expand All @@ -94,6 +95,7 @@ def load_user(user_id):

sp = Saml2Client(sp_config)


def rndstr(size=16, alphabet=""):
"""
Returns a string of random ascii characters or digits
Expand Down Expand Up @@ -162,18 +164,21 @@ def login():
print(error)
return Response("An error occurred", status=500)


@app.route("/profile/", methods=["GET"])
@login_required
def profile():
"""Display the user's profile page."""
return render_template("profile.html")


@app.route("/logout/", methods=["GET"])
def logout():
"""Logout the current user and redirect to the index page."""
logout_user()
return redirect(url_for("index"))


@app.route("/acs/post", methods=["POST"])
def acs_post():
"""Handle the SAML authentication response received via POST request."""
Expand All @@ -192,7 +197,7 @@ def acs_post():
db.session.add(user)
db.session.commit()
login_user(user, remember=True)
return redirect(url_for("profile", data={"email":email}))
return redirect(url_for("profile", data={"email": email}))


@app.route("/acs/redirect", methods=["GET"])
Expand All @@ -205,5 +210,6 @@ def acs_redirect():
)
return str(authn_response.ava)


if __name__ == "__main__":
app.run()
4 changes: 3 additions & 1 deletion mslib/auth_client_sp/app/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
"""
import secrets


class DefaultSPSettings:
"""
Default settings for the SP (Service Provider) application.

This class provides default configuration settings for the SP application.
Modify these settings as needed for your specific application requirements.
"""
Expand All @@ -38,4 +39,5 @@ class DefaultSPSettings:
# used to generate and parse tokens
SECRET_KEY = secrets.token_urlsafe(16)


sp_settings = DefaultSPSettings()
17 changes: 8 additions & 9 deletions mslib/idp/idp.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
limitations under the License.
"""
# Additional Info:
# This file is imported from
# https://github.com/IdentityPython/pysaml2/blob/master/example/idp2/idp.py
# and customized as MSS requirements. Pylint has been disabled for this imported file.
# This file is imported from
# https://github.com/IdentityPython/pysaml2/blob/master/example/idp2/idp.py
# and customized as MSS requirements. Pylint has been disabled for this imported file.

# Parts of the code

Expand Down Expand Up @@ -1104,12 +1104,12 @@ def application(environ, start_response):

IDP = server.Server(args.config, cache=Cache())
IDP.ticket = {}

current_directory = os.getcwd()

LOOKUP = TemplateLookup(
directories=[current_directory+"/mslib/idp/templates", current_directory+"/mslib/idp/htdocs"],
module_directory= current_directory+"/mslib/idp/modules",
directories=[current_directory + "/mslib/idp/templates", current_directory + "/mslib/idp/htdocs"],
module_directory=current_directory + "/mslib/idp/modules",
nilupulmanodya marked this conversation as resolved.
Show resolved Hide resolved
input_encoding="utf-8",
output_encoding="utf-8",
)
Expand All @@ -1135,9 +1135,8 @@ def application(environ, start_response):
https = "using HTTPS"
# Creating an SSL context
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
ssl_context.load_cert_chain(CONFIG.SERVER_CERT,
CONFIG.SERVER_KEY)
SRV = WSGIServer(HOST, PORT, application, ssl_context= ssl_context)
ssl_context.load_cert_chain(CONFIG.SERVER_CERT, CONFIG.SERVER_KEY)
SRV = WSGIServer(HOST, PORT, application, ssl_context=ssl_context)

logger.info("Server starting")
print(f"IDP listening on {HOST}:{PORT}{_https}")
Expand Down
30 changes: 13 additions & 17 deletions mslib/idp/idp_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@

XMLSEC_PATH = get_xmlsec_binary()

# CRTs and metadata files can be generated through the mscolab server. if configured that way CRTs DIRs should be same in both IDP and mscolab server.
# CRTs and metadata files can be generated through the mscolab server.
# if configured that way CRTs DIRs should be same in both IDP and mscolab server.
BASE_DIR = os.path.expanduser("~")
DATA_DIR = os.path.join(BASE_DIR, "colabdata")
MSCOLAB_SSO_DIR = os.path.join(DATA_DIR, 'datasso')
Expand All @@ -53,10 +54,12 @@ def full_path(local_file):

return os.path.join(BASEDIR, local_file)


def sso_dir_path(local_file):
"""Return the full path by joining the MSCOLAB_SSO_DIR and local_file."""
return os.path.join(MSCOLAB_SSO_DIR, local_file)


HOST = 'localhost'
PORT = 8088

Expand All @@ -73,14 +76,14 @@ def sso_dir_path(local_file):
CERT_CHAIN = ""
SIGN_ALG = None
DIGEST_ALG = None
#SIGN_ALG = ds.SIG_RSA_SHA512
#DIGEST_ALG = ds.DIGEST_SHA512
# SIGN_ALG = ds.SIG_RSA_SHA512
# DIGEST_ALG = ds.DIGEST_SHA512


CONFIG = {
"entityid": f"{BASE}/idp.xml",
"description": "My IDP",
#"valid_for": 168,
# "valid_for": 168,
"service": {
"aa": {
"endpoints": {
Expand Down Expand Up @@ -133,18 +136,11 @@ def sso_dir_path(local_file):
"policy": {
"default": {
"lifetime": {"minutes": 15},
"attribute_restrictions": None, # means all I have
"attribute_restrictions": None, # means all I have
"name_form": NAME_FORMAT_URI,
#"entity_categories": ["swamid", "edugain"]
# "entity_categories": ["swamid", "edugain"]
},
},
# ToDo refactor, Could we also move the idp/modules to the colabdata? For what are they needed?
# see discussion in https://github.com/Open-MSS/MSS/pull/1818#pullrequestreview-1554358384

# ToDo refactor, Is this token needed ? see discussion
# in https://github.com/Open-MSS/MSS/pull/1818#issuecomment-1658030366

"subject_data": "./idp.subject",
"name_id_format": [NAMEID_FORMAT_TRANSIENT,
NAMEID_FORMAT_PERSISTENT]
},
Expand Down Expand Up @@ -175,7 +171,7 @@ def sso_dir_path(local_file):
# This database holds the map between a subject's local identifier and
# the identifier returned to a SP
"xmlsec_binary": XMLSEC_PATH,
#"attribute_map_dir": "../attributemaps",
# "attribute_map_dir": "../attributemaps",
"logging": {
"version": 1,
"formatters": {
Expand Down Expand Up @@ -207,13 +203,13 @@ def sso_dir_path(local_file):

# Authentication contexts

#(r'verify?(.*)$', do_verify),
# (r'verify?(.*)$', do_verify),

CAS_SERVER = "https://cas.umu.se"
nilupulmanodya marked this conversation as resolved.
Show resolved Hide resolved
CAS_VERIFY = f"{BASE}/verify_cas"
PWD_VERIFY = f"{BASE}/verify_pwd"

AUTHORIZATION = {
"CAS" : {"ACR": "CAS", "WEIGHT": 1, "URL": CAS_VERIFY},
"UserPassword" : {"ACR": "PASSWORD", "WEIGHT": 2, "URL": PWD_VERIFY}
"CAS": {"ACR": "CAS", "WEIGHT": 1, "URL": CAS_VERIFY},
"UserPassword": {"ACR": "PASSWORD", "WEIGHT": 2, "URL": PWD_VERIFY}
}
13 changes: 5 additions & 8 deletions mslib/idp/idp_uwsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
limitations under the License.
"""
# Additional Info:
# This file is imported from
# https://github.com/IdentityPython/pysaml2/blob/master/example/idp2/idp_uwsgi.py
# and customized as MSS requirements. Pylint has been disabled for this imported file.
# This file is imported from
# https://github.com/IdentityPython/pysaml2/blob/master/example/idp2/idp_uwsgi.py
# and customized as MSS requirements. Pylint has been disabled for this imported file.

# Parts of the code

Expand Down Expand Up @@ -75,8 +75,6 @@
from mako.lookup import TemplateLookup


# ToDo refactor, Try to avoid global as much as possible,
# See discussion in https://github.com/Open-MSS/MSS/pull/1818#issuecomment-1658068466
logger = logging.getLogger("saml2.idp")


Expand Down Expand Up @@ -177,7 +175,7 @@ def operation(self, saml_msg, binding):
Performs the SAML operation based on the provided SAML message and binding.
"""
logger.debug("_operation: %s", saml_msg)
if not saml_msg or not "SAMLRequest" in saml_msg:
if not saml_msg or "SAMLRequest" not in saml_msg:
resp = BadRequest("Error parsing request or no request")
return resp(self.environ, self.start_response)
else:
Expand Down Expand Up @@ -530,7 +528,7 @@ def do_authentication(environ, start_response, authn_context, key, redirect_uri)
logger.debug("Do authentication")
auth_info = AUTHN_BROKER.pick(authn_context)

if len(auth_info)>=0:
if len(auth_info) >= 0:
method, reference = auth_info[0]
logger.debug("Authn chosen: %s (ref=%s)", method, reference)
return method(environ, start_response, reference, key, redirect_uri)
Expand Down Expand Up @@ -569,7 +567,6 @@ def verify_username_and_password(dic):
"""
Verifies the username and password stored in the dictionary.
"""
global PASSWD
# verify username and password
if PASSWD[dic["login"][0]] == dic["password"][0]:
return True, dic["login"][0]
Expand Down
11 changes: 6 additions & 5 deletions mslib/mscolab/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,13 @@ class default_mscolab_settings:
# idp settings
CONFIGURED_IDPS = [
{
'idp_identity_name':'localhost_test_idp',
'idp_name':'Testing Identity Provider'
'idp_identity_name': 'localhost_test_idp',
'idp_name': 'Testing Identity Provider'
},
# {'idp_identity_name':'idp_2','idp_name':'idp 2'},
# {'idp_identity_name':'idp_3','idp_name':'idp 3'},
]
# {'idp_identity_name': 'idp_2','idp_name':'idp 2'},
# {'idp_identity_name': 'idp_3','idp_name':'idp 3'},
]


mscolab_settings = default_mscolab_settings()

Expand Down
Loading