diff --git a/docs/conf.py b/docs/conf.py index 71e81bbac..111986e36 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # pysaml2 documentation build configuration file, created by # sphinx-quickstart on Mon Aug 24 08:13:41 2009. @@ -11,7 +10,6 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from __future__ import unicode_literals import os @@ -19,33 +17,34 @@ import saml2.version + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) +# sys.path.append(os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage'] +extensions = ["sphinx.ext.autodoc", "sphinx.ext.doctest", "sphinx.ext.coverage"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8' +# source_encoding = 'utf-8' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = 'pysaml2' -copyright = '2010-2011, Roland Hedberg' +project = "pysaml2" +copyright = "2010-2011, Roland Hedberg" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -54,44 +53,44 @@ # The short X.Y version. version = str(saml2.version.version) # The full version, including alpha/beta/rc tags. -release = '' +release = "" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. -#unused_docs = [] +# unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. -exclude_trees = ['_build'] +exclude_trees = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- @@ -99,114 +98,114 @@ # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. html_theme_path = [alabaster.get_path()] -html_theme = 'alabaster' -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +html_theme = "alabaster" +on_rtd = os.environ.get("READTHEDOCS", None) == "True" if on_rtd: # only import and set the theme if we're building docs locally - html_theme = 'sphinx_rtd_theme' + html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_use_modindex = True +# html_use_modindex = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' +# html_file_suffix = '' # Output file base name for HTML help builder. -htmlhelp_basename = 'pysaml2doc' +htmlhelp_basename = "pysaml2doc" # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' +# latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' +# latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ( - 'index', - 'pysaml2.tex', - 'pysaml2 Documentation', - 'Roland Hedberg', - 'manual', + "index", + "pysaml2.tex", + "pysaml2 Documentation", + "Roland Hedberg", + "manual", ), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # Additional stuff for the LaTeX preamble. -#latex_preamble = '' +# latex_preamble = '' # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_use_modindex = True +# latex_use_modindex = True diff --git a/example/attributemaps/saml_uri.py b/example/attributemaps/saml_uri.py index aa02559fd..5f5d91456 100644 --- a/example/attributemaps/saml_uri.py +++ b/example/attributemaps/saml_uri.py @@ -11,189 +11,189 @@ MAP = { "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "fro": { - EDUPERSON_OID + "2": "eduPersonNickname", - EDUPERSON_OID + "9": "eduPersonScopedAffiliation", - EDUPERSON_OID + "11": "eduPersonAssurance", - EDUPERSON_OID + "10": "eduPersonTargetedID", - EDUPERSON_OID + "4": "eduPersonOrgUnitDN", - NOREDUPERSON_OID + "6": "norEduOrgAcronym", - NOREDUPERSON_OID + "7": "norEduOrgUniqueIdentifier", - NOREDUPERSON_OID + "4": "norEduPersonLIN", - EDUPERSON_OID + "1": "eduPersonAffiliation", - NOREDUPERSON_OID + "2": "norEduOrgUnitUniqueNumber", - NETSCAPE_LDAP + "40": "userSMIMECertificate", - NOREDUPERSON_OID + "1": "norEduOrgUniqueNumber", - NETSCAPE_LDAP + "241": "displayName", - UCL_DIR_PILOT + "37": "associatedDomain", - EDUPERSON_OID + "6": "eduPersonPrincipalName", - NOREDUPERSON_OID + "8": "norEduOrgUnitUniqueIdentifier", - NOREDUPERSON_OID + "9": "federationFeideSchemaVersion", - X500ATTR_OID + "53": "deltaRevocationList", - X500ATTR_OID + "52": "supportedAlgorithms", - X500ATTR_OID + "51": "houseIdentifier", - X500ATTR_OID + "50": "uniqueMember", - X500ATTR_OID + "19": "physicalDeliveryOfficeName", - X500ATTR_OID + "18": "postOfficeBox", - X500ATTR_OID + "17": "postalCode", - X500ATTR_OID + "16": "postalAddress", - X500ATTR_OID + "15": "businessCategory", - X500ATTR_OID + "14": "searchGuide", - EDUPERSON_OID + "5": "eduPersonPrimaryAffiliation", - X500ATTR_OID + "12": "title", - X500ATTR_OID + "11": "ou", - X500ATTR_OID + "10": "o", - X500ATTR_OID + "37": "cACertificate", - X500ATTR_OID + "36": "userCertificate", - X500ATTR_OID + "31": "member", - X500ATTR_OID + "30": "supportedApplicationContext", - X500ATTR_OID + "33": "roleOccupant", - X500ATTR_OID + "32": "owner", - NETSCAPE_LDAP + "1": "carLicense", - PKCS_9 + "1": "email", - NETSCAPE_LDAP + "3": "employeeNumber", - NETSCAPE_LDAP + "2": "departmentNumber", - X500ATTR_OID + "39": "certificateRevocationList", - X500ATTR_OID + "38": "authorityRevocationList", - NETSCAPE_LDAP + "216": "userPKCS12", - EDUPERSON_OID + "8": "eduPersonPrimaryOrgUnitDN", - X500ATTR_OID + "9": "street", - X500ATTR_OID + "8": "st", - NETSCAPE_LDAP + "39": "preferredLanguage", - EDUPERSON_OID + "7": "eduPersonEntitlement", - X500ATTR_OID + "2": "knowledgeInformation", - X500ATTR_OID + "7": "l", - X500ATTR_OID + "6": "c", - X500ATTR_OID + "5": "serialNumber", - X500ATTR_OID + "4": "sn", - UCL_DIR_PILOT + "60": "jpegPhoto", - X500ATTR_OID + "65": "pseudonym", - NOREDUPERSON_OID + "5": "norEduPersonNIN", - UCL_DIR_PILOT + "3": "mail", - UCL_DIR_PILOT + "25": "dc", - X500ATTR_OID + "40": "crossCertificatePair", - X500ATTR_OID + "42": "givenName", - X500ATTR_OID + "43": "initials", - X500ATTR_OID + "44": "generationQualifier", - X500ATTR_OID + "45": "x500UniqueIdentifier", - X500ATTR_OID + "46": "dnQualifier", - X500ATTR_OID + "47": "enhancedSearchGuide", - X500ATTR_OID + "48": "protocolInformation", - X500ATTR_OID + "54": "dmdName", - NETSCAPE_LDAP + "4": "employeeType", - X500ATTR_OID + "22": "teletexTerminalIdentifier", - X500ATTR_OID + "23": "facsimileTelephoneNumber", - X500ATTR_OID + "20": "telephoneNumber", - X500ATTR_OID + "21": "telexNumber", - X500ATTR_OID + "26": "registeredAddress", - X500ATTR_OID + "27": "destinationIndicator", - X500ATTR_OID + "24": "x121Address", - X500ATTR_OID + "25": "internationaliSDNNumber", - X500ATTR_OID + "28": "preferredDeliveryMethod", - X500ATTR_OID + "29": "presentationAddress", - EDUPERSON_OID + "3": "eduPersonOrgDN", - NOREDUPERSON_OID + "3": "norEduPersonBirthDate", - UMICH + "57": "labeledURI", - UCL_DIR_PILOT + "1": "uid", + f"{EDUPERSON_OID}2": "eduPersonNickname", + f"{EDUPERSON_OID}9": "eduPersonScopedAffiliation", + f"{EDUPERSON_OID}11": "eduPersonAssurance", + f"{EDUPERSON_OID}10": "eduPersonTargetedID", + f"{EDUPERSON_OID}4": "eduPersonOrgUnitDN", + f"{NOREDUPERSON_OID}6": "norEduOrgAcronym", + f"{NOREDUPERSON_OID}7": "norEduOrgUniqueIdentifier", + f"{NOREDUPERSON_OID}4": "norEduPersonLIN", + f"{EDUPERSON_OID}1": "eduPersonAffiliation", + f"{NOREDUPERSON_OID}2": "norEduOrgUnitUniqueNumber", + f"{NETSCAPE_LDAP}40": "userSMIMECertificate", + f"{NOREDUPERSON_OID}1": "norEduOrgUniqueNumber", + f"{NETSCAPE_LDAP}241": "displayName", + f"{UCL_DIR_PILOT}37": "associatedDomain", + f"{EDUPERSON_OID}6": "eduPersonPrincipalName", + f"{NOREDUPERSON_OID}8": "norEduOrgUnitUniqueIdentifier", + f"{NOREDUPERSON_OID}9": "federationFeideSchemaVersion", + f"{X500ATTR_OID}53": "deltaRevocationList", + f"{X500ATTR_OID}52": "supportedAlgorithms", + f"{X500ATTR_OID}51": "houseIdentifier", + f"{X500ATTR_OID}50": "uniqueMember", + f"{X500ATTR_OID}19": "physicalDeliveryOfficeName", + f"{X500ATTR_OID}18": "postOfficeBox", + f"{X500ATTR_OID}17": "postalCode", + f"{X500ATTR_OID}16": "postalAddress", + f"{X500ATTR_OID}15": "businessCategory", + f"{X500ATTR_OID}14": "searchGuide", + f"{EDUPERSON_OID}5": "eduPersonPrimaryAffiliation", + f"{X500ATTR_OID}12": "title", + f"{X500ATTR_OID}11": "ou", + f"{X500ATTR_OID}10": "o", + f"{X500ATTR_OID}37": "cACertificate", + f"{X500ATTR_OID}36": "userCertificate", + f"{X500ATTR_OID}31": "member", + f"{X500ATTR_OID}30": "supportedApplicationContext", + f"{X500ATTR_OID}33": "roleOccupant", + f"{X500ATTR_OID}32": "owner", + f"{NETSCAPE_LDAP}1": "carLicense", + f"{PKCS_9}1": "email", + f"{NETSCAPE_LDAP}3": "employeeNumber", + f"{NETSCAPE_LDAP}2": "departmentNumber", + f"{X500ATTR_OID}39": "certificateRevocationList", + f"{X500ATTR_OID}38": "authorityRevocationList", + f"{NETSCAPE_LDAP}216": "userPKCS12", + f"{EDUPERSON_OID}8": "eduPersonPrimaryOrgUnitDN", + f"{X500ATTR_OID}9": "street", + f"{X500ATTR_OID}8": "st", + f"{NETSCAPE_LDAP}39": "preferredLanguage", + f"{EDUPERSON_OID}7": "eduPersonEntitlement", + f"{X500ATTR_OID}2": "knowledgeInformation", + f"{X500ATTR_OID}7": "l", + f"{X500ATTR_OID}6": "c", + f"{X500ATTR_OID}5": "serialNumber", + f"{X500ATTR_OID}4": "sn", + f"{UCL_DIR_PILOT}60": "jpegPhoto", + f"{X500ATTR_OID}65": "pseudonym", + f"{NOREDUPERSON_OID}5": "norEduPersonNIN", + f"{UCL_DIR_PILOT}3": "mail", + f"{UCL_DIR_PILOT}25": "dc", + f"{X500ATTR_OID}40": "crossCertificatePair", + f"{X500ATTR_OID}42": "givenName", + f"{X500ATTR_OID}43": "initials", + f"{X500ATTR_OID}44": "generationQualifier", + f"{X500ATTR_OID}45": "x500UniqueIdentifier", + f"{X500ATTR_OID}46": "dnQualifier", + f"{X500ATTR_OID}47": "enhancedSearchGuide", + f"{X500ATTR_OID}48": "protocolInformation", + f"{X500ATTR_OID}54": "dmdName", + f"{NETSCAPE_LDAP}4": "employeeType", + f"{X500ATTR_OID}22": "teletexTerminalIdentifier", + f"{X500ATTR_OID}23": "facsimileTelephoneNumber", + f"{X500ATTR_OID}20": "telephoneNumber", + f"{X500ATTR_OID}21": "telexNumber", + f"{X500ATTR_OID}26": "registeredAddress", + f"{X500ATTR_OID}27": "destinationIndicator", + f"{X500ATTR_OID}24": "x121Address", + f"{X500ATTR_OID}25": "internationaliSDNNumber", + f"{X500ATTR_OID}28": "preferredDeliveryMethod", + f"{X500ATTR_OID}29": "presentationAddress", + f"{EDUPERSON_OID}3": "eduPersonOrgDN", + f"{NOREDUPERSON_OID}3": "norEduPersonBirthDate", + f"{UMICH}57": "labeledURI", + f"{UCL_DIR_PILOT}1": "uid", }, "to": { - "roleOccupant": X500ATTR_OID + "33", - "gn": X500ATTR_OID + "42", - "norEduPersonNIN": NOREDUPERSON_OID + "5", - "title": X500ATTR_OID + "12", - "facsimileTelephoneNumber": X500ATTR_OID + "23", - "mail": UCL_DIR_PILOT + "3", - "postOfficeBox": X500ATTR_OID + "18", - "fax": X500ATTR_OID + "23", - "telephoneNumber": X500ATTR_OID + "20", - "norEduPersonBirthDate": NOREDUPERSON_OID + "3", - "rfc822Mailbox": UCL_DIR_PILOT + "3", - "dc": UCL_DIR_PILOT + "25", - "countryName": X500ATTR_OID + "6", - "emailAddress": PKCS_9 + "1", - "employeeNumber": NETSCAPE_LDAP + "3", - "organizationName": X500ATTR_OID + "10", - "eduPersonAssurance": EDUPERSON_OID + "11", - "norEduOrgAcronym": NOREDUPERSON_OID + "6", - "registeredAddress": X500ATTR_OID + "26", - "physicalDeliveryOfficeName": X500ATTR_OID + "19", - "associatedDomain": UCL_DIR_PILOT + "37", - "l": X500ATTR_OID + "7", - "stateOrProvinceName": X500ATTR_OID + "8", - "federationFeideSchemaVersion": NOREDUPERSON_OID + "9", - "pkcs9email": PKCS_9 + "1", - "givenName": X500ATTR_OID + "42", - "givenname": X500ATTR_OID + "42", - "x500UniqueIdentifier": X500ATTR_OID + "45", - "eduPersonNickname": EDUPERSON_OID + "2", - "houseIdentifier": X500ATTR_OID + "51", - "street": X500ATTR_OID + "9", - "supportedAlgorithms": X500ATTR_OID + "52", - "preferredLanguage": NETSCAPE_LDAP + "39", - "postalAddress": X500ATTR_OID + "16", - "email": PKCS_9 + "1", - "norEduOrgUnitUniqueIdentifier": NOREDUPERSON_OID + "8", - "eduPersonPrimaryOrgUnitDN": EDUPERSON_OID + "8", - "c": X500ATTR_OID + "6", - "teletexTerminalIdentifier": X500ATTR_OID + "22", - "o": X500ATTR_OID + "10", - "cACertificate": X500ATTR_OID + "37", - "telexNumber": X500ATTR_OID + "21", - "ou": X500ATTR_OID + "11", - "initials": X500ATTR_OID + "43", - "eduPersonOrgUnitDN": EDUPERSON_OID + "4", - "deltaRevocationList": X500ATTR_OID + "53", - "norEduPersonLIN": NOREDUPERSON_OID + "4", - "supportedApplicationContext": X500ATTR_OID + "30", - "eduPersonEntitlement": EDUPERSON_OID + "7", - "generationQualifier": X500ATTR_OID + "44", - "eduPersonAffiliation": EDUPERSON_OID + "1", - "eduPersonPrincipalName": EDUPERSON_OID + "6", - "edupersonprincipalname": EDUPERSON_OID + "6", - "localityName": X500ATTR_OID + "7", - "owner": X500ATTR_OID + "32", - "norEduOrgUnitUniqueNumber": NOREDUPERSON_OID + "2", - "searchGuide": X500ATTR_OID + "14", - "certificateRevocationList": X500ATTR_OID + "39", - "organizationalUnitName": X500ATTR_OID + "11", - "userCertificate": X500ATTR_OID + "36", - "preferredDeliveryMethod": X500ATTR_OID + "28", - "internationaliSDNNumber": X500ATTR_OID + "25", - "uniqueMember": X500ATTR_OID + "50", - "departmentNumber": NETSCAPE_LDAP + "2", - "enhancedSearchGuide": X500ATTR_OID + "47", - "userPKCS12": NETSCAPE_LDAP + "216", - "eduPersonTargetedID": EDUPERSON_OID + "10", - "norEduOrgUniqueNumber": NOREDUPERSON_OID + "1", - "x121Address": X500ATTR_OID + "24", - "destinationIndicator": X500ATTR_OID + "27", - "eduPersonPrimaryAffiliation": EDUPERSON_OID + "5", - "surname": X500ATTR_OID + "4", - "jpegPhoto": UCL_DIR_PILOT + "60", - "eduPersonScopedAffiliation": EDUPERSON_OID + "9", - "edupersonscopedaffiliation": EDUPERSON_OID + "9", - "protocolInformation": X500ATTR_OID + "48", - "knowledgeInformation": X500ATTR_OID + "2", - "employeeType": NETSCAPE_LDAP + "4", - "userSMIMECertificate": NETSCAPE_LDAP + "40", - "member": X500ATTR_OID + "31", - "streetAddress": X500ATTR_OID + "9", - "dmdName": X500ATTR_OID + "54", - "postalCode": X500ATTR_OID + "17", - "pseudonym": X500ATTR_OID + "65", - "dnQualifier": X500ATTR_OID + "46", - "crossCertificatePair": X500ATTR_OID + "40", - "eduPersonOrgDN": EDUPERSON_OID + "3", - "authorityRevocationList": X500ATTR_OID + "38", - "displayName": NETSCAPE_LDAP + "241", - "businessCategory": X500ATTR_OID + "15", - "serialNumber": X500ATTR_OID + "5", - "norEduOrgUniqueIdentifier": NOREDUPERSON_OID + "7", - "st": X500ATTR_OID + "8", - "carLicense": NETSCAPE_LDAP + "1", - "presentationAddress": X500ATTR_OID + "29", - "sn": X500ATTR_OID + "4", - "domainComponent": UCL_DIR_PILOT + "25", - "labeledURI": UMICH + "57", - "uid": UCL_DIR_PILOT + "1", + "roleOccupant": f"{X500ATTR_OID}33", + "gn": f"{X500ATTR_OID}42", + "norEduPersonNIN": f"{NOREDUPERSON_OID}5", + "title": f"{X500ATTR_OID}12", + "facsimileTelephoneNumber": f"{X500ATTR_OID}23", + "mail": f"{UCL_DIR_PILOT}3", + "postOfficeBox": f"{X500ATTR_OID}18", + "fax": f"{X500ATTR_OID}23", + "telephoneNumber": f"{X500ATTR_OID}20", + "norEduPersonBirthDate": f"{NOREDUPERSON_OID}3", + "rfc822Mailbox": f"{UCL_DIR_PILOT}3", + "dc": f"{UCL_DIR_PILOT}25", + "countryName": f"{X500ATTR_OID}6", + "emailAddress": f"{PKCS_9}1", + "employeeNumber": f"{NETSCAPE_LDAP}3", + "organizationName": f"{X500ATTR_OID}10", + "eduPersonAssurance": f"{EDUPERSON_OID}11", + "norEduOrgAcronym": f"{NOREDUPERSON_OID}6", + "registeredAddress": f"{X500ATTR_OID}26", + "physicalDeliveryOfficeName": f"{X500ATTR_OID}19", + "associatedDomain": f"{UCL_DIR_PILOT}37", + "l": f"{X500ATTR_OID}7", + "stateOrProvinceName": f"{X500ATTR_OID}8", + "federationFeideSchemaVersion": f"{NOREDUPERSON_OID}9", + "pkcs9email": f"{PKCS_9}1", + "givenName": f"{X500ATTR_OID}42", + "givenname": f"{X500ATTR_OID}42", + "x500UniqueIdentifier": f"{X500ATTR_OID}45", + "eduPersonNickname": f"{EDUPERSON_OID}2", + "houseIdentifier": f"{X500ATTR_OID}51", + "street": f"{X500ATTR_OID}9", + "supportedAlgorithms": f"{X500ATTR_OID}52", + "preferredLanguage": f"{NETSCAPE_LDAP}39", + "postalAddress": f"{X500ATTR_OID}16", + "email": f"{PKCS_9}1", + "norEduOrgUnitUniqueIdentifier": f"{NOREDUPERSON_OID}8", + "eduPersonPrimaryOrgUnitDN": f"{EDUPERSON_OID}8", + "c": f"{X500ATTR_OID}6", + "teletexTerminalIdentifier": f"{X500ATTR_OID}22", + "o": f"{X500ATTR_OID}10", + "cACertificate": f"{X500ATTR_OID}37", + "telexNumber": f"{X500ATTR_OID}21", + "ou": f"{X500ATTR_OID}11", + "initials": f"{X500ATTR_OID}43", + "eduPersonOrgUnitDN": f"{EDUPERSON_OID}4", + "deltaRevocationList": f"{X500ATTR_OID}53", + "norEduPersonLIN": f"{NOREDUPERSON_OID}4", + "supportedApplicationContext": f"{X500ATTR_OID}30", + "eduPersonEntitlement": f"{EDUPERSON_OID}7", + "generationQualifier": f"{X500ATTR_OID}44", + "eduPersonAffiliation": f"{EDUPERSON_OID}1", + "eduPersonPrincipalName": f"{EDUPERSON_OID}6", + "edupersonprincipalname": f"{EDUPERSON_OID}6", + "localityName": f"{X500ATTR_OID}7", + "owner": f"{X500ATTR_OID}32", + "norEduOrgUnitUniqueNumber": f"{NOREDUPERSON_OID}2", + "searchGuide": f"{X500ATTR_OID}14", + "certificateRevocationList": f"{X500ATTR_OID}39", + "organizationalUnitName": f"{X500ATTR_OID}11", + "userCertificate": f"{X500ATTR_OID}36", + "preferredDeliveryMethod": f"{X500ATTR_OID}28", + "internationaliSDNNumber": f"{X500ATTR_OID}25", + "uniqueMember": f"{X500ATTR_OID}50", + "departmentNumber": f"{NETSCAPE_LDAP}2", + "enhancedSearchGuide": f"{X500ATTR_OID}47", + "userPKCS12": f"{NETSCAPE_LDAP}216", + "eduPersonTargetedID": f"{EDUPERSON_OID}10", + "norEduOrgUniqueNumber": f"{NOREDUPERSON_OID}1", + "x121Address": f"{X500ATTR_OID}24", + "destinationIndicator": f"{X500ATTR_OID}27", + "eduPersonPrimaryAffiliation": f"{EDUPERSON_OID}5", + "surname": f"{X500ATTR_OID}4", + "jpegPhoto": f"{UCL_DIR_PILOT}60", + "eduPersonScopedAffiliation": f"{EDUPERSON_OID}9", + "edupersonscopedaffiliation": f"{EDUPERSON_OID}9", + "protocolInformation": f"{X500ATTR_OID}48", + "knowledgeInformation": f"{X500ATTR_OID}2", + "employeeType": f"{NETSCAPE_LDAP}4", + "userSMIMECertificate": f"{NETSCAPE_LDAP}40", + "member": f"{X500ATTR_OID}31", + "streetAddress": f"{X500ATTR_OID}9", + "dmdName": f"{X500ATTR_OID}54", + "postalCode": f"{X500ATTR_OID}17", + "pseudonym": f"{X500ATTR_OID}65", + "dnQualifier": f"{X500ATTR_OID}46", + "crossCertificatePair": f"{X500ATTR_OID}40", + "eduPersonOrgDN": f"{EDUPERSON_OID}3", + "authorityRevocationList": f"{X500ATTR_OID}38", + "displayName": f"{NETSCAPE_LDAP}241", + "businessCategory": f"{X500ATTR_OID}15", + "serialNumber": f"{X500ATTR_OID}5", + "norEduOrgUniqueIdentifier": f"{NOREDUPERSON_OID}7", + "st": f"{X500ATTR_OID}8", + "carLicense": f"{NETSCAPE_LDAP}1", + "presentationAddress": f"{X500ATTR_OID}29", + "sn": f"{X500ATTR_OID}4", + "domainComponent": f"{UCL_DIR_PILOT}25", + "labeledURI": f"{UMICH}57", + "uid": f"{UCL_DIR_PILOT}1", }, } diff --git a/example/attributemaps/shibboleth_uri.py b/example/attributemaps/shibboleth_uri.py index 30b31503d..992a2219e 100644 --- a/example/attributemaps/shibboleth_uri.py +++ b/example/attributemaps/shibboleth_uri.py @@ -9,182 +9,182 @@ MAP = { "identifier": "urn:mace:shibboleth:1.0:attributeNamespace:uri", "fro": { - EDUPERSON_OID + "2": "eduPersonNickname", - EDUPERSON_OID + "9": "eduPersonScopedAffiliation", - EDUPERSON_OID + "11": "eduPersonAssurance", - EDUPERSON_OID + "10": "eduPersonTargetedID", - EDUPERSON_OID + "4": "eduPersonOrgUnitDN", - NOREDUPERSON_OID + "6": "norEduOrgAcronym", - NOREDUPERSON_OID + "7": "norEduOrgUniqueIdentifier", - NOREDUPERSON_OID + "4": "norEduPersonLIN", - EDUPERSON_OID + "1": "eduPersonAffiliation", - NOREDUPERSON_OID + "2": "norEduOrgUnitUniqueNumber", - NETSCAPE_LDAP + "40": "userSMIMECertificate", - NOREDUPERSON_OID + "1": "norEduOrgUniqueNumber", - NETSCAPE_LDAP + "241": "displayName", - UCL_DIR_PILOT + "37": "associatedDomain", - EDUPERSON_OID + "6": "eduPersonPrincipalName", - NOREDUPERSON_OID + "8": "norEduOrgUnitUniqueIdentifier", - NOREDUPERSON_OID + "9": "federationFeideSchemaVersion", - X500ATTR + "53": "deltaRevocationList", - X500ATTR + "52": "supportedAlgorithms", - X500ATTR + "51": "houseIdentifier", - X500ATTR + "50": "uniqueMember", - X500ATTR + "19": "physicalDeliveryOfficeName", - X500ATTR + "18": "postOfficeBox", - X500ATTR + "17": "postalCode", - X500ATTR + "16": "postalAddress", - X500ATTR + "15": "businessCategory", - X500ATTR + "14": "searchGuide", - EDUPERSON_OID + "5": "eduPersonPrimaryAffiliation", - X500ATTR + "12": "title", - X500ATTR + "11": "ou", - X500ATTR + "10": "o", - X500ATTR + "37": "cACertificate", - X500ATTR + "36": "userCertificate", - X500ATTR + "31": "member", - X500ATTR + "30": "supportedApplicationContext", - X500ATTR + "33": "roleOccupant", - X500ATTR + "32": "owner", - NETSCAPE_LDAP + "1": "carLicense", - PKCS_9 + "1": "email", - NETSCAPE_LDAP + "3": "employeeNumber", - NETSCAPE_LDAP + "2": "departmentNumber", - X500ATTR + "39": "certificateRevocationList", - X500ATTR + "38": "authorityRevocationList", - NETSCAPE_LDAP + "216": "userPKCS12", - EDUPERSON_OID + "8": "eduPersonPrimaryOrgUnitDN", - X500ATTR + "9": "street", - X500ATTR + "8": "st", - NETSCAPE_LDAP + "39": "preferredLanguage", - EDUPERSON_OID + "7": "eduPersonEntitlement", - X500ATTR + "2": "knowledgeInformation", - X500ATTR + "7": "l", - X500ATTR + "6": "c", - X500ATTR + "5": "serialNumber", - X500ATTR + "4": "sn", - UCL_DIR_PILOT + "60": "jpegPhoto", - X500ATTR + "65": "pseudonym", - NOREDUPERSON_OID + "5": "norEduPersonNIN", - UCL_DIR_PILOT + "3": "mail", - UCL_DIR_PILOT + "25": "dc", - X500ATTR + "40": "crossCertificatePair", - X500ATTR + "42": "givenName", - X500ATTR + "43": "initials", - X500ATTR + "44": "generationQualifier", - X500ATTR + "45": "x500UniqueIdentifier", - X500ATTR + "46": "dnQualifier", - X500ATTR + "47": "enhancedSearchGuide", - X500ATTR + "48": "protocolInformation", - X500ATTR + "54": "dmdName", - NETSCAPE_LDAP + "4": "employeeType", - X500ATTR + "22": "teletexTerminalIdentifier", - X500ATTR + "23": "facsimileTelephoneNumber", - X500ATTR + "20": "telephoneNumber", - X500ATTR + "21": "telexNumber", - X500ATTR + "26": "registeredAddress", - X500ATTR + "27": "destinationIndicator", - X500ATTR + "24": "x121Address", - X500ATTR + "25": "internationaliSDNNumber", - X500ATTR + "28": "preferredDeliveryMethod", - X500ATTR + "29": "presentationAddress", - EDUPERSON_OID + "3": "eduPersonOrgDN", - NOREDUPERSON_OID + "3": "norEduPersonBirthDate", + f"{EDUPERSON_OID}2": "eduPersonNickname", + f"{EDUPERSON_OID}9": "eduPersonScopedAffiliation", + f"{EDUPERSON_OID}11": "eduPersonAssurance", + f"{EDUPERSON_OID}10": "eduPersonTargetedID", + f"{EDUPERSON_OID}4": "eduPersonOrgUnitDN", + f"{NOREDUPERSON_OID}6": "norEduOrgAcronym", + f"{NOREDUPERSON_OID}7": "norEduOrgUniqueIdentifier", + f"{NOREDUPERSON_OID}4": "norEduPersonLIN", + f"{EDUPERSON_OID}1": "eduPersonAffiliation", + f"{NOREDUPERSON_OID}2": "norEduOrgUnitUniqueNumber", + f"{NETSCAPE_LDAP}40": "userSMIMECertificate", + f"{NOREDUPERSON_OID}1": "norEduOrgUniqueNumber", + f"{NETSCAPE_LDAP}241": "displayName", + f"{UCL_DIR_PILOT}37": "associatedDomain", + f"{EDUPERSON_OID}6": "eduPersonPrincipalName", + f"{NOREDUPERSON_OID}8": "norEduOrgUnitUniqueIdentifier", + f"{NOREDUPERSON_OID}9": "federationFeideSchemaVersion", + f"{X500ATTR}53": "deltaRevocationList", + f"{X500ATTR}52": "supportedAlgorithms", + f"{X500ATTR}51": "houseIdentifier", + f"{X500ATTR}50": "uniqueMember", + f"{X500ATTR}19": "physicalDeliveryOfficeName", + f"{X500ATTR}18": "postOfficeBox", + f"{X500ATTR}17": "postalCode", + f"{X500ATTR}16": "postalAddress", + f"{X500ATTR}15": "businessCategory", + f"{X500ATTR}14": "searchGuide", + f"{EDUPERSON_OID}5": "eduPersonPrimaryAffiliation", + f"{X500ATTR}12": "title", + f"{X500ATTR}11": "ou", + f"{X500ATTR}10": "o", + f"{X500ATTR}37": "cACertificate", + f"{X500ATTR}36": "userCertificate", + f"{X500ATTR}31": "member", + f"{X500ATTR}30": "supportedApplicationContext", + f"{X500ATTR}33": "roleOccupant", + f"{X500ATTR}32": "owner", + f"{NETSCAPE_LDAP}1": "carLicense", + f"{PKCS_9}1": "email", + f"{NETSCAPE_LDAP}3": "employeeNumber", + f"{NETSCAPE_LDAP}2": "departmentNumber", + f"{X500ATTR}39": "certificateRevocationList", + f"{X500ATTR}38": "authorityRevocationList", + f"{NETSCAPE_LDAP}216": "userPKCS12", + f"{EDUPERSON_OID}8": "eduPersonPrimaryOrgUnitDN", + f"{X500ATTR}9": "street", + f"{X500ATTR}8": "st", + f"{NETSCAPE_LDAP}39": "preferredLanguage", + f"{EDUPERSON_OID}7": "eduPersonEntitlement", + f"{X500ATTR}2": "knowledgeInformation", + f"{X500ATTR}7": "l", + f"{X500ATTR}6": "c", + f"{X500ATTR}5": "serialNumber", + f"{X500ATTR}4": "sn", + f"{UCL_DIR_PILOT}60": "jpegPhoto", + f"{X500ATTR}65": "pseudonym", + f"{NOREDUPERSON_OID}5": "norEduPersonNIN", + f"{UCL_DIR_PILOT}3": "mail", + f"{UCL_DIR_PILOT}25": "dc", + f"{X500ATTR}40": "crossCertificatePair", + f"{X500ATTR}42": "givenName", + f"{X500ATTR}43": "initials", + f"{X500ATTR}44": "generationQualifier", + f"{X500ATTR}45": "x500UniqueIdentifier", + f"{X500ATTR}46": "dnQualifier", + f"{X500ATTR}47": "enhancedSearchGuide", + f"{X500ATTR}48": "protocolInformation", + f"{X500ATTR}54": "dmdName", + f"{NETSCAPE_LDAP}4": "employeeType", + f"{X500ATTR}22": "teletexTerminalIdentifier", + f"{X500ATTR}23": "facsimileTelephoneNumber", + f"{X500ATTR}20": "telephoneNumber", + f"{X500ATTR}21": "telexNumber", + f"{X500ATTR}26": "registeredAddress", + f"{X500ATTR}27": "destinationIndicator", + f"{X500ATTR}24": "x121Address", + f"{X500ATTR}25": "internationaliSDNNumber", + f"{X500ATTR}28": "preferredDeliveryMethod", + f"{X500ATTR}29": "presentationAddress", + f"{EDUPERSON_OID}3": "eduPersonOrgDN", + f"{NOREDUPERSON_OID}3": "norEduPersonBirthDate", }, "to": { - "roleOccupant": X500ATTR + "33", - "gn": X500ATTR + "42", - "norEduPersonNIN": NOREDUPERSON_OID + "5", - "title": X500ATTR + "12", - "facsimileTelephoneNumber": X500ATTR + "23", - "mail": UCL_DIR_PILOT + "3", - "postOfficeBox": X500ATTR + "18", - "fax": X500ATTR + "23", - "telephoneNumber": X500ATTR + "20", - "norEduPersonBirthDate": NOREDUPERSON_OID + "3", - "rfc822Mailbox": UCL_DIR_PILOT + "3", - "dc": UCL_DIR_PILOT + "25", - "countryName": X500ATTR + "6", - "emailAddress": PKCS_9 + "1", - "employeeNumber": NETSCAPE_LDAP + "3", - "organizationName": X500ATTR + "10", - "eduPersonAssurance": EDUPERSON_OID + "11", - "norEduOrgAcronym": NOREDUPERSON_OID + "6", - "registeredAddress": X500ATTR + "26", - "physicalDeliveryOfficeName": X500ATTR + "19", - "associatedDomain": UCL_DIR_PILOT + "37", - "l": X500ATTR + "7", - "stateOrProvinceName": X500ATTR + "8", - "federationFeideSchemaVersion": NOREDUPERSON_OID + "9", - "pkcs9email": PKCS_9 + "1", - "givenName": X500ATTR + "42", - "x500UniqueIdentifier": X500ATTR + "45", - "eduPersonNickname": EDUPERSON_OID + "2", - "houseIdentifier": X500ATTR + "51", - "street": X500ATTR + "9", - "supportedAlgorithms": X500ATTR + "52", - "preferredLanguage": NETSCAPE_LDAP + "39", - "postalAddress": X500ATTR + "16", - "email": PKCS_9 + "1", - "norEduOrgUnitUniqueIdentifier": NOREDUPERSON_OID + "8", - "eduPersonPrimaryOrgUnitDN": EDUPERSON_OID + "8", - "c": X500ATTR + "6", - "teletexTerminalIdentifier": X500ATTR + "22", - "o": X500ATTR + "10", - "cACertificate": X500ATTR + "37", - "telexNumber": X500ATTR + "21", - "ou": X500ATTR + "11", - "initials": X500ATTR + "43", - "eduPersonOrgUnitDN": EDUPERSON_OID + "4", - "deltaRevocationList": X500ATTR + "53", - "norEduPersonLIN": NOREDUPERSON_OID + "4", - "supportedApplicationContext": X500ATTR + "30", - "eduPersonEntitlement": EDUPERSON_OID + "7", - "generationQualifier": X500ATTR + "44", - "eduPersonAffiliation": EDUPERSON_OID + "1", - "eduPersonPrincipalName": EDUPERSON_OID + "6", - "localityName": X500ATTR + "7", - "owner": X500ATTR + "32", - "norEduOrgUnitUniqueNumber": NOREDUPERSON_OID + "2", - "searchGuide": X500ATTR + "14", - "certificateRevocationList": X500ATTR + "39", - "organizationalUnitName": X500ATTR + "11", - "userCertificate": X500ATTR + "36", - "preferredDeliveryMethod": X500ATTR + "28", - "internationaliSDNNumber": X500ATTR + "25", - "uniqueMember": X500ATTR + "50", - "departmentNumber": NETSCAPE_LDAP + "2", - "enhancedSearchGuide": X500ATTR + "47", - "userPKCS12": NETSCAPE_LDAP + "216", - "eduPersonTargetedID": EDUPERSON_OID + "10", - "norEduOrgUniqueNumber": NOREDUPERSON_OID + "1", - "x121Address": X500ATTR + "24", - "destinationIndicator": X500ATTR + "27", - "eduPersonPrimaryAffiliation": EDUPERSON_OID + "5", - "surname": X500ATTR + "4", - "jpegPhoto": UCL_DIR_PILOT + "60", - "eduPersonScopedAffiliation": EDUPERSON_OID + "9", - "protocolInformation": X500ATTR + "48", - "knowledgeInformation": X500ATTR + "2", - "employeeType": NETSCAPE_LDAP + "4", - "userSMIMECertificate": NETSCAPE_LDAP + "40", - "member": X500ATTR + "31", - "streetAddress": X500ATTR + "9", - "dmdName": X500ATTR + "54", - "postalCode": X500ATTR + "17", - "pseudonym": X500ATTR + "65", - "dnQualifier": X500ATTR + "46", - "crossCertificatePair": X500ATTR + "40", - "eduPersonOrgDN": EDUPERSON_OID + "3", - "authorityRevocationList": X500ATTR + "38", - "displayName": NETSCAPE_LDAP + "241", - "businessCategory": X500ATTR + "15", - "serialNumber": X500ATTR + "5", - "norEduOrgUniqueIdentifier": NOREDUPERSON_OID + "7", - "st": X500ATTR + "8", - "carLicense": NETSCAPE_LDAP + "1", - "presentationAddress": X500ATTR + "29", - "sn": X500ATTR + "4", - "domainComponent": UCL_DIR_PILOT + "25", + "roleOccupant": f"{X500ATTR}33", + "gn": f"{X500ATTR}42", + "norEduPersonNIN": f"{NOREDUPERSON_OID}5", + "title": f"{X500ATTR}12", + "facsimileTelephoneNumber": f"{X500ATTR}23", + "mail": f"{UCL_DIR_PILOT}3", + "postOfficeBox": f"{X500ATTR}18", + "fax": f"{X500ATTR}23", + "telephoneNumber": f"{X500ATTR}20", + "norEduPersonBirthDate": f"{NOREDUPERSON_OID}3", + "rfc822Mailbox": f"{UCL_DIR_PILOT}3", + "dc": f"{UCL_DIR_PILOT}25", + "countryName": f"{X500ATTR}6", + "emailAddress": f"{PKCS_9}1", + "employeeNumber": f"{NETSCAPE_LDAP}3", + "organizationName": f"{X500ATTR}10", + "eduPersonAssurance": f"{EDUPERSON_OID}11", + "norEduOrgAcronym": f"{NOREDUPERSON_OID}6", + "registeredAddress": f"{X500ATTR}26", + "physicalDeliveryOfficeName": f"{X500ATTR}19", + "associatedDomain": f"{UCL_DIR_PILOT}37", + "l": f"{X500ATTR}7", + "stateOrProvinceName": f"{X500ATTR}8", + "federationFeideSchemaVersion": f"{NOREDUPERSON_OID}9", + "pkcs9email": f"{PKCS_9}1", + "givenName": f"{X500ATTR}42", + "x500UniqueIdentifier": f"{X500ATTR}45", + "eduPersonNickname": f"{EDUPERSON_OID}2", + "houseIdentifier": f"{X500ATTR}51", + "street": f"{X500ATTR}9", + "supportedAlgorithms": f"{X500ATTR}52", + "preferredLanguage": f"{NETSCAPE_LDAP}39", + "postalAddress": f"{X500ATTR}16", + "email": f"{PKCS_9}1", + "norEduOrgUnitUniqueIdentifier": f"{NOREDUPERSON_OID}8", + "eduPersonPrimaryOrgUnitDN": f"{EDUPERSON_OID}8", + "c": f"{X500ATTR}6", + "teletexTerminalIdentifier": f"{X500ATTR}22", + "o": f"{X500ATTR}10", + "cACertificate": f"{X500ATTR}37", + "telexNumber": f"{X500ATTR}21", + "ou": f"{X500ATTR}11", + "initials": f"{X500ATTR}43", + "eduPersonOrgUnitDN": f"{EDUPERSON_OID}4", + "deltaRevocationList": f"{X500ATTR}53", + "norEduPersonLIN": f"{NOREDUPERSON_OID}4", + "supportedApplicationContext": f"{X500ATTR}30", + "eduPersonEntitlement": f"{EDUPERSON_OID}7", + "generationQualifier": f"{X500ATTR}44", + "eduPersonAffiliation": f"{EDUPERSON_OID}1", + "eduPersonPrincipalName": f"{EDUPERSON_OID}6", + "localityName": f"{X500ATTR}7", + "owner": f"{X500ATTR}32", + "norEduOrgUnitUniqueNumber": f"{NOREDUPERSON_OID}2", + "searchGuide": f"{X500ATTR}14", + "certificateRevocationList": f"{X500ATTR}39", + "organizationalUnitName": f"{X500ATTR}11", + "userCertificate": f"{X500ATTR}36", + "preferredDeliveryMethod": f"{X500ATTR}28", + "internationaliSDNNumber": f"{X500ATTR}25", + "uniqueMember": f"{X500ATTR}50", + "departmentNumber": f"{NETSCAPE_LDAP}2", + "enhancedSearchGuide": f"{X500ATTR}47", + "userPKCS12": f"{NETSCAPE_LDAP}216", + "eduPersonTargetedID": f"{EDUPERSON_OID}10", + "norEduOrgUniqueNumber": f"{NOREDUPERSON_OID}1", + "x121Address": f"{X500ATTR}24", + "destinationIndicator": f"{X500ATTR}27", + "eduPersonPrimaryAffiliation": f"{EDUPERSON_OID}5", + "surname": f"{X500ATTR}4", + "jpegPhoto": f"{UCL_DIR_PILOT}60", + "eduPersonScopedAffiliation": f"{EDUPERSON_OID}9", + "protocolInformation": f"{X500ATTR}48", + "knowledgeInformation": f"{X500ATTR}2", + "employeeType": f"{NETSCAPE_LDAP}4", + "userSMIMECertificate": f"{NETSCAPE_LDAP}40", + "member": f"{X500ATTR}31", + "streetAddress": f"{X500ATTR}9", + "dmdName": f"{X500ATTR}54", + "postalCode": f"{X500ATTR}17", + "pseudonym": f"{X500ATTR}65", + "dnQualifier": f"{X500ATTR}46", + "crossCertificatePair": f"{X500ATTR}40", + "eduPersonOrgDN": f"{EDUPERSON_OID}3", + "authorityRevocationList": f"{X500ATTR}38", + "displayName": f"{NETSCAPE_LDAP}241", + "businessCategory": f"{X500ATTR}15", + "serialNumber": f"{X500ATTR}5", + "norEduOrgUniqueIdentifier": f"{NOREDUPERSON_OID}7", + "st": f"{X500ATTR}8", + "carLicense": f"{NETSCAPE_LDAP}1", + "presentationAddress": f"{X500ATTR}29", + "sn": f"{X500ATTR}4", + "domainComponent": f"{UCL_DIR_PILOT}25", }, } diff --git a/example/idp2/idp.py b/example/idp2/idp.py index d8d713992..170136462 100755 --- a/example/idp2/idp.py +++ b/example/idp2/idp.py @@ -2,18 +2,17 @@ import argparse import base64 from hashlib import sha1 +from http.cookies import SimpleCookie import importlib import logging import os import re import time +from urllib.parse import parse_qs from idp_user import EXTRA from idp_user import USERS from mako.lookup import TemplateLookup -import six -from six.moves.http_cookies import SimpleCookie -from six.moves.urllib.parse import parse_qs from saml2 import BINDING_HTTP_ARTIFACT from saml2 import BINDING_HTTP_POST @@ -61,7 +60,7 @@ logger.setLevel(logging.WARNING) -class Cache(object): +class Cache: def __init__(self): self.user2uid = {} self.uid2user = {} @@ -93,7 +92,7 @@ def dict2list_of_tuples(d): # ----------------------------------------------------------------------------- -class Service(object): +class Service: def __init__(self, environ, start_response, user=None): self.environ = environ logger.debug("ENVIRON: %s", environ) @@ -103,7 +102,7 @@ def __init__(self, environ, start_response, user=None): def unpack_redirect(self): if "QUERY_STRING" in self.environ: _qs = self.environ["QUERY_STRING"] - return dict([(k, v[0]) for k, v in parse_qs(_qs).items()]) + return {k: v[0] for k, v in parse_qs(_qs).items()} else: return None @@ -112,7 +111,7 @@ def unpack_post(self): _dict = parse_qs(post_data if isinstance(post_data, str) else post_data.decode("utf-8")) logger.debug("unpack_post:: %s", _dict) try: - return dict([(k, v[0]) for k, v in _dict.items()]) + return {k: v[0] for k, v in _dict.items()} except Exception: return None @@ -323,11 +322,11 @@ def do(self, query, binding_in, relay_state="", encrypt_cert=None, **kwargs): resp_args, _resp = self.verify_request(query, binding_in) except UnknownPrincipal as excp: logger.error("UnknownPrincipal: %s", excp) - resp = ServiceError("UnknownPrincipal: %s" % (excp,)) + resp = ServiceError(f"UnknownPrincipal: {excp}") return resp(self.environ, self.start_response) except UnsupportedBinding as excp: logger.error("UnsupportedBinding: %s", excp) - resp = ServiceError("UnsupportedBinding: %s" % (excp,)) + resp = ServiceError(f"UnsupportedBinding: {excp}") return resp(self.environ, self.start_response) if not _resp: @@ -350,7 +349,7 @@ def do(self, query, binding_in, relay_state="", encrypt_cert=None, **kwargs): ) except Exception as excp: logging.error(exception_trace(excp)) - resp = ServiceError("Exception: %s" % (excp,)) + resp = ServiceError(f"Exception: {excp}") return resp(self.environ, self.start_response) logger.info("AuthNResponse: %s", _resp) @@ -360,7 +359,7 @@ def do(self, query, binding_in, relay_state="", encrypt_cert=None, **kwargs): kwargs = {} http_args = IDP.apply_binding( - self.binding_out, "%s" % _resp, self.destination, relay_state, response=True, **kwargs + self.binding_out, f"{_resp}", self.destination, relay_state, response=True, **kwargs ) logger.debug("HTTPargs: %s", http_args) @@ -566,7 +565,7 @@ def verify_username_and_password(dic): def do_verify(environ, start_response, _): query_str = get_post(environ) - if not isinstance(query_str, six.string_types): + if not isinstance(query_str, str): query_str = query_str.decode("ascii") query = parse_qs(query_str) @@ -588,7 +587,7 @@ def do_verify(environ, start_response, _): kaka = set_cookie("idpauthn", "/", uid, query["authn_reference"][0]) - lox = "%s?id=%s&key=%s" % (query["redirect_uri"][0], uid, query["key"][0]) + lox = f"{query['redirect_uri'][0]}?id={uid}&key={query['key'][0]}" logger.debug("Redirect => %s", lox) resp = Redirect(lox, headers=[kaka], content="text/html") @@ -623,7 +622,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None, **kwargs): req_info = IDP.parse_logout_request(request, binding) except Exception as exc: logger.error("Bad request: %s", exc) - resp = BadRequest("%s" % exc) + resp = BadRequest(f"{exc}") return resp(self.environ, self.start_response) msg = req_info.message @@ -653,10 +652,10 @@ def do(self, request, binding, relay_state="", encrypt_cert=None, **kwargs): response = True try: - hinfo = IDP.apply_binding(binding, "%s" % resp, destination, relay_state, response=response) + hinfo = IDP.apply_binding(binding, f"{resp}", destination, relay_state, response=response) except Exception as exc: logger.error("ServiceError: %s", exc) - resp = ServiceError("%s" % exc) + resp = ServiceError(f"{exc}") return resp(self.environ, self.start_response) # _tlh = dict2list_of_tuples(hinfo["headers"]) @@ -699,7 +698,7 @@ def do(self, query, binding, relay_state="", encrypt_cert=None): _resp = IDP.create_manage_name_id_response(request) # It's using SOAP binding - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % _resp, "", relay_state, response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{_resp}", "", relay_state, response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -721,7 +720,7 @@ def do(self, aid, binding, relay_state="", encrypt_cert=None): resp = NotFound(aid) return resp(self.environ, self.start_response) - hinfo = IDP.apply_binding(BINDING_URI, "%s" % assertion, response=True) + hinfo = IDP.apply_binding(BINDING_URI, f"{assertion}", response=True) logger.debug("HINFO: %s", hinfo) resp = Response(hinfo["data"], headers=hinfo["headers"]) @@ -747,7 +746,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None): msg = IDP.create_artifact_response(_req, _req.artifact.text) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -768,7 +767,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None): msg = IDP.create_authn_query_response(_query.subject, _query.requested_authn_context, _query.session_index) logger.debug("response: %s", msg) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -797,7 +796,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None): msg = IDP.create_attribute_response(identity, name_id=name_id, **args) logger.debug("response: %s", msg) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -830,7 +829,7 @@ def do(self, query, binding, relay_state="", encrypt_cert=None): _resp = IDP.create_name_id_mapping_response(name_id, **info) # Only SOAP - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % _resp, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{_resp}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -849,7 +848,7 @@ def info_from_cookie(kaka): if morsel: try: data = base64.b64decode(morsel.value) - if not isinstance(data, six.string_types): + if not isinstance(data, str): data = data.decode("ascii") key, ref = data.split(":", 1) return IDP.cache.uid2user[key], ref @@ -879,11 +878,11 @@ def set_cookie(name, _, *args): cookie = SimpleCookie() data = ":".join(args) - if not isinstance(data, six.binary_type): + if not isinstance(data, bytes): data = data.encode("ascii") data64 = base64.b64encode(data) - if not isinstance(data64, six.string_types): + if not isinstance(data64, str): data64 = data64.decode("ascii") cookie[name] = data64 @@ -979,7 +978,7 @@ def staticfile(environ, start_response): resp = Unauthorized() return resp(environ, start_response) start_response("200 OK", [("Content-Type", "text/xml")]) - return open(path, "r").read() + return open(path).read() except Exception as ex: logger.error("An error occured while creating metadata: %s", ex.message) return not_found(environ, start_response) @@ -1079,8 +1078,8 @@ def application(environ, start_response): _rot = args.mako_root LOOKUP = TemplateLookup( - directories=[_rot + "templates", _rot + "htdocs"], - module_directory=_rot + "modules", + directories=[f"{_rot}templates", f"{_rot}htdocs"], + module_directory=f"{_rot}modules", input_encoding="utf-8", output_encoding="utf-8", ) @@ -1110,7 +1109,7 @@ def application(environ, start_response): SRV.ssl_adapter = BuiltinSSLAdapter(CONFIG.SERVER_CERT, CONFIG.SERVER_KEY, CONFIG.CERT_CHAIN) logger.info("Server starting") - print("IDP listening on %s:%s%s" % (HOST, PORT, _https)) + print(f"IDP listening on {HOST}:{PORT}{_https}") try: SRV.start() except KeyboardInterrupt: diff --git a/example/idp2/idp_uwsgi.py b/example/idp2/idp_uwsgi.py index 89f3bade0..af559d518 100755 --- a/example/idp2/idp_uwsgi.py +++ b/example/idp2/idp_uwsgi.py @@ -47,7 +47,7 @@ logger = logging.getLogger("saml2.idp") -class Cache(object): +class Cache: def __init__(self): self.user2uid = {} self.uid2user = {} @@ -83,7 +83,7 @@ def dict2list_of_tuples(d): # ----------------------------------------------------------------------------- -class Service(object): +class Service: def __init__(self, environ, start_response, user=None): self.environ = environ logger.debug("ENVIRON: %s", environ) @@ -93,7 +93,7 @@ def __init__(self, environ, start_response, user=None): def unpack_redirect(self): if "QUERY_STRING" in self.environ: _qs = self.environ["QUERY_STRING"] - return dict([(k, v[0]) for k, v in parse_qs(_qs).items()]) + return {k: v[0] for k, v in parse_qs(_qs).items()} else: return None @@ -101,7 +101,7 @@ def unpack_post(self): _dict = parse_qs(get_post(self.environ)) logger.debug("unpack_post:: %s", _dict) try: - return dict([(k, v[0]) for k, v in _dict.items()]) + return {k: v[0] for k, v in _dict.items()} except Exception: return None @@ -276,11 +276,11 @@ def do(self, query, binding_in, relay_state="", encrypt_cert=None): resp_args, _resp = self.verify_request(query, binding_in) except UnknownPrincipal as excp: logger.error("UnknownPrincipal: %s", excp) - resp = ServiceError("UnknownPrincipal: %s" % (excp,)) + resp = ServiceError(f"UnknownPrincipal: {excp}") return resp(self.environ, self.start_response) except UnsupportedBinding as excp: logger.error("UnsupportedBinding: %s", excp) - resp = ServiceError("UnsupportedBinding: %s" % (excp,)) + resp = ServiceError(f"UnsupportedBinding: {excp}") return resp(self.environ, self.start_response) if not _resp: @@ -301,7 +301,7 @@ def do(self, query, binding_in, relay_state="", encrypt_cert=None): _resp = IDP.create_authn_response(identity, userid=self.user, encrypt_cert=encrypt_cert, **resp_args) except Exception as excp: logging.error(exception_trace(excp)) - resp = ServiceError("Exception: %s" % (excp,)) + resp = ServiceError(f"Exception: {excp}") return resp(self.environ, self.start_response) logger.info("AuthNResponse: %s", _resp) @@ -311,7 +311,7 @@ def do(self, query, binding_in, relay_state="", encrypt_cert=None): kwargs = {} http_args = IDP.apply_binding( - self.binding_out, "%s" % _resp, self.destination, relay_state, response=True, **kwargs + self.binding_out, f"{_resp}", self.destination, relay_state, response=True, **kwargs ) logger.debug("HTTPargs: %s", http_args) @@ -511,7 +511,7 @@ def do_verify(environ, start_response, _): kaka = set_cookie("idpauthn", "/", uid, query["authn_reference"][0]) - lox = "%s?id=%s&key=%s" % (query["redirect_uri"][0], uid, query["key"][0]) + lox = f"{query['redirect_uri'][0]}?id={uid}&key={query['key'][0]}" logger.debug("Redirect => %s", lox) resp = Redirect(lox, headers=[kaka], content="text/html") @@ -545,7 +545,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None): req_info = IDP.parse_logout_request(body, binding) except Exception as exc: logger.error("Bad request: %s", exc) - resp = BadRequest("%s" % exc) + resp = BadRequest(f"{exc}") return resp(self.environ, self.start_response) msg = req_info.message @@ -562,16 +562,16 @@ def do(self, request, binding, relay_state="", encrypt_cert=None): IDP.session_db.remove_authn_statements(msg.name_id) except KeyError as exc: logger.error("ServiceError: %s", exc) - resp = ServiceError("%s" % exc) + resp = ServiceError(f"{exc}") return resp(self.environ, self.start_response) resp = IDP.create_logout_response(msg, [binding]) try: - hinfo = IDP.apply_binding(binding, "%s" % resp, "", relay_state) + hinfo = IDP.apply_binding(binding, f"{resp}", "", relay_state) except Exception as exc: logger.error("ServiceError: %s", exc) - resp = ServiceError("%s" % exc) + resp = ServiceError(f"{exc}") return resp(self.environ, self.start_response) # _tlh = dict2list_of_tuples(hinfo["headers"]) @@ -604,7 +604,7 @@ def do(self, query, binding, relay_state="", encrypt_cert=None): _resp = IDP.create_manage_name_id_response(request) # It's using SOAP binding - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % _resp, "", relay_state, response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{_resp}", "", relay_state, response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -626,7 +626,7 @@ def do(self, aid, binding, relay_state="", encrypt_cert=None): resp = NotFound(aid) return resp(self.environ, self.start_response) - hinfo = IDP.apply_binding(BINDING_URI, "%s" % assertion, response=True) + hinfo = IDP.apply_binding(BINDING_URI, f"{assertion}", response=True) logger.debug("HINFO: %s", hinfo) resp = Response(hinfo["data"], headers=hinfo["headers"]) @@ -652,7 +652,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None): msg = IDP.create_artifact_response(_req, _req.artifact.text) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -673,7 +673,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None): msg = IDP.create_authn_query_response(_query.subject, _query.requested_authn_context, _query.session_index) logger.debug("response: %s", msg) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -702,7 +702,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None): msg = IDP.create_attribute_response(identity, name_id=name_id, **args) logger.debug("response: %s", msg) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -735,7 +735,7 @@ def do(self, query, binding, relay_state="", encrypt_cert=None): _resp = IDP.create_name_id_mapping_response(name_id, **info) # Only SOAP - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % _resp, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{_resp}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -861,7 +861,7 @@ def staticfile(environ, start_response): resp = Unauthorized() return resp(environ, start_response) start_response("200 OK", [("Content-Type", "text/xml")]) - return open(path, "r").read() + return open(path).read() except Exception as ex: logger.error("An error occured while creating metadata:", ex.message) return not_found(environ, start_response) @@ -948,8 +948,8 @@ def application(environ, start_response): AUTHN_BROKER = AuthnBroker() -AUTHN_BROKER.add(authn_context_class_ref(PASSWORD), username_password_authn, 10, "http://%s" % socket.gethostname()) -AUTHN_BROKER.add(authn_context_class_ref(UNSPECIFIED), "", 0, "http://%s" % socket.gethostname()) +AUTHN_BROKER.add(authn_context_class_ref(PASSWORD), username_password_authn, 10, f"http://{socket.gethostname()}") +AUTHN_BROKER.add(authn_context_class_ref(UNSPECIFIED), "", 0, f"http://{socket.gethostname()}") CONFIG = importlib.import_module(args.config) IDP = server.Server(args.config, cache=Cache()) IDP.ticket = {} @@ -975,8 +975,8 @@ def application(environ, start_response): _rot = args.mako_root LOOKUP = TemplateLookup( - directories=[_rot + "templates", _rot + "htdocs"], - module_directory=_rot + "modules", + directories=[f"{_rot}templates", f"{_rot}htdocs"], + module_directory=f"{_rot}modules", input_encoding="utf-8", output_encoding="utf-8", ) @@ -985,13 +985,13 @@ def application(environ, start_response): PORT = CONFIG.PORT SRV = make_server(HOST, PORT, application) - print("IdP listening on %s:%s" % (HOST, PORT)) + print(f"IdP listening on {HOST}:{PORT}") SRV.serve_forever() else: _rot = args.mako_root LOOKUP = TemplateLookup( - directories=[_rot + "templates", _rot + "htdocs"], - module_directory=_rot + "modules", + directories=[f"{_rot}templates", f"{_rot}htdocs"], + module_directory=f"{_rot}modules", input_encoding="utf-8", output_encoding="utf-8", ) diff --git a/example/idp2_repoze/idp.py b/example/idp2_repoze/idp.py index aae2a3f19..cc36e9ec2 100755 --- a/example/idp2_repoze/idp.py +++ b/example/idp2_repoze/idp.py @@ -44,7 +44,7 @@ logger = logging.getLogger("saml2.idp") -class Cache(object): +class Cache: def __init__(self): self.user2uid = {} self.uid2user = {} @@ -80,7 +80,7 @@ def dict2list_of_tuples(d): # ----------------------------------------------------------------------------- -class Service(object): +class Service: def __init__(self, environ, start_response, user=None): self.environ = environ logger.debug("ENVIRON: %s", environ) @@ -90,7 +90,7 @@ def __init__(self, environ, start_response, user=None): def unpack_redirect(self): if "QUERY_STRING" in self.environ: _qs = self.environ["QUERY_STRING"] - return dict([(k, v[0]) for k, v in parse_qs(_qs).items()]) + return {k: v[0] for k, v in parse_qs(_qs).items()} else: return None @@ -98,7 +98,7 @@ def unpack_post(self): _dict = parse_qs(get_post(self.environ)) logger.debug("unpack_post:: %s", _dict) try: - return dict([(k, v[0]) for k, v in _dict.items()]) + return {k: v[0] for k, v in _dict.items()} except Exception: return None @@ -277,11 +277,11 @@ def do(self, query, binding_in, relay_state=""): resp_args, _resp = self.verify_request(query, binding_in) except UnknownPrincipal as excp: logger.error("UnknownPrincipal: %s", excp) - resp = ServiceError("UnknownPrincipal: %s" % (excp,)) + resp = ServiceError(f"UnknownPrincipal: {excp}") return resp(self.environ, self.start_response) except UnsupportedBinding as excp: logger.error("UnsupportedBinding: %s", excp) - resp = ServiceError("UnsupportedBinding: %s" % (excp,)) + resp = ServiceError(f"UnsupportedBinding: {excp}") return resp(self.environ, self.start_response) if not _resp: @@ -301,15 +301,15 @@ def do(self, query, binding_in, relay_state=""): authn=AUTHN_BROKER[self.environ["idp.authn_ref"]], sign_assertion=sign_assertion, sign_response=False, - **resp_args + **resp_args, ) except Exception as excp: logging.error(exception_trace(excp)) - resp = ServiceError("Exception: %s" % (excp,)) + resp = ServiceError(f"Exception: {excp}") return resp(self.environ, self.start_response) logger.info("AuthNResponse: %s", _resp) - http_args = IDP.apply_binding(self.binding_out, "%s" % _resp, self.destination, relay_state, response=True) + http_args = IDP.apply_binding(self.binding_out, f"{_resp}", self.destination, relay_state, response=True) logger.debug("HTTPargs: %s", http_args) return self.response(self.binding_out, http_args) @@ -505,7 +505,7 @@ def do_verify(environ, start_response, _): kaka = set_cookie("idpauthn", "/", uid, query["authn_reference"][0]) - lox = "%s?id=%s&key=%s" % (query["redirect_uri"][0], uid, query["key"][0]) + lox = f"{query['redirect_uri'][0]}?id={uid}&key={query['key'][0]}" logger.debug("Redirect => %s", lox) resp = Redirect(lox, headers=[kaka], content="text/html") @@ -539,7 +539,7 @@ def do(self, request, binding, relay_state=""): req_info = IDP.parse_logout_request(body, binding) except Exception as exc: logger.error("Bad request: %s", exc) - resp = BadRequest("%s" % exc) + resp = BadRequest(f"{exc}") return resp(self.environ, self.start_response) msg = req_info.message @@ -556,16 +556,16 @@ def do(self, request, binding, relay_state=""): IDP.session_db.remove_authn_statements(msg.name_id) except KeyError as exc: logger.error("ServiceError: %s", exc) - resp = ServiceError("%s" % exc) + resp = ServiceError(f"{exc}") return resp(self.environ, self.start_response) resp = IDP.create_logout_response(msg, [binding]) try: - hinfo = IDP.apply_binding(binding, "%s" % resp, "", relay_state) + hinfo = IDP.apply_binding(binding, f"{resp}", "", relay_state) except Exception as exc: logger.error("ServiceError: %s", exc) - resp = ServiceError("%s" % exc) + resp = ServiceError(f"{exc}") return resp(self.environ, self.start_response) # _tlh = dict2list_of_tuples(hinfo["headers"]) @@ -598,7 +598,7 @@ def do(self, query, binding, relay_state=""): _resp = IDP.create_manage_name_id_response(request) # It's using SOAP binding - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % _resp, "", relay_state, response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{_resp}", "", relay_state, response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -620,7 +620,7 @@ def do(self, aid, binding, relay_state=""): resp = NotFound(aid) return resp(self.environ, self.start_response) - hinfo = IDP.apply_binding(BINDING_URI, "%s" % assertion, response=True) + hinfo = IDP.apply_binding(BINDING_URI, f"{assertion}", response=True) logger.debug("HINFO: %s", hinfo) resp = Response(hinfo["data"], headers=hinfo["headers"]) @@ -646,7 +646,7 @@ def do(self, request, binding, relay_state=""): msg = IDP.create_artifact_response(_req, _req.artifact.text) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -667,7 +667,7 @@ def do(self, request, binding, relay_state=""): msg = IDP.create_authn_query_response(_query.subject, _query.requested_authn_context, _query.session_index) logger.debug("response: %s", msg) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -696,7 +696,7 @@ def do(self, request, binding, relay_state=""): msg = IDP.create_attribute_response(identity, name_id=name_id, **args) logger.debug("response: %s", msg) - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{msg}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -729,7 +729,7 @@ def do(self, query, binding, relay_state=""): _resp = IDP.create_name_id_mapping_response(name_id, **info) # Only SOAP - hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % _resp, "", "", response=True) + hinfo = IDP.apply_binding(BINDING_SOAP, f"{_resp}", "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response) @@ -851,7 +851,7 @@ def staticfile(environ, start_response): path += "/" path += environ.get("PATH_INFO", "").lstrip("/") start_response("200 OK", [("Content-Type", "text/xml")]) - return open(path, "r").read() + return open(path).read() except Exception as ex: logger.error("An error occured while creating metadata: %s", ex.message) return not_found(environ, start_response) @@ -937,8 +937,8 @@ def application(environ, start_response): AUTHN_BROKER = AuthnBroker() -AUTHN_BROKER.add(authn_context_class_ref(PASSWORD), username_password_authn, 10, "http://%s" % socket.gethostname()) -AUTHN_BROKER.add(authn_context_class_ref(UNSPECIFIED), "", 0, "http://%s" % socket.gethostname()) +AUTHN_BROKER.add(authn_context_class_ref(PASSWORD), username_password_authn, 10, f"http://{socket.gethostname()}") +AUTHN_BROKER.add(authn_context_class_ref(UNSPECIFIED), "", 0, f"http://{socket.gethostname()}") IDP = server.Server(args.config, cache=Cache()) IDP.ticket = {} @@ -962,8 +962,8 @@ def application(environ, start_response): _rot = args.mako_root LOOKUP = TemplateLookup( - directories=[_rot + "templates", _rot + "htdocs"], - module_directory=_rot + "modules", + directories=[f"{_rot}templates", f"{_rot}htdocs"], + module_directory=f"{_rot}modules", input_encoding="utf-8", output_encoding="utf-8", ) @@ -972,13 +972,13 @@ def application(environ, start_response): PORT = 8088 SRV = make_server(HOST, PORT, application) - print("IdP listening on %s:%s" % (HOST, PORT)) + print(f"IdP listening on {HOST}:{PORT}") SRV.serve_forever() else: _rot = args.mako_root LOOKUP = TemplateLookup( - directories=[_rot + "templates", _rot + "htdocs"], - module_directory=_rot + "modules", + directories=[f"{_rot}templates", f"{_rot}htdocs"], + module_directory=f"{_rot}modules", input_encoding="utf-8", output_encoding="utf-8", ) diff --git a/example/idp2_repoze/modules/login.mako.py b/example/idp2_repoze/modules/login.mako.py index 4603f6fb6..211fa37f1 100644 --- a/example/idp2_repoze/modules/login.mako.py +++ b/example/idp2_repoze/modules/login.mako.py @@ -1,5 +1,4 @@ -# -*- encoding:utf-8 -*- -from mako import runtime, filters, cache +from mako import cache, runtime UNDEFINED = runtime.UNDEFINED __M_dict_builtin = dict diff --git a/example/idp2_repoze/modules/root.mako.py b/example/idp2_repoze/modules/root.mako.py index 9b21c4b38..411992323 100644 --- a/example/idp2_repoze/modules/root.mako.py +++ b/example/idp2_repoze/modules/root.mako.py @@ -1,4 +1,3 @@ -# -*- encoding:utf-8 -*- from mako import runtime, filters, cache UNDEFINED = runtime.UNDEFINED @@ -76,7 +75,6 @@ def render_css_link(context, path, media=""): __M_writer('" media="') __M_writer(unicode(media)) __M_writer('">\n') - pass # SOURCE LINE 6 __M_writer(" ") self.seen_css.add(path) diff --git a/example/sp-repoze/attributemaps/saml_uri.py b/example/sp-repoze/attributemaps/saml_uri.py index 245d05ed7..a66725590 100644 --- a/example/sp-repoze/attributemaps/saml_uri.py +++ b/example/sp-repoze/attributemaps/saml_uri.py @@ -11,189 +11,189 @@ MAP = { "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "fro": { - EDUPERSON_OID + "2": "eduPersonNickname", - EDUPERSON_OID + "9": "eduPersonScopedAffiliation", - EDUPERSON_OID + "11": "eduPersonAssurance", - EDUPERSON_OID + "10": "eduPersonTargetedID", - EDUPERSON_OID + "4": "eduPersonOrgUnitDN", - NOREDUPERSON_OID + "6": "norEduOrgAcronym", - NOREDUPERSON_OID + "7": "norEduOrgUniqueIdentifier", - NOREDUPERSON_OID + "4": "norEduPersonLIN", - EDUPERSON_OID + "1": "eduPersonAffiliation", - NOREDUPERSON_OID + "2": "norEduOrgUnitUniqueNumber", - NETSCAPE_LDAP + "40": "userSMIMECertificate", - NOREDUPERSON_OID + "1": "norEduOrgUniqueNumber", - NETSCAPE_LDAP + "241": "displayName", - UCL_DIR_PILOT + "37": "associatedDomain", - EDUPERSON_OID + "6": "eduPersonPrincipalName", - NOREDUPERSON_OID + "8": "norEduOrgUnitUniqueIdentifier", - NOREDUPERSON_OID + "9": "federationFeideSchemaVersion", - X500ATTR_OID + "53": "deltaRevocationList", - X500ATTR_OID + "52": "supportedAlgorithms", - X500ATTR_OID + "51": "houseIdentifier", - X500ATTR_OID + "50": "uniqueMember", - X500ATTR_OID + "19": "physicalDeliveryOfficeName", - X500ATTR_OID + "18": "postOfficeBox", - X500ATTR_OID + "17": "postalCode", - X500ATTR_OID + "16": "postalAddress", - X500ATTR_OID + "15": "businessCategory", - X500ATTR_OID + "14": "searchGuide", - EDUPERSON_OID + "5": "eduPersonPrimaryAffiliation", - X500ATTR_OID + "12": "title", - X500ATTR_OID + "11": "ou", - X500ATTR_OID + "10": "o", - X500ATTR_OID + "37": "cACertificate", - X500ATTR_OID + "36": "userCertificate", - X500ATTR_OID + "31": "member", - X500ATTR_OID + "30": "supportedApplicationContext", - X500ATTR_OID + "33": "roleOccupant", - X500ATTR_OID + "32": "owner", - NETSCAPE_LDAP + "1": "carLicense", - PKCS_9 + "1": "email", - NETSCAPE_LDAP + "3": "employeeNumber", - NETSCAPE_LDAP + "2": "departmentNumber", - X500ATTR_OID + "39": "certificateRevocationList", - X500ATTR_OID + "38": "authorityRevocationList", - NETSCAPE_LDAP + "216": "userPKCS12", - EDUPERSON_OID + "8": "eduPersonPrimaryOrgUnitDN", - X500ATTR_OID + "9": "street", - X500ATTR_OID + "8": "st", - NETSCAPE_LDAP + "39": "preferredLanguage", - EDUPERSON_OID + "7": "eduPersonEntitlement", - X500ATTR_OID + "2": "knowledgeInformation", - X500ATTR_OID + "7": "l", - X500ATTR_OID + "6": "c", - X500ATTR_OID + "5": "serialNumber", - X500ATTR_OID + "4": "sn", - UCL_DIR_PILOT + "60": "jpegPhoto", - X500ATTR_OID + "65": "pseudonym", - NOREDUPERSON_OID + "5": "norEduPersonNIN", - UCL_DIR_PILOT + "3": "mail", - UCL_DIR_PILOT + "25": "dc", - X500ATTR_OID + "40": "crossCertificatePair", - X500ATTR_OID + "42": "givenName", - X500ATTR_OID + "43": "initials", - X500ATTR_OID + "44": "generationQualifier", - X500ATTR_OID + "45": "x500UniqueIdentifier", - X500ATTR_OID + "46": "dnQualifier", - X500ATTR_OID + "47": "enhancedSearchGuide", - X500ATTR_OID + "48": "protocolInformation", - X500ATTR_OID + "54": "dmdName", - NETSCAPE_LDAP + "4": "employeeType", - X500ATTR_OID + "22": "teletexTerminalIdentifier", - X500ATTR_OID + "23": "facsimileTelephoneNumber", - X500ATTR_OID + "20": "telephoneNumber", - X500ATTR_OID + "21": "telexNumber", - X500ATTR_OID + "26": "registeredAddress", - X500ATTR_OID + "27": "destinationIndicator", - X500ATTR_OID + "24": "x121Address", - X500ATTR_OID + "25": "internationaliSDNNumber", - X500ATTR_OID + "28": "preferredDeliveryMethod", - X500ATTR_OID + "29": "presentationAddress", - EDUPERSON_OID + "3": "eduPersonOrgDN", - NOREDUPERSON_OID + "3": "norEduPersonBirthDate", - UMICH + "57": "labeledURI", - UCL_DIR_PILOT + "1": "uid", + f"{EDUPERSON_OID}2": "eduPersonNickname", + f"{EDUPERSON_OID}9": "eduPersonScopedAffiliation", + f"{EDUPERSON_OID}11": "eduPersonAssurance", + f"{EDUPERSON_OID}10": "eduPersonTargetedID", + f"{EDUPERSON_OID}4": "eduPersonOrgUnitDN", + f"{NOREDUPERSON_OID}6": "norEduOrgAcronym", + f"{NOREDUPERSON_OID}7": "norEduOrgUniqueIdentifier", + f"{NOREDUPERSON_OID}4": "norEduPersonLIN", + f"{EDUPERSON_OID}1": "eduPersonAffiliation", + f"{NOREDUPERSON_OID}2": "norEduOrgUnitUniqueNumber", + f"{NETSCAPE_LDAP}40": "userSMIMECertificate", + f"{NOREDUPERSON_OID}1": "norEduOrgUniqueNumber", + f"{NETSCAPE_LDAP}241": "displayName", + f"{UCL_DIR_PILOT}37": "associatedDomain", + f"{EDUPERSON_OID}6": "eduPersonPrincipalName", + f"{NOREDUPERSON_OID}8": "norEduOrgUnitUniqueIdentifier", + f"{NOREDUPERSON_OID}9": "federationFeideSchemaVersion", + f"{X500ATTR_OID}53": "deltaRevocationList", + f"{X500ATTR_OID}52": "supportedAlgorithms", + f"{X500ATTR_OID}51": "houseIdentifier", + f"{X500ATTR_OID}50": "uniqueMember", + f"{X500ATTR_OID}19": "physicalDeliveryOfficeName", + f"{X500ATTR_OID}18": "postOfficeBox", + f"{X500ATTR_OID}17": "postalCode", + f"{X500ATTR_OID}16": "postalAddress", + f"{X500ATTR_OID}15": "businessCategory", + f"{X500ATTR_OID}14": "searchGuide", + f"{EDUPERSON_OID}5": "eduPersonPrimaryAffiliation", + f"{X500ATTR_OID}12": "title", + f"{X500ATTR_OID}11": "ou", + f"{X500ATTR_OID}10": "o", + f"{X500ATTR_OID}37": "cACertificate", + f"{X500ATTR_OID}36": "userCertificate", + f"{X500ATTR_OID}31": "member", + f"{X500ATTR_OID}30": "supportedApplicationContext", + f"{X500ATTR_OID}33": "roleOccupant", + f"{X500ATTR_OID}32": "owner", + f"{NETSCAPE_LDAP}1": "carLicense", + f"{PKCS_9}1": "email", + f"{NETSCAPE_LDAP}3": "employeeNumber", + f"{NETSCAPE_LDAP}2": "departmentNumber", + f"{X500ATTR_OID}39": "certificateRevocationList", + f"{X500ATTR_OID}38": "authorityRevocationList", + f"{NETSCAPE_LDAP}216": "userPKCS12", + f"{EDUPERSON_OID}8": "eduPersonPrimaryOrgUnitDN", + f"{X500ATTR_OID}9": "street", + f"{X500ATTR_OID}8": "st", + f"{NETSCAPE_LDAP}39": "preferredLanguage", + f"{EDUPERSON_OID}7": "eduPersonEntitlement", + f"{X500ATTR_OID}2": "knowledgeInformation", + f"{X500ATTR_OID}7": "l", + f"{X500ATTR_OID}6": "c", + f"{X500ATTR_OID}5": "serialNumber", + f"{X500ATTR_OID}4": "sn", + f"{UCL_DIR_PILOT}60": "jpegPhoto", + f"{X500ATTR_OID}65": "pseudonym", + f"{NOREDUPERSON_OID}5": "norEduPersonNIN", + f"{UCL_DIR_PILOT}3": "mail", + f"{UCL_DIR_PILOT}25": "dc", + f"{X500ATTR_OID}40": "crossCertificatePair", + f"{X500ATTR_OID}42": "givenName", + f"{X500ATTR_OID}43": "initials", + f"{X500ATTR_OID}44": "generationQualifier", + f"{X500ATTR_OID}45": "x500UniqueIdentifier", + f"{X500ATTR_OID}46": "dnQualifier", + f"{X500ATTR_OID}47": "enhancedSearchGuide", + f"{X500ATTR_OID}48": "protocolInformation", + f"{X500ATTR_OID}54": "dmdName", + f"{NETSCAPE_LDAP}4": "employeeType", + f"{X500ATTR_OID}22": "teletexTerminalIdentifier", + f"{X500ATTR_OID}23": "facsimileTelephoneNumber", + f"{X500ATTR_OID}20": "telephoneNumber", + f"{X500ATTR_OID}21": "telexNumber", + f"{X500ATTR_OID}26": "registeredAddress", + f"{X500ATTR_OID}27": "destinationIndicator", + f"{X500ATTR_OID}24": "x121Address", + f"{X500ATTR_OID}25": "internationaliSDNNumber", + f"{X500ATTR_OID}28": "preferredDeliveryMethod", + f"{X500ATTR_OID}29": "presentationAddress", + f"{EDUPERSON_OID}3": "eduPersonOrgDN", + f"{NOREDUPERSON_OID}3": "norEduPersonBirthDate", + f"{UMICH}57": "labeledURI", + f"{UCL_DIR_PILOT}1": "uid", }, "to": { - "roleOccupant": X500ATTR_OID + "33", - "gn": X500ATTR_OID + "42", - "norEduPersonNIN": NOREDUPERSON_OID + "5", - "title": X500ATTR_OID + "12", - "facsimileTelephoneNumber": X500ATTR_OID + "23", - "mail": UCL_DIR_PILOT + "3", - "postOfficeBox": X500ATTR_OID + "18", - "fax": X500ATTR_OID + "23", - "telephoneNumber": X500ATTR_OID + "20", - "norEduPersonBirthDate": NOREDUPERSON_OID + "3", - "rfc822Mailbox": UCL_DIR_PILOT + "3", - "dc": UCL_DIR_PILOT + "25", - "countryName": X500ATTR_OID + "6", - "emailAddress": PKCS_9 + "1", - "employeeNumber": NETSCAPE_LDAP + "3", - "organizationName": X500ATTR_OID + "10", - "eduPersonAssurance": EDUPERSON_OID + "11", - "norEduOrgAcronym": NOREDUPERSON_OID + "6", - "registeredAddress": X500ATTR_OID + "26", - "physicalDeliveryOfficeName": X500ATTR_OID + "19", - "associatedDomain": UCL_DIR_PILOT + "37", - "l": X500ATTR_OID + "7", - "stateOrProvinceName": X500ATTR_OID + "8", - "federationFeideSchemaVersion": NOREDUPERSON_OID + "9", - "pkcs9email": PKCS_9 + "1", - "givenName": X500ATTR_OID + "42", - "givenname": X500ATTR_OID + "42", - "x500UniqueIdentifier": X500ATTR_OID + "45", - "eduPersonNickname": EDUPERSON_OID + "2", - "houseIdentifier": X500ATTR_OID + "51", - "street": X500ATTR_OID + "9", - "supportedAlgorithms": X500ATTR_OID + "52", - "preferredLanguage": NETSCAPE_LDAP + "39", - "postalAddress": X500ATTR_OID + "16", - "email": PKCS_9 + "1", - "norEduOrgUnitUniqueIdentifier": NOREDUPERSON_OID + "8", - "eduPersonPrimaryOrgUnitDN": EDUPERSON_OID + "8", - "c": X500ATTR_OID + "6", - "teletexTerminalIdentifier": X500ATTR_OID + "22", - "o": X500ATTR_OID + "10", - "cACertificate": X500ATTR_OID + "37", - "telexNumber": X500ATTR_OID + "21", - "ou": X500ATTR_OID + "11", - "initials": X500ATTR_OID + "43", - "eduPersonOrgUnitDN": EDUPERSON_OID + "4", - "deltaRevocationList": X500ATTR_OID + "53", - "norEduPersonLIN": NOREDUPERSON_OID + "4", - "supportedApplicationContext": X500ATTR_OID + "30", - "eduPersonEntitlement": EDUPERSON_OID + "7", - "generationQualifier": X500ATTR_OID + "44", - "eduPersonAffiliation": EDUPERSON_OID + "1", - "eduPersonPrincipalName": EDUPERSON_OID + "6", - "edupersonprincipalname": EDUPERSON_OID + "6", - "localityName": X500ATTR_OID + "7", - "owner": X500ATTR_OID + "32", - "norEduOrgUnitUniqueNumber": NOREDUPERSON_OID + "2", - "searchGuide": X500ATTR_OID + "14", - "certificateRevocationList": X500ATTR_OID + "39", - "organizationalUnitName": X500ATTR_OID + "11", - "userCertificate": X500ATTR_OID + "36", - "preferredDeliveryMethod": X500ATTR_OID + "28", - "internationaliSDNNumber": X500ATTR_OID + "25", - "uniqueMember": X500ATTR_OID + "50", - "departmentNumber": NETSCAPE_LDAP + "2", - "enhancedSearchGuide": X500ATTR_OID + "47", - "userPKCS12": NETSCAPE_LDAP + "216", - "eduPersonTargetedID": EDUPERSON_OID + "10", - "norEduOrgUniqueNumber": NOREDUPERSON_OID + "1", - "x121Address": X500ATTR_OID + "24", - "destinationIndicator": X500ATTR_OID + "27", - "eduPersonPrimaryAffiliation": EDUPERSON_OID + "5", - "surname": X500ATTR_OID + "4", - "jpegPhoto": UCL_DIR_PILOT + "60", - "eduPersonScopedAffiliation": EDUPERSON_OID + "9", - "edupersonscopedaffiliation": EDUPERSON_OID + "9", - "protocolInformation": X500ATTR_OID + "48", - "knowledgeInformation": X500ATTR_OID + "2", - "employeeType": NETSCAPE_LDAP + "4", - "userSMIMECertificate": NETSCAPE_LDAP + "40", - "member": X500ATTR_OID + "31", - "streetAddress": X500ATTR_OID + "9", - "dmdName": X500ATTR_OID + "54", - "postalCode": X500ATTR_OID + "17", - "pseudonym": X500ATTR_OID + "65", - "dnQualifier": X500ATTR_OID + "46", - "crossCertificatePair": X500ATTR_OID + "40", - "eduPersonOrgDN": EDUPERSON_OID + "3", - "authorityRevocationList": X500ATTR_OID + "38", - "displayName": NETSCAPE_LDAP + "241", - "businessCategory": X500ATTR_OID + "15", - "serialNumber": X500ATTR_OID + "5", - "norEduOrgUniqueIdentifier": NOREDUPERSON_OID + "7", - "st": X500ATTR_OID + "8", - "carLicense": NETSCAPE_LDAP + "1", - "presentationAddress": X500ATTR_OID + "29", - "sn": X500ATTR_OID + "4", - "domainComponent": UCL_DIR_PILOT + "25", - "labeledURI": UMICH + "57", - "uid": UCL_DIR_PILOT + "1", + "roleOccupant": f"{X500ATTR_OID}33", + "gn": f"{X500ATTR_OID}42", + "norEduPersonNIN": f"{NOREDUPERSON_OID}5", + "title": f"{X500ATTR_OID}12", + "facsimileTelephoneNumber": f"{X500ATTR_OID}23", + "mail": f"{UCL_DIR_PILOT}3", + "postOfficeBox": f"{X500ATTR_OID}18", + "fax": f"{X500ATTR_OID}23", + "telephoneNumber": f"{X500ATTR_OID}20", + "norEduPersonBirthDate": f"{NOREDUPERSON_OID}3", + "rfc822Mailbox": f"{UCL_DIR_PILOT}3", + "dc": f"{UCL_DIR_PILOT}25", + "countryName": f"{X500ATTR_OID}6", + "emailAddress": f"{PKCS_9}1", + "employeeNumber": f"{NETSCAPE_LDAP}3", + "organizationName": f"{X500ATTR_OID}10", + "eduPersonAssurance": f"{EDUPERSON_OID}11", + "norEduOrgAcronym": f"{NOREDUPERSON_OID}6", + "registeredAddress": f"{X500ATTR_OID}26", + "physicalDeliveryOfficeName": f"{X500ATTR_OID}19", + "associatedDomain": f"{UCL_DIR_PILOT}37", + "l": f"{X500ATTR_OID}7", + "stateOrProvinceName": f"{X500ATTR_OID}8", + "federationFeideSchemaVersion": f"{NOREDUPERSON_OID}9", + "pkcs9email": f"{PKCS_9}1", + "givenName": f"{X500ATTR_OID}42", + "givenname": f"{X500ATTR_OID}42", + "x500UniqueIdentifier": f"{X500ATTR_OID}45", + "eduPersonNickname": f"{EDUPERSON_OID}2", + "houseIdentifier": f"{X500ATTR_OID}51", + "street": f"{X500ATTR_OID}9", + "supportedAlgorithms": f"{X500ATTR_OID}52", + "preferredLanguage": f"{NETSCAPE_LDAP}39", + "postalAddress": f"{X500ATTR_OID}16", + "email": f"{PKCS_9}1", + "norEduOrgUnitUniqueIdentifier": f"{NOREDUPERSON_OID}8", + "eduPersonPrimaryOrgUnitDN": f"{EDUPERSON_OID}8", + "c": f"{X500ATTR_OID}6", + "teletexTerminalIdentifier": f"{X500ATTR_OID}22", + "o": f"{X500ATTR_OID}10", + "cACertificate": f"{X500ATTR_OID}37", + "telexNumber": f"{X500ATTR_OID}21", + "ou": f"{X500ATTR_OID}11", + "initials": f"{X500ATTR_OID}43", + "eduPersonOrgUnitDN": f"{EDUPERSON_OID}4", + "deltaRevocationList": f"{X500ATTR_OID}53", + "norEduPersonLIN": f"{NOREDUPERSON_OID}4", + "supportedApplicationContext": f"{X500ATTR_OID}30", + "eduPersonEntitlement": f"{EDUPERSON_OID}7", + "generationQualifier": f"{X500ATTR_OID}44", + "eduPersonAffiliation": f"{EDUPERSON_OID}1", + "eduPersonPrincipalName": f"{EDUPERSON_OID}6", + "edupersonprincipalname": f"{EDUPERSON_OID}6", + "localityName": f"{X500ATTR_OID}7", + "owner": f"{X500ATTR_OID}32", + "norEduOrgUnitUniqueNumber": f"{NOREDUPERSON_OID}2", + "searchGuide": f"{X500ATTR_OID}14", + "certificateRevocationList": f"{X500ATTR_OID}39", + "organizationalUnitName": f"{X500ATTR_OID}11", + "userCertificate": f"{X500ATTR_OID}36", + "preferredDeliveryMethod": f"{X500ATTR_OID}28", + "internationaliSDNNumber": f"{X500ATTR_OID}25", + "uniqueMember": f"{X500ATTR_OID}50", + "departmentNumber": f"{NETSCAPE_LDAP}2", + "enhancedSearchGuide": f"{X500ATTR_OID}47", + "userPKCS12": f"{NETSCAPE_LDAP}216", + "eduPersonTargetedID": f"{EDUPERSON_OID}10", + "norEduOrgUniqueNumber": f"{NOREDUPERSON_OID}1", + "x121Address": f"{X500ATTR_OID}24", + "destinationIndicator": f"{X500ATTR_OID}27", + "eduPersonPrimaryAffiliation": f"{EDUPERSON_OID}5", + "surname": f"{X500ATTR_OID}4", + "jpegPhoto": f"{UCL_DIR_PILOT}60", + "eduPersonScopedAffiliation": f"{EDUPERSON_OID}9", + "edupersonscopedaffiliation": f"{EDUPERSON_OID}9", + "protocolInformation": f"{X500ATTR_OID}48", + "knowledgeInformation": f"{X500ATTR_OID}2", + "employeeType": f"{NETSCAPE_LDAP}4", + "userSMIMECertificate": f"{NETSCAPE_LDAP}40", + "member": f"{X500ATTR_OID}31", + "streetAddress": f"{X500ATTR_OID}9", + "dmdName": f"{X500ATTR_OID}54", + "postalCode": f"{X500ATTR_OID}17", + "pseudonym": f"{X500ATTR_OID}65", + "dnQualifier": f"{X500ATTR_OID}46", + "crossCertificatePair": f"{X500ATTR_OID}40", + "eduPersonOrgDN": f"{EDUPERSON_OID}3", + "authorityRevocationList": f"{X500ATTR_OID}38", + "displayName": f"{NETSCAPE_LDAP}241", + "businessCategory": f"{X500ATTR_OID}15", + "serialNumber": f"{X500ATTR_OID}5", + "norEduOrgUniqueIdentifier": f"{NOREDUPERSON_OID}7", + "st": f"{X500ATTR_OID}8", + "carLicense": f"{NETSCAPE_LDAP}1", + "presentationAddress": f"{X500ATTR_OID}29", + "sn": f"{X500ATTR_OID}4", + "domainComponent": f"{UCL_DIR_PILOT}25", + "labeledURI": f"{UMICH}57", + "uid": f"{UCL_DIR_PILOT}1", }, } diff --git a/example/sp-repoze/attributemaps/shibboleth_uri.py b/example/sp-repoze/attributemaps/shibboleth_uri.py index 30b31503d..992a2219e 100644 --- a/example/sp-repoze/attributemaps/shibboleth_uri.py +++ b/example/sp-repoze/attributemaps/shibboleth_uri.py @@ -9,182 +9,182 @@ MAP = { "identifier": "urn:mace:shibboleth:1.0:attributeNamespace:uri", "fro": { - EDUPERSON_OID + "2": "eduPersonNickname", - EDUPERSON_OID + "9": "eduPersonScopedAffiliation", - EDUPERSON_OID + "11": "eduPersonAssurance", - EDUPERSON_OID + "10": "eduPersonTargetedID", - EDUPERSON_OID + "4": "eduPersonOrgUnitDN", - NOREDUPERSON_OID + "6": "norEduOrgAcronym", - NOREDUPERSON_OID + "7": "norEduOrgUniqueIdentifier", - NOREDUPERSON_OID + "4": "norEduPersonLIN", - EDUPERSON_OID + "1": "eduPersonAffiliation", - NOREDUPERSON_OID + "2": "norEduOrgUnitUniqueNumber", - NETSCAPE_LDAP + "40": "userSMIMECertificate", - NOREDUPERSON_OID + "1": "norEduOrgUniqueNumber", - NETSCAPE_LDAP + "241": "displayName", - UCL_DIR_PILOT + "37": "associatedDomain", - EDUPERSON_OID + "6": "eduPersonPrincipalName", - NOREDUPERSON_OID + "8": "norEduOrgUnitUniqueIdentifier", - NOREDUPERSON_OID + "9": "federationFeideSchemaVersion", - X500ATTR + "53": "deltaRevocationList", - X500ATTR + "52": "supportedAlgorithms", - X500ATTR + "51": "houseIdentifier", - X500ATTR + "50": "uniqueMember", - X500ATTR + "19": "physicalDeliveryOfficeName", - X500ATTR + "18": "postOfficeBox", - X500ATTR + "17": "postalCode", - X500ATTR + "16": "postalAddress", - X500ATTR + "15": "businessCategory", - X500ATTR + "14": "searchGuide", - EDUPERSON_OID + "5": "eduPersonPrimaryAffiliation", - X500ATTR + "12": "title", - X500ATTR + "11": "ou", - X500ATTR + "10": "o", - X500ATTR + "37": "cACertificate", - X500ATTR + "36": "userCertificate", - X500ATTR + "31": "member", - X500ATTR + "30": "supportedApplicationContext", - X500ATTR + "33": "roleOccupant", - X500ATTR + "32": "owner", - NETSCAPE_LDAP + "1": "carLicense", - PKCS_9 + "1": "email", - NETSCAPE_LDAP + "3": "employeeNumber", - NETSCAPE_LDAP + "2": "departmentNumber", - X500ATTR + "39": "certificateRevocationList", - X500ATTR + "38": "authorityRevocationList", - NETSCAPE_LDAP + "216": "userPKCS12", - EDUPERSON_OID + "8": "eduPersonPrimaryOrgUnitDN", - X500ATTR + "9": "street", - X500ATTR + "8": "st", - NETSCAPE_LDAP + "39": "preferredLanguage", - EDUPERSON_OID + "7": "eduPersonEntitlement", - X500ATTR + "2": "knowledgeInformation", - X500ATTR + "7": "l", - X500ATTR + "6": "c", - X500ATTR + "5": "serialNumber", - X500ATTR + "4": "sn", - UCL_DIR_PILOT + "60": "jpegPhoto", - X500ATTR + "65": "pseudonym", - NOREDUPERSON_OID + "5": "norEduPersonNIN", - UCL_DIR_PILOT + "3": "mail", - UCL_DIR_PILOT + "25": "dc", - X500ATTR + "40": "crossCertificatePair", - X500ATTR + "42": "givenName", - X500ATTR + "43": "initials", - X500ATTR + "44": "generationQualifier", - X500ATTR + "45": "x500UniqueIdentifier", - X500ATTR + "46": "dnQualifier", - X500ATTR + "47": "enhancedSearchGuide", - X500ATTR + "48": "protocolInformation", - X500ATTR + "54": "dmdName", - NETSCAPE_LDAP + "4": "employeeType", - X500ATTR + "22": "teletexTerminalIdentifier", - X500ATTR + "23": "facsimileTelephoneNumber", - X500ATTR + "20": "telephoneNumber", - X500ATTR + "21": "telexNumber", - X500ATTR + "26": "registeredAddress", - X500ATTR + "27": "destinationIndicator", - X500ATTR + "24": "x121Address", - X500ATTR + "25": "internationaliSDNNumber", - X500ATTR + "28": "preferredDeliveryMethod", - X500ATTR + "29": "presentationAddress", - EDUPERSON_OID + "3": "eduPersonOrgDN", - NOREDUPERSON_OID + "3": "norEduPersonBirthDate", + f"{EDUPERSON_OID}2": "eduPersonNickname", + f"{EDUPERSON_OID}9": "eduPersonScopedAffiliation", + f"{EDUPERSON_OID}11": "eduPersonAssurance", + f"{EDUPERSON_OID}10": "eduPersonTargetedID", + f"{EDUPERSON_OID}4": "eduPersonOrgUnitDN", + f"{NOREDUPERSON_OID}6": "norEduOrgAcronym", + f"{NOREDUPERSON_OID}7": "norEduOrgUniqueIdentifier", + f"{NOREDUPERSON_OID}4": "norEduPersonLIN", + f"{EDUPERSON_OID}1": "eduPersonAffiliation", + f"{NOREDUPERSON_OID}2": "norEduOrgUnitUniqueNumber", + f"{NETSCAPE_LDAP}40": "userSMIMECertificate", + f"{NOREDUPERSON_OID}1": "norEduOrgUniqueNumber", + f"{NETSCAPE_LDAP}241": "displayName", + f"{UCL_DIR_PILOT}37": "associatedDomain", + f"{EDUPERSON_OID}6": "eduPersonPrincipalName", + f"{NOREDUPERSON_OID}8": "norEduOrgUnitUniqueIdentifier", + f"{NOREDUPERSON_OID}9": "federationFeideSchemaVersion", + f"{X500ATTR}53": "deltaRevocationList", + f"{X500ATTR}52": "supportedAlgorithms", + f"{X500ATTR}51": "houseIdentifier", + f"{X500ATTR}50": "uniqueMember", + f"{X500ATTR}19": "physicalDeliveryOfficeName", + f"{X500ATTR}18": "postOfficeBox", + f"{X500ATTR}17": "postalCode", + f"{X500ATTR}16": "postalAddress", + f"{X500ATTR}15": "businessCategory", + f"{X500ATTR}14": "searchGuide", + f"{EDUPERSON_OID}5": "eduPersonPrimaryAffiliation", + f"{X500ATTR}12": "title", + f"{X500ATTR}11": "ou", + f"{X500ATTR}10": "o", + f"{X500ATTR}37": "cACertificate", + f"{X500ATTR}36": "userCertificate", + f"{X500ATTR}31": "member", + f"{X500ATTR}30": "supportedApplicationContext", + f"{X500ATTR}33": "roleOccupant", + f"{X500ATTR}32": "owner", + f"{NETSCAPE_LDAP}1": "carLicense", + f"{PKCS_9}1": "email", + f"{NETSCAPE_LDAP}3": "employeeNumber", + f"{NETSCAPE_LDAP}2": "departmentNumber", + f"{X500ATTR}39": "certificateRevocationList", + f"{X500ATTR}38": "authorityRevocationList", + f"{NETSCAPE_LDAP}216": "userPKCS12", + f"{EDUPERSON_OID}8": "eduPersonPrimaryOrgUnitDN", + f"{X500ATTR}9": "street", + f"{X500ATTR}8": "st", + f"{NETSCAPE_LDAP}39": "preferredLanguage", + f"{EDUPERSON_OID}7": "eduPersonEntitlement", + f"{X500ATTR}2": "knowledgeInformation", + f"{X500ATTR}7": "l", + f"{X500ATTR}6": "c", + f"{X500ATTR}5": "serialNumber", + f"{X500ATTR}4": "sn", + f"{UCL_DIR_PILOT}60": "jpegPhoto", + f"{X500ATTR}65": "pseudonym", + f"{NOREDUPERSON_OID}5": "norEduPersonNIN", + f"{UCL_DIR_PILOT}3": "mail", + f"{UCL_DIR_PILOT}25": "dc", + f"{X500ATTR}40": "crossCertificatePair", + f"{X500ATTR}42": "givenName", + f"{X500ATTR}43": "initials", + f"{X500ATTR}44": "generationQualifier", + f"{X500ATTR}45": "x500UniqueIdentifier", + f"{X500ATTR}46": "dnQualifier", + f"{X500ATTR}47": "enhancedSearchGuide", + f"{X500ATTR}48": "protocolInformation", + f"{X500ATTR}54": "dmdName", + f"{NETSCAPE_LDAP}4": "employeeType", + f"{X500ATTR}22": "teletexTerminalIdentifier", + f"{X500ATTR}23": "facsimileTelephoneNumber", + f"{X500ATTR}20": "telephoneNumber", + f"{X500ATTR}21": "telexNumber", + f"{X500ATTR}26": "registeredAddress", + f"{X500ATTR}27": "destinationIndicator", + f"{X500ATTR}24": "x121Address", + f"{X500ATTR}25": "internationaliSDNNumber", + f"{X500ATTR}28": "preferredDeliveryMethod", + f"{X500ATTR}29": "presentationAddress", + f"{EDUPERSON_OID}3": "eduPersonOrgDN", + f"{NOREDUPERSON_OID}3": "norEduPersonBirthDate", }, "to": { - "roleOccupant": X500ATTR + "33", - "gn": X500ATTR + "42", - "norEduPersonNIN": NOREDUPERSON_OID + "5", - "title": X500ATTR + "12", - "facsimileTelephoneNumber": X500ATTR + "23", - "mail": UCL_DIR_PILOT + "3", - "postOfficeBox": X500ATTR + "18", - "fax": X500ATTR + "23", - "telephoneNumber": X500ATTR + "20", - "norEduPersonBirthDate": NOREDUPERSON_OID + "3", - "rfc822Mailbox": UCL_DIR_PILOT + "3", - "dc": UCL_DIR_PILOT + "25", - "countryName": X500ATTR + "6", - "emailAddress": PKCS_9 + "1", - "employeeNumber": NETSCAPE_LDAP + "3", - "organizationName": X500ATTR + "10", - "eduPersonAssurance": EDUPERSON_OID + "11", - "norEduOrgAcronym": NOREDUPERSON_OID + "6", - "registeredAddress": X500ATTR + "26", - "physicalDeliveryOfficeName": X500ATTR + "19", - "associatedDomain": UCL_DIR_PILOT + "37", - "l": X500ATTR + "7", - "stateOrProvinceName": X500ATTR + "8", - "federationFeideSchemaVersion": NOREDUPERSON_OID + "9", - "pkcs9email": PKCS_9 + "1", - "givenName": X500ATTR + "42", - "x500UniqueIdentifier": X500ATTR + "45", - "eduPersonNickname": EDUPERSON_OID + "2", - "houseIdentifier": X500ATTR + "51", - "street": X500ATTR + "9", - "supportedAlgorithms": X500ATTR + "52", - "preferredLanguage": NETSCAPE_LDAP + "39", - "postalAddress": X500ATTR + "16", - "email": PKCS_9 + "1", - "norEduOrgUnitUniqueIdentifier": NOREDUPERSON_OID + "8", - "eduPersonPrimaryOrgUnitDN": EDUPERSON_OID + "8", - "c": X500ATTR + "6", - "teletexTerminalIdentifier": X500ATTR + "22", - "o": X500ATTR + "10", - "cACertificate": X500ATTR + "37", - "telexNumber": X500ATTR + "21", - "ou": X500ATTR + "11", - "initials": X500ATTR + "43", - "eduPersonOrgUnitDN": EDUPERSON_OID + "4", - "deltaRevocationList": X500ATTR + "53", - "norEduPersonLIN": NOREDUPERSON_OID + "4", - "supportedApplicationContext": X500ATTR + "30", - "eduPersonEntitlement": EDUPERSON_OID + "7", - "generationQualifier": X500ATTR + "44", - "eduPersonAffiliation": EDUPERSON_OID + "1", - "eduPersonPrincipalName": EDUPERSON_OID + "6", - "localityName": X500ATTR + "7", - "owner": X500ATTR + "32", - "norEduOrgUnitUniqueNumber": NOREDUPERSON_OID + "2", - "searchGuide": X500ATTR + "14", - "certificateRevocationList": X500ATTR + "39", - "organizationalUnitName": X500ATTR + "11", - "userCertificate": X500ATTR + "36", - "preferredDeliveryMethod": X500ATTR + "28", - "internationaliSDNNumber": X500ATTR + "25", - "uniqueMember": X500ATTR + "50", - "departmentNumber": NETSCAPE_LDAP + "2", - "enhancedSearchGuide": X500ATTR + "47", - "userPKCS12": NETSCAPE_LDAP + "216", - "eduPersonTargetedID": EDUPERSON_OID + "10", - "norEduOrgUniqueNumber": NOREDUPERSON_OID + "1", - "x121Address": X500ATTR + "24", - "destinationIndicator": X500ATTR + "27", - "eduPersonPrimaryAffiliation": EDUPERSON_OID + "5", - "surname": X500ATTR + "4", - "jpegPhoto": UCL_DIR_PILOT + "60", - "eduPersonScopedAffiliation": EDUPERSON_OID + "9", - "protocolInformation": X500ATTR + "48", - "knowledgeInformation": X500ATTR + "2", - "employeeType": NETSCAPE_LDAP + "4", - "userSMIMECertificate": NETSCAPE_LDAP + "40", - "member": X500ATTR + "31", - "streetAddress": X500ATTR + "9", - "dmdName": X500ATTR + "54", - "postalCode": X500ATTR + "17", - "pseudonym": X500ATTR + "65", - "dnQualifier": X500ATTR + "46", - "crossCertificatePair": X500ATTR + "40", - "eduPersonOrgDN": EDUPERSON_OID + "3", - "authorityRevocationList": X500ATTR + "38", - "displayName": NETSCAPE_LDAP + "241", - "businessCategory": X500ATTR + "15", - "serialNumber": X500ATTR + "5", - "norEduOrgUniqueIdentifier": NOREDUPERSON_OID + "7", - "st": X500ATTR + "8", - "carLicense": NETSCAPE_LDAP + "1", - "presentationAddress": X500ATTR + "29", - "sn": X500ATTR + "4", - "domainComponent": UCL_DIR_PILOT + "25", + "roleOccupant": f"{X500ATTR}33", + "gn": f"{X500ATTR}42", + "norEduPersonNIN": f"{NOREDUPERSON_OID}5", + "title": f"{X500ATTR}12", + "facsimileTelephoneNumber": f"{X500ATTR}23", + "mail": f"{UCL_DIR_PILOT}3", + "postOfficeBox": f"{X500ATTR}18", + "fax": f"{X500ATTR}23", + "telephoneNumber": f"{X500ATTR}20", + "norEduPersonBirthDate": f"{NOREDUPERSON_OID}3", + "rfc822Mailbox": f"{UCL_DIR_PILOT}3", + "dc": f"{UCL_DIR_PILOT}25", + "countryName": f"{X500ATTR}6", + "emailAddress": f"{PKCS_9}1", + "employeeNumber": f"{NETSCAPE_LDAP}3", + "organizationName": f"{X500ATTR}10", + "eduPersonAssurance": f"{EDUPERSON_OID}11", + "norEduOrgAcronym": f"{NOREDUPERSON_OID}6", + "registeredAddress": f"{X500ATTR}26", + "physicalDeliveryOfficeName": f"{X500ATTR}19", + "associatedDomain": f"{UCL_DIR_PILOT}37", + "l": f"{X500ATTR}7", + "stateOrProvinceName": f"{X500ATTR}8", + "federationFeideSchemaVersion": f"{NOREDUPERSON_OID}9", + "pkcs9email": f"{PKCS_9}1", + "givenName": f"{X500ATTR}42", + "x500UniqueIdentifier": f"{X500ATTR}45", + "eduPersonNickname": f"{EDUPERSON_OID}2", + "houseIdentifier": f"{X500ATTR}51", + "street": f"{X500ATTR}9", + "supportedAlgorithms": f"{X500ATTR}52", + "preferredLanguage": f"{NETSCAPE_LDAP}39", + "postalAddress": f"{X500ATTR}16", + "email": f"{PKCS_9}1", + "norEduOrgUnitUniqueIdentifier": f"{NOREDUPERSON_OID}8", + "eduPersonPrimaryOrgUnitDN": f"{EDUPERSON_OID}8", + "c": f"{X500ATTR}6", + "teletexTerminalIdentifier": f"{X500ATTR}22", + "o": f"{X500ATTR}10", + "cACertificate": f"{X500ATTR}37", + "telexNumber": f"{X500ATTR}21", + "ou": f"{X500ATTR}11", + "initials": f"{X500ATTR}43", + "eduPersonOrgUnitDN": f"{EDUPERSON_OID}4", + "deltaRevocationList": f"{X500ATTR}53", + "norEduPersonLIN": f"{NOREDUPERSON_OID}4", + "supportedApplicationContext": f"{X500ATTR}30", + "eduPersonEntitlement": f"{EDUPERSON_OID}7", + "generationQualifier": f"{X500ATTR}44", + "eduPersonAffiliation": f"{EDUPERSON_OID}1", + "eduPersonPrincipalName": f"{EDUPERSON_OID}6", + "localityName": f"{X500ATTR}7", + "owner": f"{X500ATTR}32", + "norEduOrgUnitUniqueNumber": f"{NOREDUPERSON_OID}2", + "searchGuide": f"{X500ATTR}14", + "certificateRevocationList": f"{X500ATTR}39", + "organizationalUnitName": f"{X500ATTR}11", + "userCertificate": f"{X500ATTR}36", + "preferredDeliveryMethod": f"{X500ATTR}28", + "internationaliSDNNumber": f"{X500ATTR}25", + "uniqueMember": f"{X500ATTR}50", + "departmentNumber": f"{NETSCAPE_LDAP}2", + "enhancedSearchGuide": f"{X500ATTR}47", + "userPKCS12": f"{NETSCAPE_LDAP}216", + "eduPersonTargetedID": f"{EDUPERSON_OID}10", + "norEduOrgUniqueNumber": f"{NOREDUPERSON_OID}1", + "x121Address": f"{X500ATTR}24", + "destinationIndicator": f"{X500ATTR}27", + "eduPersonPrimaryAffiliation": f"{EDUPERSON_OID}5", + "surname": f"{X500ATTR}4", + "jpegPhoto": f"{UCL_DIR_PILOT}60", + "eduPersonScopedAffiliation": f"{EDUPERSON_OID}9", + "protocolInformation": f"{X500ATTR}48", + "knowledgeInformation": f"{X500ATTR}2", + "employeeType": f"{NETSCAPE_LDAP}4", + "userSMIMECertificate": f"{NETSCAPE_LDAP}40", + "member": f"{X500ATTR}31", + "streetAddress": f"{X500ATTR}9", + "dmdName": f"{X500ATTR}54", + "postalCode": f"{X500ATTR}17", + "pseudonym": f"{X500ATTR}65", + "dnQualifier": f"{X500ATTR}46", + "crossCertificatePair": f"{X500ATTR}40", + "eduPersonOrgDN": f"{EDUPERSON_OID}3", + "authorityRevocationList": f"{X500ATTR}38", + "displayName": f"{NETSCAPE_LDAP}241", + "businessCategory": f"{X500ATTR}15", + "serialNumber": f"{X500ATTR}5", + "norEduOrgUniqueIdentifier": f"{NOREDUPERSON_OID}7", + "st": f"{X500ATTR}8", + "carLicense": f"{NETSCAPE_LDAP}1", + "presentationAddress": f"{X500ATTR}29", + "sn": f"{X500ATTR}4", + "domainComponent": f"{UCL_DIR_PILOT}25", }, } diff --git a/example/sp-repoze/pki/certgeneration.py b/example/sp-repoze/pki/certgeneration.py index 4b61feeda..84061c387 100644 --- a/example/sp-repoze/pki/certgeneration.py +++ b/example/sp-repoze/pki/certgeneration.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from saml2.cert import OpenSSLWrapper diff --git a/example/sp-repoze/sp.py b/example/sp-repoze/sp.py index e3a59a89c..1c837962c 100755 --- a/example/sp-repoze/sp.py +++ b/example/sp-repoze/sp.py @@ -3,16 +3,13 @@ import logging import os import re -import subprocess from Cookie import SimpleCookie import sp_conf -from sp_conf import CONFIG from urlparse import parse_qs from saml2 import BINDING_HTTP_REDIRECT from saml2 import time_util -from saml2.config import Config from saml2.httputil import NotFound from saml2.httputil import Redirect from saml2.httputil import Response @@ -20,8 +17,6 @@ # from saml2.httputil import ServiceError from saml2.metadata import create_metadata_string -from saml2.metadata import entities_descriptor -from saml2.sigver import security_context logger = logging.getLogger("saml2.SP") @@ -31,21 +26,21 @@ def dict_to_table(ava, lev=0, width=1): - txt = ['\n' % width] + txt = [f'
\n'] for prop, valarr in ava.items(): txt.append("\n") if isinstance(valarr, basestring): - txt.append("\n" % str(prop)) + txt.append(f"\n") try: - txt.append("\n" % valarr.encode("utf8")) + txt.append(f"\n") except AttributeError: - txt.append("\n" % valarr) + txt.append(f"\n") elif isinstance(valarr, list): i = 0 n = len(valarr) for val in valarr: if not i: - txt.append("\n") if isinstance(val, dict): @@ -54,15 +49,15 @@ def dict_to_table(ava, lev=0, width=1): txt.append("\n") else: try: - txt.append("\n" % val.encode("utf8")) + txt.append(f"\n") except AttributeError: - txt.append("\n" % val) + txt.append(f"\n") if n > 1: txt.append("\n") n -= 1 i += 1 elif isinstance(valarr, dict): - txt.append("\n" % prop) + txt.append(f"\n") txt.append("\n") @@ -214,7 +209,7 @@ def metadata(environ, start_response): if path[-1] != "/": path += "/" metadata = create_metadata_string( - path + "sp_conf.py", None, args.valid, args.cert, args.keyfile, args.id, args.name, args.sign + f"{path}sp_conf.py", None, args.valid, args.cert, args.keyfile, args.id, args.name, args.sign ) start_response("200 OK", [("Content-Type", "text/xml")]) return metadata @@ -297,5 +292,5 @@ def application(environ, start_response): from wsgiref.simple_server import make_server srv = make_server(HOST, PORT, app_with_auth) - print("SP listening on %s:%s" % (HOST, PORT)) + print(f"SP listening on {HOST}:{PORT}") srv.serve_forever() diff --git a/example/sp-wsgi/sp.py b/example/sp-wsgi/sp.py index 9687d581c..926ea0360 100755 --- a/example/sp-wsgi/sp.py +++ b/example/sp-wsgi/sp.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -from __future__ import print_function import argparse @@ -9,17 +8,15 @@ except: import cgi as html +from http.cookies import SimpleCookie import importlib import logging import os import re import sys +from urllib.parse import parse_qs import xml.dom.minidom -import six -from six.moves.http_cookies import SimpleCookie -from six.moves.urllib.parse import parse_qs - from saml2 import BINDING_HTTP_ARTIFACT from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT @@ -75,18 +72,18 @@ def _html_escape(payload): def dict_to_table(ava, lev=0, width=1): - txt = ['
%s{str(prop)}%s{valarr.encode('utf8')}%s{valarr}%s\n" % (len(valarr), prop)) + txt.append(f"{prop}\n") else: txt.append("
%s{val.encode('utf8')}%s{val}
%s{prop}\n") txt.extend(dict_to_table(valarr, lev + 1, width - 1)) txt.append("
\n' % width] + txt = [f'
\n'] for prop, valarr in ava.items(): txt.append("\n") - if isinstance(valarr, six.string_types): - txt.append("\n" % str(prop)) - txt.append("\n" % valarr) + if isinstance(valarr, str): + txt.append(f"\n") + txt.append(f"\n") elif isinstance(valarr, list): i = 0 n = len(valarr) for val in valarr: if not i: - txt.append("\n") if isinstance(val, dict): @@ -94,13 +91,13 @@ def dict_to_table(ava, lev=0, width=1): txt.extend(dict_to_table(val, lev + 1, width - 1)) txt.append("\n") else: - txt.append("\n" % val) + txt.append(f"\n") if n > 1: txt.append("\n") n -= 1 i += 1 elif isinstance(valarr, dict): - txt.append("\n" % prop) + txt.append(f"\n") txt.append("\n") @@ -135,12 +132,12 @@ def handle_static(environ, start_response, path): resp = Response(data, headers=[("Content-Type", "image/png")]) else: resp = Response(data) - except IOError: + except OSError: resp = NotFound() return resp(environ, start_response) -class ECPResponse(object): +class ECPResponse: code = 200 title = "OK" @@ -149,7 +146,7 @@ def __init__(self, content): # noinspection PyUnusedLocal def __call__(self, environ, start_response): - start_response("%s %s" % (self.code, self.title), [("Content-Type", "text/xml")]) + start_response(f"{self.code} {self.title}", [("Content-Type", "text/xml")]) return [self.content] @@ -165,7 +162,7 @@ def _expiration(timeout, tformat=None): return time_util.in_a_while(minutes=timeout, format=tformat) -class Cache(object): +class Cache: def __init__(self): self.uid2user = {} self.cookie_name = "spauthn" @@ -222,7 +219,7 @@ def set_cookie(self, user): # ----------------------------------------------------------------------------- -class Service(object): +class Service: def __init__(self, environ, start_response, user=None): self.environ = environ logger.debug("ENVIRON: %s", environ) @@ -233,14 +230,14 @@ def __init__(self, environ, start_response, user=None): def unpack_redirect(self): if "QUERY_STRING" in self.environ: _qs = self.environ["QUERY_STRING"] - return dict([(k, v[0]) for k, v in parse_qs(_qs).items()]) + return {k: v[0] for k, v in parse_qs(_qs).items()} else: return None def unpack_post(self): _dict = parse_qs(get_post(self.environ).decode("utf8")) logger.debug("unpack_post:: %s", _dict) - return dict([(k, v[0]) for k, v in _dict.items()]) + return {k: v[0] for k, v in _dict.items()} def unpack_soap(self): try: @@ -333,7 +330,7 @@ def not_authn(self): # ----------------------------------------------------------------------------- -class User(object): +class User: def __init__(self, name_id, data, saml_response): self.name_id = name_id self.data = data @@ -382,20 +379,20 @@ def do(self, response, binding, relay_state="", mtype="response"): ) except UnknownPrincipal as excp: logger.error("UnknownPrincipal: %s", excp) - resp = ServiceError("UnknownPrincipal: %s" % (excp,)) + resp = ServiceError(f"UnknownPrincipal: {excp}") return resp(self.environ, self.start_response) except UnsupportedBinding as excp: logger.error("UnsupportedBinding: %s", excp) - resp = ServiceError("UnsupportedBinding: %s" % (excp,)) + resp = ServiceError(f"UnsupportedBinding: {excp}") return resp(self.environ, self.start_response) except VerificationError as err: - resp = ServiceError("Verification error: %s" % (err,)) + resp = ServiceError(f"Verification error: {err}") return resp(self.environ, self.start_response) except SignatureError as err: - resp = ServiceError("Signature error: %s" % (err,)) + resp = ServiceError(f"Signature error: {err}") return resp(self.environ, self.start_response) except Exception as err: - resp = ServiceError("Other error: %s" % (err,)) + resp = ServiceError(f"Other error: {err}") return resp(self.environ, self.start_response) logger.info("AVA: %s", self.response.ava) @@ -431,7 +428,7 @@ def verify_attributes(self, ava): # ----------------------------------------------------------------------------- -class SSO(object): +class SSO: def __init__( self, sp, @@ -481,7 +478,7 @@ def _wayf_redirect(self, came_from): sid_ = sid() self.cache.outstanding_queries[sid_] = came_from logger.debug("Redirect to WAYF function: %s", self.wayf) - return -1, SeeOther(headers=[("Location", "%s?%s" % (self.wayf, sid_))]) + return -1, SeeOther(headers=[("Location", f"{self.wayf}?{sid_}")]) def _pick_idp(self, came_from): """ @@ -537,7 +534,6 @@ def _pick_idp(self, came_from): idp_entity_id = _idp_entity_id except KeyError: logger.debug("No IdP entity ID in query: %s", query) - pass if not idp_entity_id: @@ -559,7 +555,7 @@ def _pick_idp(self, came_from): logger.debug("Redirect to Discovery Service function") eid = _cli.config.entityid ret = _cli.config.getattr("endpoints", "sp")["discovery_response"][0][0] - ret += "?sid=%s" % sid_ + ret += f"?sid={sid_}" loc = _cli.create_discovery_service_request(self.discosrv, eid, **{"return": ret}) return -1, SeeOther(loc) elif len(idps) == 1: @@ -602,7 +598,7 @@ def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""): ) _rstate = rndstr() self.cache.relay_state[_rstate] = came_from - ht_args = _cli.apply_binding(_binding, "%s" % req, destination, relay_state=_rstate, sigalg=sigalg) + ht_args = _cli.apply_binding(_binding, f"{req}", destination, relay_state=_rstate, sigalg=sigalg) _sid = req_id if cert is not None: @@ -610,7 +606,7 @@ def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""): except Exception as exc: logger.exception(exc) - resp = ServiceError("Failed to construct the AuthnRequest: %s" % exc) + resp = ServiceError(f"Failed to construct the AuthnRequest: {exc}") return resp # remember the request @@ -688,7 +684,7 @@ def main(environ, start_response, sp): return sso.do() body = dict_to_table(user.data) - body.append("
{authn_stmt}
".format(authn_stmt=_html_escape(user.authn_statement))) + body.append(f"
{_html_escape(user.authn_statement)}
") body.append("
logout") resp = Response(body) @@ -777,17 +773,17 @@ def finish_logout(environ, start_response): def add_urls(): base = "acs" - urls.append(("%s/post$" % base, (ACS, "post", SP))) - urls.append(("%s/post/(.*)$" % base, (ACS, "post", SP))) - urls.append(("%s/redirect$" % base, (ACS, "redirect", SP))) - urls.append(("%s/redirect/(.*)$" % base, (ACS, "redirect", SP))) + urls.append((f"{base}/post$", (ACS, "post", SP))) + urls.append((f"{base}/post/(.*)$", (ACS, "post", SP))) + urls.append((f"{base}/redirect$", (ACS, "redirect", SP))) + urls.append((f"{base}/redirect/(.*)$", (ACS, "redirect", SP))) base = "slo" - urls.append(("%s/post$" % base, (SLO, "post", SP))) - urls.append(("%s/post/(.*)$" % base, (SLO, "post", SP))) - urls.append(("%s/redirect$" % base, (SLO, "redirect", SP))) - urls.append(("%s/redirect/(.*)$" % base, (SLO, "redirect", SP))) + urls.append((f"{base}/post$", (SLO, "post", SP))) + urls.append((f"{base}/post/(.*)$", (SLO, "post", SP))) + urls.append((f"{base}/redirect$", (SLO, "redirect", SP))) + urls.append((f"{base}/redirect/(.*)$", (SLO, "redirect", SP))) # ---------------------------------------------------------------------------- @@ -801,7 +797,7 @@ def metadata(environ, start_response): if path[-1] != "/": path += "/" metadata = create_metadata_string( - path + "sp_conf.py", + f"{path}sp_conf.py", None, _args.valid, _args.cert, @@ -851,18 +847,18 @@ def application(environ, start_response): return handle_static(environ, start_response, path) return not_found(environ, start_response) except StatusError as err: - logging.error("StatusError: %s" % err) - resp = BadRequest("%s" % err) + logging.error(f"StatusError: {err}") + resp = BadRequest(f"{err}") return resp(environ, start_response) except Exception as err: # _err = exception_trace("RUN", err) # logging.error(exception_trace("RUN", _err)) print(err, file=sys.stderr) - resp = ServiceError("%s" % err) + resp = ServiceError(f"{err}") return resp(environ, start_response) -class ToBytesMiddleware(object): +class ToBytesMiddleware: """Converts a message to bytes to be sent by WSGI server.""" def __init__(self, app): @@ -936,7 +932,7 @@ def __call__(self, environ, start_response): # your cert and all the way up to the top CERT_CHAIN = service_conf.CERT_CHAIN - SP = Saml2Client(config_file="%s" % CNFBASE) + SP = Saml2Client(config_file=f"{CNFBASE}") POLICY = service_conf.POLICY @@ -960,7 +956,7 @@ def __call__(self, environ, start_response): SRV.ssl_adapter = pyopenssl.pyOpenSSLAdapter(SERVER_CERT, SERVER_KEY, CERT_CHAIN) _https = " using SSL/TLS" logger.info("Server starting") - print("SP listening on %s:%s%s" % (HOST, PORT, _https)) + print(f"SP listening on {HOST}:{PORT}{_https}") try: SRV.start() except KeyboardInterrupt: diff --git a/pyproject.toml b/pyproject.toml index c61fa3b97..92c0b66f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,6 @@ python-dateutil = "*" pytz = "*" "repoze.who" = {optional = true, version = "*"} requests = "^2" -six = "*" xmlschema = ">=1.2.1" "zope.interface" = {optional = true, version = "*"} diff --git a/script/__init__.py b/script/__init__.py index 3b031d2bf..169408711 100644 --- a/script/__init__.py +++ b/script/__init__.py @@ -1 +1 @@ -__author__ = 'rolandh' +__author__ = "rolandh" diff --git a/script/filter_testcase_ids.py b/script/filter_testcase_ids.py index 675aefe5e..d7c75a3d1 100755 --- a/script/filter_testcase_ids.py +++ b/script/filter_testcase_ids.py @@ -2,9 +2,12 @@ # extract test case IDs from json-formatted list (`sp_testdrv.py -l` or `idp_testdrv.py -l`) # usage: # sp_testdrv.py -l | filter_testcase_ids.py -__author__ = 'rhoerbe' +__author__ = "rhoerbe" + +import json +import sys + -import json, sys jdata = json.load(sys.stdin) for k in jdata: print(k["id"]) diff --git a/script/idp_testdrv.py b/script/idp_testdrv.py index df86d5c6b..c57a78671 100755 --- a/script/idp_testdrv.py +++ b/script/idp_testdrv.py @@ -1,9 +1,10 @@ #!/usr/bin/env python -__author__ = 'rohe0002' +__author__ = "rohe0002" -#from idp_test import saml2base +# from idp_test import saml2base from idp_test import SAML2client from idp_test.check import factory + cli = SAML2client(factory) -cli.run() \ No newline at end of file +cli.run() diff --git a/script/sp_testdrv.py b/script/sp_testdrv.py index 14f943039..27522257b 100755 --- a/script/sp_testdrv.py +++ b/script/sp_testdrv.py @@ -1,9 +1,10 @@ #!/usr/bin/env python -__author__ = 'rohe0002' +__author__ = "rohe0002" -from sp_test import tests from sp_test import Client +from sp_test import tests from sp_test.check import factory + cli = Client(tests, factory) -cli.run() \ No newline at end of file +cli.run() diff --git a/script/utility/filter_testcase_ids.py b/script/utility/filter_testcase_ids.py index 675aefe5e..d7c75a3d1 100755 --- a/script/utility/filter_testcase_ids.py +++ b/script/utility/filter_testcase_ids.py @@ -2,9 +2,12 @@ # extract test case IDs from json-formatted list (`sp_testdrv.py -l` or `idp_testdrv.py -l`) # usage: # sp_testdrv.py -l | filter_testcase_ids.py -__author__ = 'rhoerbe' +__author__ = "rhoerbe" + +import json +import sys + -import json, sys jdata = json.load(sys.stdin) for k in jdata: print(k["id"]) diff --git a/script/utility/run_list_of_tests.py b/script/utility/run_list_of_tests.py index e0242d49a..2b01781af 100755 --- a/script/utility/run_list_of_tests.py +++ b/script/utility/run_list_of_tests.py @@ -3,8 +3,8 @@ import fileinput from subprocess import call + for line in fileinput.input(): - cmd = "./run_oper.sh " + line.rstrip() - print("executing " + cmd) + cmd = f"./run_oper.sh {line.rstrip()}" + print(f"executing {cmd}") call(cmd, shell=True) - diff --git a/src/saml2/__init__.py b/src/saml2/__init__.py index 34272fe8e..0397a3651 100644 --- a/src/saml2/__init__.py +++ b/src/saml2/__init__.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """Contains base classes representing SAML elements. @@ -18,30 +17,14 @@ """ import logging +from xml.etree import ElementTree -import six +import defusedxml.ElementTree from saml2.validate import valid_instance from saml2.version import version as __version__ -try: - from xml.etree import cElementTree as ElementTree - - if ElementTree.VERSION < "1.3.0": - # cElementTree has no support for register_namespace - # neither _namespace_map, thus we sacrify performance - # for correctness - from xml.etree import ElementTree -except ImportError: - try: - import cElementTree as ElementTree - except ImportError: - from elementtree import ElementTree - -import defusedxml.ElementTree - - logger = logging.getLogger(__name__) NAMESPACE = "urn:oasis:names:tc:SAML:2.0:assertion" @@ -79,7 +62,7 @@ def class_name(instance): - return "%s:%s" % (instance.c_namespace, instance.c_tag) + return f"{instance.c_namespace}:{instance.c_tag}" def create_class_from_xml_string(target_class, xml_string): @@ -96,7 +79,7 @@ def create_class_from_xml_string(target_class, xml_string): the contents of the XML - or None if the root XML tag and namespace did not match those of the target class. """ - if not isinstance(xml_string, six.binary_type): + if not isinstance(xml_string, bytes): xml_string = xml_string.encode("utf-8") tree = defusedxml.ElementTree.fromstring(xml_string) return create_class_from_element_tree(target_class, tree) @@ -126,7 +109,7 @@ class members. namespace = target_class.c_namespace if tag is None: tag = target_class.c_tag - if tree.tag == "{%s}%s" % (namespace, tag): + if tree.tag == f"{{{namespace}}}{tag}": target = target_class() target.harvest_element_tree(tree) return target @@ -137,14 +120,12 @@ class members. class Error(Exception): """Exception class thrown by this module.""" - pass - class SAMLError(Exception): pass -class ExtensionElement(object): +class ExtensionElement: """XML which is not part of the SAML specification, these are called extension elements. If a classes parser encounters an unexpected XML construct, it is translated into an @@ -184,7 +165,7 @@ def transfer_to_element_tree(self): element_tree = ElementTree.Element("") if self.namespace is not None: - element_tree.tag = "{%s}%s" % (self.namespace, self.tag) + element_tree.tag = f"{{{self.namespace}}}{self.tag}" else: element_tree.tag = self.tag @@ -300,7 +281,7 @@ def _extension_element_from_element_tree(element_tree): return extension -class ExtensionContainer(object): +class ExtensionContainer: c_tag = "" c_namespace = "" @@ -464,8 +445,7 @@ class SamlBase(ExtensionContainer): def _get_all_c_children_with_order(self): if len(self.c_child_order) > 0: - for child in self.c_child_order: - yield child + yield from self.c_child_order else: for _, values in iter(self.__class__.c_children.items()): yield values[0] @@ -542,7 +522,7 @@ def _to_element_tree(self): should not be called on in this class. """ - new_tree = ElementTree.Element("{%s}%s" % (self.__class__.c_namespace, self.__class__.c_tag)) + new_tree = ElementTree.Element(f"{{{self.__class__.c_namespace}}}{self.__class__.c_tag}") self._add_members_to_element_tree(new_tree) return new_tree @@ -591,7 +571,7 @@ def get_prefix_map(self, elements): uri_set = self.get_ns_map(elements, set()) prefix_map = {} for uri in sorted(uri_set): - prefix_map["encas%d" % len(prefix_map)] = uri + prefix_map[f"encas{len(prefix_map)}"] = uri return prefix_map def get_xml_string_with_self_contained_assertion_within_advice_encrypted_assertion(self, assertion_tag, advice_tag): @@ -632,7 +612,7 @@ def set_prefixes(self, elem, prefix_map): uri_map = {} for prefix, uri in prefix_map.items(): uri_map[uri] = prefix - elem.set("xmlns:" + prefix, uri) + elem.set(f"xmlns:{prefix}", uri) # fixup all elements in the tree memo = {} @@ -648,7 +628,7 @@ def fixup(name): return uri, tag = name[1:].split("}") if uri in uri_map: - new_name = uri_map[uri] + ":" + tag + new_name = f"{uri_map[uri]}:{tag}" memo[name] = new_name return new_name @@ -689,7 +669,7 @@ def to_string(self, nspair=None): def __str__(self): # Yes this is confusing. http://bugs.python.org/issue10942 x = self.to_string() - if not isinstance(x, six.string_types): + if not isinstance(x, str): x = x.decode("utf-8") return x @@ -742,12 +722,12 @@ def set_text(self, val, base64encode=False): self.text = "true" if val else "false" elif isinstance(val, int): self.text = str(val) - elif isinstance(val, six.string_types): + elif isinstance(val, str): self.text = val elif val is None: pass else: - raise ValueError("Type shouldn't be '%s'" % val) + raise ValueError(f"Type shouldn't be '{val}'") return self @@ -817,7 +797,7 @@ def __eq__(self, other): continue svals = self.__dict__[key] ovals = other.__dict__[key] - if isinstance(svals, six.string_types): + if isinstance(svals, str): if svals != ovals: return False elif isinstance(svals, list): diff --git a/src/saml2/assertion.py b/src/saml2/assertion.py index 237bca7bd..344c78630 100644 --- a/src/saml2/assertion.py +++ b/src/saml2/assertion.py @@ -1,13 +1,10 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import copy import importlib import logging import re from warnings import warn as _warn -import six - from saml2 import saml from saml2 import xmlenc from saml2.attribute_converter import ac_factory @@ -40,7 +37,7 @@ def _filter_values(vals, vlist=None, must=False): if vals is None: # cannot iterate over None, return early return vals - if isinstance(vlist, six.string_types): + if isinstance(vlist, str): vlist = [vlist] res = [] @@ -120,7 +117,7 @@ def _apply_attr_value_restrictions(attr, res, must=False): if _fn: _apply_attr_value_restrictions(attr, res, True) elif fail_on_unfulfilled_requirements: - desc = "Required attribute missing: '%s'" % (attr["name"]) + desc = f"Required attribute missing: '{attr['name']}'" raise MissingValue(desc) if optional is None: @@ -148,7 +145,7 @@ def filter_on_demands(ava, required=None, optional=None): if required is None: required = {} - lava = dict([(k.lower(), k) for k in ava.keys()]) + lava = {k.lower(): k for k in ava.keys()} for attr, vals in required.items(): attr = attr.lower() @@ -156,9 +153,9 @@ def filter_on_demands(ava, required=None, optional=None): if vals: for val in vals: if val not in ava[lava[attr]]: - raise MissingValue("Required attribute value missing: %s,%s" % (attr, val)) + raise MissingValue(f"Required attribute value missing: {attr},{val}") else: - raise MissingValue("Required attribute missing: %s" % (attr,)) + raise MissingValue(f"Required attribute missing: {attr}") if optional is None: optional = {} @@ -184,7 +181,7 @@ def filter_on_wire_representation(ava, acs, required=None, optional=None): :param optional: A list of saml.Attributes :return: Dictionary of expected/wanted attributes and values """ - acsdic = dict([(ac.name_format, ac) for ac in acs]) + acsdic = {ac.name_format: ac for ac in acs} if required is None: required = [] @@ -239,7 +236,7 @@ def filter_attribute_value_assertions(ava, attribute_restrictions=None): else: if _rests is None: continue - if isinstance(vals, six.string_types): + if isinstance(vals, str): vals = [vals] rvals = [] for restr in _rests: @@ -287,7 +284,7 @@ def compile(restrictions): try: _mod = importlib.import_module(cat) except ImportError: - _mod = importlib.import_module("saml2.entity_category.%s" % cat) + _mod = importlib.import_module(f"saml2.entity_category.{cat}") _ec = {} for key, items in _mod.RELEASE.items(): @@ -308,7 +305,7 @@ def compile(restrictions): return restrictions -class Policy(object): +class Policy: """Handles restrictions on assertions.""" def __init__(self, restrictions=None, mds=None): @@ -582,7 +579,7 @@ def conditions(self, sp_entity_id): ) -class EntityCategories(object): +class EntityCategories: pass @@ -791,7 +788,7 @@ def construct( if encrypt == "attributes": for attr in attr_statement.attribute: - enc = sec_context.encrypt(text="%s" % attr) + enc = sec_context.encrypt(text=f"{attr}") encd = xmlenc.encrypted_data_from_string(enc) encattr = saml.EncryptedAttribute(encrypted_data=encd) diff --git a/src/saml2/attribute_converter.py b/src/saml2/attribute_converter.py index 900384f9d..7e86b9170 100644 --- a/src/saml2/attribute_converter.py +++ b/src/saml2/attribute_converter.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # from importlib import import_module @@ -71,7 +70,7 @@ def ac_factory(path=""): from saml2 import attributemaps for typ in attributemaps.__all__: - mod = import_module(".%s" % typ, "saml2.attributemaps") + mod = import_module(f".{typ}", "saml2.attributemaps") acs.extend(_attribute_map_module_to_acs(mod)) return acs @@ -131,7 +130,7 @@ def list_to_local(acs, attrlist, allow_unknown_attributes=False): acs = [AttributeConverter()] acsd = {"": acs} else: - acsd = dict([(a.name_format, a) for a in acs]) + acsd = {a.name_format: a for a in acs} ava = {} for attr in attrlist: @@ -224,10 +223,10 @@ def d_to_local_name(acs, attr): try: return attr["friendly_name"] except KeyError: - raise ConverterError("Could not find local name for %s" % attr) + raise ConverterError(f"Could not find local name for {attr}") -class AttributeConverter(object): +class AttributeConverter: """Converts from an attribute statement to a key,value dictionary and vice-versa""" @@ -242,9 +241,9 @@ def adjust(self): """ if self._fro is None and self._to is not None: - self._fro = dict([(value.lower(), key) for key, value in self._to.items()]) + self._fro = {value.lower(): key for key, value in self._to.items()} if self._to is None and self._fro is not None: - self._to = dict([(value.lower(), key) for key, value in self._fro.items()]) + self._to = {value.lower(): key for key, value in self._fro.items()} def from_dict(self, mapdict): """Import the attribute map from a dictionary @@ -254,11 +253,11 @@ def from_dict(self, mapdict): self.name_format = mapdict["identifier"] try: - self._fro = dict([(k.lower(), v) for k, v in mapdict["fro"].items()]) + self._fro = {k.lower(): v for k, v in mapdict["fro"].items()} except KeyError: pass try: - self._to = dict([(k.lower(), v) for k, v in mapdict["to"].items()]) + self._to = {k.lower(): v for k, v in mapdict["to"].items()} except KeyError: pass diff --git a/src/saml2/attribute_resolver.py b/src/saml2/attribute_resolver.py index c89dd095e..e555c58ce 100644 --- a/src/saml2/attribute_resolver.py +++ b/src/saml2/attribute_resolver.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """ @@ -17,7 +16,7 @@ DEFAULT_BINDING = BINDING_SOAP -class AttributeResolver(object): +class AttributeResolver: def __init__(self, saml2client, metadata=None, config=None): self.metadata = metadata self.saml2client = saml2client diff --git a/src/saml2/attributemaps/adfs_v1x.py b/src/saml2/attributemaps/adfs_v1x.py index 69f99fbd2..0e405bfb9 100644 --- a/src/saml2/attributemaps/adfs_v1x.py +++ b/src/saml2/attributemaps/adfs_v1x.py @@ -4,15 +4,15 @@ MAP = { "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified", "fro": { - CLAIMS + "commonname": "commonName", - CLAIMS + "emailaddress": "emailAddress", - CLAIMS + "group": "group", - CLAIMS + "upn": "upn", + f"{CLAIMS}commonname": "commonName", + f"{CLAIMS}emailaddress": "emailAddress", + f"{CLAIMS}group": "group", + f"{CLAIMS}upn": "upn", }, "to": { - "commonName": CLAIMS + "commonname", - "emailAddress": CLAIMS + "emailaddress", - "group": CLAIMS + "group", - "upn": CLAIMS + "upn", + "commonName": f"{CLAIMS}commonname", + "emailAddress": f"{CLAIMS}emailaddress", + "group": f"{CLAIMS}group", + "upn": f"{CLAIMS}upn", }, } diff --git a/src/saml2/attributemaps/adfs_v20.py b/src/saml2/attributemaps/adfs_v20.py index ab2e30882..20a006756 100644 --- a/src/saml2/attributemaps/adfs_v20.py +++ b/src/saml2/attributemaps/adfs_v20.py @@ -7,43 +7,43 @@ MAP = { "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified", "fro": { - CLAIMS + "commonname": "commonName", - CLAIMS + "group": "group", - COM_WS_CLAIMS + "denyonlysid": "denyOnlySid", - MS_CLAIMS + "authenticationmethod": "authenticationMethod", - MS_CLAIMS + "denyonlyprimarygroupsid": "denyOnlyPrimaryGroupSid", - MS_CLAIMS + "denyonlyprimarysid": "denyOnlyPrimarySid", - MS_CLAIMS + "groupsid": "groupSid", - MS_CLAIMS + "primarygroupsid": "primaryGroupSid", - MS_CLAIMS + "primarysid": "primarySid", - MS_CLAIMS + "role": "role", - MS_CLAIMS + "windowsaccountname": "windowsAccountName", - ORG_WS_CLAIMS + "emailaddress": "emailAddress", - ORG_WS_CLAIMS + "givenname": "givenName", - ORG_WS_CLAIMS + "name": "name", - ORG_WS_CLAIMS + "nameidentifier": "nameId", - ORG_WS_CLAIMS + "privatepersonalidentifier": "privatePersonalId", - ORG_WS_CLAIMS + "surname": "surname", - ORG_WS_CLAIMS + "upn": "upn", + f"{CLAIMS}commonname": "commonName", + f"{CLAIMS}group": "group", + f"{COM_WS_CLAIMS}denyonlysid": "denyOnlySid", + f"{MS_CLAIMS}authenticationmethod": "authenticationMethod", + f"{MS_CLAIMS}denyonlyprimarygroupsid": "denyOnlyPrimaryGroupSid", + f"{MS_CLAIMS}denyonlyprimarysid": "denyOnlyPrimarySid", + f"{MS_CLAIMS}groupsid": "groupSid", + f"{MS_CLAIMS}primarygroupsid": "primaryGroupSid", + f"{MS_CLAIMS}primarysid": "primarySid", + f"{MS_CLAIMS}role": "role", + f"{MS_CLAIMS}windowsaccountname": "windowsAccountName", + f"{ORG_WS_CLAIMS}emailaddress": "emailAddress", + f"{ORG_WS_CLAIMS}givenname": "givenName", + f"{ORG_WS_CLAIMS}name": "name", + f"{ORG_WS_CLAIMS}nameidentifier": "nameId", + f"{ORG_WS_CLAIMS}privatepersonalidentifier": "privatePersonalId", + f"{ORG_WS_CLAIMS}surname": "surname", + f"{ORG_WS_CLAIMS}upn": "upn", }, "to": { - "authenticationMethod": MS_CLAIMS + "authenticationmethod", - "commonName": CLAIMS + "commonname", - "denyOnlyPrimaryGroupSid": MS_CLAIMS + "denyonlyprimarygroupsid", - "denyOnlyPrimarySid": MS_CLAIMS + "denyonlyprimarysid", - "denyOnlySid": COM_WS_CLAIMS + "denyonlysid", - "emailAddress": ORG_WS_CLAIMS + "emailaddress", - "givenName": ORG_WS_CLAIMS + "givenname", - "group": CLAIMS + "group", - "groupSid": MS_CLAIMS + "groupsid", - "name": ORG_WS_CLAIMS + "name", - "nameId": ORG_WS_CLAIMS + "nameidentifier", - "primaryGroupSid": MS_CLAIMS + "primarygroupsid", - "primarySid": MS_CLAIMS + "primarysid", - "privatePersonalId": ORG_WS_CLAIMS + "privatepersonalidentifier", - "role": MS_CLAIMS + "role", - "surname": ORG_WS_CLAIMS + "surname", - "upn": ORG_WS_CLAIMS + "upn", - "windowsAccountName": MS_CLAIMS + "windowsaccountname", + "authenticationMethod": f"{MS_CLAIMS}authenticationmethod", + "commonName": f"{CLAIMS}commonname", + "denyOnlyPrimaryGroupSid": f"{MS_CLAIMS}denyonlyprimarygroupsid", + "denyOnlyPrimarySid": f"{MS_CLAIMS}denyonlyprimarysid", + "denyOnlySid": f"{COM_WS_CLAIMS}denyonlysid", + "emailAddress": f"{ORG_WS_CLAIMS}emailaddress", + "givenName": f"{ORG_WS_CLAIMS}givenname", + "group": f"{CLAIMS}group", + "groupSid": f"{MS_CLAIMS}groupsid", + "name": f"{ORG_WS_CLAIMS}name", + "nameId": f"{ORG_WS_CLAIMS}nameidentifier", + "primaryGroupSid": f"{MS_CLAIMS}primarygroupsid", + "primarySid": f"{MS_CLAIMS}primarysid", + "privatePersonalId": f"{ORG_WS_CLAIMS}privatepersonalidentifier", + "role": f"{MS_CLAIMS}role", + "surname": f"{ORG_WS_CLAIMS}surname", + "upn": f"{ORG_WS_CLAIMS}upn", + "windowsAccountName": f"{MS_CLAIMS}windowsaccountname", }, } diff --git a/src/saml2/attributemaps/basic.py b/src/saml2/attributemaps/basic.py index 9ad8fb54b..995dbd431 100644 --- a/src/saml2/attributemaps/basic.py +++ b/src/saml2/attributemaps/basic.py @@ -4,339 +4,339 @@ MAP = { "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:basic", "fro": { - DEF + "aRecord": "aRecord", - DEF + "aliasedEntryName": "aliasedEntryName", - DEF + "aliasedObjectName": "aliasedObjectName", - DEF + "associatedDomain": "associatedDomain", - DEF + "associatedName": "associatedName", - DEF + "audio": "audio", - DEF + "authorityRevocationList": "authorityRevocationList", - DEF + "buildingName": "buildingName", - DEF + "businessCategory": "businessCategory", - DEF + "c": "c", - DEF + "cACertificate": "cACertificate", - DEF + "cNAMERecord": "cNAMERecord", - DEF + "carLicense": "carLicense", - DEF + "certificateRevocationList": "certificateRevocationList", - DEF + "cn": "cn", - DEF + "co": "co", - DEF + "commonName": "commonName", - DEF + "countryName": "countryName", - DEF + "crossCertificatePair": "crossCertificatePair", - DEF + "dITRedirect": "dITRedirect", - DEF + "dSAQuality": "dSAQuality", - DEF + "dc": "dc", - DEF + "deltaRevocationList": "deltaRevocationList", - DEF + "departmentNumber": "departmentNumber", - DEF + "description": "description", - DEF + "destinationIndicator": "destinationIndicator", - DEF + "displayName": "displayName", - DEF + "distinguishedName": "distinguishedName", - DEF + "dmdName": "dmdName", - DEF + "dnQualifier": "dnQualifier", - DEF + "documentAuthor": "documentAuthor", - DEF + "documentIdentifier": "documentIdentifier", - DEF + "documentLocation": "documentLocation", - DEF + "documentPublisher": "documentPublisher", - DEF + "documentTitle": "documentTitle", - DEF + "documentVersion": "documentVersion", - DEF + "domainComponent": "domainComponent", - DEF + "drink": "drink", - DEF + "eduOrgHomePageURI": "eduOrgHomePageURI", - DEF + "eduOrgIdentityAuthNPolicyURI": "eduOrgIdentityAuthNPolicyURI", - DEF + "eduOrgLegalName": "eduOrgLegalName", - DEF + "eduOrgSuperiorURI": "eduOrgSuperiorURI", - DEF + "eduOrgWhitePagesURI": "eduOrgWhitePagesURI", - DEF + "eduCourseOffering": "eduCourseOffering", - DEF + "eduCourseMember": "eduCourseMember", - DEF + "eduPersonAffiliation": "eduPersonAffiliation", - DEF + "eduPersonEntitlement": "eduPersonEntitlement", - DEF + "eduPersonNickname": "eduPersonNickname", - DEF + "eduPersonOrgDN": "eduPersonOrgDN", - DEF + "eduPersonOrgUnitDN": "eduPersonOrgUnitDN", - DEF + "eduPersonPrimaryAffiliation": "eduPersonPrimaryAffiliation", - DEF + "eduPersonPrimaryOrgUnitDN": "eduPersonPrimaryOrgUnitDN", - DEF + "eduPersonPrincipalName": "eduPersonPrincipalName", - DEF + "eduPersonPrincipalNamePrior": "eduPersonPrincipalNamePrior", - DEF + "eduPersonScopedAffiliation": "eduPersonScopedAffiliation", - DEF + "eduPersonTargetedID": "eduPersonTargetedID", - DEF + "eduPersonAssurance": "eduPersonAssurance", - DEF + "eduPersonUniqueId": "eduPersonUniqueId", - DEF + "eduPersonOrcid": "eduPersonOrcid", - DEF + "email": "email", - DEF + "emailAddress": "emailAddress", - DEF + "employeeNumber": "employeeNumber", - DEF + "employeeType": "employeeType", - DEF + "enhancedSearchGuide": "enhancedSearchGuide", - DEF + "facsimileTelephoneNumber": "facsimileTelephoneNumber", - DEF + "favouriteDrink": "favouriteDrink", - DEF + "fax": "fax", - DEF + "federationFeideSchemaVersion": "federationFeideSchemaVersion", - DEF + "friendlyCountryName": "friendlyCountryName", - DEF + "generationQualifier": "generationQualifier", - DEF + "givenName": "givenName", - DEF + "gn": "gn", - DEF + "homePhone": "homePhone", - DEF + "homePostalAddress": "homePostalAddress", - DEF + "homeTelephoneNumber": "homeTelephoneNumber", - DEF + "host": "host", - DEF + "houseIdentifier": "houseIdentifier", - DEF + "info": "info", - DEF + "initials": "initials", - DEF + "internationaliSDNNumber": "internationaliSDNNumber", - DEF + "isMemberOf": "isMemberOf", - DEF + "janetMailbox": "janetMailbox", - DEF + "jpegPhoto": "jpegPhoto", - DEF + "knowledgeInformation": "knowledgeInformation", - DEF + "l": "l", - DEF + "labeledURI": "labeledURI", - DEF + "localityName": "localityName", - DEF + "mDRecord": "mDRecord", - DEF + "mXRecord": "mXRecord", - DEF + "mail": "mail", - DEF + "mailPreferenceOption": "mailPreferenceOption", - DEF + "manager": "manager", - DEF + "member": "member", - DEF + "mobile": "mobile", - DEF + "mobileTelephoneNumber": "mobileTelephoneNumber", - DEF + "nSRecord": "nSRecord", - DEF + "name": "name", - DEF + "norEduOrgAcronym": "norEduOrgAcronym", - DEF + "norEduOrgNIN": "norEduOrgNIN", - DEF + "norEduOrgSchemaVersion": "norEduOrgSchemaVersion", - DEF + "norEduOrgUniqueIdentifier": "norEduOrgUniqueIdentifier", - DEF + "norEduOrgUniqueNumber": "norEduOrgUniqueNumber", - DEF + "norEduOrgUnitUniqueIdentifier": "norEduOrgUnitUniqueIdentifier", - DEF + "norEduOrgUnitUniqueNumber": "norEduOrgUnitUniqueNumber", - DEF + "norEduPersonBirthDate": "norEduPersonBirthDate", - DEF + "norEduPersonLIN": "norEduPersonLIN", - DEF + "norEduPersonNIN": "norEduPersonNIN", - DEF + "o": "o", - DEF + "objectClass": "objectClass", - DEF + "organizationName": "organizationName", - DEF + "organizationalStatus": "organizationalStatus", - DEF + "organizationalUnitName": "organizationalUnitName", - DEF + "otherMailbox": "otherMailbox", - DEF + "ou": "ou", - DEF + "owner": "owner", - DEF + "pager": "pager", - DEF + "pagerTelephoneNumber": "pagerTelephoneNumber", - DEF + "personalSignature": "personalSignature", - DEF + "personalTitle": "personalTitle", - DEF + "photo": "photo", - DEF + "physicalDeliveryOfficeName": "physicalDeliveryOfficeName", - DEF + "pkcs9email": "pkcs9email", - DEF + "postOfficeBox": "postOfficeBox", - DEF + "postalAddress": "postalAddress", - DEF + "postalCode": "postalCode", - DEF + "preferredDeliveryMethod": "preferredDeliveryMethod", - DEF + "preferredLanguage": "preferredLanguage", - DEF + "presentationAddress": "presentationAddress", - DEF + "protocolInformation": "protocolInformation", - DEF + "pseudonym": "pseudonym", - DEF + "registeredAddress": "registeredAddress", - DEF + "rfc822Mailbox": "rfc822Mailbox", - DEF + "roleOccupant": "roleOccupant", - DEF + "roomNumber": "roomNumber", - DEF + "sOARecord": "sOARecord", - DEF + "searchGuide": "searchGuide", - DEF + "secretary": "secretary", - DEF + "seeAlso": "seeAlso", - DEF + "serialNumber": "serialNumber", - DEF + "singleLevelQuality": "singleLevelQuality", - DEF + "sn": "sn", - DEF + "st": "st", - DEF + "stateOrProvinceName": "stateOrProvinceName", - DEF + "street": "street", - DEF + "streetAddress": "streetAddress", - DEF + "subtreeMaximumQuality": "subtreeMaximumQuality", - DEF + "subtreeMinimumQuality": "subtreeMinimumQuality", - DEF + "supportedAlgorithms": "supportedAlgorithms", - DEF + "supportedApplicationContext": "supportedApplicationContext", - DEF + "surname": "surname", - DEF + "telephoneNumber": "telephoneNumber", - DEF + "teletexTerminalIdentifier": "teletexTerminalIdentifier", - DEF + "telexNumber": "telexNumber", - DEF + "textEncodedORAddress": "textEncodedORAddress", - DEF + "title": "title", - DEF + "uid": "uid", - DEF + "uniqueIdentifier": "uniqueIdentifier", - DEF + "uniqueMember": "uniqueMember", - DEF + "userCertificate": "userCertificate", - DEF + "userClass": "userClass", - DEF + "userPKCS12": "userPKCS12", - DEF + "userPassword": "userPassword", - DEF + "userSMIMECertificate": "userSMIMECertificate", - DEF + "userid": "userid", - DEF + "x121Address": "x121Address", - DEF + "x500UniqueIdentifier": "x500UniqueIdentifier", + f"{DEF}aRecord": "aRecord", + f"{DEF}aliasedEntryName": "aliasedEntryName", + f"{DEF}aliasedObjectName": "aliasedObjectName", + f"{DEF}associatedDomain": "associatedDomain", + f"{DEF}associatedName": "associatedName", + f"{DEF}audio": "audio", + f"{DEF}authorityRevocationList": "authorityRevocationList", + f"{DEF}buildingName": "buildingName", + f"{DEF}businessCategory": "businessCategory", + f"{DEF}c": "c", + f"{DEF}cACertificate": "cACertificate", + f"{DEF}cNAMERecord": "cNAMERecord", + f"{DEF}carLicense": "carLicense", + f"{DEF}certificateRevocationList": "certificateRevocationList", + f"{DEF}cn": "cn", + f"{DEF}co": "co", + f"{DEF}commonName": "commonName", + f"{DEF}countryName": "countryName", + f"{DEF}crossCertificatePair": "crossCertificatePair", + f"{DEF}dITRedirect": "dITRedirect", + f"{DEF}dSAQuality": "dSAQuality", + f"{DEF}dc": "dc", + f"{DEF}deltaRevocationList": "deltaRevocationList", + f"{DEF}departmentNumber": "departmentNumber", + f"{DEF}description": "description", + f"{DEF}destinationIndicator": "destinationIndicator", + f"{DEF}displayName": "displayName", + f"{DEF}distinguishedName": "distinguishedName", + f"{DEF}dmdName": "dmdName", + f"{DEF}dnQualifier": "dnQualifier", + f"{DEF}documentAuthor": "documentAuthor", + f"{DEF}documentIdentifier": "documentIdentifier", + f"{DEF}documentLocation": "documentLocation", + f"{DEF}documentPublisher": "documentPublisher", + f"{DEF}documentTitle": "documentTitle", + f"{DEF}documentVersion": "documentVersion", + f"{DEF}domainComponent": "domainComponent", + f"{DEF}drink": "drink", + f"{DEF}eduOrgHomePageURI": "eduOrgHomePageURI", + f"{DEF}eduOrgIdentityAuthNPolicyURI": "eduOrgIdentityAuthNPolicyURI", + f"{DEF}eduOrgLegalName": "eduOrgLegalName", + f"{DEF}eduOrgSuperiorURI": "eduOrgSuperiorURI", + f"{DEF}eduOrgWhitePagesURI": "eduOrgWhitePagesURI", + f"{DEF}eduCourseOffering": "eduCourseOffering", + f"{DEF}eduCourseMember": "eduCourseMember", + f"{DEF}eduPersonAffiliation": "eduPersonAffiliation", + f"{DEF}eduPersonEntitlement": "eduPersonEntitlement", + f"{DEF}eduPersonNickname": "eduPersonNickname", + f"{DEF}eduPersonOrgDN": "eduPersonOrgDN", + f"{DEF}eduPersonOrgUnitDN": "eduPersonOrgUnitDN", + f"{DEF}eduPersonPrimaryAffiliation": "eduPersonPrimaryAffiliation", + f"{DEF}eduPersonPrimaryOrgUnitDN": "eduPersonPrimaryOrgUnitDN", + f"{DEF}eduPersonPrincipalName": "eduPersonPrincipalName", + f"{DEF}eduPersonPrincipalNamePrior": "eduPersonPrincipalNamePrior", + f"{DEF}eduPersonScopedAffiliation": "eduPersonScopedAffiliation", + f"{DEF}eduPersonTargetedID": "eduPersonTargetedID", + f"{DEF}eduPersonAssurance": "eduPersonAssurance", + f"{DEF}eduPersonUniqueId": "eduPersonUniqueId", + f"{DEF}eduPersonOrcid": "eduPersonOrcid", + f"{DEF}email": "email", + f"{DEF}emailAddress": "emailAddress", + f"{DEF}employeeNumber": "employeeNumber", + f"{DEF}employeeType": "employeeType", + f"{DEF}enhancedSearchGuide": "enhancedSearchGuide", + f"{DEF}facsimileTelephoneNumber": "facsimileTelephoneNumber", + f"{DEF}favouriteDrink": "favouriteDrink", + f"{DEF}fax": "fax", + f"{DEF}federationFeideSchemaVersion": "federationFeideSchemaVersion", + f"{DEF}friendlyCountryName": "friendlyCountryName", + f"{DEF}generationQualifier": "generationQualifier", + f"{DEF}givenName": "givenName", + f"{DEF}gn": "gn", + f"{DEF}homePhone": "homePhone", + f"{DEF}homePostalAddress": "homePostalAddress", + f"{DEF}homeTelephoneNumber": "homeTelephoneNumber", + f"{DEF}host": "host", + f"{DEF}houseIdentifier": "houseIdentifier", + f"{DEF}info": "info", + f"{DEF}initials": "initials", + f"{DEF}internationaliSDNNumber": "internationaliSDNNumber", + f"{DEF}isMemberOf": "isMemberOf", + f"{DEF}janetMailbox": "janetMailbox", + f"{DEF}jpegPhoto": "jpegPhoto", + f"{DEF}knowledgeInformation": "knowledgeInformation", + f"{DEF}l": "l", + f"{DEF}labeledURI": "labeledURI", + f"{DEF}localityName": "localityName", + f"{DEF}mDRecord": "mDRecord", + f"{DEF}mXRecord": "mXRecord", + f"{DEF}mail": "mail", + f"{DEF}mailPreferenceOption": "mailPreferenceOption", + f"{DEF}manager": "manager", + f"{DEF}member": "member", + f"{DEF}mobile": "mobile", + f"{DEF}mobileTelephoneNumber": "mobileTelephoneNumber", + f"{DEF}nSRecord": "nSRecord", + f"{DEF}name": "name", + f"{DEF}norEduOrgAcronym": "norEduOrgAcronym", + f"{DEF}norEduOrgNIN": "norEduOrgNIN", + f"{DEF}norEduOrgSchemaVersion": "norEduOrgSchemaVersion", + f"{DEF}norEduOrgUniqueIdentifier": "norEduOrgUniqueIdentifier", + f"{DEF}norEduOrgUniqueNumber": "norEduOrgUniqueNumber", + f"{DEF}norEduOrgUnitUniqueIdentifier": "norEduOrgUnitUniqueIdentifier", + f"{DEF}norEduOrgUnitUniqueNumber": "norEduOrgUnitUniqueNumber", + f"{DEF}norEduPersonBirthDate": "norEduPersonBirthDate", + f"{DEF}norEduPersonLIN": "norEduPersonLIN", + f"{DEF}norEduPersonNIN": "norEduPersonNIN", + f"{DEF}o": "o", + f"{DEF}objectClass": "objectClass", + f"{DEF}organizationName": "organizationName", + f"{DEF}organizationalStatus": "organizationalStatus", + f"{DEF}organizationalUnitName": "organizationalUnitName", + f"{DEF}otherMailbox": "otherMailbox", + f"{DEF}ou": "ou", + f"{DEF}owner": "owner", + f"{DEF}pager": "pager", + f"{DEF}pagerTelephoneNumber": "pagerTelephoneNumber", + f"{DEF}personalSignature": "personalSignature", + f"{DEF}personalTitle": "personalTitle", + f"{DEF}photo": "photo", + f"{DEF}physicalDeliveryOfficeName": "physicalDeliveryOfficeName", + f"{DEF}pkcs9email": "pkcs9email", + f"{DEF}postOfficeBox": "postOfficeBox", + f"{DEF}postalAddress": "postalAddress", + f"{DEF}postalCode": "postalCode", + f"{DEF}preferredDeliveryMethod": "preferredDeliveryMethod", + f"{DEF}preferredLanguage": "preferredLanguage", + f"{DEF}presentationAddress": "presentationAddress", + f"{DEF}protocolInformation": "protocolInformation", + f"{DEF}pseudonym": "pseudonym", + f"{DEF}registeredAddress": "registeredAddress", + f"{DEF}rfc822Mailbox": "rfc822Mailbox", + f"{DEF}roleOccupant": "roleOccupant", + f"{DEF}roomNumber": "roomNumber", + f"{DEF}sOARecord": "sOARecord", + f"{DEF}searchGuide": "searchGuide", + f"{DEF}secretary": "secretary", + f"{DEF}seeAlso": "seeAlso", + f"{DEF}serialNumber": "serialNumber", + f"{DEF}singleLevelQuality": "singleLevelQuality", + f"{DEF}sn": "sn", + f"{DEF}st": "st", + f"{DEF}stateOrProvinceName": "stateOrProvinceName", + f"{DEF}street": "street", + f"{DEF}streetAddress": "streetAddress", + f"{DEF}subtreeMaximumQuality": "subtreeMaximumQuality", + f"{DEF}subtreeMinimumQuality": "subtreeMinimumQuality", + f"{DEF}supportedAlgorithms": "supportedAlgorithms", + f"{DEF}supportedApplicationContext": "supportedApplicationContext", + f"{DEF}surname": "surname", + f"{DEF}telephoneNumber": "telephoneNumber", + f"{DEF}teletexTerminalIdentifier": "teletexTerminalIdentifier", + f"{DEF}telexNumber": "telexNumber", + f"{DEF}textEncodedORAddress": "textEncodedORAddress", + f"{DEF}title": "title", + f"{DEF}uid": "uid", + f"{DEF}uniqueIdentifier": "uniqueIdentifier", + f"{DEF}uniqueMember": "uniqueMember", + f"{DEF}userCertificate": "userCertificate", + f"{DEF}userClass": "userClass", + f"{DEF}userPKCS12": "userPKCS12", + f"{DEF}userPassword": "userPassword", + f"{DEF}userSMIMECertificate": "userSMIMECertificate", + f"{DEF}userid": "userid", + f"{DEF}x121Address": "x121Address", + f"{DEF}x500UniqueIdentifier": "x500UniqueIdentifier", }, "to": { - "aRecord": DEF + "aRecord", - "aliasedEntryName": DEF + "aliasedEntryName", - "aliasedObjectName": DEF + "aliasedObjectName", - "associatedDomain": DEF + "associatedDomain", - "associatedName": DEF + "associatedName", - "audio": DEF + "audio", - "authorityRevocationList": DEF + "authorityRevocationList", - "buildingName": DEF + "buildingName", - "businessCategory": DEF + "businessCategory", - "c": DEF + "c", - "cACertificate": DEF + "cACertificate", - "cNAMERecord": DEF + "cNAMERecord", - "carLicense": DEF + "carLicense", - "certificateRevocationList": DEF + "certificateRevocationList", - "cn": DEF + "cn", - "co": DEF + "co", - "commonName": DEF + "commonName", - "countryName": DEF + "countryName", - "crossCertificatePair": DEF + "crossCertificatePair", - "dITRedirect": DEF + "dITRedirect", - "dSAQuality": DEF + "dSAQuality", - "dc": DEF + "dc", - "deltaRevocationList": DEF + "deltaRevocationList", - "departmentNumber": DEF + "departmentNumber", - "description": DEF + "description", - "destinationIndicator": DEF + "destinationIndicator", - "displayName": DEF + "displayName", - "distinguishedName": DEF + "distinguishedName", - "dmdName": DEF + "dmdName", - "dnQualifier": DEF + "dnQualifier", - "documentAuthor": DEF + "documentAuthor", - "documentIdentifier": DEF + "documentIdentifier", - "documentLocation": DEF + "documentLocation", - "documentPublisher": DEF + "documentPublisher", - "documentTitle": DEF + "documentTitle", - "documentVersion": DEF + "documentVersion", - "domainComponent": DEF + "domainComponent", - "drink": DEF + "drink", - "eduOrgHomePageURI": DEF + "eduOrgHomePageURI", - "eduOrgIdentityAuthNPolicyURI": DEF + "eduOrgIdentityAuthNPolicyURI", - "eduOrgLegalName": DEF + "eduOrgLegalName", - "eduOrgSuperiorURI": DEF + "eduOrgSuperiorURI", - "eduOrgWhitePagesURI": DEF + "eduOrgWhitePagesURI", - "eduCourseMember": DEF + "eduCourseMember", - "eduCourseOffering": DEF + "eduCourseOffering", - "eduPersonAffiliation": DEF + "eduPersonAffiliation", - "eduPersonEntitlement": DEF + "eduPersonEntitlement", - "eduPersonNickname": DEF + "eduPersonNickname", - "eduPersonOrgDN": DEF + "eduPersonOrgDN", - "eduPersonOrgUnitDN": DEF + "eduPersonOrgUnitDN", - "eduPersonPrimaryAffiliation": DEF + "eduPersonPrimaryAffiliation", - "eduPersonPrimaryOrgUnitDN": DEF + "eduPersonPrimaryOrgUnitDN", - "eduPersonPrincipalName": DEF + "eduPersonPrincipalName", - "eduPersonPrincipalNamePrior": DEF + "eduPersonPrincipalNamePrior", - "eduPersonScopedAffiliation": DEF + "eduPersonScopedAffiliation", - "eduPersonTargetedID": DEF + "eduPersonTargetedID", - "eduPersonAssurance": DEF + "eduPersonAssurance", - "eduPersonUniqueId": DEF + "eduPersonUniqueId", - "eduPersonOrcid": DEF + "eduPersonOrcid", - "email": DEF + "email", - "emailAddress": DEF + "emailAddress", - "employeeNumber": DEF + "employeeNumber", - "employeeType": DEF + "employeeType", - "enhancedSearchGuide": DEF + "enhancedSearchGuide", - "facsimileTelephoneNumber": DEF + "facsimileTelephoneNumber", - "favouriteDrink": DEF + "favouriteDrink", - "fax": DEF + "fax", - "federationFeideSchemaVersion": DEF + "federationFeideSchemaVersion", - "friendlyCountryName": DEF + "friendlyCountryName", - "generationQualifier": DEF + "generationQualifier", - "givenName": DEF + "givenName", - "gn": DEF + "gn", - "homePhone": DEF + "homePhone", - "homePostalAddress": DEF + "homePostalAddress", - "homeTelephoneNumber": DEF + "homeTelephoneNumber", - "host": DEF + "host", - "houseIdentifier": DEF + "houseIdentifier", - "info": DEF + "info", - "initials": DEF + "initials", - "internationaliSDNNumber": DEF + "internationaliSDNNumber", - "isMemberOf": DEF + "isMemberOf", - "janetMailbox": DEF + "janetMailbox", - "jpegPhoto": DEF + "jpegPhoto", - "knowledgeInformation": DEF + "knowledgeInformation", - "l": DEF + "l", - "labeledURI": DEF + "labeledURI", - "localityName": DEF + "localityName", - "mDRecord": DEF + "mDRecord", - "mXRecord": DEF + "mXRecord", - "mail": DEF + "mail", - "mailPreferenceOption": DEF + "mailPreferenceOption", - "manager": DEF + "manager", - "member": DEF + "member", - "mobile": DEF + "mobile", - "mobileTelephoneNumber": DEF + "mobileTelephoneNumber", - "nSRecord": DEF + "nSRecord", - "name": DEF + "name", - "norEduOrgAcronym": DEF + "norEduOrgAcronym", - "norEduOrgNIN": DEF + "norEduOrgNIN", - "norEduOrgSchemaVersion": DEF + "norEduOrgSchemaVersion", - "norEduOrgUniqueIdentifier": DEF + "norEduOrgUniqueIdentifier", - "norEduOrgUniqueNumber": DEF + "norEduOrgUniqueNumber", - "norEduOrgUnitUniqueIdentifier": DEF + "norEduOrgUnitUniqueIdentifier", - "norEduOrgUnitUniqueNumber": DEF + "norEduOrgUnitUniqueNumber", - "norEduPersonBirthDate": DEF + "norEduPersonBirthDate", - "norEduPersonLIN": DEF + "norEduPersonLIN", - "norEduPersonNIN": DEF + "norEduPersonNIN", - "o": DEF + "o", - "objectClass": DEF + "objectClass", - "organizationName": DEF + "organizationName", - "organizationalStatus": DEF + "organizationalStatus", - "organizationalUnitName": DEF + "organizationalUnitName", - "otherMailbox": DEF + "otherMailbox", - "ou": DEF + "ou", - "owner": DEF + "owner", - "pager": DEF + "pager", - "pagerTelephoneNumber": DEF + "pagerTelephoneNumber", - "personalSignature": DEF + "personalSignature", - "personalTitle": DEF + "personalTitle", - "photo": DEF + "photo", - "physicalDeliveryOfficeName": DEF + "physicalDeliveryOfficeName", - "pkcs9email": DEF + "pkcs9email", - "postOfficeBox": DEF + "postOfficeBox", - "postalAddress": DEF + "postalAddress", - "postalCode": DEF + "postalCode", - "preferredDeliveryMethod": DEF + "preferredDeliveryMethod", - "preferredLanguage": DEF + "preferredLanguage", - "presentationAddress": DEF + "presentationAddress", - "protocolInformation": DEF + "protocolInformation", - "pseudonym": DEF + "pseudonym", - "registeredAddress": DEF + "registeredAddress", - "rfc822Mailbox": DEF + "rfc822Mailbox", - "roleOccupant": DEF + "roleOccupant", - "roomNumber": DEF + "roomNumber", - "sOARecord": DEF + "sOARecord", - "searchGuide": DEF + "searchGuide", - "secretary": DEF + "secretary", - "seeAlso": DEF + "seeAlso", - "serialNumber": DEF + "serialNumber", - "singleLevelQuality": DEF + "singleLevelQuality", - "sn": DEF + "sn", - "st": DEF + "st", - "stateOrProvinceName": DEF + "stateOrProvinceName", - "street": DEF + "street", - "streetAddress": DEF + "streetAddress", - "subtreeMaximumQuality": DEF + "subtreeMaximumQuality", - "subtreeMinimumQuality": DEF + "subtreeMinimumQuality", - "supportedAlgorithms": DEF + "supportedAlgorithms", - "supportedApplicationContext": DEF + "supportedApplicationContext", - "surname": DEF + "surname", - "telephoneNumber": DEF + "telephoneNumber", - "teletexTerminalIdentifier": DEF + "teletexTerminalIdentifier", - "telexNumber": DEF + "telexNumber", - "textEncodedORAddress": DEF + "textEncodedORAddress", - "title": DEF + "title", - "uid": DEF + "uid", - "uniqueIdentifier": DEF + "uniqueIdentifier", - "uniqueMember": DEF + "uniqueMember", - "userCertificate": DEF + "userCertificate", - "userClass": DEF + "userClass", - "userPKCS12": DEF + "userPKCS12", - "userPassword": DEF + "userPassword", - "userSMIMECertificate": DEF + "userSMIMECertificate", - "userid": DEF + "userid", - "x121Address": DEF + "x121Address", - "x500UniqueIdentifier": DEF + "x500UniqueIdentifier", + "aRecord": f"{DEF}aRecord", + "aliasedEntryName": f"{DEF}aliasedEntryName", + "aliasedObjectName": f"{DEF}aliasedObjectName", + "associatedDomain": f"{DEF}associatedDomain", + "associatedName": f"{DEF}associatedName", + "audio": f"{DEF}audio", + "authorityRevocationList": f"{DEF}authorityRevocationList", + "buildingName": f"{DEF}buildingName", + "businessCategory": f"{DEF}businessCategory", + "c": f"{DEF}c", + "cACertificate": f"{DEF}cACertificate", + "cNAMERecord": f"{DEF}cNAMERecord", + "carLicense": f"{DEF}carLicense", + "certificateRevocationList": f"{DEF}certificateRevocationList", + "cn": f"{DEF}cn", + "co": f"{DEF}co", + "commonName": f"{DEF}commonName", + "countryName": f"{DEF}countryName", + "crossCertificatePair": f"{DEF}crossCertificatePair", + "dITRedirect": f"{DEF}dITRedirect", + "dSAQuality": f"{DEF}dSAQuality", + "dc": f"{DEF}dc", + "deltaRevocationList": f"{DEF}deltaRevocationList", + "departmentNumber": f"{DEF}departmentNumber", + "description": f"{DEF}description", + "destinationIndicator": f"{DEF}destinationIndicator", + "displayName": f"{DEF}displayName", + "distinguishedName": f"{DEF}distinguishedName", + "dmdName": f"{DEF}dmdName", + "dnQualifier": f"{DEF}dnQualifier", + "documentAuthor": f"{DEF}documentAuthor", + "documentIdentifier": f"{DEF}documentIdentifier", + "documentLocation": f"{DEF}documentLocation", + "documentPublisher": f"{DEF}documentPublisher", + "documentTitle": f"{DEF}documentTitle", + "documentVersion": f"{DEF}documentVersion", + "domainComponent": f"{DEF}domainComponent", + "drink": f"{DEF}drink", + "eduOrgHomePageURI": f"{DEF}eduOrgHomePageURI", + "eduOrgIdentityAuthNPolicyURI": f"{DEF}eduOrgIdentityAuthNPolicyURI", + "eduOrgLegalName": f"{DEF}eduOrgLegalName", + "eduOrgSuperiorURI": f"{DEF}eduOrgSuperiorURI", + "eduOrgWhitePagesURI": f"{DEF}eduOrgWhitePagesURI", + "eduCourseMember": f"{DEF}eduCourseMember", + "eduCourseOffering": f"{DEF}eduCourseOffering", + "eduPersonAffiliation": f"{DEF}eduPersonAffiliation", + "eduPersonEntitlement": f"{DEF}eduPersonEntitlement", + "eduPersonNickname": f"{DEF}eduPersonNickname", + "eduPersonOrgDN": f"{DEF}eduPersonOrgDN", + "eduPersonOrgUnitDN": f"{DEF}eduPersonOrgUnitDN", + "eduPersonPrimaryAffiliation": f"{DEF}eduPersonPrimaryAffiliation", + "eduPersonPrimaryOrgUnitDN": f"{DEF}eduPersonPrimaryOrgUnitDN", + "eduPersonPrincipalName": f"{DEF}eduPersonPrincipalName", + "eduPersonPrincipalNamePrior": f"{DEF}eduPersonPrincipalNamePrior", + "eduPersonScopedAffiliation": f"{DEF}eduPersonScopedAffiliation", + "eduPersonTargetedID": f"{DEF}eduPersonTargetedID", + "eduPersonAssurance": f"{DEF}eduPersonAssurance", + "eduPersonUniqueId": f"{DEF}eduPersonUniqueId", + "eduPersonOrcid": f"{DEF}eduPersonOrcid", + "email": f"{DEF}email", + "emailAddress": f"{DEF}emailAddress", + "employeeNumber": f"{DEF}employeeNumber", + "employeeType": f"{DEF}employeeType", + "enhancedSearchGuide": f"{DEF}enhancedSearchGuide", + "facsimileTelephoneNumber": f"{DEF}facsimileTelephoneNumber", + "favouriteDrink": f"{DEF}favouriteDrink", + "fax": f"{DEF}fax", + "federationFeideSchemaVersion": f"{DEF}federationFeideSchemaVersion", + "friendlyCountryName": f"{DEF}friendlyCountryName", + "generationQualifier": f"{DEF}generationQualifier", + "givenName": f"{DEF}givenName", + "gn": f"{DEF}gn", + "homePhone": f"{DEF}homePhone", + "homePostalAddress": f"{DEF}homePostalAddress", + "homeTelephoneNumber": f"{DEF}homeTelephoneNumber", + "host": f"{DEF}host", + "houseIdentifier": f"{DEF}houseIdentifier", + "info": f"{DEF}info", + "initials": f"{DEF}initials", + "internationaliSDNNumber": f"{DEF}internationaliSDNNumber", + "isMemberOf": f"{DEF}isMemberOf", + "janetMailbox": f"{DEF}janetMailbox", + "jpegPhoto": f"{DEF}jpegPhoto", + "knowledgeInformation": f"{DEF}knowledgeInformation", + "l": f"{DEF}l", + "labeledURI": f"{DEF}labeledURI", + "localityName": f"{DEF}localityName", + "mDRecord": f"{DEF}mDRecord", + "mXRecord": f"{DEF}mXRecord", + "mail": f"{DEF}mail", + "mailPreferenceOption": f"{DEF}mailPreferenceOption", + "manager": f"{DEF}manager", + "member": f"{DEF}member", + "mobile": f"{DEF}mobile", + "mobileTelephoneNumber": f"{DEF}mobileTelephoneNumber", + "nSRecord": f"{DEF}nSRecord", + "name": f"{DEF}name", + "norEduOrgAcronym": f"{DEF}norEduOrgAcronym", + "norEduOrgNIN": f"{DEF}norEduOrgNIN", + "norEduOrgSchemaVersion": f"{DEF}norEduOrgSchemaVersion", + "norEduOrgUniqueIdentifier": f"{DEF}norEduOrgUniqueIdentifier", + "norEduOrgUniqueNumber": f"{DEF}norEduOrgUniqueNumber", + "norEduOrgUnitUniqueIdentifier": f"{DEF}norEduOrgUnitUniqueIdentifier", + "norEduOrgUnitUniqueNumber": f"{DEF}norEduOrgUnitUniqueNumber", + "norEduPersonBirthDate": f"{DEF}norEduPersonBirthDate", + "norEduPersonLIN": f"{DEF}norEduPersonLIN", + "norEduPersonNIN": f"{DEF}norEduPersonNIN", + "o": f"{DEF}o", + "objectClass": f"{DEF}objectClass", + "organizationName": f"{DEF}organizationName", + "organizationalStatus": f"{DEF}organizationalStatus", + "organizationalUnitName": f"{DEF}organizationalUnitName", + "otherMailbox": f"{DEF}otherMailbox", + "ou": f"{DEF}ou", + "owner": f"{DEF}owner", + "pager": f"{DEF}pager", + "pagerTelephoneNumber": f"{DEF}pagerTelephoneNumber", + "personalSignature": f"{DEF}personalSignature", + "personalTitle": f"{DEF}personalTitle", + "photo": f"{DEF}photo", + "physicalDeliveryOfficeName": f"{DEF}physicalDeliveryOfficeName", + "pkcs9email": f"{DEF}pkcs9email", + "postOfficeBox": f"{DEF}postOfficeBox", + "postalAddress": f"{DEF}postalAddress", + "postalCode": f"{DEF}postalCode", + "preferredDeliveryMethod": f"{DEF}preferredDeliveryMethod", + "preferredLanguage": f"{DEF}preferredLanguage", + "presentationAddress": f"{DEF}presentationAddress", + "protocolInformation": f"{DEF}protocolInformation", + "pseudonym": f"{DEF}pseudonym", + "registeredAddress": f"{DEF}registeredAddress", + "rfc822Mailbox": f"{DEF}rfc822Mailbox", + "roleOccupant": f"{DEF}roleOccupant", + "roomNumber": f"{DEF}roomNumber", + "sOARecord": f"{DEF}sOARecord", + "searchGuide": f"{DEF}searchGuide", + "secretary": f"{DEF}secretary", + "seeAlso": f"{DEF}seeAlso", + "serialNumber": f"{DEF}serialNumber", + "singleLevelQuality": f"{DEF}singleLevelQuality", + "sn": f"{DEF}sn", + "st": f"{DEF}st", + "stateOrProvinceName": f"{DEF}stateOrProvinceName", + "street": f"{DEF}street", + "streetAddress": f"{DEF}streetAddress", + "subtreeMaximumQuality": f"{DEF}subtreeMaximumQuality", + "subtreeMinimumQuality": f"{DEF}subtreeMinimumQuality", + "supportedAlgorithms": f"{DEF}supportedAlgorithms", + "supportedApplicationContext": f"{DEF}supportedApplicationContext", + "surname": f"{DEF}surname", + "telephoneNumber": f"{DEF}telephoneNumber", + "teletexTerminalIdentifier": f"{DEF}teletexTerminalIdentifier", + "telexNumber": f"{DEF}telexNumber", + "textEncodedORAddress": f"{DEF}textEncodedORAddress", + "title": f"{DEF}title", + "uid": f"{DEF}uid", + "uniqueIdentifier": f"{DEF}uniqueIdentifier", + "uniqueMember": f"{DEF}uniqueMember", + "userCertificate": f"{DEF}userCertificate", + "userClass": f"{DEF}userClass", + "userPKCS12": f"{DEF}userPKCS12", + "userPassword": f"{DEF}userPassword", + "userSMIMECertificate": f"{DEF}userSMIMECertificate", + "userid": f"{DEF}userid", + "x121Address": f"{DEF}x121Address", + "x500UniqueIdentifier": f"{DEF}x500UniqueIdentifier", }, } diff --git a/src/saml2/attributemaps/saml_uri.py b/src/saml2/attributemaps/saml_uri.py index b574b08e0..a7b5c7185 100644 --- a/src/saml2/attributemaps/saml_uri.py +++ b/src/saml2/attributemaps/saml_uri.py @@ -52,439 +52,439 @@ MAP = { "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "fro": { - DIGG_OID + "1": "orgAffiliation", - DIGG_OID + "2": "transactionIdentifier", - DIGG_OID + "3": "authContextParams", - DIGG_OID + "4": "prid", - DIGG_OID + "5": "pridPersistence", - DIGG_OID + "6": "personalIdentityNumberBinding", - DIGG_OID + "7": "eidasPersonIdentifier", - DIGG_OID + "8": "birthName", - DIGG_OID + "9": "eidasNaturalPersonAddress", - DIGG_OID + "10": "userCertificate", - DIGG_OID + "11": "userSignature", - DIGG_OID + "12": "sad", - DIGG_OID + "13": "authServerSignature", - DIGG_OID + "14": "signMessageDigest", - EIDAS_LEGALPERSON + "LegalPersonIdentifier": "LegalPersonIdentifier", - EIDAS_LEGALPERSON + "LegalPersonAddress": "LegalAddress", - EIDAS_LEGALPERSON + "LegalName": "LegalName", - EIDAS_LEGALPERSON + "VATRegistrationNumber": "VATRegistration", - EIDAS_LEGALPERSON + "TaxReference": "TaxReference", - EIDAS_LEGALPERSON + "BusinessCodes": "BusinessCodes", - EIDAS_LEGALPERSON + "LEI": "LEI", - EIDAS_LEGALPERSON + "EORI": "EORI", - EIDAS_LEGALPERSON + "SEED": "SEED", - EIDAS_LEGALPERSON + "SIC": "SIC", - EIDAS_LEGALPERSON + "D-2012-17-EUIdentifier": "D-2012-17-EUIdentifier", - EIDAS_NATURALPERSON + "PersonIdentifier": "PersonIdentifier", - EIDAS_NATURALPERSON + "CurrentFamilyName": "FamilyName", - EIDAS_NATURALPERSON + "CurrentGivenName": "FirstName", - EIDAS_NATURALPERSON + "DateOfBirth": "DateOfBirth", - EIDAS_NATURALPERSON + "BirthName": "BirthName", - EIDAS_NATURALPERSON + "PlaceOfBirth": "PlaceOfBirth", - EIDAS_NATURALPERSON + "CurrentAddress": "CurrentAddress", - EIDAS_NATURALPERSON + "Gender": "Gender", - EDUCOURSE_OID + "1": "eduCourseOffering", - EDUCOURSE_OID + "2": "eduCourseMember", - EDUMEMBER1_OID + "1": "isMemberOf", - EDUPERSON_OID + "1": "eduPersonAffiliation", - EDUPERSON_OID + "2": "eduPersonNickname", - EDUPERSON_OID + "3": "eduPersonOrgDN", - EDUPERSON_OID + "4": "eduPersonOrgUnitDN", - EDUPERSON_OID + "5": "eduPersonPrimaryAffiliation", - EDUPERSON_OID + "6": "eduPersonPrincipalName", - EDUPERSON_OID + "7": "eduPersonEntitlement", - EDUPERSON_OID + "8": "eduPersonPrimaryOrgUnitDN", - EDUPERSON_OID + "9": "eduPersonScopedAffiliation", - EDUPERSON_OID + "10": "eduPersonTargetedID", - EDUPERSON_OID + "11": "eduPersonAssurance", - EDUPERSON_OID + "12": "eduPersonPrincipalNamePrior", - EDUPERSON_OID + "13": "eduPersonUniqueId", - EDUPERSON_OID + "16": "eduPersonOrcid", - INERA_OID + "1": "employeeHsaId", - INERA_OID + "13": "personalIdentityNumber", - LDAPGVAT_OID + "1": "PVP-GID", - LDAPGVAT_OID + "149": "PVP-BPK", - LDAPGVAT_OID + "153": "PVP-OU-OKZ", - LDAPGVAT_OID + "261.10": "PVP-VERSION", - LDAPGVAT_OID + "261.20": "PVP-PRINCIPAL-NAME", - LDAPGVAT_OID + "261.24": "PVP-PARTICIPANT-OKZ", - LDAPGVAT_OID + "261.30": "PVP-ROLES", - LDAPGVAT_OID + "261.40": "PVP-INVOICE-RECPT-ID", - LDAPGVAT_OID + "261.50": "PVP-COST-CENTER-ID", - LDAPGVAT_OID + "261.60": "PVP-CHARGE-CODE", - LDAPGVAT_OID + "3": "PVP-OU-GV-OU-ID", - LDAPGVAT_OID + "33": "PVP-FUNCTION", - LDAPGVAT_OID + "55": "PVP-BIRTHDATE", - LDAPGVAT_OID + "71": "PVP-PARTICIPANT-ID", - LDAPGVAT_UCL_DIR_PILOT + "1": "PVP-USERID", - LDAPGVAT_UCL_DIR_PILOT + "3": "PVP-MAIL", - LDAPGVAT_X500ATTR_OID + "11": "PVP-OU", - LDAPGVAT_X500ATTR_OID + "20": "PVP-TEL", - LDAPGVAT_X500ATTR_OID + "42": "PVP-GIVENNAME", - NETSCAPE_LDAP + "1": "carLicense", - NETSCAPE_LDAP + "2": "departmentNumber", - NETSCAPE_LDAP + "3": "employeeNumber", - NETSCAPE_LDAP + "4": "employeeType", - NETSCAPE_LDAP + "39": "preferredLanguage", - NETSCAPE_LDAP + "40": "userSMIMECertificate", - NETSCAPE_LDAP + "216": "userPKCS12", - NETSCAPE_LDAP + "241": "displayName", - NOREDUPERSON_OID + "1": "norEduOrgUniqueNumber", - NOREDUPERSON_OID + "2": "norEduOrgUnitUniqueNumber", - NOREDUPERSON_OID + "3": "norEduPersonBirthDate", - NOREDUPERSON_OID + "4": "norEduPersonLIN", - NOREDUPERSON_OID + "5": "norEduPersonNIN", - NOREDUPERSON_OID + "6": "norEduOrgAcronym", - NOREDUPERSON_OID + "7": "norEduOrgUniqueIdentifier", - NOREDUPERSON_OID + "8": "norEduOrgUnitUniqueIdentifier", - NOREDUPERSON_OID + "9": "federationFeideSchemaVersion", - NOREDUPERSON_OID + "10": "norEduPersonLegalName", - NOREDUPERSON_OID + "11": "norEduOrgSchemaVersion", - NOREDUPERSON_OID + "12": "norEduOrgNIN", - OPENOSI_OID + "17": "osiHomeUrl", - OPENOSI_OID + "19": "osiPreferredTZ", - OPENOSI_OID + "72": "osiICardTimeLastUpdated", - OPENOSI_OID + "104": "osiMiddleName", - OPENOSI_OID + "107": "osiOtherEmail", - OPENOSI_OID + "109": "osiOtherHomePhone", - OPENOSI_OID + "120": "osiWorkURL", - PKCS_9 + "1": "email", - PKIX_OID + "1": "dateOfBirth", - PKIX_OID + "2": "placeOfBirth", - PKIX_OID + "3": "gender", - PKIX_OID + "4": "countryOfCitizenship", - PKIX_OID + "5": "countryOfResidence", - SAML_SUBJECT_ID + "subject-id": "subject-id", - SAML_SUBJECT_ID + "pairwise-id": "pairwise-id", - SCHAC + "1": "schacMotherTongue", - SCHAC + "2": "schacGender", - SCHAC + "3": "schacDateOfBirth", - SCHAC + "4": "schacPlaceOfBirth", - SCHAC + "5": "schacCountryOfCitizenship", - SCHAC + "6": "schacSn1", - SCHAC + "7": "schacSn2", - SCHAC + "8": "schacPersonalTitle", - SCHAC + "9": "schacHomeOrganization", - SCHAC + "10": "schacHomeOrganizationType", - SCHAC + "11": "schacCountryOfResidence", - SCHAC + "12": "schacUserPresenceID", - SCHAC + "13": "schacPersonalPosition", - SCHAC + "14": "schacPersonalUniqueCode", - SCHAC + "15": "schacPersonalUniqueID", - SCHAC + "17": "schacExpiryDate", - SCHAC + "18": "schacUserPrivateAttribute", - SCHAC + "19": "schacUserStatus", - SCHAC + "20": "schacProjectMembership", - SCHAC + "21": "schacProjectSpecificRole", - SIS + "1": "sisLegalGuardianFor", - SIS + "2": "sisSchoolGrade", - UCL_DIR_PILOT + "1": "uid", - UCL_DIR_PILOT + "3": "mail", - UCL_DIR_PILOT + "25": "dc", - UCL_DIR_PILOT + "37": "associatedDomain", - UCL_DIR_PILOT + "43": "co", - UCL_DIR_PILOT + "60": "jpegPhoto", - UMBRELLA_EAAUser_ID + "1": "EAAHash", - UMBRELLA_EAAUser_ID + "3": "EAAKey", - UMICH + "57": "labeledURI", - X500ATTR_OID + "2": "knowledgeInformation", - X500ATTR_OID + "3": "cn", - X500ATTR_OID + "4": "sn", - X500ATTR_OID + "5": "serialNumber", - X500ATTR_OID + "6": "c", - X500ATTR_OID + "7": "l", - X500ATTR_OID + "8": "st", - X500ATTR_OID + "9": "street", - X500ATTR_OID + "10": "o", - X500ATTR_OID + "11": "ou", - X500ATTR_OID + "12": "title", - X500ATTR_OID + "14": "searchGuide", - X500ATTR_OID + "15": "businessCategory", - X500ATTR_OID + "16": "postalAddress", - X500ATTR_OID + "17": "postalCode", - X500ATTR_OID + "18": "postOfficeBox", - X500ATTR_OID + "19": "physicalDeliveryOfficeName", - X500ATTR_OID + "20": "telephoneNumber", - X500ATTR_OID + "21": "telexNumber", - X500ATTR_OID + "22": "teletexTerminalIdentifier", - X500ATTR_OID + "23": "facsimileTelephoneNumber", - X500ATTR_OID + "24": "x121Address", - X500ATTR_OID + "25": "internationaliSDNNumber", - X500ATTR_OID + "26": "registeredAddress", - X500ATTR_OID + "27": "destinationIndicator", - X500ATTR_OID + "28": "preferredDeliveryMethod", - X500ATTR_OID + "29": "presentationAddress", - X500ATTR_OID + "30": "supportedApplicationContext", - X500ATTR_OID + "31": "member", - X500ATTR_OID + "32": "owner", - X500ATTR_OID + "33": "roleOccupant", - X500ATTR_OID + "36": "userCertificate", - X500ATTR_OID + "37": "cACertificate", - X500ATTR_OID + "38": "authorityRevocationList", - X500ATTR_OID + "39": "certificateRevocationList", - X500ATTR_OID + "40": "crossCertificatePair", - X500ATTR_OID + "42": "givenName", - X500ATTR_OID + "43": "initials", - X500ATTR_OID + "44": "generationQualifier", - X500ATTR_OID + "45": "x500UniqueIdentifier", - X500ATTR_OID + "46": "dnQualifier", - X500ATTR_OID + "47": "enhancedSearchGuide", - X500ATTR_OID + "48": "protocolInformation", - X500ATTR_OID + "50": "uniqueMember", - X500ATTR_OID + "51": "houseIdentifier", - X500ATTR_OID + "52": "supportedAlgorithms", - X500ATTR_OID + "53": "deltaRevocationList", - X500ATTR_OID + "54": "dmdName", - X500ATTR_OID + "65": "pseudonym", - SWISSEDUPERSON_OID + "1": "swissEduPersonUniqueID", - SWISSEDUPERSON_OID + "2": "swissEduPersonDateOfBirth", - SWISSEDUPERSON_OID + "3": "swissEduPersonGender", - SWISSEDUPERSON_OID + "4": "swissEduPersonHomeOrganization", - SWISSEDUPERSON_OID + "5": "swissEduPersonHomeOrganizationType", - SWISSEDUPERSON_OID + "6": "swissEduPersonStudyBranch1", - SWISSEDUPERSON_OID + "7": "swissEduPersonStudyBranch2", - SWISSEDUPERSON_OID + "8": "swissEduPersonStudyBranch3", - SWISSEDUPERSON_OID + "9": "swissEduPersonStudyLevel", - SWISSEDUPERSON_OID + "10": "swissEduPersonStaffCategory", - SWISSEDUPERSON_OID + "11": "swissEduPersonMatriculationNumber", - SWISSEDUPERSON_OID + "12": "swissEduPersonCardUID", - SWISSEDUPERSON_OID + "13": "swissEduID", - SWISSEDUPERSON_OID + "1023": "swissLibraryPersonAffiliation", - SWISSEDUPERSON_OID + "1025": "swissLibraryPersonResidence", - VOPERSON_V2_OID + "1": "voPersonApplicationUID", - VOPERSON_V2_OID + "2": "voPersonAuthorName", - VOPERSON_V2_OID + "3": "voPersonCertificateDN", - VOPERSON_V2_OID + "4": "voPersonCertificateIssuerDN", - VOPERSON_V2_OID + "5": "voPersonExternalID", - VOPERSON_V2_OID + "6": "voPersonID", - VOPERSON_V2_OID + "7": "voPersonPolicyAgreement", - VOPERSON_V2_OID + "8": "voPersonSoRID", - VOPERSON_V2_OID + "9": "voPersonStatus", - VOPERSON_V2_OID + "10": "voPersonAffiliation", - VOPERSON_V2_OID + "11": "voPersonExternalAffiliation", - VOPERSON_V2_OID + "12": "voPersonScopedAffiliation", - VOPERSON_V2_OID + "13": "voPersonApplicationPassword", - VOPERSON_V2_OID + "14": "voPersonVerifiedEmail", - VOPERSON_V2_OID + "15": "voPersonToken", + f"{DIGG_OID}1": "orgAffiliation", + f"{DIGG_OID}2": "transactionIdentifier", + f"{DIGG_OID}3": "authContextParams", + f"{DIGG_OID}4": "prid", + f"{DIGG_OID}5": "pridPersistence", + f"{DIGG_OID}6": "personalIdentityNumberBinding", + f"{DIGG_OID}7": "eidasPersonIdentifier", + f"{DIGG_OID}8": "birthName", + f"{DIGG_OID}9": "eidasNaturalPersonAddress", + f"{DIGG_OID}10": "userCertificate", + f"{DIGG_OID}11": "userSignature", + f"{DIGG_OID}12": "sad", + f"{DIGG_OID}13": "authServerSignature", + f"{DIGG_OID}14": "signMessageDigest", + f"{EIDAS_LEGALPERSON}LegalPersonIdentifier": "LegalPersonIdentifier", + f"{EIDAS_LEGALPERSON}LegalPersonAddress": "LegalAddress", + f"{EIDAS_LEGALPERSON}LegalName": "LegalName", + f"{EIDAS_LEGALPERSON}VATRegistrationNumber": "VATRegistration", + f"{EIDAS_LEGALPERSON}TaxReference": "TaxReference", + f"{EIDAS_LEGALPERSON}BusinessCodes": "BusinessCodes", + f"{EIDAS_LEGALPERSON}LEI": "LEI", + f"{EIDAS_LEGALPERSON}EORI": "EORI", + f"{EIDAS_LEGALPERSON}SEED": "SEED", + f"{EIDAS_LEGALPERSON}SIC": "SIC", + f"{EIDAS_LEGALPERSON}D-2012-17-EUIdentifier": "D-2012-17-EUIdentifier", + f"{EIDAS_NATURALPERSON}PersonIdentifier": "PersonIdentifier", + f"{EIDAS_NATURALPERSON}CurrentFamilyName": "FamilyName", + f"{EIDAS_NATURALPERSON}CurrentGivenName": "FirstName", + f"{EIDAS_NATURALPERSON}DateOfBirth": "DateOfBirth", + f"{EIDAS_NATURALPERSON}BirthName": "BirthName", + f"{EIDAS_NATURALPERSON}PlaceOfBirth": "PlaceOfBirth", + f"{EIDAS_NATURALPERSON}CurrentAddress": "CurrentAddress", + f"{EIDAS_NATURALPERSON}Gender": "Gender", + f"{EDUCOURSE_OID}1": "eduCourseOffering", + f"{EDUCOURSE_OID}2": "eduCourseMember", + f"{EDUMEMBER1_OID}1": "isMemberOf", + f"{EDUPERSON_OID}1": "eduPersonAffiliation", + f"{EDUPERSON_OID}2": "eduPersonNickname", + f"{EDUPERSON_OID}3": "eduPersonOrgDN", + f"{EDUPERSON_OID}4": "eduPersonOrgUnitDN", + f"{EDUPERSON_OID}5": "eduPersonPrimaryAffiliation", + f"{EDUPERSON_OID}6": "eduPersonPrincipalName", + f"{EDUPERSON_OID}7": "eduPersonEntitlement", + f"{EDUPERSON_OID}8": "eduPersonPrimaryOrgUnitDN", + f"{EDUPERSON_OID}9": "eduPersonScopedAffiliation", + f"{EDUPERSON_OID}10": "eduPersonTargetedID", + f"{EDUPERSON_OID}11": "eduPersonAssurance", + f"{EDUPERSON_OID}12": "eduPersonPrincipalNamePrior", + f"{EDUPERSON_OID}13": "eduPersonUniqueId", + f"{EDUPERSON_OID}16": "eduPersonOrcid", + f"{INERA_OID}1": "employeeHsaId", + f"{INERA_OID}13": "personalIdentityNumber", + f"{LDAPGVAT_OID}1": "PVP-GID", + f"{LDAPGVAT_OID}149": "PVP-BPK", + f"{LDAPGVAT_OID}153": "PVP-OU-OKZ", + f"{LDAPGVAT_OID}261.10": "PVP-VERSION", + f"{LDAPGVAT_OID}261.20": "PVP-PRINCIPAL-NAME", + f"{LDAPGVAT_OID}261.24": "PVP-PARTICIPANT-OKZ", + f"{LDAPGVAT_OID}261.30": "PVP-ROLES", + f"{LDAPGVAT_OID}261.40": "PVP-INVOICE-RECPT-ID", + f"{LDAPGVAT_OID}261.50": "PVP-COST-CENTER-ID", + f"{LDAPGVAT_OID}261.60": "PVP-CHARGE-CODE", + f"{LDAPGVAT_OID}3": "PVP-OU-GV-OU-ID", + f"{LDAPGVAT_OID}33": "PVP-FUNCTION", + f"{LDAPGVAT_OID}55": "PVP-BIRTHDATE", + f"{LDAPGVAT_OID}71": "PVP-PARTICIPANT-ID", + f"{LDAPGVAT_UCL_DIR_PILOT}1": "PVP-USERID", + f"{LDAPGVAT_UCL_DIR_PILOT}3": "PVP-MAIL", + f"{LDAPGVAT_X500ATTR_OID}11": "PVP-OU", + f"{LDAPGVAT_X500ATTR_OID}20": "PVP-TEL", + f"{LDAPGVAT_X500ATTR_OID}42": "PVP-GIVENNAME", + f"{NETSCAPE_LDAP}1": "carLicense", + f"{NETSCAPE_LDAP}2": "departmentNumber", + f"{NETSCAPE_LDAP}3": "employeeNumber", + f"{NETSCAPE_LDAP}4": "employeeType", + f"{NETSCAPE_LDAP}39": "preferredLanguage", + f"{NETSCAPE_LDAP}40": "userSMIMECertificate", + f"{NETSCAPE_LDAP}216": "userPKCS12", + f"{NETSCAPE_LDAP}241": "displayName", + f"{NOREDUPERSON_OID}1": "norEduOrgUniqueNumber", + f"{NOREDUPERSON_OID}2": "norEduOrgUnitUniqueNumber", + f"{NOREDUPERSON_OID}3": "norEduPersonBirthDate", + f"{NOREDUPERSON_OID}4": "norEduPersonLIN", + f"{NOREDUPERSON_OID}5": "norEduPersonNIN", + f"{NOREDUPERSON_OID}6": "norEduOrgAcronym", + f"{NOREDUPERSON_OID}7": "norEduOrgUniqueIdentifier", + f"{NOREDUPERSON_OID}8": "norEduOrgUnitUniqueIdentifier", + f"{NOREDUPERSON_OID}9": "federationFeideSchemaVersion", + f"{NOREDUPERSON_OID}10": "norEduPersonLegalName", + f"{NOREDUPERSON_OID}11": "norEduOrgSchemaVersion", + f"{NOREDUPERSON_OID}12": "norEduOrgNIN", + f"{OPENOSI_OID}17": "osiHomeUrl", + f"{OPENOSI_OID}19": "osiPreferredTZ", + f"{OPENOSI_OID}72": "osiICardTimeLastUpdated", + f"{OPENOSI_OID}104": "osiMiddleName", + f"{OPENOSI_OID}107": "osiOtherEmail", + f"{OPENOSI_OID}109": "osiOtherHomePhone", + f"{OPENOSI_OID}120": "osiWorkURL", + f"{PKCS_9}1": "email", + f"{PKIX_OID}1": "dateOfBirth", + f"{PKIX_OID}2": "placeOfBirth", + f"{PKIX_OID}3": "gender", + f"{PKIX_OID}4": "countryOfCitizenship", + f"{PKIX_OID}5": "countryOfResidence", + f"{SAML_SUBJECT_ID}subject-id": "subject-id", + f"{SAML_SUBJECT_ID}pairwise-id": "pairwise-id", + f"{SCHAC}1": "schacMotherTongue", + f"{SCHAC}2": "schacGender", + f"{SCHAC}3": "schacDateOfBirth", + f"{SCHAC}4": "schacPlaceOfBirth", + f"{SCHAC}5": "schacCountryOfCitizenship", + f"{SCHAC}6": "schacSn1", + f"{SCHAC}7": "schacSn2", + f"{SCHAC}8": "schacPersonalTitle", + f"{SCHAC}9": "schacHomeOrganization", + f"{SCHAC}10": "schacHomeOrganizationType", + f"{SCHAC}11": "schacCountryOfResidence", + f"{SCHAC}12": "schacUserPresenceID", + f"{SCHAC}13": "schacPersonalPosition", + f"{SCHAC}14": "schacPersonalUniqueCode", + f"{SCHAC}15": "schacPersonalUniqueID", + f"{SCHAC}17": "schacExpiryDate", + f"{SCHAC}18": "schacUserPrivateAttribute", + f"{SCHAC}19": "schacUserStatus", + f"{SCHAC}20": "schacProjectMembership", + f"{SCHAC}21": "schacProjectSpecificRole", + f"{SIS}1": "sisLegalGuardianFor", + f"{SIS}2": "sisSchoolGrade", + f"{UCL_DIR_PILOT}1": "uid", + f"{UCL_DIR_PILOT}3": "mail", + f"{UCL_DIR_PILOT}25": "dc", + f"{UCL_DIR_PILOT}37": "associatedDomain", + f"{UCL_DIR_PILOT}43": "co", + f"{UCL_DIR_PILOT}60": "jpegPhoto", + f"{UMBRELLA_EAAUser_ID}1": "EAAHash", + f"{UMBRELLA_EAAUser_ID}3": "EAAKey", + f"{UMICH}57": "labeledURI", + f"{X500ATTR_OID}2": "knowledgeInformation", + f"{X500ATTR_OID}3": "cn", + f"{X500ATTR_OID}4": "sn", + f"{X500ATTR_OID}5": "serialNumber", + f"{X500ATTR_OID}6": "c", + f"{X500ATTR_OID}7": "l", + f"{X500ATTR_OID}8": "st", + f"{X500ATTR_OID}9": "street", + f"{X500ATTR_OID}10": "o", + f"{X500ATTR_OID}11": "ou", + f"{X500ATTR_OID}12": "title", + f"{X500ATTR_OID}14": "searchGuide", + f"{X500ATTR_OID}15": "businessCategory", + f"{X500ATTR_OID}16": "postalAddress", + f"{X500ATTR_OID}17": "postalCode", + f"{X500ATTR_OID}18": "postOfficeBox", + f"{X500ATTR_OID}19": "physicalDeliveryOfficeName", + f"{X500ATTR_OID}20": "telephoneNumber", + f"{X500ATTR_OID}21": "telexNumber", + f"{X500ATTR_OID}22": "teletexTerminalIdentifier", + f"{X500ATTR_OID}23": "facsimileTelephoneNumber", + f"{X500ATTR_OID}24": "x121Address", + f"{X500ATTR_OID}25": "internationaliSDNNumber", + f"{X500ATTR_OID}26": "registeredAddress", + f"{X500ATTR_OID}27": "destinationIndicator", + f"{X500ATTR_OID}28": "preferredDeliveryMethod", + f"{X500ATTR_OID}29": "presentationAddress", + f"{X500ATTR_OID}30": "supportedApplicationContext", + f"{X500ATTR_OID}31": "member", + f"{X500ATTR_OID}32": "owner", + f"{X500ATTR_OID}33": "roleOccupant", + f"{X500ATTR_OID}36": "userCertificate", + f"{X500ATTR_OID}37": "cACertificate", + f"{X500ATTR_OID}38": "authorityRevocationList", + f"{X500ATTR_OID}39": "certificateRevocationList", + f"{X500ATTR_OID}40": "crossCertificatePair", + f"{X500ATTR_OID}42": "givenName", + f"{X500ATTR_OID}43": "initials", + f"{X500ATTR_OID}44": "generationQualifier", + f"{X500ATTR_OID}45": "x500UniqueIdentifier", + f"{X500ATTR_OID}46": "dnQualifier", + f"{X500ATTR_OID}47": "enhancedSearchGuide", + f"{X500ATTR_OID}48": "protocolInformation", + f"{X500ATTR_OID}50": "uniqueMember", + f"{X500ATTR_OID}51": "houseIdentifier", + f"{X500ATTR_OID}52": "supportedAlgorithms", + f"{X500ATTR_OID}53": "deltaRevocationList", + f"{X500ATTR_OID}54": "dmdName", + f"{X500ATTR_OID}65": "pseudonym", + f"{SWISSEDUPERSON_OID}1": "swissEduPersonUniqueID", + f"{SWISSEDUPERSON_OID}2": "swissEduPersonDateOfBirth", + f"{SWISSEDUPERSON_OID}3": "swissEduPersonGender", + f"{SWISSEDUPERSON_OID}4": "swissEduPersonHomeOrganization", + f"{SWISSEDUPERSON_OID}5": "swissEduPersonHomeOrganizationType", + f"{SWISSEDUPERSON_OID}6": "swissEduPersonStudyBranch1", + f"{SWISSEDUPERSON_OID}7": "swissEduPersonStudyBranch2", + f"{SWISSEDUPERSON_OID}8": "swissEduPersonStudyBranch3", + f"{SWISSEDUPERSON_OID}9": "swissEduPersonStudyLevel", + f"{SWISSEDUPERSON_OID}10": "swissEduPersonStaffCategory", + f"{SWISSEDUPERSON_OID}11": "swissEduPersonMatriculationNumber", + f"{SWISSEDUPERSON_OID}12": "swissEduPersonCardUID", + f"{SWISSEDUPERSON_OID}13": "swissEduID", + f"{SWISSEDUPERSON_OID}1023": "swissLibraryPersonAffiliation", + f"{SWISSEDUPERSON_OID}1025": "swissLibraryPersonResidence", + f"{VOPERSON_V2_OID}1": "voPersonApplicationUID", + f"{VOPERSON_V2_OID}2": "voPersonAuthorName", + f"{VOPERSON_V2_OID}3": "voPersonCertificateDN", + f"{VOPERSON_V2_OID}4": "voPersonCertificateIssuerDN", + f"{VOPERSON_V2_OID}5": "voPersonExternalID", + f"{VOPERSON_V2_OID}6": "voPersonID", + f"{VOPERSON_V2_OID}7": "voPersonPolicyAgreement", + f"{VOPERSON_V2_OID}8": "voPersonSoRID", + f"{VOPERSON_V2_OID}9": "voPersonStatus", + f"{VOPERSON_V2_OID}10": "voPersonAffiliation", + f"{VOPERSON_V2_OID}11": "voPersonExternalAffiliation", + f"{VOPERSON_V2_OID}12": "voPersonScopedAffiliation", + f"{VOPERSON_V2_OID}13": "voPersonApplicationPassword", + f"{VOPERSON_V2_OID}14": "voPersonVerifiedEmail", + f"{VOPERSON_V2_OID}15": "voPersonToken", }, "to": { - "LegalPersonIdentifier": EIDAS_LEGALPERSON + "LegalPersonIdentifier", - "LegalAddress": EIDAS_LEGALPERSON + "LegalPersonAddress", - "LegalName": EIDAS_LEGALPERSON + "LegalName", - "VATRegistration": EIDAS_LEGALPERSON + "VATRegistrationNumber", - "TaxReference": EIDAS_LEGALPERSON + "TaxReference", - "BusinessCodes": EIDAS_LEGALPERSON + "BusinessCodes", - "LEI": EIDAS_LEGALPERSON + "LEI", - "EORI": EIDAS_LEGALPERSON + "EORI", - "SEED": EIDAS_LEGALPERSON + "SEED", - "SIC": EIDAS_LEGALPERSON + "SIC", - "D-2012-17-EUIdentifier": EIDAS_LEGALPERSON + "D-2012-17-EUIdentifier", - "PersonIdentifier": EIDAS_NATURALPERSON + "PersonIdentifier", - "FamilyName": EIDAS_NATURALPERSON + "CurrentFamilyName", - "FirstName": EIDAS_NATURALPERSON + "CurrentGivenName", - "DateOfBirth": EIDAS_NATURALPERSON + "DateOfBirth", - "BirthName": EIDAS_NATURALPERSON + "BirthName", - "PlaceOfBirth": EIDAS_NATURALPERSON + "PlaceOfBirth", - "CurrentAddress": EIDAS_NATURALPERSON + "CurrentAddress", - "Gender": EIDAS_NATURALPERSON + "Gender", - "associatedDomain": UCL_DIR_PILOT + "37", - "authContextParams": DIGG_OID + "3", - "authorityRevocationList": X500ATTR_OID + "38", - "authServerSignature": DIGG_OID + "13", - "birthName": DIGG_OID + "8", - "businessCategory": X500ATTR_OID + "15", - "c": X500ATTR_OID + "6", - "cACertificate": X500ATTR_OID + "37", - "carLicense": NETSCAPE_LDAP + "1", - "certificateRevocationList": X500ATTR_OID + "39", - "cn": X500ATTR_OID + "3", - "co": UCL_DIR_PILOT + "43", - "countryOfCitizenship": PKIX_OID + "4", - "countryOfResidence": PKIX_OID + "5", - "crossCertificatePair": X500ATTR_OID + "40", - "dateOfBirth": PKIX_OID + "1", - "dc": UCL_DIR_PILOT + "25", - "deltaRevocationList": X500ATTR_OID + "53", - "departmentNumber": NETSCAPE_LDAP + "2", - "destinationIndicator": X500ATTR_OID + "27", - "displayName": NETSCAPE_LDAP + "241", - "dmdName": X500ATTR_OID + "54", - "dnQualifier": X500ATTR_OID + "46", - "EAAHash": UMBRELLA_EAAUser_ID + "1", - "EAAKey": UMBRELLA_EAAUser_ID + "3", - "eduCourseMember": EDUCOURSE_OID + "2", - "eduCourseOffering": EDUCOURSE_OID + "1", - "eduPersonAffiliation": EDUPERSON_OID + "1", - "eduPersonEntitlement": EDUPERSON_OID + "7", - "eduPersonNickname": EDUPERSON_OID + "2", - "eduPersonOrgDN": EDUPERSON_OID + "3", - "eduPersonOrgUnitDN": EDUPERSON_OID + "4", - "eduPersonPrimaryAffiliation": EDUPERSON_OID + "5", - "eduPersonPrimaryOrgUnitDN": EDUPERSON_OID + "8", - "eduPersonPrincipalName": EDUPERSON_OID + "6", - "eduPersonPrincipalNamePrior": EDUPERSON_OID + "12", - "eduPersonScopedAffiliation": EDUPERSON_OID + "9", - "eduPersonTargetedID": EDUPERSON_OID + "10", - "eduPersonAssurance": EDUPERSON_OID + "11", - "eduPersonUniqueId": EDUPERSON_OID + "13", - "eduPersonOrcid": EDUPERSON_OID + "16", - "eidasNaturalPersonAddress": DIGG_OID + "9", - "eidasPersonIdentifier": DIGG_OID + "7", - "email": PKCS_9 + "1", - "employeeHsaId": INERA_OID + "1", - "employeeNumber": NETSCAPE_LDAP + "3", - "employeeType": NETSCAPE_LDAP + "4", - "enhancedSearchGuide": X500ATTR_OID + "47", - "facsimileTelephoneNumber": X500ATTR_OID + "23", - "federationFeideSchemaVersion": NOREDUPERSON_OID + "9", - "gender": PKIX_OID + "3", - "generationQualifier": X500ATTR_OID + "44", - "givenName": X500ATTR_OID + "42", - "houseIdentifier": X500ATTR_OID + "51", - "initials": X500ATTR_OID + "43", - "internationaliSDNNumber": X500ATTR_OID + "25", - "isMemberOf": EDUMEMBER1_OID + "1", - "jpegPhoto": UCL_DIR_PILOT + "60", - "knowledgeInformation": X500ATTR_OID + "2", - "l": X500ATTR_OID + "7", - "labeledURI": UMICH + "57", - "mail": UCL_DIR_PILOT + "3", - "member": X500ATTR_OID + "31", - "norEduOrgAcronym": NOREDUPERSON_OID + "6", - "norEduOrgNIN": NOREDUPERSON_OID + "12", - "norEduOrgSchemaVersion": NOREDUPERSON_OID + "11", - "norEduOrgUniqueIdentifier": NOREDUPERSON_OID + "7", - "norEduOrgUniqueNumber": NOREDUPERSON_OID + "1", - "norEduOrgUnitUniqueIdentifier": NOREDUPERSON_OID + "8", - "norEduOrgUnitUniqueNumber": NOREDUPERSON_OID + "2", - "norEduPersonBirthDate": NOREDUPERSON_OID + "3", - "norEduPersonLIN": NOREDUPERSON_OID + "4", - "norEduPersonLegalName": NOREDUPERSON_OID + "10", - "norEduPersonNIN": NOREDUPERSON_OID + "5", - "o": X500ATTR_OID + "10", - "osiHomeUrl": OPENOSI_OID + "17", - "osiPreferredTZ": OPENOSI_OID + "19", - "osiICardTimeLastUpdated": OPENOSI_OID + "72", - "osiMiddleName": OPENOSI_OID + "104", - "osiOtherEmail": OPENOSI_OID + "107", - "osiOtherHomePhone": OPENOSI_OID + "109", - "osiWorkURL": OPENOSI_OID + "120", - "ou": X500ATTR_OID + "11", - "orgAffiliation": DIGG_OID + "1", - "owner": X500ATTR_OID + "32", - "pairwise-id": SAML_SUBJECT_ID + "pairwise-id", - "personalIdentityNumber": INERA_OID + "13", - "personalIdentityNumberBinding": DIGG_OID + "6", - "physicalDeliveryOfficeName": X500ATTR_OID + "19", - "placeOfBirth": PKIX_OID + "2", - "postOfficeBox": X500ATTR_OID + "18", - "postalAddress": X500ATTR_OID + "16", - "postalCode": X500ATTR_OID + "17", - "preferredDeliveryMethod": X500ATTR_OID + "28", - "preferredLanguage": NETSCAPE_LDAP + "39", - "presentationAddress": X500ATTR_OID + "29", - "prid": DIGG_OID + "4", - "pridPersistence": DIGG_OID + "5", - "protocolInformation": X500ATTR_OID + "48", - "pseudonym": X500ATTR_OID + "65", - "PVP-USERID": LDAPGVAT_UCL_DIR_PILOT + "1", - "PVP-MAIL": LDAPGVAT_UCL_DIR_PILOT + "3", - "PVP-GID": LDAPGVAT_OID + "1", - "PVP-BPK": LDAPGVAT_OID + "149", - "PVP-OU-OKZ": LDAPGVAT_OID + "153", - "PVP-VERSION": LDAPGVAT_OID + "261.10", - "PVP-PRINCIPAL-NAME": LDAPGVAT_OID + "261.20", - "PVP-PARTICIPANT-OKZ": LDAPGVAT_OID + "261.24", - "PVP-ROLES": LDAPGVAT_OID + "261.30", - "PVP-INVOICE-RECPT-ID": LDAPGVAT_OID + "261.40", - "PVP-COST-CENTER-ID": LDAPGVAT_OID + "261.50", - "PVP-CHARGE-CODE": LDAPGVAT_OID + "261.60", - "PVP-OU-GV-OU-ID": LDAPGVAT_OID + "3", - "PVP-FUNCTION": LDAPGVAT_OID + "33", - "PVP-BIRTHDATE": LDAPGVAT_OID + "55", - "PVP-PARTICIPANT-ID": LDAPGVAT_OID + "71", - "PVP-OU": LDAPGVAT_X500ATTR_OID + "11", - "PVP-TEL": LDAPGVAT_X500ATTR_OID + "20", - "PVP-GIVENNAME": LDAPGVAT_X500ATTR_OID + "42", - "registeredAddress": X500ATTR_OID + "26", - "roleOccupant": X500ATTR_OID + "33", - "sad": DIGG_OID + "12", - "schacCountryOfCitizenship": SCHAC + "5", - "schacCountryOfResidence": SCHAC + "11", - "schacDateOfBirth": SCHAC + "3", - "schacExpiryDate": SCHAC + "17", - "schacGender": SCHAC + "2", - "schacHomeOrganization": SCHAC + "9", - "schacHomeOrganizationType": SCHAC + "10", - "schacMotherTongue": SCHAC + "1", - "schacPersonalPosition": SCHAC + "13", - "schacPersonalTitle": SCHAC + "8", - "schacPersonalUniqueCode": SCHAC + "14", - "schacPersonalUniqueID": SCHAC + "15", - "schacPlaceOfBirth": SCHAC + "4", - "schacProjectMembership": SCHAC + "20", - "schacProjectSpecificRole": SCHAC + "21", - "schacSn1": SCHAC + "6", - "schacSn2": SCHAC + "7", - "schacUserPresenceID": SCHAC + "12", - "schacUserPrivateAttribute": SCHAC + "18", - "schacUserStatus": SCHAC + "19", - "searchGuide": X500ATTR_OID + "14", - "serialNumber": X500ATTR_OID + "5", - "signMessageDigest": DIGG_OID + "14", - "sisLegalGuardianFor": SIS + "1", - "sisSchoolGrade": SIS + "2", - "sn": X500ATTR_OID + "4", - "st": X500ATTR_OID + "8", - "street": X500ATTR_OID + "9", - "subject-id": SAML_SUBJECT_ID + "subject-id", - "supportedAlgorithms": X500ATTR_OID + "52", - "supportedApplicationContext": X500ATTR_OID + "30", - "telephoneNumber": X500ATTR_OID + "20", - "teletexTerminalIdentifier": X500ATTR_OID + "22", - "telexNumber": X500ATTR_OID + "21", - "title": X500ATTR_OID + "12", - "transactionIdentifier": DIGG_OID + "2", - "uid": UCL_DIR_PILOT + "1", - "uniqueMember": X500ATTR_OID + "50", - "userCertificate": X500ATTR_OID + "36", + "LegalPersonIdentifier": f"{EIDAS_LEGALPERSON}LegalPersonIdentifier", + "LegalAddress": f"{EIDAS_LEGALPERSON}LegalPersonAddress", + "LegalName": f"{EIDAS_LEGALPERSON}LegalName", + "VATRegistration": f"{EIDAS_LEGALPERSON}VATRegistrationNumber", + "TaxReference": f"{EIDAS_LEGALPERSON}TaxReference", + "BusinessCodes": f"{EIDAS_LEGALPERSON}BusinessCodes", + "LEI": f"{EIDAS_LEGALPERSON}LEI", + "EORI": f"{EIDAS_LEGALPERSON}EORI", + "SEED": f"{EIDAS_LEGALPERSON}SEED", + "SIC": f"{EIDAS_LEGALPERSON}SIC", + "D-2012-17-EUIdentifier": f"{EIDAS_LEGALPERSON}D-2012-17-EUIdentifier", + "PersonIdentifier": f"{EIDAS_NATURALPERSON}PersonIdentifier", + "FamilyName": f"{EIDAS_NATURALPERSON}CurrentFamilyName", + "FirstName": f"{EIDAS_NATURALPERSON}CurrentGivenName", + "DateOfBirth": f"{EIDAS_NATURALPERSON}DateOfBirth", + "BirthName": f"{EIDAS_NATURALPERSON}BirthName", + "PlaceOfBirth": f"{EIDAS_NATURALPERSON}PlaceOfBirth", + "CurrentAddress": f"{EIDAS_NATURALPERSON}CurrentAddress", + "Gender": f"{EIDAS_NATURALPERSON}Gender", + "associatedDomain": f"{UCL_DIR_PILOT}37", + "authContextParams": f"{DIGG_OID}3", + "authorityRevocationList": f"{X500ATTR_OID}38", + "authServerSignature": f"{DIGG_OID}13", + "birthName": f"{DIGG_OID}8", + "businessCategory": f"{X500ATTR_OID}15", + "c": f"{X500ATTR_OID}6", + "cACertificate": f"{X500ATTR_OID}37", + "carLicense": f"{NETSCAPE_LDAP}1", + "certificateRevocationList": f"{X500ATTR_OID}39", + "cn": f"{X500ATTR_OID}3", + "co": f"{UCL_DIR_PILOT}43", + "countryOfCitizenship": f"{PKIX_OID}4", + "countryOfResidence": f"{PKIX_OID}5", + "crossCertificatePair": f"{X500ATTR_OID}40", + "dateOfBirth": f"{PKIX_OID}1", + "dc": f"{UCL_DIR_PILOT}25", + "deltaRevocationList": f"{X500ATTR_OID}53", + "departmentNumber": f"{NETSCAPE_LDAP}2", + "destinationIndicator": f"{X500ATTR_OID}27", + "displayName": f"{NETSCAPE_LDAP}241", + "dmdName": f"{X500ATTR_OID}54", + "dnQualifier": f"{X500ATTR_OID}46", + "EAAHash": f"{UMBRELLA_EAAUser_ID}1", + "EAAKey": f"{UMBRELLA_EAAUser_ID}3", + "eduCourseMember": f"{EDUCOURSE_OID}2", + "eduCourseOffering": f"{EDUCOURSE_OID}1", + "eduPersonAffiliation": f"{EDUPERSON_OID}1", + "eduPersonEntitlement": f"{EDUPERSON_OID}7", + "eduPersonNickname": f"{EDUPERSON_OID}2", + "eduPersonOrgDN": f"{EDUPERSON_OID}3", + "eduPersonOrgUnitDN": f"{EDUPERSON_OID}4", + "eduPersonPrimaryAffiliation": f"{EDUPERSON_OID}5", + "eduPersonPrimaryOrgUnitDN": f"{EDUPERSON_OID}8", + "eduPersonPrincipalName": f"{EDUPERSON_OID}6", + "eduPersonPrincipalNamePrior": f"{EDUPERSON_OID}12", + "eduPersonScopedAffiliation": f"{EDUPERSON_OID}9", + "eduPersonTargetedID": f"{EDUPERSON_OID}10", + "eduPersonAssurance": f"{EDUPERSON_OID}11", + "eduPersonUniqueId": f"{EDUPERSON_OID}13", + "eduPersonOrcid": f"{EDUPERSON_OID}16", + "eidasNaturalPersonAddress": f"{DIGG_OID}9", + "eidasPersonIdentifier": f"{DIGG_OID}7", + "email": f"{PKCS_9}1", + "employeeHsaId": f"{INERA_OID}1", + "employeeNumber": f"{NETSCAPE_LDAP}3", + "employeeType": f"{NETSCAPE_LDAP}4", + "enhancedSearchGuide": f"{X500ATTR_OID}47", + "facsimileTelephoneNumber": f"{X500ATTR_OID}23", + "federationFeideSchemaVersion": f"{NOREDUPERSON_OID}9", + "gender": f"{PKIX_OID}3", + "generationQualifier": f"{X500ATTR_OID}44", + "givenName": f"{X500ATTR_OID}42", + "houseIdentifier": f"{X500ATTR_OID}51", + "initials": f"{X500ATTR_OID}43", + "internationaliSDNNumber": f"{X500ATTR_OID}25", + "isMemberOf": f"{EDUMEMBER1_OID}1", + "jpegPhoto": f"{UCL_DIR_PILOT}60", + "knowledgeInformation": f"{X500ATTR_OID}2", + "l": f"{X500ATTR_OID}7", + "labeledURI": f"{UMICH}57", + "mail": f"{UCL_DIR_PILOT}3", + "member": f"{X500ATTR_OID}31", + "norEduOrgAcronym": f"{NOREDUPERSON_OID}6", + "norEduOrgNIN": f"{NOREDUPERSON_OID}12", + "norEduOrgSchemaVersion": f"{NOREDUPERSON_OID}11", + "norEduOrgUniqueIdentifier": f"{NOREDUPERSON_OID}7", + "norEduOrgUniqueNumber": f"{NOREDUPERSON_OID}1", + "norEduOrgUnitUniqueIdentifier": f"{NOREDUPERSON_OID}8", + "norEduOrgUnitUniqueNumber": f"{NOREDUPERSON_OID}2", + "norEduPersonBirthDate": f"{NOREDUPERSON_OID}3", + "norEduPersonLIN": f"{NOREDUPERSON_OID}4", + "norEduPersonLegalName": f"{NOREDUPERSON_OID}10", + "norEduPersonNIN": f"{NOREDUPERSON_OID}5", + "o": f"{X500ATTR_OID}10", + "osiHomeUrl": f"{OPENOSI_OID}17", + "osiPreferredTZ": f"{OPENOSI_OID}19", + "osiICardTimeLastUpdated": f"{OPENOSI_OID}72", + "osiMiddleName": f"{OPENOSI_OID}104", + "osiOtherEmail": f"{OPENOSI_OID}107", + "osiOtherHomePhone": f"{OPENOSI_OID}109", + "osiWorkURL": f"{OPENOSI_OID}120", + "ou": f"{X500ATTR_OID}11", + "orgAffiliation": f"{DIGG_OID}1", + "owner": f"{X500ATTR_OID}32", + "pairwise-id": f"{SAML_SUBJECT_ID}pairwise-id", + "personalIdentityNumber": f"{INERA_OID}13", + "personalIdentityNumberBinding": f"{DIGG_OID}6", + "physicalDeliveryOfficeName": f"{X500ATTR_OID}19", + "placeOfBirth": f"{PKIX_OID}2", + "postOfficeBox": f"{X500ATTR_OID}18", + "postalAddress": f"{X500ATTR_OID}16", + "postalCode": f"{X500ATTR_OID}17", + "preferredDeliveryMethod": f"{X500ATTR_OID}28", + "preferredLanguage": f"{NETSCAPE_LDAP}39", + "presentationAddress": f"{X500ATTR_OID}29", + "prid": f"{DIGG_OID}4", + "pridPersistence": f"{DIGG_OID}5", + "protocolInformation": f"{X500ATTR_OID}48", + "pseudonym": f"{X500ATTR_OID}65", + "PVP-USERID": f"{LDAPGVAT_UCL_DIR_PILOT}1", + "PVP-MAIL": f"{LDAPGVAT_UCL_DIR_PILOT}3", + "PVP-GID": f"{LDAPGVAT_OID}1", + "PVP-BPK": f"{LDAPGVAT_OID}149", + "PVP-OU-OKZ": f"{LDAPGVAT_OID}153", + "PVP-VERSION": f"{LDAPGVAT_OID}261.10", + "PVP-PRINCIPAL-NAME": f"{LDAPGVAT_OID}261.20", + "PVP-PARTICIPANT-OKZ": f"{LDAPGVAT_OID}261.24", + "PVP-ROLES": f"{LDAPGVAT_OID}261.30", + "PVP-INVOICE-RECPT-ID": f"{LDAPGVAT_OID}261.40", + "PVP-COST-CENTER-ID": f"{LDAPGVAT_OID}261.50", + "PVP-CHARGE-CODE": f"{LDAPGVAT_OID}261.60", + "PVP-OU-GV-OU-ID": f"{LDAPGVAT_OID}3", + "PVP-FUNCTION": f"{LDAPGVAT_OID}33", + "PVP-BIRTHDATE": f"{LDAPGVAT_OID}55", + "PVP-PARTICIPANT-ID": f"{LDAPGVAT_OID}71", + "PVP-OU": f"{LDAPGVAT_X500ATTR_OID}11", + "PVP-TEL": f"{LDAPGVAT_X500ATTR_OID}20", + "PVP-GIVENNAME": f"{LDAPGVAT_X500ATTR_OID}42", + "registeredAddress": f"{X500ATTR_OID}26", + "roleOccupant": f"{X500ATTR_OID}33", + "sad": f"{DIGG_OID}12", + "schacCountryOfCitizenship": f"{SCHAC}5", + "schacCountryOfResidence": f"{SCHAC}11", + "schacDateOfBirth": f"{SCHAC}3", + "schacExpiryDate": f"{SCHAC}17", + "schacGender": f"{SCHAC}2", + "schacHomeOrganization": f"{SCHAC}9", + "schacHomeOrganizationType": f"{SCHAC}10", + "schacMotherTongue": f"{SCHAC}1", + "schacPersonalPosition": f"{SCHAC}13", + "schacPersonalTitle": f"{SCHAC}8", + "schacPersonalUniqueCode": f"{SCHAC}14", + "schacPersonalUniqueID": f"{SCHAC}15", + "schacPlaceOfBirth": f"{SCHAC}4", + "schacProjectMembership": f"{SCHAC}20", + "schacProjectSpecificRole": f"{SCHAC}21", + "schacSn1": f"{SCHAC}6", + "schacSn2": f"{SCHAC}7", + "schacUserPresenceID": f"{SCHAC}12", + "schacUserPrivateAttribute": f"{SCHAC}18", + "schacUserStatus": f"{SCHAC}19", + "searchGuide": f"{X500ATTR_OID}14", + "serialNumber": f"{X500ATTR_OID}5", + "signMessageDigest": f"{DIGG_OID}14", + "sisLegalGuardianFor": f"{SIS}1", + "sisSchoolGrade": f"{SIS}2", + "sn": f"{X500ATTR_OID}4", + "st": f"{X500ATTR_OID}8", + "street": f"{X500ATTR_OID}9", + "subject-id": f"{SAML_SUBJECT_ID}subject-id", + "supportedAlgorithms": f"{X500ATTR_OID}52", + "supportedApplicationContext": f"{X500ATTR_OID}30", + "telephoneNumber": f"{X500ATTR_OID}20", + "teletexTerminalIdentifier": f"{X500ATTR_OID}22", + "telexNumber": f"{X500ATTR_OID}21", + "title": f"{X500ATTR_OID}12", + "transactionIdentifier": f"{DIGG_OID}2", + "uid": f"{UCL_DIR_PILOT}1", + "uniqueMember": f"{X500ATTR_OID}50", + "userCertificate": f"{X500ATTR_OID}36", # 'userCertificate': DIGG_OID+'10', - "userPKCS12": NETSCAPE_LDAP + "216", - "userSMIMECertificate": NETSCAPE_LDAP + "40", - "userSignature": DIGG_OID + "11", - "x121Address": X500ATTR_OID + "24", - "x500UniqueIdentifier": X500ATTR_OID + "45", - "swissEduPersonUniqueID": SWISSEDUPERSON_OID + "1", - "swissEduPersonDateOfBirth": SWISSEDUPERSON_OID + "2", - "swissEduPersonGender": SWISSEDUPERSON_OID + "3", - "swissEduPersonHomeOrganization": SWISSEDUPERSON_OID + "4", - "swissEduPersonHomeOrganizationType": SWISSEDUPERSON_OID + "5", - "swissEduPersonStudyBranch1": SWISSEDUPERSON_OID + "6", - "swissEduPersonStudyBranch2": SWISSEDUPERSON_OID + "7", - "swissEduPersonStudyBranch3": SWISSEDUPERSON_OID + "8", - "swissEduPersonStudyLevel": SWISSEDUPERSON_OID + "9", - "swissEduPersonStaffCategory": SWISSEDUPERSON_OID + "10", - "swissEduPersonMatriculationNumber": SWISSEDUPERSON_OID + "11", - "swissEduPersonCardUID": SWISSEDUPERSON_OID + "12", - "swissEduID": SWISSEDUPERSON_OID + "13", - "swissLibraryPersonAffiliation": SWISSEDUPERSON_OID + "1023", - "swissLibraryPersonResidence": SWISSEDUPERSON_OID + "1025", - "voPersonAffiliation": VOPERSON_V2_OID + "10", - "voPersonApplicationPassword": VOPERSON_V2_OID + "13", - "voPersonApplicationUID": VOPERSON_V2_OID + "1", - "voPersonAuthorName": VOPERSON_V2_OID + "2", - "voPersonCertificateDN": VOPERSON_V2_OID + "3", - "voPersonCertificateIssuerDN": VOPERSON_V2_OID + "4", - "voPersonExternalAffiliation": VOPERSON_V2_OID + "11", - "voPersonExternalID": VOPERSON_V2_OID + "5", - "voPersonID": VOPERSON_V2_OID + "6", - "voPersonPolicyAgreement": VOPERSON_V2_OID + "7", - "voPersonScopedAffiliation": VOPERSON_V2_OID + "12", - "voPersonSoRID": VOPERSON_V2_OID + "8", - "voPersonStatus": VOPERSON_V2_OID + "9", - "voPersonToken": VOPERSON_V2_OID + "15", - "voPersonVerifiedEmail": VOPERSON_V2_OID + "14", + "userPKCS12": f"{NETSCAPE_LDAP}216", + "userSMIMECertificate": f"{NETSCAPE_LDAP}40", + "userSignature": f"{DIGG_OID}11", + "x121Address": f"{X500ATTR_OID}24", + "x500UniqueIdentifier": f"{X500ATTR_OID}45", + "swissEduPersonUniqueID": f"{SWISSEDUPERSON_OID}1", + "swissEduPersonDateOfBirth": f"{SWISSEDUPERSON_OID}2", + "swissEduPersonGender": f"{SWISSEDUPERSON_OID}3", + "swissEduPersonHomeOrganization": f"{SWISSEDUPERSON_OID}4", + "swissEduPersonHomeOrganizationType": f"{SWISSEDUPERSON_OID}5", + "swissEduPersonStudyBranch1": f"{SWISSEDUPERSON_OID}6", + "swissEduPersonStudyBranch2": f"{SWISSEDUPERSON_OID}7", + "swissEduPersonStudyBranch3": f"{SWISSEDUPERSON_OID}8", + "swissEduPersonStudyLevel": f"{SWISSEDUPERSON_OID}9", + "swissEduPersonStaffCategory": f"{SWISSEDUPERSON_OID}10", + "swissEduPersonMatriculationNumber": f"{SWISSEDUPERSON_OID}11", + "swissEduPersonCardUID": f"{SWISSEDUPERSON_OID}12", + "swissEduID": f"{SWISSEDUPERSON_OID}13", + "swissLibraryPersonAffiliation": f"{SWISSEDUPERSON_OID}1023", + "swissLibraryPersonResidence": f"{SWISSEDUPERSON_OID}1025", + "voPersonAffiliation": f"{VOPERSON_V2_OID}10", + "voPersonApplicationPassword": f"{VOPERSON_V2_OID}13", + "voPersonApplicationUID": f"{VOPERSON_V2_OID}1", + "voPersonAuthorName": f"{VOPERSON_V2_OID}2", + "voPersonCertificateDN": f"{VOPERSON_V2_OID}3", + "voPersonCertificateIssuerDN": f"{VOPERSON_V2_OID}4", + "voPersonExternalAffiliation": f"{VOPERSON_V2_OID}11", + "voPersonExternalID": f"{VOPERSON_V2_OID}5", + "voPersonID": f"{VOPERSON_V2_OID}6", + "voPersonPolicyAgreement": f"{VOPERSON_V2_OID}7", + "voPersonScopedAffiliation": f"{VOPERSON_V2_OID}12", + "voPersonSoRID": f"{VOPERSON_V2_OID}8", + "voPersonStatus": f"{VOPERSON_V2_OID}9", + "voPersonToken": f"{VOPERSON_V2_OID}15", + "voPersonVerifiedEmail": f"{VOPERSON_V2_OID}14", }, } diff --git a/src/saml2/attributemaps/shibboleth_uri.py b/src/saml2/attributemaps/shibboleth_uri.py index 6de6b2764..7ddef3e0b 100644 --- a/src/saml2/attributemaps/shibboleth_uri.py +++ b/src/saml2/attributemaps/shibboleth_uri.py @@ -10,188 +10,188 @@ MAP = { "identifier": "urn:mace:shibboleth:1.0:attributeNamespace:uri", "fro": { - EDUPERSON_OID + "1": "eduPersonAffiliation", - EDUPERSON_OID + "2": "eduPersonNickname", - EDUPERSON_OID + "3": "eduPersonOrgDN", - EDUPERSON_OID + "4": "eduPersonOrgUnitDN", - EDUPERSON_OID + "5": "eduPersonPrimaryAffiliation", - EDUPERSON_OID + "6": "eduPersonPrincipalName", - EDUPERSON_OID + "7": "eduPersonEntitlement", - EDUPERSON_OID + "8": "eduPersonPrimaryOrgUnitDN", - EDUPERSON_OID + "9": "eduPersonScopedAffiliation", - EDUPERSON_OID + "10": "eduPersonTargetedID", - EDUPERSON_OID + "11": "eduPersonAssurance", - EDUPERSON_OID + "12": "eduPersonPrincipalNamePrior", - EDUPERSON_OID + "13": "eduPersonUniqueId", - EDUPERSON_OID + "16": "eduPersonOrcid", - NETSCAPE_LDAP + "1": "carLicense", - NETSCAPE_LDAP + "2": "departmentNumber", - NETSCAPE_LDAP + "3": "employeeNumber", - NETSCAPE_LDAP + "4": "employeeType", - NETSCAPE_LDAP + "39": "preferredLanguage", - NETSCAPE_LDAP + "40": "userSMIMECertificate", - NETSCAPE_LDAP + "216": "userPKCS12", - NETSCAPE_LDAP + "241": "displayName", - NOREDUPERSON_OID + "1": "norEduOrgUniqueNumber", - NOREDUPERSON_OID + "2": "norEduOrgUnitUniqueNumber", - NOREDUPERSON_OID + "3": "norEduPersonBirthDate", - NOREDUPERSON_OID + "4": "norEduPersonLIN", - NOREDUPERSON_OID + "5": "norEduPersonNIN", - NOREDUPERSON_OID + "6": "norEduOrgAcronym", - NOREDUPERSON_OID + "7": "norEduOrgUniqueIdentifier", - NOREDUPERSON_OID + "8": "norEduOrgUnitUniqueIdentifier", - NOREDUPERSON_OID + "9": "federationFeideSchemaVersion", - PKCS_9 + "1": "email", - UCL_DIR_PILOT + "3": "mail", - UCL_DIR_PILOT + "25": "dc", - UCL_DIR_PILOT + "37": "associatedDomain", - UCL_DIR_PILOT + "60": "jpegPhoto", - X500ATTR + "2": "knowledgeInformation", - X500ATTR + "4": "sn", - X500ATTR + "5": "serialNumber", - X500ATTR + "6": "c", - X500ATTR + "7": "l", - X500ATTR + "8": "st", - X500ATTR + "9": "street", - X500ATTR + "10": "o", - X500ATTR + "11": "ou", - X500ATTR + "12": "title", - X500ATTR + "14": "searchGuide", - X500ATTR + "15": "businessCategory", - X500ATTR + "16": "postalAddress", - X500ATTR + "17": "postalCode", - X500ATTR + "18": "postOfficeBox", - X500ATTR + "19": "physicalDeliveryOfficeName", - X500ATTR + "20": "telephoneNumber", - X500ATTR + "21": "telexNumber", - X500ATTR + "22": "teletexTerminalIdentifier", - X500ATTR + "23": "facsimileTelephoneNumber", - X500ATTR + "24": "x121Address", - X500ATTR + "25": "internationaliSDNNumber", - X500ATTR + "26": "registeredAddress", - X500ATTR + "27": "destinationIndicator", - X500ATTR + "28": "preferredDeliveryMethod", - X500ATTR + "29": "presentationAddress", - X500ATTR + "30": "supportedApplicationContext", - X500ATTR + "31": "member", - X500ATTR + "32": "owner", - X500ATTR + "33": "roleOccupant", - X500ATTR + "36": "userCertificate", - X500ATTR + "37": "cACertificate", - X500ATTR + "38": "authorityRevocationList", - X500ATTR + "39": "certificateRevocationList", - X500ATTR + "40": "crossCertificatePair", - X500ATTR + "42": "givenName", - X500ATTR + "43": "initials", - X500ATTR + "44": "generationQualifier", - X500ATTR + "45": "x500UniqueIdentifier", - X500ATTR + "46": "dnQualifier", - X500ATTR + "47": "enhancedSearchGuide", - X500ATTR + "48": "protocolInformation", - X500ATTR + "50": "uniqueMember", - X500ATTR + "51": "houseIdentifier", - X500ATTR + "52": "supportedAlgorithms", - X500ATTR + "53": "deltaRevocationList", - X500ATTR + "54": "dmdName", - X500ATTR + "65": "pseudonym", + f"{EDUPERSON_OID}1": "eduPersonAffiliation", + f"{EDUPERSON_OID}2": "eduPersonNickname", + f"{EDUPERSON_OID}3": "eduPersonOrgDN", + f"{EDUPERSON_OID}4": "eduPersonOrgUnitDN", + f"{EDUPERSON_OID}5": "eduPersonPrimaryAffiliation", + f"{EDUPERSON_OID}6": "eduPersonPrincipalName", + f"{EDUPERSON_OID}7": "eduPersonEntitlement", + f"{EDUPERSON_OID}8": "eduPersonPrimaryOrgUnitDN", + f"{EDUPERSON_OID}9": "eduPersonScopedAffiliation", + f"{EDUPERSON_OID}10": "eduPersonTargetedID", + f"{EDUPERSON_OID}11": "eduPersonAssurance", + f"{EDUPERSON_OID}12": "eduPersonPrincipalNamePrior", + f"{EDUPERSON_OID}13": "eduPersonUniqueId", + f"{EDUPERSON_OID}16": "eduPersonOrcid", + f"{NETSCAPE_LDAP}1": "carLicense", + f"{NETSCAPE_LDAP}2": "departmentNumber", + f"{NETSCAPE_LDAP}3": "employeeNumber", + f"{NETSCAPE_LDAP}4": "employeeType", + f"{NETSCAPE_LDAP}39": "preferredLanguage", + f"{NETSCAPE_LDAP}40": "userSMIMECertificate", + f"{NETSCAPE_LDAP}216": "userPKCS12", + f"{NETSCAPE_LDAP}241": "displayName", + f"{NOREDUPERSON_OID}1": "norEduOrgUniqueNumber", + f"{NOREDUPERSON_OID}2": "norEduOrgUnitUniqueNumber", + f"{NOREDUPERSON_OID}3": "norEduPersonBirthDate", + f"{NOREDUPERSON_OID}4": "norEduPersonLIN", + f"{NOREDUPERSON_OID}5": "norEduPersonNIN", + f"{NOREDUPERSON_OID}6": "norEduOrgAcronym", + f"{NOREDUPERSON_OID}7": "norEduOrgUniqueIdentifier", + f"{NOREDUPERSON_OID}8": "norEduOrgUnitUniqueIdentifier", + f"{NOREDUPERSON_OID}9": "federationFeideSchemaVersion", + f"{PKCS_9}1": "email", + f"{UCL_DIR_PILOT}3": "mail", + f"{UCL_DIR_PILOT}25": "dc", + f"{UCL_DIR_PILOT}37": "associatedDomain", + f"{UCL_DIR_PILOT}60": "jpegPhoto", + f"{X500ATTR}2": "knowledgeInformation", + f"{X500ATTR}4": "sn", + f"{X500ATTR}5": "serialNumber", + f"{X500ATTR}6": "c", + f"{X500ATTR}7": "l", + f"{X500ATTR}8": "st", + f"{X500ATTR}9": "street", + f"{X500ATTR}10": "o", + f"{X500ATTR}11": "ou", + f"{X500ATTR}12": "title", + f"{X500ATTR}14": "searchGuide", + f"{X500ATTR}15": "businessCategory", + f"{X500ATTR}16": "postalAddress", + f"{X500ATTR}17": "postalCode", + f"{X500ATTR}18": "postOfficeBox", + f"{X500ATTR}19": "physicalDeliveryOfficeName", + f"{X500ATTR}20": "telephoneNumber", + f"{X500ATTR}21": "telexNumber", + f"{X500ATTR}22": "teletexTerminalIdentifier", + f"{X500ATTR}23": "facsimileTelephoneNumber", + f"{X500ATTR}24": "x121Address", + f"{X500ATTR}25": "internationaliSDNNumber", + f"{X500ATTR}26": "registeredAddress", + f"{X500ATTR}27": "destinationIndicator", + f"{X500ATTR}28": "preferredDeliveryMethod", + f"{X500ATTR}29": "presentationAddress", + f"{X500ATTR}30": "supportedApplicationContext", + f"{X500ATTR}31": "member", + f"{X500ATTR}32": "owner", + f"{X500ATTR}33": "roleOccupant", + f"{X500ATTR}36": "userCertificate", + f"{X500ATTR}37": "cACertificate", + f"{X500ATTR}38": "authorityRevocationList", + f"{X500ATTR}39": "certificateRevocationList", + f"{X500ATTR}40": "crossCertificatePair", + f"{X500ATTR}42": "givenName", + f"{X500ATTR}43": "initials", + f"{X500ATTR}44": "generationQualifier", + f"{X500ATTR}45": "x500UniqueIdentifier", + f"{X500ATTR}46": "dnQualifier", + f"{X500ATTR}47": "enhancedSearchGuide", + f"{X500ATTR}48": "protocolInformation", + f"{X500ATTR}50": "uniqueMember", + f"{X500ATTR}51": "houseIdentifier", + f"{X500ATTR}52": "supportedAlgorithms", + f"{X500ATTR}53": "deltaRevocationList", + f"{X500ATTR}54": "dmdName", + f"{X500ATTR}65": "pseudonym", }, "to": { - "associatedDomain": UCL_DIR_PILOT + "37", - "authorityRevocationList": X500ATTR + "38", - "businessCategory": X500ATTR + "15", - "c": X500ATTR + "6", - "cACertificate": X500ATTR + "37", - "carLicense": NETSCAPE_LDAP + "1", - "certificateRevocationList": X500ATTR + "39", - "countryName": X500ATTR + "6", - "crossCertificatePair": X500ATTR + "40", - "dc": UCL_DIR_PILOT + "25", - "deltaRevocationList": X500ATTR + "53", - "departmentNumber": NETSCAPE_LDAP + "2", - "destinationIndicator": X500ATTR + "27", - "displayName": NETSCAPE_LDAP + "241", - "dmdName": X500ATTR + "54", - "dnQualifier": X500ATTR + "46", - "domainComponent": UCL_DIR_PILOT + "25", - "eduPersonAffiliation": EDUPERSON_OID + "1", - "eduPersonEntitlement": EDUPERSON_OID + "7", - "eduPersonNickname": EDUPERSON_OID + "2", - "eduPersonOrgDN": EDUPERSON_OID + "3", - "eduPersonOrgUnitDN": EDUPERSON_OID + "4", - "eduPersonPrimaryAffiliation": EDUPERSON_OID + "5", - "eduPersonPrimaryOrgUnitDN": EDUPERSON_OID + "8", - "eduPersonPrincipalName": EDUPERSON_OID + "6", - "eduPersonPrincipalNamePrior": EDUPERSON_OID + "12", - "eduPersonScopedAffiliation": EDUPERSON_OID + "9", - "eduPersonTargetedID": EDUPERSON_OID + "10", - "eduPersonAssurance": EDUPERSON_OID + "11", - "eduPersonUniqueId": EDUPERSON_OID + "13", - "eduPersonOrcid": EDUPERSON_OID + "16", - "email": PKCS_9 + "1", - "emailAddress": PKCS_9 + "1", - "employeeNumber": NETSCAPE_LDAP + "3", - "employeeType": NETSCAPE_LDAP + "4", - "enhancedSearchGuide": X500ATTR + "47", - "facsimileTelephoneNumber": X500ATTR + "23", - "fax": X500ATTR + "23", - "federationFeideSchemaVersion": NOREDUPERSON_OID + "9", - "generationQualifier": X500ATTR + "44", - "givenName": X500ATTR + "42", - "gn": X500ATTR + "42", - "houseIdentifier": X500ATTR + "51", - "initials": X500ATTR + "43", - "internationaliSDNNumber": X500ATTR + "25", - "jpegPhoto": UCL_DIR_PILOT + "60", - "knowledgeInformation": X500ATTR + "2", - "l": X500ATTR + "7", - "localityName": X500ATTR + "7", - "mail": UCL_DIR_PILOT + "3", - "member": X500ATTR + "31", - "norEduOrgAcronym": NOREDUPERSON_OID + "6", - "norEduOrgUniqueIdentifier": NOREDUPERSON_OID + "7", - "norEduOrgUniqueNumber": NOREDUPERSON_OID + "1", - "norEduOrgUnitUniqueIdentifier": NOREDUPERSON_OID + "8", - "norEduOrgUnitUniqueNumber": NOREDUPERSON_OID + "2", - "norEduPersonBirthDate": NOREDUPERSON_OID + "3", - "norEduPersonLIN": NOREDUPERSON_OID + "4", - "norEduPersonNIN": NOREDUPERSON_OID + "5", - "o": X500ATTR + "10", - "organizationName": X500ATTR + "10", - "organizationalUnitName": X500ATTR + "11", - "ou": X500ATTR + "11", - "owner": X500ATTR + "32", - "physicalDeliveryOfficeName": X500ATTR + "19", - "pkcs9email": PKCS_9 + "1", - "postOfficeBox": X500ATTR + "18", - "postalAddress": X500ATTR + "16", - "postalCode": X500ATTR + "17", - "preferredDeliveryMethod": X500ATTR + "28", - "preferredLanguage": NETSCAPE_LDAP + "39", - "presentationAddress": X500ATTR + "29", - "protocolInformation": X500ATTR + "48", - "pseudonym": X500ATTR + "65", - "registeredAddress": X500ATTR + "26", - "rfc822Mailbox": UCL_DIR_PILOT + "3", - "roleOccupant": X500ATTR + "33", - "searchGuide": X500ATTR + "14", - "serialNumber": X500ATTR + "5", - "sn": X500ATTR + "4", - "st": X500ATTR + "8", - "stateOrProvinceName": X500ATTR + "8", - "street": X500ATTR + "9", - "streetAddress": X500ATTR + "9", - "supportedAlgorithms": X500ATTR + "52", - "supportedApplicationContext": X500ATTR + "30", - "surname": X500ATTR + "4", - "telephoneNumber": X500ATTR + "20", - "teletexTerminalIdentifier": X500ATTR + "22", - "telexNumber": X500ATTR + "21", - "title": X500ATTR + "12", - "uniqueMember": X500ATTR + "50", - "userCertificate": X500ATTR + "36", - "userPKCS12": NETSCAPE_LDAP + "216", - "userSMIMECertificate": NETSCAPE_LDAP + "40", - "x121Address": X500ATTR + "24", - "x500UniqueIdentifier": X500ATTR + "45", + "associatedDomain": f"{UCL_DIR_PILOT}37", + "authorityRevocationList": f"{X500ATTR}38", + "businessCategory": f"{X500ATTR}15", + "c": f"{X500ATTR}6", + "cACertificate": f"{X500ATTR}37", + "carLicense": f"{NETSCAPE_LDAP}1", + "certificateRevocationList": f"{X500ATTR}39", + "countryName": f"{X500ATTR}6", + "crossCertificatePair": f"{X500ATTR}40", + "dc": f"{UCL_DIR_PILOT}25", + "deltaRevocationList": f"{X500ATTR}53", + "departmentNumber": f"{NETSCAPE_LDAP}2", + "destinationIndicator": f"{X500ATTR}27", + "displayName": f"{NETSCAPE_LDAP}241", + "dmdName": f"{X500ATTR}54", + "dnQualifier": f"{X500ATTR}46", + "domainComponent": f"{UCL_DIR_PILOT}25", + "eduPersonAffiliation": f"{EDUPERSON_OID}1", + "eduPersonEntitlement": f"{EDUPERSON_OID}7", + "eduPersonNickname": f"{EDUPERSON_OID}2", + "eduPersonOrgDN": f"{EDUPERSON_OID}3", + "eduPersonOrgUnitDN": f"{EDUPERSON_OID}4", + "eduPersonPrimaryAffiliation": f"{EDUPERSON_OID}5", + "eduPersonPrimaryOrgUnitDN": f"{EDUPERSON_OID}8", + "eduPersonPrincipalName": f"{EDUPERSON_OID}6", + "eduPersonPrincipalNamePrior": f"{EDUPERSON_OID}12", + "eduPersonScopedAffiliation": f"{EDUPERSON_OID}9", + "eduPersonTargetedID": f"{EDUPERSON_OID}10", + "eduPersonAssurance": f"{EDUPERSON_OID}11", + "eduPersonUniqueId": f"{EDUPERSON_OID}13", + "eduPersonOrcid": f"{EDUPERSON_OID}16", + "email": f"{PKCS_9}1", + "emailAddress": f"{PKCS_9}1", + "employeeNumber": f"{NETSCAPE_LDAP}3", + "employeeType": f"{NETSCAPE_LDAP}4", + "enhancedSearchGuide": f"{X500ATTR}47", + "facsimileTelephoneNumber": f"{X500ATTR}23", + "fax": f"{X500ATTR}23", + "federationFeideSchemaVersion": f"{NOREDUPERSON_OID}9", + "generationQualifier": f"{X500ATTR}44", + "givenName": f"{X500ATTR}42", + "gn": f"{X500ATTR}42", + "houseIdentifier": f"{X500ATTR}51", + "initials": f"{X500ATTR}43", + "internationaliSDNNumber": f"{X500ATTR}25", + "jpegPhoto": f"{UCL_DIR_PILOT}60", + "knowledgeInformation": f"{X500ATTR}2", + "l": f"{X500ATTR}7", + "localityName": f"{X500ATTR}7", + "mail": f"{UCL_DIR_PILOT}3", + "member": f"{X500ATTR}31", + "norEduOrgAcronym": f"{NOREDUPERSON_OID}6", + "norEduOrgUniqueIdentifier": f"{NOREDUPERSON_OID}7", + "norEduOrgUniqueNumber": f"{NOREDUPERSON_OID}1", + "norEduOrgUnitUniqueIdentifier": f"{NOREDUPERSON_OID}8", + "norEduOrgUnitUniqueNumber": f"{NOREDUPERSON_OID}2", + "norEduPersonBirthDate": f"{NOREDUPERSON_OID}3", + "norEduPersonLIN": f"{NOREDUPERSON_OID}4", + "norEduPersonNIN": f"{NOREDUPERSON_OID}5", + "o": f"{X500ATTR}10", + "organizationName": f"{X500ATTR}10", + "organizationalUnitName": f"{X500ATTR}11", + "ou": f"{X500ATTR}11", + "owner": f"{X500ATTR}32", + "physicalDeliveryOfficeName": f"{X500ATTR}19", + "pkcs9email": f"{PKCS_9}1", + "postOfficeBox": f"{X500ATTR}18", + "postalAddress": f"{X500ATTR}16", + "postalCode": f"{X500ATTR}17", + "preferredDeliveryMethod": f"{X500ATTR}28", + "preferredLanguage": f"{NETSCAPE_LDAP}39", + "presentationAddress": f"{X500ATTR}29", + "protocolInformation": f"{X500ATTR}48", + "pseudonym": f"{X500ATTR}65", + "registeredAddress": f"{X500ATTR}26", + "rfc822Mailbox": f"{UCL_DIR_PILOT}3", + "roleOccupant": f"{X500ATTR}33", + "searchGuide": f"{X500ATTR}14", + "serialNumber": f"{X500ATTR}5", + "sn": f"{X500ATTR}4", + "st": f"{X500ATTR}8", + "stateOrProvinceName": f"{X500ATTR}8", + "street": f"{X500ATTR}9", + "streetAddress": f"{X500ATTR}9", + "supportedAlgorithms": f"{X500ATTR}52", + "supportedApplicationContext": f"{X500ATTR}30", + "surname": f"{X500ATTR}4", + "telephoneNumber": f"{X500ATTR}20", + "teletexTerminalIdentifier": f"{X500ATTR}22", + "telexNumber": f"{X500ATTR}21", + "title": f"{X500ATTR}12", + "uniqueMember": f"{X500ATTR}50", + "userCertificate": f"{X500ATTR}36", + "userPKCS12": f"{NETSCAPE_LDAP}216", + "userSMIMECertificate": f"{NETSCAPE_LDAP}40", + "x121Address": f"{X500ATTR}24", + "x500UniqueIdentifier": f"{X500ATTR}45", }, } diff --git a/src/saml2/authn.py b/src/saml2/authn.py index 156c3795d..dfd0a9259 100644 --- a/src/saml2/authn.py +++ b/src/saml2/authn.py @@ -1,10 +1,8 @@ import logging import time - -import six -from six.moves.urllib.parse import parse_qs -from six.moves.urllib.parse import urlencode -from six.moves.urllib.parse import urlsplit +from urllib.parse import parse_qs +from urllib.parse import urlencode +from urllib.parse import urlsplit from saml2 import SAMLError import saml2.cryptography.symmetric @@ -28,7 +26,7 @@ class EncodeError(SAMLError): pass -class UserAuthnMethod(object): +class UserAuthnMethod: def __init__(self, srv): self.srv = srv @@ -80,7 +78,7 @@ def create_return_url(base, query, **kwargs): for key, values in parse_qs(query).items(): if key in kwargs: - if isinstance(kwargs[key], six.string_types): + if isinstance(kwargs[key], str): kwargs[key] = [kwargs[key]] kwargs[key].extend(values) else: @@ -89,7 +87,7 @@ def create_return_url(base, query, **kwargs): if part.query: for key, values in parse_qs(part.query).items(): if key in kwargs: - if isinstance(kwargs[key], six.string_types): + if isinstance(kwargs[key], str): kwargs[key] = [kwargs[key]] kwargs[key].extend(values) else: @@ -99,9 +97,9 @@ def create_return_url(base, query, **kwargs): else: _pre = base - logger.debug("kwargs: %s" % kwargs) + logger.debug(f"kwargs: {kwargs}") - return "%s?%s" % (_pre, url_encode_params(kwargs)) + return f"{_pre}?{url_encode_params(kwargs)}" class UsernamePasswordMako(UserAuthnMethod): @@ -146,7 +144,7 @@ def __call__(self, cookie=None, policy_url=None, logo_url=None, query="", **kwar "logo_url": logo_url, "query": query, } - logger.debug("do_authentication argv: %s" % argv) + logger.debug(f"do_authentication argv: {argv}") mte = self.template_lookup.get_template(self.mako_template) resp.message = mte.render(**argv) return resp @@ -166,7 +164,7 @@ def verify(self, request, **kwargs): """ # logger.debug("verify(%s)" % request) - if isinstance(request, six.string_types): + if isinstance(request, str): _dict = parse_qs(request) elif isinstance(request, dict): _dict = request @@ -192,7 +190,7 @@ def authenticated_as(self, cookie=None, **kwargs): if cookie is None: return None else: - logger.debug("kwargs: %s" % kwargs) + logger.debug(f"kwargs: {kwargs}") try: info, timestamp = parse_cookie(self.cookie_name, self.srv.seed, cookie) if self.active[info] == timestamp: @@ -225,7 +223,7 @@ def callback(self, server_env, cookie=None, sid="", query="", **kwargs): return self.social.callback(server_env, cookie, sid, query, **kwargs) -class AuthnMethodChooser(object): +class AuthnMethodChooser: def __init__(self, methods=None): self.methods = methods diff --git a/src/saml2/authn_context/__init__.py b/src/saml2/authn_context/__init__.py index 8209f7dfb..766495296 100644 --- a/src/saml2/authn_context/__init__.py +++ b/src/saml2/authn_context/__init__.py @@ -26,7 +26,7 @@ CMP_TYPE = ["exact", "minimum", "maximum", "better"] -class AuthnBroker(object): +class AuthnBroker: def __init__(self): self.db = {"info": {}, "key": {}} self.next = 0 diff --git a/src/saml2/cache.py b/src/saml2/cache.py index dab915468..5aaddbdb4 100644 --- a/src/saml2/cache.py +++ b/src/saml2/cache.py @@ -3,8 +3,6 @@ import logging import shelve -import six - from saml2 import SAMLError from saml2 import time_util from saml2.ident import code @@ -30,7 +28,7 @@ class CacheError(SAMLError): pass -class Cache(object): +class Cache: def __init__(self, filename=None): if filename: self._db = shelve.open(filename, writeback=True, protocol=2) @@ -106,9 +104,9 @@ def get(self, name_id, entity_id, check_not_on_or_after=True): (timestamp, info) = self._db[cni][entity_id] info = info.copy() if check_not_on_or_after and time_util.after(timestamp): - raise TooOld("past %s" % str(timestamp)) + raise TooOld(f"past {str(timestamp)}") - if "name_id" in info and isinstance(info["name_id"], six.string_types): + if "name_id" in info and isinstance(info["name_id"], str): info["name_id"] = decode(info["name_id"]) return info or None @@ -123,7 +121,7 @@ def set(self, name_id, entity_id, info, not_on_or_after=0): :param not_on_or_after: A time after which the assertion is not valid. """ info = dict(info) - if "name_id" in info and not isinstance(info["name_id"], six.string_types): + if "name_id" in info and not isinstance(info["name_id"], str): # make friendly to (JSON) serialization info["name_id"] = code(name_id) diff --git a/src/saml2/cert.py b/src/saml2/cert.py index 2354a714f..c5f626601 100644 --- a/src/saml2/cert.py +++ b/src/saml2/cert.py @@ -8,7 +8,6 @@ from OpenSSL import crypto import dateutil.parser import pytz -import six import saml2.cryptography.pki @@ -25,7 +24,7 @@ class PayloadError(Exception): pass -class OpenSSLWrapper(object): +class OpenSSLWrapper: def __init__(self): pass @@ -118,8 +117,8 @@ def create_certificate( k_f = None if write_to_file: - cert_file = "%s.crt" % cn - key_file = "%s.key" % cn + cert_file = f"{cn}.crt" + key_file = f"{cn}.key" try: remove(cert_file) except Exception: @@ -165,15 +164,15 @@ def create_certificate( tmp_key = None if cipher_passphrase is not None: passphrase = cipher_passphrase["passphrase"] - if isinstance(cipher_passphrase["passphrase"], six.string_types): + if isinstance(cipher_passphrase["passphrase"], str): passphrase = passphrase.encode("utf-8") tmp_key = crypto.dump_privatekey(crypto.FILETYPE_PEM, k, cipher_passphrase["cipher"], passphrase) else: tmp_key = crypto.dump_privatekey(crypto.FILETYPE_PEM, k) if write_to_file: - with open(c_f, "wt") as fc: + with open(c_f, "w") as fc: fc.write(tmp_cert.decode("utf-8")) - with open(k_f, "wt") as fk: + with open(k_f, "w") as fk: fk.write(tmp_key.decode("utf-8")) return c_f, k_f return tmp_cert, tmp_key @@ -181,7 +180,7 @@ def create_certificate( raise CertificateError("Certificate cannot be generated.", ex) def write_str_to_file(self, file, str_data): - with open(file, "wt") as f: + with open(file, "w") as f: f.write(str_data) def read_str_from_file(self, file, type="pem"): @@ -256,7 +255,7 @@ def create_cert_signed_certificate( cert.sign(ca_key, hash_alg) cert_dump = crypto.dump_certificate(crypto.FILETYPE_PEM, cert) - if isinstance(cert_dump, six.string_types): + if isinstance(cert_dump, str): return cert_dump return cert_dump.decode("utf-8") @@ -323,9 +322,8 @@ def verify(self, signing_cert_str, cert_str): return False, ("CN may not be equal for CA certificate and the " "signed certificate.") cert_algorithm = cert.get_signature_algorithm() - if six.PY3: - cert_algorithm = cert_algorithm.decode("ascii") - cert_str = cert_str.encode("ascii") + cert_algorithm = cert_algorithm.decode("ascii") + cert_str = cert_str.encode("ascii") cert_crypto = saml2.cryptography.pki.load_pem_x509_certificate(cert_str) @@ -333,9 +331,9 @@ def verify(self, signing_cert_str, cert_str): crypto.verify(ca_cert, cert_crypto.signature, cert_crypto.tbs_certificate_bytes, cert_algorithm) return True, "Signed certificate is valid and correctly signed by CA certificate." except crypto.Error as e: - return False, "Certificate is incorrectly signed: %s" % str(e) + return False, f"Certificate is incorrectly signed: {str(e)}" except Exception as e: - return False, "Certificate is not valid for an unknown reason. %s" % str(e) + return False, f"Certificate is not valid for an unknown reason. {str(e)}" def read_cert_from_file(cert_file, cert_type="pem"): diff --git a/src/saml2/client.py b/src/saml2/client.py index bf07cf6a4..0e77bad19 100644 --- a/src/saml2/client.py +++ b/src/saml2/client.py @@ -1,7 +1,5 @@ # !/usr/bin/env python -# -*- coding: utf-8 -*- # -import six """Contains classes and functions that a SAML2.0 Service Provider (SP) may use @@ -88,9 +86,7 @@ def prepare_for_authenticate( ) if negotiated_binding != binding: - raise ValueError( - "Negotiated binding '{}' does not match binding to use '{}'".format(negotiated_binding, binding) - ) + raise ValueError(f"Negotiated binding '{negotiated_binding}' does not match binding to use '{binding}'") return reqid, info @@ -212,7 +208,7 @@ def global_logout( conversation. """ - if isinstance(name_id, six.string_types): + if isinstance(name_id, str): name_id = decode(name_id) logger.debug("logout request for: %s", name_id) @@ -379,7 +375,7 @@ def do_logout( if not_done: # upstream should try later - raise LogoutError("%s" % (entity_ids,)) + raise LogoutError(f"{entity_ids}") return responses @@ -431,8 +427,8 @@ def handle_logout_response(self, response, sign_alg=None, digest_alg=None): ) def _use_soap(self, destination, query_type, **kwargs): - _create_func = getattr(self, "create_%s" % query_type) - _response_func = getattr(self, "parse_%s_response" % query_type) + _create_func = getattr(self, f"create_{query_type}") + _response_func = getattr(self, f"parse_{query_type}_response") try: response_args = kwargs["response_args"] del kwargs["response_args"] @@ -455,7 +451,7 @@ def _use_soap(self, destination, query_type, **kwargs): else: response = _response_func(response.content) else: - raise HTTPError("%d:%s" % (response.status_code, response.error)) + raise HTTPError(f"{int(response.status_code)}:{response.error}") if response: # not_done.remove(entity_id) @@ -505,9 +501,9 @@ def do_assertion_id_request(self, assertion_ids, entity_id, consent=None, extens srvs = self.metadata.assertion_id_request_service(entity_id, BINDING_SOAP) if not srvs: - raise NoServiceDefined("%s: %s" % (entity_id, "assertion_id_request_service")) + raise NoServiceDefined(f"{entity_id}: assertion_id_request_service") - if isinstance(assertion_ids, six.string_types): + if isinstance(assertion_ids, str): assertion_ids = [assertion_ids] _id_refs = [AssertionIDRef(_id) for _id in assertion_ids] diff --git a/src/saml2/client_base.py b/src/saml2/client_base.py index 69f1b3afc..673dae750 100644 --- a/src/saml2/client_base.py +++ b/src/saml2/client_base.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """Contains classes and functions that a SAML2.0 Service Provider (SP) may use @@ -9,13 +8,11 @@ import threading import time from typing import Mapping +from urllib.parse import parse_qs +from urllib.parse import urlencode +from urllib.parse import urlparse from warnings import warn as _warn -import six -from six.moves.urllib.parse import parse_qs -from six.moves.urllib.parse import urlencode -from six.moves.urllib.parse import urlparse - import saml2 from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT @@ -223,7 +220,7 @@ def _sso_location(self, entityid=None, binding=BINDING_HTTP_REDIRECT): # IdP in the configuration raise exception eids = self.metadata.with_descriptor("idpsso") if len(eids) > 1: - raise IdpUnspecified("Too many IdPs to choose from: %s" % eids) + raise IdpUnspecified(f"Too many IdPs to choose from: {eids}") try: srvs = self.metadata.single_sign_on_service(list(eids.keys())[0], binding) @@ -383,7 +380,7 @@ def create_authn_request( if isinstance(_item, _msg.child_class(param)): args[param] = _item else: - raise ValueError("Wrong type for param {name}".format(name=param)) + raise ValueError(f"Wrong type for param {param}") # NameIDPolicy nameid_policy_format_config = self.config.getattr("name_id_policy_format", "sp") @@ -513,7 +510,7 @@ def create_attribute_query( pass else: raise AttributeError("Missing required parameter") - elif isinstance(name_id, six.string_types): + elif isinstance(name_id, str): name_id = saml.NameID(text=name_id) for key in ["sp_name_qualifier", "name_qualifier", "format"]: try: @@ -627,7 +624,7 @@ def create_authz_decision_query_using_assertion( """ if action: - if isinstance(action, six.string_types): + if isinstance(action, str): _action = [saml.Action(text=action)] else: _action = [saml.Action(text=a) for a in action] @@ -657,7 +654,7 @@ def create_assertion_id_request(assertion_id_refs, **kwargs): :return: One ID ref """ - if isinstance(assertion_id_refs, six.string_types): + if isinstance(assertion_id_refs, str): return 0, assertion_id_refs else: return 0, assertion_id_refs[0] @@ -1003,9 +1000,9 @@ def create_discovery_service_request(url, entity_id, **kwargs): params = urlencode({k: v for k, v in args.items() if v}) # url can already contain some parameters if "?" in url: - return "%s&%s" % (url, params) + return f"{url}&{params}" else: - return "%s?%s" % (url, params) + return f"{url}?{params}" @staticmethod def parse_discovery_service_response(url="", query="", returnIDParam="entityID"): diff --git a/src/saml2/config.py b/src/saml2/config.py index a92642d98..dcf8fd75c 100644 --- a/src/saml2/config.py +++ b/src/saml2/config.py @@ -163,7 +163,7 @@ class ConfigurationError(SAMLError): pass -class Config(object): +class Config: def_context = "" def __init__(self, homedir="."): @@ -234,7 +234,7 @@ def setattr(self, context, attr, val): if context == "": setattr(self, attr, val) else: - setattr(self, "_%s_%s" % (context, attr), val) + setattr(self, f"_{context}_{attr}", val) def getattr(self, attr, context=None): if context is None: @@ -243,7 +243,7 @@ def getattr(self, attr, context=None): if context == "": return getattr(self, attr, None) else: - return getattr(self, "_%s_%s" % (context, attr), None) + return getattr(self, f"_{context}_{attr}", None) def load_special(self, cnf, typ): for arg in SPEC[typ]: diff --git a/src/saml2/country_codes.py b/src/saml2/country_codes.py index bf4b60a4d..55271d7b0 100644 --- a/src/saml2/country_codes.py +++ b/src/saml2/country_codes.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# This Python file uses the following encoding: utf-8 # ISO 3166-1 country names and codes from http://opencountrycodes.appspot.com/python COUNTRIES = ( diff --git a/src/saml2/cryptography/symmetric.py b/src/saml2/cryptography/symmetric.py index 636bc3400..ea4565b8a 100644 --- a/src/saml2/cryptography/symmetric.py +++ b/src/saml2/cryptography/symmetric.py @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) -class Fernet(object): +class Fernet: """The default symmetric cryptography method.""" @staticmethod @@ -97,7 +97,7 @@ def build_cipher(self, *args, **kwargs): _warn(_deprecation_msg, DeprecationWarning) -class AESCipher(object): +class AESCipher: """[deprecated] Symmetric cryptography method using AES. The default parameter set is AES 128bit in CBC mode. @@ -142,18 +142,18 @@ def build_cipher(self, alg="aes_128_cbc"): iv = _os.urandom(self.AES_BLOCK_SIZE) if len(iv) != self.AES_BLOCK_SIZE: - raise Exception("Wrong iv size: {}".format(len(iv))) + raise Exception(f"Wrong iv size: {len(iv)}") if bits not in _ciphers.algorithms.AES.key_sizes: - raise Exception("Unsupported key length: {}".format(bits)) + raise Exception(f"Unsupported key length: {bits}") if len(self.key) != bits / 8: - raise Exception("Wrong Key length: {}".format(len(self.key))) + raise Exception(f"Wrong Key length: {len(self.key)}") try: mode = self.POSTFIX_MODE[cmode] except KeyError: - raise Exception("Unsupported chaining mode: {}".format(cmode)) + raise Exception(f"Unsupported chaining mode: {cmode}") cipher = _ciphers.Cipher(_ciphers.algorithms.AES(self.key), mode(iv)) diff --git a/src/saml2/discovery.py b/src/saml2/discovery.py index f7de497bf..2f777d017 100644 --- a/src/saml2/discovery.py +++ b/src/saml2/discovery.py @@ -1,4 +1,4 @@ -from six.moves.urllib import parse +from urllib import parse from saml2.entity import Entity from saml2.response import VerificationError @@ -28,7 +28,7 @@ def parse_discovery_service_request(self, url="", query=""): for key in ["isPassive", "return", "returnIDParam", "policy", "entityID"]: try: if len(dsr[key]) != 1: - raise Exception("Invalid DS request keys: {k}".format(k=key)) + raise Exception(f"Invalid DS request keys: {key}") dsr[key] = dsr[key][0] except KeyError: pass @@ -52,7 +52,7 @@ def parse_discovery_service_request(self, url="", query=""): is_passive = dsr.get("isPassive") if is_passive not in ["true", "false"]: - raise ValueError("Invalid value '{v}' for attribute '{attr}'".format(v=is_passive, attr="isPassive")) + raise ValueError(f"Invalid value '{is_passive}' for attribute 'isPassive'") if "isPassive" in dsr and dsr["isPassive"] == "true": dsr["isPassive"] = True @@ -77,9 +77,9 @@ def create_discovery_service_response(return_url=None, returnIDParam="entityID", part = parse.urlparse(return_url) if part.query: # Iff there is a query part add the new info at the end - return_url = "%s&%s" % (return_url, qp) + return_url = f"{return_url}&{qp}" else: - return_url = "%s?%s" % (return_url, qp) + return_url = f"{return_url}?{qp}" return return_url diff --git a/src/saml2/ecp.py b/src/saml2/ecp.py index 676544c4a..5e1ad0b77 100644 --- a/src/saml2/ecp.py +++ b/src/saml2/ecp.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """ @@ -31,7 +30,7 @@ def ecp_capable(headers): if MIME_PAOS in headers["Accept"]: if "PAOS" in headers: - if 'ver="%s";"%s"' % (paos.NAMESPACE, SERVICE) in headers["PAOS"]: + if f'ver="{paos.NAMESPACE}";"{SERVICE}"' in headers["PAOS"]: return True return False @@ -70,7 +69,7 @@ def ecp_auth_request(cls, entityid=None, relay_state="", sign=None, sign_alg=Non # # ---------------------------------------- - logger.info("entityid: %s, binding: %s" % (entityid, BINDING_SOAP)) + logger.info(f"entityid: {entityid}, binding: {BINDING_SOAP}") location = cls._sso_location(entityid, binding=BINDING_SOAP) req_id, authn_req = cls.create_authn_request( @@ -138,7 +137,7 @@ def handle_ecp_authn_response(cls, soap_message, outstanding=None): response = authn_response(cls.config, cls.service_urls(), outstanding, allow_unsolicited=True) - response.loads("%s" % rdict["body"], False, soap_message) + response.loads(f"{rdict['body']}", False, soap_message) response.verify() cls.users.add_information_about_person(response.session_info()) @@ -164,7 +163,7 @@ def ecp_response(target_url, response): soap_envelope = soapenv.Envelope(header=header, body=body) - return "%s" % soap_envelope + return f"{soap_envelope}" class ECPServer(Server): diff --git a/src/saml2/ecp_client.py b/src/saml2/ecp_client.py index 8286ccea1..fe0519901 100644 --- a/src/saml2/ecp_client.py +++ b/src/saml2/ecp_client.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """ @@ -7,10 +6,9 @@ programs. """ +from http import cookiejar as cookielib import logging -from six.moves import http_cookiejar as cookielib - from saml2 import BINDING_SOAP from saml2 import SAMLError from saml2 import saml @@ -28,7 +26,7 @@ SERVICE = "urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp" -PAOS_HEADER_INFO = 'ver="%s";"%s"' % (paos.NAMESPACE, SERVICE) +PAOS_HEADER_INFO = f'ver="{paos.NAMESPACE}";"{SERVICE}"' logger = logging.getLogger(__name__) @@ -139,9 +137,7 @@ def phase2( logger.debug("[P2] Got IdP response: %s", response) if response.status_code != 200: - raise SAMLError( - "Request to IdP failed ({status}): {text}".format(status=response.status_code, text=response.text) - ) + raise SAMLError(f"Request to IdP failed ({response.status_code}): {response.text}") # SAMLP response in a SOAP envelope body, ecp response in headers respdict = self.parse_soap_message(response.text) @@ -171,8 +167,8 @@ def phase2( _acs_url = _ecp_response.assertion_consumer_service_url if rc_url != _acs_url: error = ( - "response_consumer_url '%s' does not match" % rc_url, - "assertion_consumer_service_url '%s" % _acs_url, + f"response_consumer_url '{rc_url}' does not match", + f"assertion_consumer_service_url '{_acs_url}", ) # Send an error message to the SP _ = self.send(rc_url, "POST", data=soap.soap_fault(error)) @@ -251,7 +247,7 @@ def ecp_conversation(self, respdict, idp_entity_id=None): # url I started off with. pass else: - raise SAMLError("Error POSTing package to SP: %s" % response.text) + raise SAMLError(f"Error POSTing package to SP: {response.text}") logger.debug("[P3] SP response: %s", response.text) @@ -266,14 +262,14 @@ def add_paos_headers(headers=None): headers = set_list2dict(headers) headers["PAOS"] = PAOS_HEADER_INFO if "Accept" in headers: - headers["Accept"] += ";%s" % MIME_PAOS + headers["Accept"] += f";{MIME_PAOS}" elif "accept" in headers: headers["Accept"] = headers["accept"] - headers["Accept"] += ";%s" % MIME_PAOS + headers["Accept"] += f";{MIME_PAOS}" del headers["accept"] headers = dict2set_list(headers) else: - headers = [("Accept", "text/html; %s" % MIME_PAOS), ("PAOS", PAOS_HEADER_INFO)] + headers = [("Accept", f"text/html; {MIME_PAOS}"), ("PAOS", PAOS_HEADER_INFO)] return headers @@ -302,7 +298,7 @@ def operation(self, url, idp_entity_id, op, **opargs): print(response.text) if response.status_code != 200: - raise SAMLError("Request to SP failed: %s" % response.text) + raise SAMLError(f"Request to SP failed: {response.text}") # The response might be a AuthnRequest instance in a SOAP envelope # body. If so it's the start of the ECP conversation @@ -322,7 +318,7 @@ def operation(self, url, idp_entity_id, op, **opargs): raise if response.status_code >= 400: - raise SAMLError("Error performing operation: %s" % (response.text,)) + raise SAMLError(f"Error performing operation: {response.text}") return response diff --git a/src/saml2/entity.py b/src/saml2/entity.py index aac23afc9..9d0d2dcfe 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -5,7 +5,6 @@ import logging import requests -import six from saml2 import BINDING_HTTP_ARTIFACT from saml2 import BINDING_HTTP_POST @@ -117,13 +116,13 @@ def create_artifact(entity_id, message_handle, endpoint_index=0): :param endpoint_index: :return: """ - if not isinstance(entity_id, six.binary_type): + if not isinstance(entity_id, bytes): entity_id = entity_id.encode("utf-8") sourceid = sha1(entity_id) - if not isinstance(message_handle, six.binary_type): + if not isinstance(message_handle, bytes): message_handle = message_handle.encode("utf-8") - ter = b"".join((ARTIFACT_TYPECODE, ("%.2x" % endpoint_index).encode("ascii"), sourceid.digest(), message_handle)) + ter = b"".join((ARTIFACT_TYPECODE, (f"{endpoint_index:02x}").encode("ascii"), sourceid.digest(), message_handle)) return base64.b64encode(ter).decode("ascii") @@ -161,7 +160,7 @@ def __init__(self, entity_type, config=None, config_file="", virtual_organizatio tmp = make_temp(r.text, ".pem", False, self.config.delete_tmpfiles) setattr(self.config, item, tmp.name) else: - raise Exception("Could not fetch certificate from %s" % _val) + raise Exception(f"Could not fetch certificate from {_val}") HTTPBase.__init__( self, @@ -182,7 +181,7 @@ def __init__(self, entity_type, config=None, config_file="", virtual_organizatio self.sec = security_context(self.config) if virtual_organization: - if isinstance(virtual_organization, six.string_types): + if isinstance(virtual_organization, str): self.vorg = self.config.vorg[virtual_organization] elif isinstance(virtual_organization, VirtualOrg): self.vorg = virtual_organization @@ -215,7 +214,7 @@ def reload_metadata(self, metadata_conf): try: self.metadata.reload(metadata_conf) except Exception as ex: - logger.error("Loading metadata failed; reason: %s" % str(ex)) + logger.error(f"Loading metadata failed; reason: {str(ex)}") return False self.sourceid = self.metadata.construct_source_id() @@ -268,7 +267,7 @@ def apply_binding( sign = sign if sign is not None else self.should_sign sign_alg = sigalg or self.signing_algorithm if sign_alg not in [long_name for short_name, long_name in SIG_ALLOWED_ALG]: - raise Exception("Signature algo not in allowed list: {algo}".format(algo=sign_alg)) + raise Exception(f"Signature algo not in allowed list: {sign_alg}") # unless if BINDING_HTTP_ARTIFACT if response: @@ -306,7 +305,7 @@ def apply_binding( else: info = self.use_http_artifact(msg_str, destination, relay_state) else: - raise SAMLError("Unknown binding type: %s" % binding) + raise SAMLError(f"Unknown binding type: {binding}") return info @@ -328,8 +327,8 @@ def pick_binding(self, service, bindings=None, descr_type="", request=None, enti else: descr_type = "spsso" - _url = getattr(request, "%s_url" % service, None) - _index = getattr(request, "%s_index" % service, None) + _url = getattr(request, f"{service}_url", None) + _index = getattr(request, f"{service}_index", None) for binding in bindings: try: @@ -439,7 +438,7 @@ def unravel(txt, binding, msgtype="response"): BINDING_HTTP_ARTIFACT, None, ]: - raise UnknownBinding("Don't know how to handle '%s'" % binding) + raise UnknownBinding(f"Don't know how to handle '{binding}'") else: try: if binding == BINDING_HTTP_REDIRECT: @@ -447,14 +446,14 @@ def unravel(txt, binding, msgtype="response"): elif binding == BINDING_HTTP_POST: xmlstr = base64.b64decode(txt) elif binding == BINDING_SOAP: - func = getattr(soap, "parse_soap_enveloped_saml_%s" % msgtype) + func = getattr(soap, f"parse_soap_enveloped_saml_{msgtype}") xmlstr = func(txt) elif binding == BINDING_HTTP_ARTIFACT: xmlstr = base64.b64decode(txt) else: xmlstr = txt except Exception: - raise UnravelError("Unravelling binding '%s' failed" % binding) + raise UnravelError(f"Unravelling binding '{binding}' failed") return xmlstr @@ -499,9 +498,9 @@ def sign( sign_alg = sign_alg or self.signing_algorithm digest_alg = digest_alg or self.digest_algorithm if sign_alg not in [long_name for short_name, long_name in SIG_ALLOWED_ALG]: - raise Exception("Signature algo not in allowed list: {algo}".format(algo=sign_alg)) + raise Exception(f"Signature algo not in allowed list: {sign_alg}") if digest_alg not in [long_name for short_name, long_name in DIGEST_ALLOWED_ALG]: - raise Exception("Digest algo not in allowed list: {algo}".format(algo=digest_alg)) + raise Exception(f"Digest algo not in allowed list: {digest_alg}") if msg.signature is None: msg.signature = pre_signature_part(msg.id, self.sec.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg) @@ -674,7 +673,6 @@ def _encrypt_assertion(self, encrypt_cert, sp_entity_id, response, node_xpath=No return response except Exception as ex: exception = ex - pass if exception: raise exception return response @@ -839,7 +837,7 @@ def _response( ) node_xpath = "".join( [ - '/*[local-name()="%s"]' % v + f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] ] ) @@ -1461,7 +1459,7 @@ def _parse_response( logger.error("Unsolicited response") raise except Exception as err: - if "not well-formed" in "%s" % err: + if "not well-formed" in f"{err}": logger.error("Not well-formed XML") raise else: @@ -1581,11 +1579,7 @@ def artifact2destination(self, artifact, descriptor): typecode = _art[:2] if typecode != ARTIFACT_TYPECODE: - raise ValueError( - "Invalid artifact typecode '{invalid}' should be {valid}".format( - invalid=typecode, valid=ARTIFACT_TYPECODE - ) - ) + raise ValueError(f"Invalid artifact typecode '{typecode}' should be {ARTIFACT_TYPECODE}") try: endpoint_index = str(int(_art[2:4])) @@ -1594,7 +1588,7 @@ def artifact2destination(self, artifact, descriptor): entity = self.sourceid[_art[4:24]] destination = None - for desc in entity["%s_descriptor" % descriptor]: + for desc in entity[f"{descriptor}_descriptor"]: for srv in desc["artifact_resolution_service"]: if srv["index"] == endpoint_index: destination = srv["location"] diff --git a/src/saml2/eptid.py b/src/saml2/eptid.py index de32015e2..b6186fde5 100644 --- a/src/saml2/eptid.py +++ b/src/saml2/eptid.py @@ -8,13 +8,11 @@ import logging import shelve -import six - logger = logging.getLogger(__name__) -class Eptid(object): +class Eptid: def __init__(self, secret): self._db = {} self.secret = secret @@ -23,27 +21,27 @@ def make(self, idp, sp, args): md5 = hashlib.md5() for arg in args: md5.update(arg.encode("utf-8")) - if isinstance(sp, six.binary_type): + if isinstance(sp, bytes): md5.update(sp) else: md5.update(sp.encode("utf-8")) - if isinstance(self.secret, six.binary_type): + if isinstance(self.secret, bytes): md5.update(self.secret) else: md5.update(self.secret.encode("utf-8")) md5.digest() hashval = md5.hexdigest() - if isinstance(hashval, six.binary_type): + if isinstance(hashval, bytes): hashval = hashval.decode("ascii") return "!".join([idp, sp, hashval]) def __getitem__(self, key): - if six.PY3 and isinstance(key, six.binary_type): + if isinstance(key, bytes): key = key.decode("utf-8") return self._db[key] def __setitem__(self, key, value): - if six.PY3 and isinstance(key, six.binary_type): + if isinstance(key, bytes): key = key.decode("utf-8") self._db[key] = value @@ -64,9 +62,8 @@ def close(self): class EptidShelve(Eptid): def __init__(self, secret, filename): Eptid.__init__(self, secret) - if six.PY3: - if filename.endswith(".db"): - filename = filename.rsplit(".db", 1)[0] + if filename.endswith(".db"): + filename = filename.rsplit(".db", 1)[0] self._db = shelve.open(filename, writeback=True, protocol=2) def close(self): diff --git a/src/saml2/filter.py b/src/saml2/filter.py index 6aad1000c..849cfe5d1 100644 --- a/src/saml2/filter.py +++ b/src/saml2/filter.py @@ -1,7 +1,7 @@ __author__ = "roland" -class Filter(object): +class Filter: def __init__(self): pass @@ -16,7 +16,7 @@ def __init__(self, allow): :param allow: List of allowed descriptors :return: """ - super(AllowDescriptor, self).__init__() + super().__init__() self.allow = allow def __call__(self, entity_descriptor): diff --git a/src/saml2/httpbase.py b/src/saml2/httpbase.py index 4c0a5ad48..5a1d99261 100644 --- a/src/saml2/httpbase.py +++ b/src/saml2/httpbase.py @@ -1,14 +1,14 @@ import calendar import copy +import http.cookiejar as http_cookiejar +from http.cookies import SimpleCookie import logging import re import time +from urllib.parse import urlencode +from urllib.parse import urlparse import requests -from six.moves import http_cookiejar -from six.moves.http_cookies import SimpleCookie -from six.moves.urllib.parse import urlencode -from six.moves.urllib.parse import urlparse from saml2 import SAMLError from saml2 import class_name @@ -80,7 +80,7 @@ def _since_epoch(cdate): break if t == -1: - err = 'ValueError: Date "{0}" does not match any of: {1}'.format(cdate, TIME_FORMAT) + err = f'ValueError: Date "{cdate}" does not match any of: {TIME_FORMAT}' raise Exception(err) return calendar.timegm(t) @@ -94,7 +94,7 @@ def dict2set_list(dic): return [(k, v) for k, v in dic.items()] -class HTTPBase(object): +class HTTPBase: def __init__(self, verify=True, ca_bundle=None, key_file=None, cert_file=None, http_client_timeout=None): self.request_args = {"allow_redirects": False} # self.cookies = {} @@ -134,7 +134,7 @@ def cookies(self, url): # print(cookie) if cookie.expires and cookie.expires <= now: continue - if not re.search("%s$" % cookie.domain, _domain): + if not re.search(f"{cookie.domain}$", _domain): continue if not re.match(cookie.path, part.path): continue @@ -233,7 +233,7 @@ def send(self, url, method="GET", **kwargs): r = requests.request(method, url, **_kwargs) logger.debug("Response status: %s", r.status_code) except requests.ConnectionError as exc: - raise ConnectionError("%s" % exc) + raise ConnectionError(f"{exc}") try: self.set_cookie(SimpleCookie(r.headers["set-cookie"]), r) @@ -250,7 +250,7 @@ def use_http_artifact(message, destination="", relay_state=""): query = urlencode({"SAMLart": message, "RelayState": relay_state}) else: query = urlencode({"SAMLart": message}) - info = {"data": "", "url": "%s?%s" % (destination, query)} + info = {"data": "", "url": f"{destination}?{query}"} return info @staticmethod @@ -274,7 +274,7 @@ def use_http_uri(message, typ, destination="", relay_state=""): query = urlencode({"ID": message, "RelayState": relay_state}) else: query = urlencode({"ID": message}) - info = {"data": "", "url": "%s?%s" % (destination, query)} + info = {"data": "", "url": f"{destination}?{query}"} else: raise NotImplementedError diff --git a/src/saml2/httputil.py b/src/saml2/httputil.py index 2e5e7c277..7217b1471 100644 --- a/src/saml2/httputil.py +++ b/src/saml2/httputil.py @@ -1,13 +1,11 @@ import cgi import hashlib import hmac +from http.cookies import SimpleCookie import logging import time - -import six -from six.moves.http_cookies import SimpleCookie -from six.moves.urllib.parse import parse_qs -from six.moves.urllib.parse import quote +from urllib.parse import parse_qs +from urllib.parse import quote from saml2 import BINDING_HTTP_ARTIFACT from saml2 import BINDING_HTTP_POST @@ -23,7 +21,7 @@ logger = logging.getLogger(__name__) -class Response(object): +class Response: _template = None _status = "200 OK" _content_type = "text/html" @@ -63,9 +61,9 @@ def _response(self, message="", **argv): mte = self.mako_lookup.get_template(self.mako_template) message = mte.render(**argv) - if isinstance(message, six.string_types): + if isinstance(message, str): return [message.encode("utf-8")] - elif isinstance(message, six.binary_type): + elif isinstance(message, bytes): return [message] else: return message @@ -159,7 +157,7 @@ class BadGateway(Response): _status = "502 Bad Gateway" -class HttpParameters(object): +class HttpParameters: """GET or POST signature parameters for Redirect or POST-SimpleSign bindings because they are not contained in XML unlike the POST binding """ @@ -202,21 +200,21 @@ def geturl(environ, query=True, path=True, use_server_name=False): :param use_server_name: If SERVER_NAME/_HOST should be used instead of HTTP_HOST """ - url = [environ["wsgi.url_scheme"] + "://"] + url = [f"{environ['wsgi.url_scheme']}://"] if use_server_name: url.append(environ["SERVER_NAME"]) if environ["wsgi.url_scheme"] == "https": if environ["SERVER_PORT"] != "443": - url.append(":" + environ["SERVER_PORT"]) + url.append(f":{environ['SERVER_PORT']}") else: if environ["SERVER_PORT"] != "80": - url.append(":" + environ["SERVER_PORT"]) + url.append(f":{environ['SERVER_PORT']}") else: url.append(environ["HTTP_HOST"]) if path: url.append(getpath(environ)) if query and environ.get("QUERY_STRING"): - url.append("?" + environ["QUERY_STRING"]) + url.append(f"?{environ['QUERY_STRING']}") return "".join(url) @@ -253,13 +251,13 @@ def get_response(environ, start_response): def unpack_redirect(environ): if "QUERY_STRING" in environ: _qs = environ["QUERY_STRING"] - return dict([(k, v[0]) for k, v in parse_qs(_qs).items()]) + return {k: v[0] for k, v in parse_qs(_qs).items()} else: return None def unpack_post(environ): - return dict([(k, v[0]) for k, v in parse_qs(get_post(environ))]) + return {k: v[0] for k, v in parse_qs(get_post(environ))} def unpack_soap(environ): diff --git a/src/saml2/ident.py b/src/saml2/ident.py index d52051d1a..c7d37c0d4 100644 --- a/src/saml2/ident.py +++ b/src/saml2/ident.py @@ -2,10 +2,8 @@ from hashlib import sha256 import logging import shelve - -import six -from six.moves.urllib.parse import quote -from six.moves.urllib.parse import unquote +from urllib.parse import quote +from urllib.parse import unquote from saml2 import SAMLError from saml2.s_utils import PolicyError @@ -42,7 +40,7 @@ class that is used. for attr in ATTR: val = getattr(item, attr) if val: - _res.append("%d=%s" % (i, quote(val))) + _res.append(f"{int(i)}={quote(val)}") i += 1 return ",".join(_res) @@ -52,7 +50,7 @@ def code_binary(item): Return a binary 'code' suitable for hashing. """ code_str = code(item) - if isinstance(code_str, six.string_types): + if isinstance(code_str, str): return code_str.encode("utf-8") return code_str @@ -73,13 +71,13 @@ def decode(txt): return _nid -class IdentDB(object): +class IdentDB: """A class that handles identifiers of entities Keeps a list of all nameIDs returned per SP """ def __init__(self, db, domain="", name_qualifier=""): - if isinstance(db, six.string_types): + if isinstance(db, str): self.db = shelve.open(db, protocol=2) else: self.db = db @@ -88,15 +86,15 @@ def __init__(self, db, domain="", name_qualifier=""): def _create_id(self, nformat, name_qualifier="", sp_name_qualifier=""): _id = sha256(rndbytes(32)) - if not isinstance(nformat, six.binary_type): + if not isinstance(nformat, bytes): nformat = nformat.encode("utf-8") _id.update(nformat) if name_qualifier: - if not isinstance(name_qualifier, six.binary_type): + if not isinstance(name_qualifier, bytes): name_qualifier = name_qualifier.encode("utf-8") _id.update(name_qualifier) if sp_name_qualifier: - if not isinstance(sp_name_qualifier, six.binary_type): + if not isinstance(sp_name_qualifier, bytes): sp_name_qualifier = sp_name_qualifier.encode("utf-8") _id.update(sp_name_qualifier) return _id.hexdigest() @@ -160,7 +158,7 @@ def get_nameid(self, userid, nformat, sp_name_qualifier, name_qualifier): if nformat == NAMEID_FORMAT_PERSISTENT: nameid = self.match_local_id(userid, sp_name_qualifier, name_qualifier) if nameid: - logger.debug("Found existing persistent NameId %s for user %s" % (nameid, userid)) + logger.debug(f"Found existing persistent NameId {nameid} for user {userid}") return nameid _id = self.create_id(nformat, name_qualifier, sp_name_qualifier) @@ -169,7 +167,7 @@ def get_nameid(self, userid, nformat, sp_name_qualifier, name_qualifier): if not self.domain: raise SAMLError("Can't issue email nameids, unknown domain") - _id = "%s@%s" % (_id, self.domain) + _id = f"{_id}@{self.domain}" nameid = NameID( format=nformat, diff --git a/src/saml2/mcache.py b/src/saml2/mcache.py index f89e616c2..c464cfc29 100644 --- a/src/saml2/mcache.py +++ b/src/saml2/mcache.py @@ -16,10 +16,10 @@ def _key(prefix, name): - return "%s_%s" % (prefix, name) + return f"{prefix}_{name}" -class Cache(object): +class Cache: def __init__(self, servers, debug=0): self._cache = memcache.Client(servers, debug) @@ -57,7 +57,7 @@ def get_identity(self, subject_id, entities=None): res = {} oldees = [] - for (entity_id, item) in self._cache.get_multi(entities, subject_id + "_").items(): + for (entity_id, item) in self._cache.get_multi(entities, f"{subject_id}_").items(): try: info = self.get_info(item) except TooOld: diff --git a/src/saml2/mdbcache.py b/src/saml2/mdbcache.py index 01b50e13c..20215bb66 100644 --- a/src/saml2/mdbcache.py +++ b/src/saml2/mdbcache.py @@ -17,7 +17,7 @@ logger = logging.getLogger(__name__) -class Cache(object): +class Cache: def __init__(self, server=None, debug=0, db=None): if server: connection = MongoClient(server) diff --git a/src/saml2/mdie.py b/src/saml2/mdie.py index 9a7414952..ae81d71fa 100644 --- a/src/saml2/mdie.py +++ b/src/saml2/mdie.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -import six from saml2 import ExtensionElement from saml2 import SamlBase @@ -26,7 +25,7 @@ def _eval(val, onts, mdb_safe): :param onts: Schemas to be used in the conversion :return: The basic dictionary """ - if isinstance(val, six.string_types): + if isinstance(val, str): val = val.strip() if not val: return None @@ -57,7 +56,7 @@ def to_dict(_dict, onts, mdb_safe=False): """ res = {} if isinstance(_dict, SamlBase): - res["__class__"] = "%s&%s" % (_dict.c_namespace, _dict.c_tag) + res["__class__"] = f"{_dict.c_namespace}&{_dict.c_tag}" for key in _dict.keyswv(): if key in IMP_SKIP: continue @@ -67,7 +66,7 @@ def to_dict(_dict, onts, mdb_safe=False): _val = [_eval(_v, onts, mdb_safe) for _v in _eel] elif key == "extension_attributes": if mdb_safe: - _val = dict([(k.replace(".", "__"), v) for k, v in val.items()]) + _val = {k.replace(".", "__"): v for k, v in val.items()} # _val = {k.replace(".", "__"): v for k, v in val.items()} else: _val = val @@ -86,7 +85,7 @@ def to_dict(_dict, onts, mdb_safe=False): for _val in [_eval(val, onts, mdb_safe)] if _val } - res["__class__"] = "%s&%s" % (_dict.namespace, _dict.tag) + res["__class__"] = f"{_dict.namespace}&{_dict.tag}" else: for key, val in _dict.items(): _val = _eval(val, onts, mdb_safe) @@ -110,11 +109,11 @@ def _kwa(val, onts, mdb_safe=False): :return: A converted dictionary """ if not mdb_safe: - return dict([(k, from_dict(v, onts)) for k, v in val.items() if k not in EXP_SKIP]) + return {k: from_dict(v, onts) for k, v in val.items() if k not in EXP_SKIP} else: _skip = ["_id"] _skip.extend(EXP_SKIP) - return dict([(k.replace("__", "."), from_dict(v, onts)) for k, v in val.items() if k not in _skip]) + return {k.replace("__", "."): from_dict(v, onts) for k, v in val.items() if k not in _skip} def from_dict(val, onts, mdb_safe=False): @@ -151,7 +150,7 @@ def from_dict(val, onts, mdb_safe=False): key = key.replace("__", ".") res[key] = from_dict(v, onts) return res - elif isinstance(val, six.string_types): + elif isinstance(val, str): return val elif isinstance(val, list): return [from_dict(v, onts) for v in val] diff --git a/src/saml2/mdstore.py b/src/saml2/mdstore.py index 3030f6a78..b2bae0a74 100644 --- a/src/saml2/mdstore.py +++ b/src/saml2/mdstore.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import hashlib from hashlib import sha1 import importlib @@ -14,7 +12,6 @@ from warnings import warn as _warn import requests -import six from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT @@ -69,21 +66,21 @@ logger = logging.getLogger(__name__) classnames = { - "mdattr_entityattributes": "{ns}&{tag}".format(ns=NS_MDATTR, tag=EntityAttributes.c_tag), - "algsupport_signing_method": "{ns}&{tag}".format(ns=NS_ALGSUPPORT, tag=SigningMethod.c_tag), - "algsupport_digest_method": "{ns}&{tag}".format(ns=NS_ALGSUPPORT, tag=DigestMethod.c_tag), - "mdui_uiinfo": "{ns}&{tag}".format(ns=NS_MDUI, tag=UIInfo.c_tag), - "mdui_uiinfo_display_name": "{ns}&{tag}".format(ns=NS_MDUI, tag=DisplayName.c_tag), - "mdui_uiinfo_description": "{ns}&{tag}".format(ns=NS_MDUI, tag=Description.c_tag), - "mdui_uiinfo_information_url": "{ns}&{tag}".format(ns=NS_MDUI, tag=InformationURL.c_tag), - "mdui_uiinfo_privacy_statement_url": "{ns}&{tag}".format(ns=NS_MDUI, tag=PrivacyStatementURL.c_tag), - "mdui_uiinfo_logo": "{ns}&{tag}".format(ns=NS_MDUI, tag=Logo.c_tag), - "service_artifact_resolution": "{ns}&{tag}".format(ns=NS_MD, tag=ArtifactResolutionService.c_tag), - "service_single_sign_on": "{ns}&{tag}".format(ns=NS_MD, tag=SingleSignOnService.c_tag), - "service_nameid_mapping": "{ns}&{tag}".format(ns=NS_MD, tag=NameIDMappingService.c_tag), - "mdrpi_registration_info": "{ns}&{tag}".format(ns=NS_MDRPI, tag=RegistrationInfo.c_tag), - "mdrpi_registration_policy": "{ns}&{tag}".format(ns=NS_MDRPI, tag=RegistrationPolicy.c_tag), - "shibmd_scope": "{ns}&{tag}".format(ns=NS_SHIBMD, tag=Scope.c_tag), + "mdattr_entityattributes": f"{NS_MDATTR}&{EntityAttributes.c_tag}", + "algsupport_signing_method": f"{NS_ALGSUPPORT}&{SigningMethod.c_tag}", + "algsupport_digest_method": f"{NS_ALGSUPPORT}&{DigestMethod.c_tag}", + "mdui_uiinfo": f"{NS_MDUI}&{UIInfo.c_tag}", + "mdui_uiinfo_display_name": f"{NS_MDUI}&{DisplayName.c_tag}", + "mdui_uiinfo_description": f"{NS_MDUI}&{Description.c_tag}", + "mdui_uiinfo_information_url": f"{NS_MDUI}&{InformationURL.c_tag}", + "mdui_uiinfo_privacy_statement_url": f"{NS_MDUI}&{PrivacyStatementURL.c_tag}", + "mdui_uiinfo_logo": f"{NS_MDUI}&{Logo.c_tag}", + "service_artifact_resolution": f"{NS_MD}&{ArtifactResolutionService.c_tag}", + "service_single_sign_on": f"{NS_MD}&{SingleSignOnService.c_tag}", + "service_nameid_mapping": f"{NS_MD}&{NameIDMappingService.c_tag}", + "mdrpi_registration_info": f"{NS_MDRPI}&{RegistrationInfo.c_tag}", + "mdrpi_registration_policy": f"{NS_MDRPI}&{RegistrationPolicy.c_tag}", + "shibmd_scope": f"{NS_SHIBMD}&{Scope.c_tag}", } ENTITY_CATEGORY = "http://macedir.org/entity-category" @@ -134,7 +131,7 @@ def load_extensions(): from saml2 import extension package = extension - prefix = package.__name__ + "." + prefix = f"{package.__name__}." ext_map = {} for importer, modname, ispkg in pkgutil.iter_modules(package.__path__, prefix): module = __import__(modname, fromlist="dummy") @@ -242,7 +239,7 @@ def repack_cert(cert): return "\n".join([s.strip() for s in part]) -class MetaData(object): +class MetaData: def __init__(self, attrc, metadata="", node_name=None, check_validity=True, security=None, **kwargs): self.attrc = attrc self.metadata = metadata @@ -380,7 +377,7 @@ def any2(self, typ, service, binding=None): for entid, item in self.items(): hit = False try: - descr = item["{}sso_descriptor".format(typ)] + descr = item[f"{typ}sso_descriptor"] except KeyError: continue else: @@ -429,14 +426,14 @@ def with_descriptor(self, descriptor): Returns any entities with the specified descriptor """ res = {} - desc = "%s_descriptor" % descriptor + desc = f"{descriptor}_descriptor" for eid, ent in self.items(): if desc in ent: res[eid] = ent return res def __str__(self): - return "%s" % self.items() + return f"{self.items()}" def construct_source_id(self): raise NotImplementedError @@ -493,13 +490,13 @@ def extract_certs(srvs): res = [] for descr in ["spsso", "idpsso", "role", "authn_authority", "attribute_authority", "pdp"]: try: - srvs = ent["%s_descriptor" % descr] + srvs = ent[f"{descr}_descriptor"] except KeyError: continue res.extend(extract_certs(srvs)) else: - srvs = ent["%s_descriptor" % descriptor] + srvs = ent[f"{descriptor}_descriptor"] res = extract_certs(srvs) return res @@ -507,7 +504,7 @@ def extract_certs(srvs): class InMemoryMetaData(MetaData): def __init__(self, attrc, metadata="", node_name=None, check_validity=True, security=None, **kwargs): - super(InMemoryMetaData, self).__init__(attrc, metadata=metadata) + super().__init__(attrc, metadata=metadata) self.entity = {} self.security = security self.node_name = node_name @@ -555,7 +552,7 @@ def do_entity_descriptor(self, entity_descr): # have I seen this entity_id before ? If so if log: ignore it if entity_descr.entity_id in self.entity: - print("Duplicated Entity descriptor (entity id: '%s')" % entity_descr.entity_id, file=sys.stderr) + print(f"Duplicated Entity descriptor (entity id: '{entity_descr.entity_id}')", file=sys.stderr) return _ent = to_dict(entity_descr, metadata_modules()) @@ -564,7 +561,7 @@ def do_entity_descriptor(self, entity_descr): for descr in ["spsso", "idpsso", "role", "authn_authority", "attribute_authority", "pdp", "affiliation"]: _res = [] try: - _items = _ent["%s_descriptor" % descr] + _items = _ent[f"{descr}_descriptor"] except KeyError: continue @@ -579,7 +576,7 @@ def do_entity_descriptor(self, entity_descr): _res.append(item) break if not _res: - del _ent["%s_descriptor" % descr] + del _ent[f"{descr}_descriptor"] else: flag += 1 @@ -696,7 +693,7 @@ def construct_source_id(self): try: for srv in ent[desc]: if "artifact_resolution_service" in srv: - if isinstance(eid, six.string_types): + if isinstance(eid, str): eid = eid.encode("utf-8") s = sha1(eid) res[s.digest()] = ent @@ -769,7 +766,7 @@ class MetaDataFile(InMemoryMetaData): """ def __init__(self, attrc, filename=None, cert=None, **kwargs): - super(MetaDataFile, self).__init__(attrc, **kwargs) + super().__init__(attrc, **kwargs) if not filename: raise SAMLError("No file specified.") self.filename = filename @@ -791,7 +788,7 @@ class MetaDataLoader(MetaDataFile): """ def __init__(self, attrc, loader_callable, cert=None, security=None, **kwargs): - super(MetaDataLoader, self).__init__(attrc, **kwargs) + super().__init__(attrc, **kwargs) self.metadata_provider_callable = self.get_metadata_loader(loader_callable) self.cert = cert self.security = security @@ -806,15 +803,15 @@ def get_metadata_loader(func): try: mod = importlib.import_module(module) except Exception as e: - raise RuntimeError('Cannot find metadata provider function %s: "%s"' % (func, e)) + raise RuntimeError(f'Cannot find metadata provider function {func}: "{e}"') try: metadata_loader = getattr(mod, attr) except AttributeError: - raise RuntimeError('Module "%s" does not define a "%s" metadata loader' % (module, attr)) + raise RuntimeError(f'Module "{module}" does not define a "{attr}" metadata loader') if not callable(metadata_loader): - raise RuntimeError("Metadata loader %s.%s must be callable" % (module, attr)) + raise RuntimeError(f"Metadata loader {module}.{attr} must be callable") return metadata_loader @@ -836,7 +833,7 @@ def __init__(self, attrc, url=None, security=None, cert=None, http=None, **kwarg :params cert: CertificMDloaderate used to sign the metadata :params http: """ - super(MetaDataExtern, self).__init__(attrc, **kwargs) + super().__init__(attrc, **kwargs) if not url: raise SAMLError("URL not specified.") else: @@ -869,7 +866,7 @@ class MetaDataMD(InMemoryMetaData): """ def __init__(self, attrc, filename, **kwargs): - super(MetaDataMD, self).__init__(attrc, **kwargs) + super().__init__(attrc, **kwargs) self.filename = filename def load(self, *args, **kwargs): @@ -889,7 +886,7 @@ class MetaDataMDX(InMemoryMetaData): @staticmethod def sha1_entity_transform(entity_id): entity_id_sha1 = hashlib.sha1(entity_id.encode("utf-8")).hexdigest() - transform = "{{sha1}}{digest}".format(digest=entity_id_sha1) + transform = f"{{sha1}}{entity_id_sha1}" return transform def __init__( @@ -915,7 +912,7 @@ def __init__( https://www.w3.org/TR/xmlschema-2/#duration :params http_client_timeout: timeout of http requests """ - super(MetaDataMDX, self).__init__(None, **kwargs) + super().__init__(None, **kwargs) if not url: raise SAMLError("URL for MDQ server not specified.") @@ -938,26 +935,26 @@ def __init__( # element but we will not currently support # that use case since it is unlikely to be leveraged for most # flows. - self.node_name = "{ns}:{tag}".format(ns=EntityDescriptor.c_namespace, tag=EntityDescriptor.c_tag) + self.node_name = f"{EntityDescriptor.c_namespace}:{EntityDescriptor.c_tag}" def load(self, *args, **kwargs): # Do nothing pass def _fetch_metadata(self, item): - mdx_url = "{url}/entities/{id}".format(url=self.url, id=self.entity_transform(item)) + mdx_url = f"{self.url}/entities/{self.entity_transform(item)}" response = requests.get( mdx_url, headers={"Accept": SAML_METADATA_CONTENT_TYPE}, timeout=self.http_client_timeout ) if response.status_code != 200: - error_msg = "Fething {item}: Got response status {status}".format(item=item, status=response.status_code) + error_msg = f"Fething {item}: Got response status {response.status_code}" logger.warning(error_msg) raise KeyError(error_msg) _txt = response.content if not self.parse_and_check_signature(_txt): - error_msg = "Fething {item}: invalid signature".format(item=item) + error_msg = f"Fething {item}: invalid signature" logger.error(error_msg) raise KeyError(error_msg) @@ -972,7 +969,7 @@ def __getitem__(self, item): if item not in self.entity: entity = self._fetch_metadata(item) elif not self._is_metadata_fresh(item): - msg = "Metadata for {} have expired; refreshing metadata".format(item) + msg = f"Metadata for {item} have expired; refreshing metadata" logger.info(msg) _ = self.entity.pop(item) entity = self._fetch_metadata(item) @@ -1085,7 +1082,7 @@ def load(self, *args, **kwargs): url = args[1] _md = MetaDataMDX(url, http_client_timeout=self.http_client_timeout) else: - raise SAMLError("Unknown metadata type '%s'" % typ) + raise SAMLError(f"Unknown metadata type '{typ}'") _md.load() self.metadata[key] = _md @@ -1118,13 +1115,13 @@ def imp(self, spec): try: key = item["class"] except (KeyError, AttributeError): - raise SAMLError("Misconfiguration in metadata %s" % item) + raise SAMLError(f"Misconfiguration in metadata {item}") mod, clas = key.rsplit(".", 1) try: mod = importlib.import_module(mod) MDloader = getattr(mod, clas) except (ImportError, AttributeError): - raise SAMLError("Unknown metadata loader %s" % key) + raise SAMLError(f"Unknown metadata loader {key}") # Separately handle MDExtern if MDloader == MetaDataExtern: @@ -1246,25 +1243,25 @@ def assertion_id_request_service(self, entity_id, binding=None, typ=None): raise AttributeError("Missing type specification") if binding is None: binding = BINDING_SOAP - return self.service(entity_id, "%s_descriptor" % typ, "assertion_id_request_service", binding) + return self.service(entity_id, f"{typ}_descriptor", "assertion_id_request_service", binding) def single_logout_service(self, entity_id, binding=None, typ=None): # IDP + SP if typ is None: raise AttributeError("Missing type specification") - return self.service(entity_id, "%s_descriptor" % typ, "single_logout_service", binding) + return self.service(entity_id, f"{typ}_descriptor", "single_logout_service", binding) def manage_name_id_service(self, entity_id, binding=None, typ=None): # IDP + SP if binding is None: binding = BINDING_HTTP_REDIRECT - return self.service(entity_id, "%s_descriptor" % typ, "manage_name_id_service", binding) + return self.service(entity_id, f"{typ}_descriptor", "manage_name_id_service", binding) def artifact_resolution_service(self, entity_id, binding=None, typ=None): # IDP + SP if binding is None: binding = BINDING_HTTP_REDIRECT - return self.service(entity_id, "%s_descriptor" % typ, "artifact_resolution_service", binding) + return self.service(entity_id, f"{typ}_descriptor", "artifact_resolution_service", binding) def assertion_consumer_service(self, entity_id, binding=None, _="spsso"): # SP @@ -1282,7 +1279,10 @@ def discovery_response(self, entity_id, binding=None, _="spsso"): if binding is None: binding = BINDING_DISCO return self.ext_service( - entity_id, "spsso_descriptor", "%s&%s" % (DiscoveryResponse.c_namespace, DiscoveryResponse.c_tag), binding + entity_id, + "spsso_descriptor", + f"{DiscoveryResponse.c_namespace}&{DiscoveryResponse.c_tag}", + binding, ) def attribute_requirement(self, entity_id, index=None): @@ -1646,7 +1646,7 @@ def bindings(self, entity_id, typ, service): def __str__(self): _str = ["{"] for key, val in self.metadata.items(): - _str.append("%s: %s" % (key, val)) + _str.append(f"{key}: {val}") _str.append("}") return "\n".join(_str) @@ -1699,7 +1699,7 @@ def dumps(self, format="local"): except AttributeError: res.entity_descriptor.append(_md.entity_descr) - return "%s" % res + return f"{res}" elif format == "md": # self.items() returns dictitems(), convert that back into a dict return json.dumps(dict(self.items()), indent=2) diff --git a/src/saml2/metadata.py b/src/saml2/metadata.py index f8aa2c9cb..47823406b 100644 --- a/src/saml2/metadata.py +++ b/src/saml2/metadata.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -import six from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT @@ -153,7 +152,7 @@ def do_organization_info(ava): for dkey, (ckey, klass) in ORG_ATTR_TRANSL.items(): if ckey not in ava: continue - if isinstance(ava[ckey], six.string_types): + if isinstance(ava[ckey], str): setattr(org, dkey, [_localized_name(ava[ckey], klass)]) elif isinstance(ava[ckey], list): setattr(org, dkey, [_localized_name(n, klass) for n in ava[ckey]]) @@ -210,7 +209,7 @@ def do_requested_attribute(attributes, acs, is_required="false", name_format=NAM for attr in attributes: attr = from_local_name(acs, attr, name_format) args = {} - if isinstance(attr, six.string_types): + if isinstance(attr, str): args["name"] = attr else: for key in attr.keyswv(): @@ -231,7 +230,7 @@ def do_uiinfo(_uiinfo): aclass = uii.child_class(attr) inst = getattr(uii, attr) - if isinstance(val, six.string_types): + if isinstance(val, str): ainst = aclass(text=val) inst.append(ainst) elif isinstance(val, dict): @@ -241,7 +240,7 @@ def do_uiinfo(_uiinfo): inst.append(ainst) else: for value in val: - if isinstance(value, six.string_types): + if isinstance(value, str): ainst = aclass(text=value) inst.append(ainst) elif isinstance(value, dict): @@ -277,11 +276,11 @@ def do_uiinfo(_uiinfo): _attr = "keywords" val = _uiinfo[_attr] inst = getattr(uii, _attr) - # list of six.string_types, dictionary or list of dictionaries + # list of strings, bytes, dictionary or list of dictionaries if isinstance(val, list): for value in val: keyw = mdui.Keywords() - if isinstance(value, six.string_types): + if isinstance(value, str): keyw.text = value elif isinstance(value, dict): keyw.text = " ".join(value["text"]) @@ -352,7 +351,7 @@ def do_idpdisc(discovery_response): def do_extensions(mname, item): try: - _mod = __import__("saml2.extension.%s" % mname, globals(), locals(), mname) + _mod = __import__(f"saml2.extension.{mname}", globals(), locals(), mname) except ImportError: return None else: @@ -369,7 +368,7 @@ def _do_nameid_format(cls, conf, typ): if not name_id_format: return - if isinstance(name_id_format, six.string_types): + if isinstance(name_id_format, str): name_id_format = [name_id_format] formats = [md.NameIDFormat(text=format) for format in name_id_format] @@ -384,7 +383,7 @@ def do_endpoints(conf, endpoints): servs = [] i = 1 for args in conf[endpoint]: - if isinstance(args, six.string_types): # Assume it's the location + if isinstance(args, str): # Assume it's the location args = {"location": args, "binding": DEFAULT_BINDING[endpoint]} elif isinstance(args, tuple) or isinstance(args, list): if len(args) == 2: # (location, binding) @@ -394,7 +393,7 @@ def do_endpoints(conf, endpoints): if indexed: if "index" not in args: - args["index"] = "%d" % i + args["index"] = f"{int(i)}" i += 1 else: try: @@ -520,7 +519,7 @@ def do_spsso_descriptor(conf, cert=None, enc_cert=None): if val is None: setattr(spsso, key, DEFAULT[key]) # default ?! else: - strval = "{0:>s}".format(str(val)) + strval = f"{str(val):>s}" setattr(spsso, key, strval.lower()) except KeyError: setattr(spsso, key, DEFAULTS[key]) @@ -568,7 +567,7 @@ def do_idpsso_descriptor(conf, cert=None, enc_cert=None): if val is None: setattr(idpsso, key, DEFAULT[key]) else: - setattr(idpsso, key, ("%s" % val).lower()) + setattr(idpsso, key, (f"{val}").lower()) except KeyError: setattr(idpsso, key, DEFAULTS[key]) @@ -765,14 +764,14 @@ def entities_descriptor(eds, valid_for, name, ident, sign, secc, sign_alg=None, ident = sid() if not secc.key_file: - raise SAMLError("If you want to do signing you should define " + "a key to sign with") + raise SAMLError(f"If you want to do signing you should define a key to sign with") if not secc.my_cert: - raise SAMLError("If you want to do signing you should define " + "where your public key are") + raise SAMLError(f"If you want to do signing you should define where your public key are") entities.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg) entities.id = ident - xmldoc = secc.sign_statement("%s" % entities, class_name(entities)) + xmldoc = secc.sign_statement(f"{entities}", class_name(entities)) entities = md.entities_descriptor_from_string(xmldoc) else: xmldoc = None @@ -794,6 +793,6 @@ def sign_entity_descriptor(edesc, ident, secc, sign_alg=None, digest_alg=None): edesc.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg) edesc.id = ident - xmldoc = secc.sign_statement("%s" % edesc, class_name(edesc)) + xmldoc = secc.sign_statement(f"{edesc}", class_name(edesc)) edesc = md.entity_descriptor_from_string(xmldoc) return edesc, xmldoc diff --git a/src/saml2/mongo_store.py b/src/saml2/mongo_store.py index cfadd1c32..f2fc0a6e9 100644 --- a/src/saml2/mongo_store.py +++ b/src/saml2/mongo_store.py @@ -6,7 +6,6 @@ import pymongo.errors from pymongo.mongo_replica_set_client import MongoReplicaSetClient import pymongo.uri_parser -import six from saml2.eptid import Eptid from saml2.ident import IdentDB @@ -38,7 +37,7 @@ def context_match(cfilter, cntx): return True -class SessionStorageMDB(object): +class SessionStorageMDB: """Session information is stored in a MongoDB database""" def __init__(self, database="", collection="assertion", **kwargs): @@ -193,7 +192,7 @@ def handle_name_id_mapping_request(self, name_id, name_id_policy): return self.construct_nameid(_id, name_id_policy=name_id_policy) -class MDB(object): +class MDB: primary_key = "mdb" def __init__(self, database, collection, **kwargs): @@ -280,7 +279,6 @@ def _mdb_get_database(uri, **kwargs): # assume URI to be just the database name db_name = uri _conn = MongoClient() - pass else: if "replicaset" in _parsed_uri["options"]: connection_factory = MongoReplicaSetClient @@ -322,14 +320,14 @@ def protect(dic): res = {} for key, val in dic.items(): key = key.replace(".", "__") - if isinstance(val, six.string_types): + if isinstance(val, str): pass elif isinstance(val, dict): val = protect(val) elif isinstance(val, list): li = [] for va in val: - if isinstance(va, six.string_types): + if isinstance(va, str): pass elif isinstance(va, dict): va = protect(va) @@ -347,14 +345,14 @@ def unprotect(dic): pass else: key = key.replace("__", ".") - if isinstance(val, six.string_types): + if isinstance(val, str): pass elif isinstance(val, dict): val = unprotect(val) elif isinstance(val, list): li = [] for va in val: - if isinstance(va, six.string_types): + if isinstance(va, str): pass elif isinstance(val, dict): va = unprotect(va) @@ -377,7 +375,7 @@ def export_mdstore_to_mongo_db(mds, database, collection, sub_collection=""): class MetadataMDB(InMemoryMetaData): def __init__(self, attrc, database="", collection=""): - super(MetadataMDB, self).__init__(attrc) + super().__init__(attrc) self.mdb = MDB(database, collection) self.mdb.primary_key = "entity_id" @@ -424,7 +422,7 @@ def __getitem__(self, item): elif len(res) == 1: return unprotect(res[0]["entity_description"]) else: - raise CorruptDatabase("More then one document with key %s" % item) + raise CorruptDatabase(f"More then one document with key {item}") def bindings(self, entity_id, typ, service): pass diff --git a/src/saml2/pack.py b/src/saml2/pack.py index c065d2d3d..0e6923df2 100644 --- a/src/saml2/pack.py +++ b/src/saml2/pack.py @@ -16,10 +16,11 @@ import cgi as html import logging +from urllib.parse import urlencode +from urllib.parse import urlparse +from xml.etree import ElementTree as ElementTree -import six -from six.moves.urllib.parse import urlencode -from six.moves.urllib.parse import urlparse +import defusedxml.ElementTree import saml2 from saml2.s_utils import deflate_and_base64_encode @@ -28,23 +29,6 @@ from saml2.xmldsig import SIG_ALLOWED_ALG -try: - from xml.etree import cElementTree as ElementTree - - if ElementTree.VERSION < "1.3.0": - # cElementTree has no support for register_namespace - # neither _namespace_map, thus we sacrify performance - # for correctness - from xml.etree import ElementTree -except ImportError: - try: - import cElementTree as ElementTree - except ImportError: - from elementtree import ElementTree - -import defusedxml.ElementTree - - logger = logging.getLogger(__name__) NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/" @@ -89,9 +73,9 @@ def http_form_post_message(message, location, relay_state="", typ="SAMLRequest", :param relay_state: for preserving and conveying state information :return: A tuple containing header information and a HTML message. """ - if not isinstance(message, six.string_types): + if not isinstance(message, str): message = str(message) - if not isinstance(message, six.binary_type): + if not isinstance(message, bytes): message = message.encode("utf-8") if typ == "SAMLRequest" or typ == "SAMLResponse": @@ -122,9 +106,9 @@ def http_post_message(message, relay_state="", typ="SAMLRequest", **kwargs): :param relay_state: for preserving and conveying state information :return: A tuple containing header information and a HTML message. """ - if not isinstance(message, six.string_types): + if not isinstance(message, str): message = str(message) - if not isinstance(message, six.binary_type): + if not isinstance(message, bytes): message = message.encode("utf-8") if typ == "SAMLRequest" or typ == "SAMLResponse": @@ -166,8 +150,8 @@ def http_redirect_message( :return: A tuple containing header information and a HTML message. """ - if not isinstance(message, six.string_types): - message = "%s" % (message,) + if not isinstance(message, str): + message = f"{message}" _order = None if typ in ["SAMLRequest", "SAMLResponse"]: @@ -179,7 +163,7 @@ def http_redirect_message( elif typ == "SAMLart": args = {typ: message} else: - raise Exception("Unknown message type: %s" % typ) + raise Exception(f"Unknown message type: {typ}") if relay_state: args["RelayState"] = relay_state @@ -187,10 +171,10 @@ def http_redirect_message( if sign: # sigalgs, should be one defined in xmldsig if sigalg not in [long_name for short_name, long_name in SIG_ALLOWED_ALG]: - raise Exception("Signature algo not in allowed list: {algo}".format(algo=sigalg)) + raise Exception(f"Signature algo not in allowed list: {sigalg}") signer = backend.get_signer(sigalg) if sign and sigalg else None if not signer: - raise Exception("Could not init signer fro algo {algo}".format(algo=sigalg)) + raise Exception(f"Could not init signer fro algo {sigalg}") args["SigAlg"] = sigalg string = "&".join(urlencode({k: args[k]}) for k in _order if k in args) @@ -232,7 +216,7 @@ def make_soap_enveloped_saml_thingy(thingy, header_parts=None): body.tag = "{%s}Body" % NAMESPACE envelope.append(body) - if isinstance(thingy, six.string_types): + if isinstance(thingy, str): # remove the first XML version/encoding line if thingy[0:5].lower() == "", first + 14) cut2 = _str[first : last + 1] return _str.replace(cut2, thingy) @@ -287,9 +271,7 @@ def parse_soap_enveloped_saml(text, body_class, header_class=None): envelope_tag = "{%s}Envelope" % NAMESPACE if envelope.tag != envelope_tag: - raise ValueError( - "Invalid envelope tag '{invalid}' should be '{valid}'".format(invalid=envelope.tag, valid=envelope_tag) - ) + raise ValueError(f"Invalid envelope tag '{envelope.tag}' should be '{envelope_tag}'") # print(len(envelope)) body = None @@ -301,7 +283,7 @@ def parse_soap_enveloped_saml(text, body_class, header_class=None): try: body = saml2.create_class_from_element_tree(body_class, sub) except Exception: - raise Exception("Wrong body type (%s) in SOAP envelope" % sub.tag) + raise Exception(f"Wrong body type ({sub.tag}) in SOAP envelope") elif part.tag == "{%s}Header" % NAMESPACE: if not header_class: raise Exception("Header where I didn't expect one") @@ -310,7 +292,7 @@ def parse_soap_enveloped_saml(text, body_class, header_class=None): # print(">>",sub.tag) for klass in header_class: # print("?{%s}%s" % (klass.c_namespace,klass.c_tag)) - if sub.tag == "{%s}%s" % (klass.c_namespace, klass.c_tag): + if sub.tag == f"{{{klass.c_namespace}}}{klass.c_tag}": header[sub.tag] = saml2.create_class_from_element_tree(klass, sub) break @@ -329,7 +311,7 @@ def packager(identifier): try: return PACKING[identifier] except KeyError: - raise Exception("Unknown binding type: %s" % identifier) + raise Exception(f"Unknown binding type: {identifier}") def factory(binding, message, location, relay_state="", typ="SAMLRequest", **kwargs): diff --git a/src/saml2/population.py b/src/saml2/population.py index 72baa830a..ff3928b45 100644 --- a/src/saml2/population.py +++ b/src/saml2/population.py @@ -1,17 +1,15 @@ import logging -import six - from saml2.cache import Cache logger = logging.getLogger(__name__) -class Population(object): +class Population: def __init__(self, cache=None): if cache: - if isinstance(cache, six.string_types): + if isinstance(cache, str): self.cache = Cache(cache) else: self.cache = cache diff --git a/src/saml2/request.py b/src/saml2/request.py index 1d62d0edd..e013e058c 100644 --- a/src/saml2/request.py +++ b/src/saml2/request.py @@ -18,7 +18,7 @@ def _dummy(data, **_arg): return "" -class Request(object): +class Request: def __init__(self, sec_context, receiver_addrs, attribute_converters=None, timeslack=0): self.sec = sec_context self.receiver_addrs = receiver_addrs @@ -126,9 +126,7 @@ def issue_instant_ok(self): def _verify(self): valid_version = "2.0" if self.message.version != valid_version: - raise VersionMismatch( - "Invalid version {invalid} should be {valid}".format(invalid=self.message.version, valid=valid_version) - ) + raise VersionMismatch(f"Invalid version {self.message.version} should be {valid_version}") if self.message.destination and self.receiver_addrs and self.message.destination not in self.receiver_addrs: logger.error("%s not in %s", self.message.destination, self.receiver_addrs) @@ -256,15 +254,12 @@ def __init__(self, sec_context, receiver_addrs, attribute_converters=None, times def action(self): """Which action authorization is requested for""" - pass def evidence(self): """The evidence on which the decision is based""" - pass def resource(self): """On which resource the action is expected to occur""" - pass class NameIDMappingRequest(Request): diff --git a/src/saml2/response.py b/src/saml2/response.py index 403bb72b4..2bc147dbb 100644 --- a/src/saml2/response.py +++ b/src/saml2/response.py @@ -1,11 +1,8 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # import calendar import logging -import six - from saml2 import SAMLError from saml2 import class_name from saml2 import extension_elements_to_elements @@ -220,7 +217,7 @@ def for_me(conditions, myself): if audience.text and audience.text.strip() == myself: return True else: - logger.debug("AudienceRestriction - One condition not satisfied: %s != %s" % (audience.text, myself)) + logger.debug(f"AudienceRestriction - One condition not satisfied: {audience.text} != {myself}") logger.debug("AudienceRestrictions not satisfied!") return False @@ -277,7 +274,7 @@ def attribute_response(conf, return_addrs, timeslack=0, asynchop=False, test=Fal ) -class StatusResponse(object): +class StatusResponse: msgtype = "status_response" def __init__(self, sec_context, return_addrs=None, timeslack=0, request_id=0, asynchop=True, conv_info=None): @@ -334,7 +331,7 @@ def load_instance(self, instance): self.response = self.sec.check_signature(instance) except SignatureError: # The response as a whole might be signed or not - self.response = self.sec.check_signature(instance, samlp.NAMESPACE + ":Response") + self.response = self.sec.check_signature(instance, f"{samlp.NAMESPACE}:Response") else: self.not_signed = True self.response = instance @@ -344,7 +341,7 @@ def load_instance(self, instance): def _loads(self, xmldata, decode=True, origxml=None): # own copy - if isinstance(xmldata, six.binary_type): + if isinstance(xmldata, bytes): self.xmlstr = xmldata[:].decode("utf-8") else: self.xmlstr = xmldata[:] @@ -365,7 +362,7 @@ def _loads(self, xmldata, decode=True, origxml=None): origdoc=origxml, must=self.require_signature, require_response_signature=self.require_response_signature, - **args + **args, ) except TypeError: @@ -389,7 +386,7 @@ def status_ok(self): err_msg = status.status_message.text if status.status_message else err_code or "Unknown error" err_cls = STATUSCODE2EXCEPTION.get(err_code, StatusError) - msg = "Unsuccessful operation: {status}\n{msg} from {code}".format(status=status, msg=err_msg, code=err_code) + msg = f"Unsuccessful operation: {status}\n{err_msg} from {err_code}" logger.debug(msg) raise err_cls(msg) @@ -493,7 +490,7 @@ def __init__( want_assertions_or_response_signed=False, want_response_signed=False, conv_info=None, - **kwargs + **kwargs, ): StatusResponse.__init__(self, sec_context, return_addrs, timeslack, asynchop=asynchop, conv_info=conv_info) @@ -538,14 +535,14 @@ def loads(self, xmldata, decode=True, origxml=None): # del self.outstanding_queries[self.in_response_to] try: if not self.check_subject_confirmation_in_response_to(self.in_response_to): - raise UnsolicitedResponse("Unsolicited response: %s" % self.in_response_to) + raise UnsolicitedResponse(f"Unsolicited response: {self.in_response_to}") except AttributeError: pass elif self.allow_unsolicited: # Should check that I haven't seen this before pass else: - raise UnsolicitedResponse("Unsolicited response: %s" % self.in_response_to) + raise UnsolicitedResponse(f"Unsolicited response: {self.in_response_to}") return self @@ -561,7 +558,7 @@ def authn_statement_ok(self, optional=False): if optional: return True else: - msg = "Invalid number of AuthnStatement found in Response: {n}".format(n=n_authn_statements) + msg = f"Invalid number of AuthnStatement found in Response: {n_authn_statements}" raise ValueError(msg) authn_statement = self.assertion.authn_statement[0] @@ -612,7 +609,7 @@ def condition_ok(self, lax=False): if not for_me(conditions, self.entity_id): if not lax: - raise Exception("AudienceRestrictions conditions not satisfied! (Local entity_id=%s)" % self.entity_id) + raise Exception(f"AudienceRestrictions conditions not satisfied! (Local entity_id={self.entity_id})") if conditions.condition: # extra conditions for cond in conditions.condition: @@ -675,7 +672,7 @@ def get_identity(self): if _assertion.attribute_statement: logger.debug("Assertion contains %s attribute statement(s)", (len(self.assertion.attribute_statement))) for _attr_statem in _assertion.attribute_statement: - logger.debug("Attribute Statement: %s" % (_attr_statem,)) + logger.debug(f"Attribute Statement: {_attr_statem}") ava.update(self.read_attribute_statement(_attr_statem)) if not ava: logger.debug("Assertion contains no attribute statements") @@ -732,7 +729,7 @@ def get_subject(self, keys=None): raise ValueError("Missing assertion") if not self.assertion.subject: - raise ValueError("Invalid assertion subject: {subject}".format(subject=self.assertion.subject)) + raise ValueError(f"Invalid assertion subject: {self.assertion.subject}") subject = self.assertion.subject subjconf = [] @@ -751,7 +748,7 @@ def get_subject(self, keys=None): elif subject_confirmation.method == SCM_SENDER_VOUCHES: pass else: - raise ValueError("Unknown subject confirmation method: %s" % (subject_confirmation.method,)) + raise ValueError(f"Unknown subject confirmation method: {subject_confirmation.method}") _recip = _data.recipient if not _recip or not self.verify_recipient(_recip): @@ -914,9 +911,7 @@ def parse_assertion(self, keys=None): n_assertions = len(self.response.assertion) n_assertions_enc = len(self.response.encrypted_assertion) if n_assertions != 1 and n_assertions_enc != 1 and self.assertion is None: - raise InvalidAssertion( - "Invalid number of assertions in Response: {n}".format(n=n_assertions + n_assertions_enc) - ) + raise InvalidAssertion(f"Invalid number of assertions in Response: {n_assertions + n_assertions_enc}") if self.response.assertion: logger.debug("***Unencrypted assertion***") @@ -941,7 +936,7 @@ def parse_assertion(self, keys=None): resp = samlp.response_from_string(decr_text) # check and prepare for comparison between str and unicode if type(decr_text_old) != type(decr_text): - if isinstance(decr_text_old, six.binary_type): + if isinstance(decr_text_old, bytes): decr_text_old = decr_text_old.decode("utf-8") else: decr_text_old = decr_text_old.encode("utf-8") @@ -962,7 +957,7 @@ def parse_assertion(self, keys=None): _enc_assertions = self.decrypt_assertions(resp.encrypted_assertion, decr_text, verified=True) # check and prepare for comparison between str and unicode if type(decr_text_old) != type(decr_text): - if isinstance(decr_text_old, six.binary_type): + if isinstance(decr_text_old, bytes): decr_text_old = decr_text_old.decode("utf-8") else: decr_text_old = decr_text_old.encode("utf-8") @@ -1005,7 +1000,7 @@ def parse_assertion(self, keys=None): if self.context == "AuthnReq" or self.context == "AttrQuery": self.ava = self.get_identity() - logger.debug("--- AVA: %s" % self.ava) + logger.debug(f"--- AVA: {self.ava}") return True @@ -1350,7 +1345,7 @@ def response_factory( # A class of it's own -class AssertionIDResponse(object): +class AssertionIDResponse: msgtype = "assertion_id_response" def __init__(self, sec_context, attribute_converters, timeslack=0, **kwargs): diff --git a/src/saml2/s2repoze/__init__.py b/src/saml2/s2repoze/__init__.py index 766c3cb1b..1b3570aba 100644 --- a/src/saml2/s2repoze/__init__.py +++ b/src/saml2/s2repoze/__init__.py @@ -1,2 +1 @@ -# -*- coding: utf-8 -*- # Created by Roland Hedberg diff --git a/src/saml2/s2repoze/plugins/__init__.py b/src/saml2/s2repoze/plugins/__init__.py index 40a96afc6..e69de29bb 100644 --- a/src/saml2/s2repoze/plugins/__init__.py +++ b/src/saml2/s2repoze/plugins/__init__.py @@ -1 +0,0 @@ -# -*- coding: utf-8 -*- diff --git a/src/saml2/s2repoze/plugins/entitlement.py b/src/saml2/s2repoze/plugins/entitlement.py index bd5fae519..81bc0cc5f 100644 --- a/src/saml2/s2repoze/plugins/entitlement.py +++ b/src/saml2/s2repoze/plugins/entitlement.py @@ -6,7 +6,7 @@ from zope.interface import implements -class EntitlementMetadataProvider(object): +class EntitlementMetadataProvider: implements(IMetadataProvider) @@ -63,13 +63,13 @@ def add_metadata(self, environ, identity): vorg = environ["myapp.vo"] try: ents = user["entitlement"][vorg] - identity["user"] = {"entitlement": ["%s:%s" % (vorg, e) for e in ents]} + identity["user"] = {"entitlement": [f"{vorg}:{e}" for e in ents]} except KeyError: pass except KeyError: res = [] for vorg, ents in user["entitlement"].items(): - res.extend(["%s:%s" % (vorg, e) for e in ents]) + res.extend([f"{vorg}:{e}" for e in ents]) identity["user"] = res diff --git a/src/saml2/s2repoze/plugins/formswithhidden.py b/src/saml2/s2repoze/plugins/formswithhidden.py index 02e2ad95d..8c120f076 100644 --- a/src/saml2/s2repoze/plugins/formswithhidden.py +++ b/src/saml2/s2repoze/plugins/formswithhidden.py @@ -1,3 +1,5 @@ +from urllib.parse import urlencode + from paste.httpexceptions import HTTPFound from paste.httpheaders import CONTENT_LENGTH from paste.httpheaders import CONTENT_TYPE @@ -8,7 +10,6 @@ from repoze.who.interfaces import IChallenger from repoze.who.interfaces import IIdentifier from repoze.who.plugins.form import FormPlugin -from six.moves.urllib.parse import urlencode from zope.interface import implements @@ -91,7 +92,7 @@ def challenge(self, environ, status, app_headers, forget_headers): query = parse_dict_querystring(environ) hidden = [] for key, val in query.items(): - hidden.append(HIDDEN_PRE_LINE % ("_%s_" % key, val)) + hidden.append(HIDDEN_PRE_LINE % (f"_{key}_", val)) logger.info("hidden: %s", hidden) form = self.formbody or _DEFAULT_FORM @@ -114,7 +115,7 @@ def make_plugin(login_form_qs="__do_login", rememberer_name=None, form=None): if rememberer_name is None: raise ValueError("must include rememberer key (name of another IIdentifier plugin)") if form is not None: - with open(form, "r") as f: + with open(form) as f: form = f.read() plugin = FormHiddenPlugin(login_form_qs, rememberer_name, form) return plugin diff --git a/src/saml2/s2repoze/plugins/ini.py b/src/saml2/s2repoze/plugins/ini.py index 74dcc111c..ef36c6f47 100644 --- a/src/saml2/s2repoze/plugins/ini.py +++ b/src/saml2/s2repoze/plugins/ini.py @@ -5,7 +5,7 @@ from zope.interface import implements -class INIMetadataProvider(object): +class INIMetadataProvider: implements(IMetadataProvider) diff --git a/src/saml2/s2repoze/plugins/sp.py b/src/saml2/s2repoze/plugins/sp.py index ea3cd3881..7079d96fe 100644 --- a/src/saml2/s2repoze/plugins/sp.py +++ b/src/saml2/s2repoze/plugins/sp.py @@ -5,11 +5,13 @@ WSGI application. """ +from io import StringIO import logging import platform import shelve import sys import traceback +from urllib import parse from paste.httpexceptions import HTTPInternalServerError from paste.httpexceptions import HTTPNotImplemented @@ -21,9 +23,6 @@ from repoze.who.interfaces import IChallenger from repoze.who.interfaces import IIdentifier from repoze.who.interfaces import IMetadataProvider -import six -from six import StringIO -from six.moves.urllib import parse from zope.interface import implementer from saml2 import BINDING_HTTP_POST @@ -50,7 +49,7 @@ logger = logging.getLogger(__name__) -PAOS_HEADER_INFO = 'ver="%s";"%s"' % (paos.NAMESPACE, ECP_SERVICE) +PAOS_HEADER_INFO = f'ver="{paos.NAMESPACE}";"{ECP_SERVICE}"' def construct_came_from(environ): @@ -60,17 +59,17 @@ def construct_came_from(environ): came_from = environ.get("PATH_INFO") qstr = environ.get("QUERY_STRING", "") if qstr: - came_from += "?" + qstr + came_from += f"?{qstr}" return came_from def exception_trace(tag, exc, log): message = traceback.format_exception(*sys.exc_info()) - log.error("[%s] ExcList: %s" % (tag, "".join(message))) - log.error("[%s] Exception: %s" % (tag, exc)) + log.error(f"[{tag}] ExcList: {''.join(message)}") + log.error(f"[{tag}] Exception: {exc}") -class ECP_response(object): +class ECP_response: code = 200 title = "OK" @@ -79,12 +78,12 @@ def __init__(self, content): # noinspection PyUnusedLocal def __call__(self, environ, start_response): - start_response("%s %s" % (self.code, self.title), [("Content-Type", "text/xml")]) + start_response(f"{self.code} {self.title}", [("Content-Type", "text/xml")]) return [self.content] @implementer(IChallenger, IIdentifier, IAuthenticator, IMetadataProvider) -class SAML2Plugin(object): +class SAML2Plugin: def __init__( self, rememberer_name, @@ -163,7 +162,7 @@ def _wayf_redirect(self, came_from): sid_ = sid() self.outstanding_queries[sid_] = came_from logger.info("Redirect to WAYF function: %s", self.wayf) - return -1, HTTPSeeOther(headers=[("Location", "%s?%s" % (self.wayf, sid_))]) + return -1, HTTPSeeOther(headers=[("Location", f"{self.wayf}?{sid_}")]) # noinspection PyUnusedLocal def _pick_idp(self, environ, came_from): @@ -219,7 +218,6 @@ def _pick_idp(self, environ, came_from): break except KeyError: logger.debug("No IdP entity ID in query: %s", query) - pass if idp_entity_id is None: if len(idps) == 1: @@ -249,7 +247,7 @@ def _pick_idp(self, environ, came_from): logger.debug("Redirect to Discovery Service function") eid = _cli.config.entityid ret = _cli.config.getattr("endpoints", "sp")["discovery_response"][0][0] - ret += "?sid=%s" % sid_ + ret += f"?sid={sid_}" loc = _cli.create_discovery_service_request(self.discosrv, eid, **{"return": ret}) return -1, SeeOther(loc) @@ -345,7 +343,7 @@ def challenge(self, environ, _status, _app_headers, _forget_headers): sign=False, extensions=extensions, ) - msg_str = "%s" % req + msg_str = f"{req}" _sid = req_id if cert is not None: @@ -361,8 +359,8 @@ def challenge(self, environ, _status, _app_headers, _forget_headers): logger.debug("ht_args: %s", ht_args) except Exception as exc: - logger.exception("Failed to construct the AuthnRequest: %s" % str(exc)) - raise Exception("Failed to construct the AuthnRequest: %s" % exc) + logger.exception(f"Failed to construct the AuthnRequest: {str(exc)}") + raise Exception(f"Failed to construct the AuthnRequest: {exc}") try: path_info = environ.get("PATH_INFO") @@ -409,12 +407,12 @@ def _eval_authn_response(self, environ, post, binding=BINDING_HTTP_POST): ) except Exception as excp: - logger.exception("Exception: %s" % (excp,)) + logger.exception(f"Exception: {excp}") raise session_info = authresp.session_info() except TypeError as excp: - logger.exception("Exception: %s" % (excp,)) + logger.exception(f"Exception: {excp}") return None if session_info["came_from"]: @@ -553,7 +551,7 @@ def identify(self, environ): def add_metadata(self, environ, identity): """Add information to the knowledge I have about the user""" name_id = identity["repoze.who.userid"] - if isinstance(name_id, six.string_types): + if isinstance(name_id, str): try: # Make sure that userids authenticated by another plugin # don't cause problems here. diff --git a/src/saml2/s_utils.py b/src/saml2/s_utils.py index 6e2fd9c2f..2e8b44063 100644 --- a/src/saml2/s_utils.py +++ b/src/saml2/s_utils.py @@ -10,8 +10,6 @@ import traceback import zlib -import six - from saml2 import VERSION from saml2 import saml from saml2 import samlp @@ -160,7 +158,7 @@ def deflate_and_base64_encode(string_val): :param string_val: The string to deflate and encode :return: The deflated and encoded string """ - if not isinstance(string_val, six.binary_type): + if not isinstance(string_val, bytes): string_val = string_val.encode("utf-8") return base64.b64encode(zlib.compress(string_val)[2:-4]) @@ -183,7 +181,7 @@ def rndbytes(size=16, alphabet=""): Returns rndstr always as a binary type """ x = rndstr(size, alphabet) - if isinstance(x, six.string_types): + if isinstance(x, str): return x.encode("utf-8") return x @@ -196,7 +194,7 @@ def sid(): :return: A random string prefix with 'id-' to make it compliant with the NCName specification """ - return "id-" + rndstr(17) + return f"id-{rndstr(17)}" def parse_attribute_map(filenames): @@ -307,7 +305,7 @@ def _attrval(val, typ=""): def do_ava(val, typ=""): - if isinstance(val, six.string_types): + if isinstance(val, str): ava = saml.AttributeValue() ava.set_text(val) attrval = [ava] @@ -320,7 +318,7 @@ def do_ava(val, typ=""): elif val is None: attrval = None else: - raise OtherError("strange value type on: %s" % val) + raise OtherError(f"strange value type on: {val}") if typ: for ava in attrval: @@ -335,7 +333,7 @@ def do_attribute(val, typ, key): if attrval: attr.attribute_value = attrval - if isinstance(key, six.string_types): + if isinstance(key, str): attr.name = key elif isinstance(key, tuple): # 3-tuple or 2-tuple try: @@ -391,11 +389,11 @@ def factory(klass, **kwargs): def signature(secret, parts): """Generates a signature. All strings are assumed to be utf-8""" - if not isinstance(secret, six.binary_type): + if not isinstance(secret, bytes): secret = secret.encode("utf-8") newparts = [] for part in parts: - if not isinstance(part, six.binary_type): + if not isinstance(part, bytes): part = part.encode("utf-8") newparts.append(part) parts = newparts @@ -419,9 +417,9 @@ def exception_trace(exc): message = traceback.format_exception(*sys.exc_info()) try: - _exc = "Exception: %s" % exc + _exc = f"Exception: {exc}" except UnicodeEncodeError: - _exc = "Exception: %s" % exc.message.encode("utf-8", "replace") + _exc = f"Exception: {exc.message.encode('utf-8', 'replace')}" return {"message": _exc, "content": "".join(message)} diff --git a/src/saml2/saml.py b/src/saml2/saml.py index d8ac648b0..1c01dc16c 100644 --- a/src/saml2/saml.py +++ b/src/saml2/saml.py @@ -18,8 +18,6 @@ from datetime import date from datetime import datetime -import six - import saml2 from saml2 import SamlBase from saml2 import xmldsig as ds @@ -230,8 +228,7 @@ def _wrong_type_value(xsd, value): msg = msg.format(xsd=xsd, type=type(value), value=value) raise ValueError(msg) - # only work with six.string_types - if isinstance(value, six.binary_type): + if isinstance(value, bytes): value = value.decode("utf-8") type_to_xsd = { @@ -344,7 +341,7 @@ def _wrong_type_value(xsd, value): _wrong_type_value(xsd=xsd_type, value=value) text = to_text(value) - self.set_type("{ns}:{type}".format(ns=xsd_ns, type=xsd_type) if xsd_ns else xsd_type if xsd_type else "") + self.set_type(f"{xsd_ns}:{xsd_type}" if xsd_ns else xsd_type if xsd_type else "") SamlBase.__setattr__(self, "text", text) return self diff --git a/src/saml2/sdb.py b/src/saml2/sdb.py index 4349b3101..df9613a42 100644 --- a/src/saml2/sdb.py +++ b/src/saml2/sdb.py @@ -15,7 +15,7 @@ def context_match(cfilter, cntx): # The key to the stored authn statement is placed encrypted in the cookie -class SessionStorage(object): +class SessionStorage: """In memory storage of session information""" def __init__(self): diff --git a/src/saml2/server.py b/src/saml2/server.py index 2b1cbf66a..8b5572001 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """Contains classes and functions that a SAML2.0 Identity provider (IdP) @@ -11,8 +10,6 @@ import shelve import threading -import six - from saml2 import BINDING_HTTP_REDIRECT from saml2 import class_name from saml2 import element_to_extension_element @@ -110,7 +107,7 @@ def choose_session_storage(self): _spec = self.config.getattr("session_storage", "idp") if not _spec: return SessionStorage() - elif isinstance(_spec, six.string_types): + elif isinstance(_spec, str): if _spec.lower() == "memory": return SessionStorage() else: # Should be tuple @@ -137,7 +134,7 @@ def init_config(self, stype="idp"): typ = "" if not dbspec: idb = {} - elif isinstance(dbspec, six.string_types): + elif isinstance(dbspec, str): idb = _shelve_compat(dbspec, writeback=True, protocol=2) else: # database spec is a a 2-tuple (type, address) # print(>> sys.stderr, "DBSPEC: %s" % (dbspec,)) @@ -164,7 +161,7 @@ def init_config(self, stype="idp"): elif idb is not None: self.ident = IdentDB(idb) elif dbspec: - raise Exception("Couldn't open identity database: %s" % (dbspec,)) + raise Exception(f"Couldn't open identity database: {dbspec}") try: _domain = self.config.getattr("domain", "idp") @@ -404,7 +401,7 @@ def setup_assertion( if authn: # expected to be a dictionary # Would like to use dict comprehension but ... - authn_args = dict([(AUTHN_DICT_MAP[k], v) for k, v in authn.items() if k in AUTHN_DICT_MAP]) + authn_args = {AUTHN_DICT_MAP[k]: v for k, v in authn.items() if k in AUTHN_DICT_MAP} authn_args.update(kwargs) assertion = ast.construct( @@ -848,7 +845,7 @@ def create_authn_response( pefim=pefim, **kwargs, ) - except IOError as exc: + except OSError as exc: response = self.create_error_response( in_response_to, destination=destination, diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py index b8004ce42..01a12a71d 100644 --- a/src/saml2/sigver.py +++ b/src/saml2/sigver.py @@ -17,7 +17,6 @@ from uuid import uuid4 as gen_random_key import dateutil -import six # importlib.resources was introduced in python 3.7 @@ -27,9 +26,10 @@ else: from importlib_resources import files as _resource_files +from urllib import parse + from OpenSSL import crypto import pytz -from six.moves.urllib import parse from saml2 import ExtensionElement from saml2 import SamlBase @@ -70,7 +70,7 @@ logger = logging.getLogger(__name__) -SIG = "{{{ns}#}}{attribute}".format(ns=ds.NAMESPACE, attribute="Signature") +SIG = f"{{{ds.NAMESPACE}#}}Signature" # RSA_1_5 is considered deprecated RSA_1_5 = "http://www.w3.org/2001/04/xmlenc#rsa-1_5" @@ -109,8 +109,6 @@ class SignatureError(XmlsecError): class BadSignature(SigverError): """The signature is invalid.""" - pass - def get_pem_wrapped_unwrapped(cert): begin_cert = "-----BEGIN CERTIFICATE-----\n" @@ -204,7 +202,7 @@ def get_xmlsec_binary(paths=None): except OSError: pass - raise SigverError("Cannot find {binary}".format(binary=bin_name)) + raise SigverError(f"Cannot find {bin_name}") def _get_xmlsec_cryptobackend(path=None, search_paths=None, delete_tmpfiles=True): @@ -326,7 +324,7 @@ def signed_instance_factory(instance, seccont, elements_to_sign=None): return instance signed_xml = instance - if not isinstance(instance, six.string_types): + if not isinstance(instance, str): signed_xml = instance.to_string() for (node_name, nodeid) in elements_to_sign: @@ -353,7 +351,7 @@ def make_temp(content, suffix="", decode=True, delete_tmpfiles=True): close the file) and filename (which is for instance needed by the xmlsec function). """ - content_encoded = content.encode("utf-8") if not isinstance(content, six.binary_type) else content + content_encoded = content.encode("utf-8") if not isinstance(content, bytes) else content content_raw = base64.b64decode(content_encoded) if decode else content_encoded ntf = NamedTemporaryFile(suffix=suffix, delete=delete_tmpfiles) ntf.write(content_raw) @@ -492,7 +490,7 @@ def sha1_digest(msg): return hashlib.sha1(msg).digest() -class Signer(object): +class Signer: """Abstract base class for signing algorithms.""" def __init__(self, key): @@ -540,7 +538,7 @@ def verify(self, msg, sig, key=None): ] -class RSACrypto(object): +class RSACrypto: def __init__(self, key): self.key = key @@ -570,7 +568,7 @@ def verify_redirect_signature(saml_msg, crypto, cert=None, sigkey=None): try: signer = crypto.get_signer(saml_msg["SigAlg"], sigkey) except KeyError: - raise Unsupported("Signature algorithm: {alg}".format(alg=saml_msg["SigAlg"])) + raise Unsupported(f"Signature algorithm: {saml_msg['SigAlg']}") else: if saml_msg["SigAlg"] in SIGNER_ALGS: if "SAMLRequest" in saml_msg: @@ -594,7 +592,7 @@ def verify_redirect_signature(saml_msg, crypto, cert=None, sigkey=None): return bool(signer.verify(string, _sign, _key)) -class CryptoBackend(object): +class CryptoBackend: def version(self): raise NotImplementedError() @@ -614,9 +612,7 @@ def validate_signature(self, enctext, cert_file, cert_type, node_name, node_id): raise NotImplementedError() -ASSERT_XPATH = "".join( - ["/*[local-name()='{name}']".format(name=n) for n in ["Response", "EncryptedAssertion", "Assertion"]] -) +ASSERT_XPATH = "".join([f"/*[local-name()='{n}']" for n in ["Response", "EncryptedAssertion", "Assertion"]]) class CryptoBackendXmlSec1(CryptoBackend): @@ -629,7 +625,7 @@ class CryptoBackendXmlSec1(CryptoBackend): def __init__(self, xmlsec_binary, delete_tmpfiles=True, **kwargs): CryptoBackend.__init__(self, **kwargs) - if not isinstance(xmlsec_binary, six.string_types): + if not isinstance(xmlsec_binary, str): raise ValueError("xmlsec_binary should be of type string") self.xmlsec = xmlsec_binary self.delete_tmpfiles = delete_tmpfiles @@ -678,7 +674,7 @@ def encrypt(self, text, recv_key, template, session_key_type, xpath=""): try: (_stdout, _stderr, output) = self._run_xmlsec(com_list, [template]) except XmlsecError as e: - six.raise_from(EncryptError(com_list), e) + raise EncryptError(com_list) from e return output @@ -721,7 +717,7 @@ def encrypt_assertion(self, statement, enc_key, template, key_type="des-192", no try: (_stdout, _stderr, output) = self._run_xmlsec(com_list, [tmp2.name]) except XmlsecError as e: - six.raise_from(EncryptError(com_list), e) + raise EncryptError(com_list) from e return output.decode("utf-8") @@ -748,7 +744,7 @@ def decrypt(self, enctext, key_file): try: (_stdout, _stderr, output) = self._run_xmlsec(com_list, [tmp.name]) except XmlsecError as e: - six.raise_from(DecryptError(com_list), e) + raise DecryptError(com_list) from e return output.decode("utf-8") @@ -802,7 +798,7 @@ def validate_signature(self, signedtext, cert_file, cert_type, node_name, node_i :param node_id: The identifier of the node :return: Boolean True if the signature was correct otherwise False. """ - if not isinstance(signedtext, six.binary_type): + if not isinstance(signedtext, bytes): signedtext = signedtext.encode("utf-8") tmp = make_temp(signedtext, suffix=".xml", decode=False, delete_tmpfiles=self.delete_tmpfiles) @@ -814,7 +810,7 @@ def validate_signature(self, signedtext, cert_file, cert_type, node_name, node_i "empty,same-doc", "--enabled-key-data", "raw-x509-cert", - "--pubkey-cert-{type}".format(type=cert_type), + f"--pubkey-cert-{cert_type}", cert_file, "--id-attr:ID", node_name, @@ -826,7 +822,7 @@ def validate_signature(self, signedtext, cert_file, cert_type, node_name, node_i try: (_stdout, stderr, _output) = self._run_xmlsec(com_list, [tmp.name]) except XmlsecError as e: - six.raise_from(SignatureError(com_list), e) + raise SignatureError(com_list) from e return parse_xmlsec_output(stderr) @@ -850,9 +846,7 @@ def _run_xmlsec(self, com_list, extra_args): p_err = p_err.decode() if pof.returncode != 0: - errmsg = "returncode={code}\nerror={err}\noutput={out}".format( - code=pof.returncode, err=p_err, out=p_out - ) + errmsg = f"returncode={pof.returncode}\nerror={p_err}\noutput={p_out}" logger.error(errmsg) raise XmlsecError(errmsg) @@ -900,7 +894,7 @@ def sign_statement(self, statement, node_name, key_file, node_id): xml = xmlsec.parse_xml(statement) signed = xmlsec.sign(xml, key_file) signed_str = lxml.etree.tostring(signed, xml_declaration=False, encoding="UTF-8") - if not isinstance(signed_str, six.string_types): + if not isinstance(signed_str, str): signed_str = signed_str.decode("utf-8") return signed_str @@ -970,7 +964,7 @@ def security_context(conf): try: rsa_key = import_rsa_key_from_file(_file_name) except Exception as err: - logger.error("Cannot import key from {file}: {err_msg}".format(file=_file_name, err_msg=err)) + logger.error(f"Cannot import key from {_file_name}: {err}") raise else: sec_backend = RSACrypto(rsa_key) @@ -1029,7 +1023,7 @@ def encrypt_cert_from_item(item): return _encrypt_cert -class CertHandlerExtra(object): +class CertHandlerExtra: def __init__(self): pass @@ -1048,7 +1042,7 @@ def validate_cert(self, cert_str, root_cert_string, root_key_string): # Excepts to return True/False -class CertHandler(object): +class CertHandler: def __init__( self, security_context, @@ -1164,7 +1158,7 @@ def update_cert(self, active=False, client_crt=None): # How to get a rsa pub key fingerprint from a certificate # openssl x509 -inform pem -noout -in server.crt -pubkey > publickey.pem # openssl rsa -inform pem -noout -in publickey.pem -pubin -modulus -class SecurityContext(object): +class SecurityContext: my_cert = None def __init__( @@ -1292,7 +1286,7 @@ def decrypt_keys(self, enctext, keys=None): keys = [keys] keys_filtered = (key for key in keys if key) - keys_encoded = (key.encode("ascii") if not isinstance(key, six.binary_type) else key for key in keys_filtered) + keys_encoded = (key.encode("ascii") if not isinstance(key, bytes) else key for key in keys_filtered) key_files = list(make_temp(key, decode=False, delete_tmpfiles=self.delete_tmpfiles) for key in keys_encoded) key_file_names = list(tmp.name for tmp in key_files) @@ -1369,7 +1363,7 @@ def _check_signature( certs = [] for cert_name, cert in _certs: - if isinstance(cert, six.string_types): + if isinstance(cert, str): content = pem_format(cert) tmp = make_temp(content, suffix=".pem", decode=False, delete_tmpfiles=self.delete_tmpfiles) certs.append(tmp) @@ -1422,9 +1416,9 @@ def _check_signature( and references[0].uri.startswith("#") and len(references[0].uri) > 1 ) - the_anchor_points_to_the_enclosing_element_ID_attribute = the_URI_attribute_contains_an_anchor and references[ - 0 - ].uri == "#{id}".format(id=item.id) + the_anchor_points_to_the_enclosing_element_ID_attribute = ( + the_URI_attribute_contains_an_anchor and references[0].uri == f"#{item.id}" + ) # SAML implementations SHOULD use Exclusive Canonicalization, # with or without comments @@ -1498,7 +1492,6 @@ def _check_signature( break except XmlsecError as exc: logger.error("check_sig: %s", str(exc)) - pass except Exception as exc: logger.error("check_sig: %s", str(exc)) raise @@ -1541,13 +1534,13 @@ def correctly_signed_message(self, decoded_xml, msgtype, must=False, origdoc=Non :return: """ - attr = "{type}_from_string".format(type=msgtype) + attr = f"{msgtype}_from_string" _func = getattr(saml, attr, None) _func = getattr(samlp, attr, _func) msg = _func(decoded_xml) if not msg: - raise TypeError("Not a {type}".format(type=msgtype)) + raise TypeError(f"Not a {msgtype}") if not msg.signature: if must: @@ -1778,7 +1771,7 @@ def pre_signature_part( digest_method = ds.DigestMethod(algorithm=digest_alg) reference = ds.Reference( - uri="#{id}".format(id=ident), digest_value=ds.DigestValue(), transforms=transforms, digest_method=digest_method + uri=f"#{ident}", digest_value=ds.DigestValue(), transforms=transforms, digest_method=digest_method ) signed_info = ds.SignedInfo( @@ -1788,7 +1781,7 @@ def pre_signature_part( signature = ds.Signature(signed_info=signed_info, signature_value=ds.SignatureValue()) if identifier: - signature.id = "Signature{n}".format(n=identifier) + signature.id = f"Signature{identifier}" # XXX remove - do not embed the cert if public_key: @@ -1836,8 +1829,8 @@ def pre_encryption_part( encrypted_data_id=None, encrypt_cert=None, ): - ek_id = encrypted_key_id or "EK_{id}".format(id=gen_random_key()) - ed_id = encrypted_data_id or "ED_{id}".format(id=gen_random_key()) + ek_id = encrypted_key_id or f"EK_{gen_random_key()}" + ed_id = encrypted_data_id or f"ED_{gen_random_key()}" msg_encryption_method = EncryptionMethod(algorithm=msg_enc) key_encryption_method = EncryptionMethod(algorithm=key_enc) diff --git a/src/saml2/soap.py b/src/saml2/soap.py index dc2e75e50..b8015a6a5 100644 --- a/src/saml2/soap.py +++ b/src/saml2/soap.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """ @@ -7,24 +6,15 @@ """ import logging import re +from xml.etree import ElementTree as ElementTree + +import defusedxml.ElementTree from saml2 import create_class_from_element_tree from saml2.samlp import NAMESPACE as SAMLP_NAMESPACE from saml2.schema import soapenv -try: - from xml.etree import cElementTree as ElementTree -except ImportError: - try: - import cElementTree as ElementTree - except ImportError: - # noinspection PyUnresolvedReferences - from elementtree import ElementTree - -import defusedxml.ElementTree - - logger = logging.getLogger(__name__) @@ -138,9 +128,7 @@ def parse_soap_enveloped_saml_thingy(text, expected_tags): envelope_tag = "{%s}Envelope" % soapenv.NAMESPACE if envelope.tag != envelope_tag: - raise ValueError( - "Invalid envelope tag '{invalid}' should be '{valid}'".format(invalid=envelope.tag, valid=envelope_tag) - ) + raise ValueError(f"Invalid envelope tag '{envelope.tag}' should be '{envelope_tag}'") if len(envelope) < 1: raise Exception("No items in envelope.") @@ -150,7 +138,7 @@ def parse_soap_enveloped_saml_thingy(text, expected_tags): if part.tag == "{%s}Body" % soapenv.NAMESPACE: n_children = len(part) if n_children != 1: - raise Exception("Expected a single child element, found {n}".format(n=n_children)) + raise Exception(f"Expected a single child element, found {n_children}") body = part break @@ -161,7 +149,7 @@ def parse_soap_enveloped_saml_thingy(text, expected_tags): if saml_part.tag in expected_tags: return ElementTree.tostring(saml_part, encoding="UTF-8") else: - raise WrongMessageType("Was '%s' expected one of %s" % (saml_part.tag, expected_tags)) + raise WrongMessageType(f"Was '{saml_part.tag}' expected one of {expected_tags}") NS_AND_TAG = re.compile(r"\{([^}]+)\}(.*)") @@ -177,7 +165,7 @@ def instanciate_class(item, modules): return create_class_from_element_tree(target, item) except KeyError: continue - raise Exception("Unknown class: ns='%s', tag='%s'" % (ns, tag)) + raise Exception(f"Unknown class: ns='{ns}', tag='{tag}'") def class_instances_from_soap_enveloped_saml_thingies(text, modules): @@ -191,13 +179,11 @@ def class_instances_from_soap_enveloped_saml_thingies(text, modules): try: envelope = defusedxml.ElementTree.fromstring(text) except Exception as exc: - raise XmlParseError("%s" % exc) + raise XmlParseError(f"{exc}") envelope_tag = "{%s}Envelope" % soapenv.NAMESPACE if envelope.tag != envelope_tag: - raise ValueError( - "Invalid envelope tag '{invalid}' should be '{valid}'".format(invalid=envelope.tag, valid=envelope_tag) - ) + raise ValueError(f"Invalid envelope tag '{envelope.tag}' should be '{envelope_tag}'") if len(envelope) < 1: raise Exception("No items in envelope.") @@ -225,13 +211,11 @@ def open_soap_envelope(text): try: envelope = defusedxml.ElementTree.fromstring(text) except Exception as exc: - raise XmlParseError("%s" % exc) + raise XmlParseError(f"{exc}") envelope_tag = "{%s}Envelope" % soapenv.NAMESPACE if envelope.tag != envelope_tag: - raise ValueError( - "Invalid envelope tag '{invalid}' should be '{valid}'".format(invalid=envelope.tag, valid=envelope_tag) - ) + raise ValueError(f"Invalid envelope tag '{envelope.tag}' should be '{envelope_tag}'") if len(envelope) < 1: raise Exception("No items in envelope.") @@ -268,7 +252,7 @@ def make_soap_enveloped_saml_thingy(thingy, headers=None): soap_envelope.body = soapenv.Body() soap_envelope.body.add_extension_element(thingy) - return "%s" % soap_envelope + return f"{soap_envelope}" def soap_fault(message=None, actor=None, code=None, detail=None): @@ -298,4 +282,4 @@ def soap_fault(message=None, actor=None, code=None, detail=None): detail=_detail, ) - return "%s" % fault + return f"{fault}" diff --git a/src/saml2/time_util.py b/src/saml2/time_util.py index c85fdf73a..c3e5b1393 100644 --- a/src/saml2/time_util.py +++ b/src/saml2/time_util.py @@ -1,11 +1,9 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """ Implements some usefull functions when dealing with validity of different types of information. """ -from __future__ import print_function import calendar from datetime import datetime @@ -14,8 +12,6 @@ import sys import time -import six - TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" TIME_FORMAT_WITH_FRAGMENT = re.compile(r"^(\d{4,4}-\d{2,2}-\d{2,2}T\d{2,2}:\d{2,2}:\d{2,2})(\.\d*)?Z?$") @@ -71,7 +67,7 @@ def parse_duration(duration): raise ValueError("Parse Duration is not valid.") index += 1 - dic = dict([(typ, 0) for (code, typ) in D_FORMAT if typ]) + dic = {typ: 0 for (code, typ) in D_FORMAT if typ} dlen = len(duration) for code, typ in D_FORMAT: @@ -239,9 +235,9 @@ def str_to_time(timestr, format=TIME_FORMAT): try: elem = TIME_FORMAT_WITH_FRAGMENT.match(timestr) except Exception as exc: - print("Exception: %s on %s" % (exc, timestr), file=sys.stderr) + print(f"Exception: {exc} on {timestr}", file=sys.stderr) raise - then = time.strptime(elem.groups()[0] + "Z", TIME_FORMAT) + then = time.strptime(f"{elem.groups()[0]}Z", TIME_FORMAT) return time.gmtime(calendar.timegm(then)) @@ -272,7 +268,7 @@ def before(point): if not point: return True - if isinstance(point, six.string_types): + if isinstance(point, str): point = str_to_time(point) elif isinstance(point, int): point = time.gmtime(point) @@ -304,12 +300,12 @@ def utc_time_sans_frac(): def later_than(after, before): """True if then is later or equal to that""" - if isinstance(after, six.string_types): + if isinstance(after, str): after = str_to_time(after) elif isinstance(after, int): after = time.gmtime(after) - if isinstance(before, six.string_types): + if isinstance(before, str): before = str_to_time(before) elif isinstance(before, int): before = time.gmtime(before) diff --git a/src/saml2/tools/parse_xsd2.py b/src/saml2/tools/parse_xsd2.py index db775548b..49aa84faa 100644 --- a/src/saml2/tools/parse_xsd2.py +++ b/src/saml2/tools/parse_xsd2.py @@ -8,12 +8,10 @@ import time import types -import six - __version__ = 0.5 -from xml.etree import cElementTree as ElementTree +from xml.etree import ElementTree as ElementTree INDENT = 4 * " " @@ -56,7 +54,7 @@ def class_pyify(ref): def def_init(imports, attributes): indent = INDENT + INDENT indent3 = INDENT + INDENT + INDENT - line = ["%sdef __init__(self," % INDENT] + line = [f"{INDENT}def __init__(self,"] for elem in attributes: if elem[0] in PROTECTED_KEYWORDS: @@ -65,9 +63,9 @@ def def_init(imports, attributes): _name = elem[0] if elem[2]: - line.append("%s%s='%s'," % (indent3, _name, elem[2])) + line.append(f"{indent3}{_name}='{elem[2]}',") else: - line.append("%s%s=%s," % (indent3, _name, elem[2])) + line.append(f"{indent3}{_name}={elem[2]},") for _, elems in imports.items(): for elem in elems: @@ -75,12 +73,12 @@ def def_init(imports, attributes): _name = elem + "_" else: _name = elem - line.append("%s%s=None," % (indent3, _name)) + line.append(f"{indent3}{_name}=None,") - line.append("%stext=None," % indent3) - line.append("%sextension_elements=None," % indent3) - line.append("%sextension_attributes=None," % indent3) - line.append("%s):" % indent) + line.append(f"{indent3}text=None,") + line.append(f"{indent3}extension_elements=None,") + line.append(f"{indent3}extension_attributes=None,") + line.append(f"{indent}):") return line @@ -88,18 +86,18 @@ def base_init(imports): line = [] indent4 = INDENT + INDENT + INDENT + INDENT if not imports: - line.append("%sSamlBase.__init__(self, " % (INDENT + INDENT)) + line.append(f"{INDENT + INDENT}SamlBase.__init__(self, ") for attr in BASE_ELEMENT: if attr in PROTECTED_KEYWORDS: _name = attr + "_" else: _name = attr - line.append("%s%s=%s," % (indent4, _name, _name)) - line.append("%s)" % indent4) + line.append(f"{indent4}{_name}={_name},") + line.append(f"{indent4})") else: # TODO have to keep apart which properties come from which superior for sup, elems in imports.items(): - line.append("%s%s.__init__(self, " % (INDENT + INDENT, sup)) + line.append(f"{INDENT + INDENT}{sup}.__init__(self, ") lattr = elems[:] lattr.extend(BASE_ELEMENT) for attr in lattr: @@ -107,8 +105,8 @@ def base_init(imports): _name = attr + "_" else: _name = attr - line.append("%s%s=%s," % (indent4, _name, _name)) - line.append("%s)" % indent4) + line.append(f"{indent4}{_name}={_name},") + line.append(f"{indent4})") return line @@ -126,7 +124,7 @@ def initialize(attributes): else: _vname = val - line.append("%sself.%s=%s" % (indent, _name, _vname)) + line.append(f"{indent}self.{_name}={_vname}") return line @@ -211,7 +209,7 @@ def klass_namn(obj): return obj.name -class PyObj(object): +class PyObj: def __init__(self, name=None, pyname=None, root=None): self.name = name self.done = False @@ -235,15 +233,15 @@ def __init__(self, name=None, pyname=None, root=None): def child_spec(self, target_namespace, prop, mod, typ, lista): if mod: namesp = external_namespace(self.root.modul[mod]) - pkey = "{%s}%s" % (namesp, prop.name) - typ = "%s.%s" % (mod, typ) + pkey = f"{{{namesp}}}{prop.name}" + typ = f"{mod}.{typ}" else: - pkey = "{%s}%s" % (target_namespace, prop.name) + pkey = f"{{{target_namespace}}}{prop.name}" if lista: - return "c_children['%s'] = ('%s', [%s])" % (pkey, prop.pyname, typ) + return f"c_children['{pkey}'] = ('{prop.pyname}', [{typ}])" else: - return "c_children['%s'] = ('%s', %s)" % (pkey, prop.pyname, typ) + return f"c_children['{pkey}'] = ('{prop.pyname}', {typ})" def knamn(self, sup, cdict): cname = cdict[sup].class_name @@ -251,7 +249,7 @@ def knamn(self, sup, cdict): (namesp, tag) = cdict[sup].name.split(".") if namesp: ctag = self.root.modul[namesp].factory(tag).__class__.__name__ - cname = "%s.%s" % (namesp, ctag) + cname = f"{namesp}.{ctag}" else: cname = tag + "_" return cname @@ -267,7 +265,7 @@ def _do_properties(self, line, cdict, ignore, target_namespace): for prop in own: if isinstance(prop, PyAttribute): - line.append("%sc_attributes['%s'] = %s" % (INDENT, prop.name, prop.spec())) + line.append(f"{INDENT}c_attributes['{prop.name}'] = {prop.spec()}") if prop.fixed: args.append((prop.pyname, prop.fixed, None)) else: @@ -290,20 +288,20 @@ def _do_properties(self, line, cdict, ignore, target_namespace): if prop.name in ignore: pass else: - line.append("%s%s" % (INDENT, self.child_spec(target_namespace, prop, mod, cname, lista))) + line.append(f"{INDENT}{self.child_spec(target_namespace, prop, mod, cname, lista)}") pmin = int(getattr(prop, "min", 1)) if pmax == 1 and pmin == 1: pass elif prop.max == "unbounded": - line.append("%sc_cardinality['%s'] = {\"min\":%s}" % (INDENT, prop.pyname, pmin)) + line.append(f"{INDENT}c_cardinality['{prop.pyname}'] = {{\"min\":{pmin}}}") else: line.append('%sc_cardinality[\'%s\'] = {"min":%s, "max":%d}' % (INDENT, prop.pyname, pmin, pmax)) child.append(prop.pyname) if lista: - args.append((prop.pyname, "%s or []" % (prop.pyname,), None)) + args.append((prop.pyname, f"{prop.pyname} or []", None)) else: args.append((prop.pyname, prop.pyname, None)) @@ -341,38 +339,38 @@ def class_definition(self, target_namespace, cdict=None, ignore=None): c_name = klass_namn(self) if not superior: - line.append("class %s(SamlBase):" % (c_name,)) + line.append(f"class {c_name}(SamlBase):") else: - line.append("class %s(%s):" % (c_name, ",".join(sups))) + line.append(f"class {c_name}({','.join(sups)}):") if hasattr(self, "scoped"): pass else: - line.append('%s"""The %s:%s element """' % (INDENT, target_namespace, self.name)) + line.append(f'{INDENT}"""The {target_namespace}:{self.name} element """') line.append("") - line.append("%sc_tag = '%s'" % (INDENT, self.name)) - line.append("%sc_namespace = NAMESPACE" % (INDENT,)) + line.append(f"{INDENT}c_tag = '{self.name}'") + line.append(f"{INDENT}c_namespace = NAMESPACE") try: if self.value_type: - if isinstance(self.value_type, six.string_types): - line.append("%sc_value_type = '%s'" % (INDENT, self.value_type)) + if isinstance(self.value_type, str): + line.append(f"{INDENT}c_value_type = '{self.value_type}'") else: - line.append("%sc_value_type = %s" % (INDENT, self.value_type)) + line.append(f"{INDENT}c_value_type = {self.value_type}") except AttributeError: pass if not superior: for var, cps in CLASS_PROP: - line.append("%s%s = SamlBase.%s%s" % (INDENT, var, var, cps)) + line.append(f"{INDENT}{var} = SamlBase.{var}{cps}") else: for sup in sups: for var, cps in CLASS_PROP: - line.append("%s%s = %s.%s%s" % (INDENT, var, sup, var, cps)) + line.append(f"{INDENT}{var} = {sup}.{var}{cps}") (args, child, inh) = self._do_properties(line, cdict, ignore, target_namespace) if child: - line.append("%sc_child_order.extend([%s])" % (INDENT, "'" + "', '".join(child) + "'")) + line.append("{}c_child_order.extend([{}])".format(INDENT, "'" + "', '".join(child) + "'")) if args: if inh: @@ -385,8 +383,8 @@ def class_definition(self, target_namespace, cdict=None, ignore=None): line.append("") if not self.abstract or not self.class_name.endswith("_"): - line.append("def %s_from_string(xml_string):" % pyify(self.class_name)) - line.append("%sreturn saml2.create_class_from_xml_string(%s, xml_string)" % (INDENT, self.class_name)) + line.append(f"def {pyify(self.class_name)}_from_string(xml_string):") + line.append(f"{INDENT}return saml2.create_class_from_xml_string({self.class_name}, xml_string)") line.append("") self.done = True @@ -436,7 +434,7 @@ class PyElement(PyObj): def __init__(self, name=None, pyname=None, root=None, parent=""): PyObj.__init__(self, name, pyname, root) if parent: - self.class_name = "%s_%s" % (leading_uppercase(parent), self.name) + self.class_name = f"{leading_uppercase(parent)}_{self.name}" else: self.class_name = leading_uppercase(self.name) self.ref = None @@ -499,7 +497,7 @@ def _local_class(self, typ, cdict, child, target_namespace, ignore): def _external_class(self, mod, typ, cdict, child, target_namespace, ignore): # Will raise exception if class can't be found cname = self.root.modul[mod].factory(typ).__class__.__name__ - imp_name = "%s.%s" % (mod, cname) + imp_name = f"{mod}.{cname}" if imp_name not in cdict: # create import object so I can get the properties from it @@ -554,7 +552,7 @@ def text(self, target_namespace, cdict, child=True, ignore=None): if verify_import(self.root.modul[mod], typ): return req, text else: - raise Exception("Import attempted on %s from %s module failed - wasn't there" % (typ, mod)) + raise Exception(f"Import attempted on {typ} from {mod} module failed - wasn't there") elif not child: self.superior = [typ] text = self.class_definition(target_namespace, cdict, ignore=ignore) @@ -580,7 +578,7 @@ def _do(obj, target_namespace, cdict, prep): else: obj.done = True if req: - if isinstance(req, six.string_types): + if isinstance(req, str): prep.append(req) else: prep.extend(req) @@ -716,12 +714,12 @@ def text(self, _target_namespace, cdict, _child=True): def spec(self): if isinstance(self.type, PyObj): - return "('%s', %s, %s)" % (self.pyname, self.type.class_name, self.required) + return f"('{self.pyname}', {self.type.class_name}, {self.required})" else: if self.type: - return "('%s', '%s', %s)" % (self.pyname, self.type, self.required) + return f"('{self.pyname}', '{self.type}', {self.required})" else: - return "('%s', '%s', %s)" % (self.pyname, self.base, self.required) + return f"('{self.pyname}', '{self.base}', {self.required})" class PyAny(PyObj): @@ -730,14 +728,14 @@ def __init__(self, name=None, pyname=None, _external=False, _namespace=""): self.done = True -class PyAttributeGroup(object): +class PyAttributeGroup: def __init__(self, name, root): self.name = name self.root = root self.properties = [] -class PyGroup(object): +class PyGroup: def __init__(self, name, root): self.name = name self.root = root @@ -802,12 +800,12 @@ def _spec(elem): name = elem.name except AttributeError: name = "anonymous" - txt = "%s" % name + txt = f"{name}" try: - txt += " ref: %s" % elem.ref + txt += f" ref: {elem.ref}" except AttributeError: try: - txt += " type: %s" % elem.type + txt += f" type: {elem.type}" except AttributeError: pass @@ -827,8 +825,8 @@ def _spec(elem): def _do_from_string(name): print - print("def %s_from_string(xml_string):" % pyify(name)) - print("%sreturn saml2.create_class_from_xml_string(%s, xml_string)" % (INDENT, name)) + print(f"def {pyify(name)}_from_string(xml_string):") + print(f"{INDENT}return saml2.create_class_from_xml_string({name}, xml_string)") def _namespace_and_tag(obj, param, top): @@ -847,7 +845,7 @@ def _namespace_and_tag(obj, param, top): # ----------------------------------------------------------------------------- -class Simple(object): +class Simple: def __init__(self, elem): self.default = None self.fixed = None @@ -905,10 +903,10 @@ def repr(self, top=None, sup=None, _argv=None, _child=True, _parent=""): name = tag else: external = True - name = "{%s}%s" % (self.xmlns_map[namespace], tag) + name = f"{{{self.xmlns_map[namespace]}}}{tag}" else: if namespace == "xml": - name = "{%s}%s" % (XML_NAMESPACE, tag) + name = f"{{{XML_NAMESPACE}}}{tag}" except AttributeError: name = self.name pyname = pyify(name) @@ -919,7 +917,7 @@ def repr(self, top=None, sup=None, _argv=None, _child=True, _parent=""): name = self.ref pyname = pyify(name) else: # referering to what - raise Exception("Strange reference: %s" % self.ref) + raise Exception(f"Strange reference: {self.ref}") objekt = PyAttribute(name, pyname, external=external, root=top) @@ -965,7 +963,7 @@ def repr(self, top=None, sup=None, _argv=None, _child=True, _parent=""): pass if DEBUG: - print("#--ATTR py_attr:%s" % (objekt,)) + print(f"#--ATTR py_attr:{objekt}") return objekt @@ -1036,7 +1034,7 @@ def name_or_ref(elem, top): return elem.name -class Complex(object): +class Complex: def __init__(self, elem): self.value_of = "" self.parts = [] @@ -1087,7 +1085,7 @@ def collect(self, top, sup, argv=None, parent=""): if DEBUG: print(self.__dict__) - print("#-- %d parts" % len(self.parts)) + print(f"#-- {len(self.parts)} parts") self._extend(top, sup, argv, parent) @@ -1146,7 +1144,7 @@ def min_max(cls, objekt, argv): class Element(Complex): def __str__(self): - return "%s" % (self.__dict__,) + return f"{self.__dict__}" def klass(self, top): xns = None @@ -1187,7 +1185,7 @@ def elements(self, top): if ctyp: return ctyp.elements(top) elif xns: - return ["%s.%s" % (xns, name)] + return [f"{xns}.{name}"] else: return [] @@ -1207,7 +1205,7 @@ def repr(self, top=None, sup=None, argv=None, child=True, parent=""): myname = "" if DEBUG: - print("#Element.repr '%s' (child=%s) [%s]" % (myname, child, self._generated)) + print(f"#Element.repr '{myname}' (child={child}) [{self._generated}]") self.py_class = objekt = PyElement(myname, root=top) min_max(self, objekt, argv) @@ -1265,7 +1263,7 @@ def repr(self, top=None, sup=None, argv=None, child=True, parent=""): raise if parent: - objekt.class_name = "%s_%s" % (leading_uppercase(parent), objekt.name) + objekt.class_name = f"{leading_uppercase(parent)}_{objekt.name}" objekt.scoped = True return objekt @@ -1309,7 +1307,7 @@ def collect(self, top, sup, argv=None, parent=""): argv_copy[key] = val if DEBUG: - print("#Sequence: %s" % argv) + print(f"#Sequence: {argv}") return Complex.collect(self, top, sup, argv_copy, parent) @@ -1373,7 +1371,7 @@ def collect(self, top, sup, argv=None, parent=""): argv_copy["minOccurs"] = 0 if DEBUG: - print("#Choice: %s" % argv) + print(f"#Choice: {argv}") return Complex.collect(self, top, sup, argv_copy, parent=parent) @@ -1409,7 +1407,7 @@ def repr(self, top=None, sup=None, _argv=None, _child=True, parent=""): new_sup = None value_type = name else: - new_sup = "%s.%s" % (namespace, name) + new_sup = f"{namespace}.{name}" # print("#Superior: %s" % new_sup) if new_sup: @@ -1647,7 +1645,7 @@ def output(elem, target_namespace, eldict, ignore=None): for prep in preps: if prep: done = 1 - if isinstance(prep, six.string_types): + if isinstance(prep, str): print(prep) else: for item in prep: @@ -1666,16 +1664,15 @@ def output(elem, target_namespace, eldict, ignore=None): def intro(): print( - """#!/usr/bin/env python + f"""#!/usr/bin/env python # -# Generated %s by parse_xsd.py version %s. +# Generated {time.ctime()} by parse_xsd.py version {__version__}. # import saml2 from saml2 import SamlBase """ - % (time.ctime(), __version__) ) @@ -1745,7 +1742,7 @@ def _mk_list(self, objekt, alla, eldict): lista = False spec = objekt.child_spec(self.target_namespace, prop, mod, cname, lista) - lines = ["%s.%s" % (objekt.class_name, spec)] + lines = [f"{objekt.class_name}.{spec}"] tup.append((prop, lines, spec)) return tup @@ -1796,7 +1793,7 @@ def adjust(self, eldict, block): for sup in sups: if sup.name == ref: for tup in tups: - tup[1].append("%s.%s" % (objekt.class_name, tup[2])) + tup[1].append(f"{objekt.class_name}.{tup[2]}") break else: pass @@ -1842,7 +1839,7 @@ def _element_from_string(self): continue if elem.abstract: continue - print("%s%s.c_tag: %s_from_string," % (INDENT, elem.class_name, pyify(elem.class_name))) + print(f"{INDENT}{elem.class_name}.c_tag: {pyify(elem.class_name)}_from_string,") print("}") print() @@ -1855,14 +1852,14 @@ def _element_by_tag(self): if elem.abstract: continue lcen = elem.name - print("%s'%s': %s," % (INDENT, lcen, elem.class_name)) + print(f"{INDENT}'{lcen}': {elem.class_name},") listed.append(lcen) for elem in self.elems: if isinstance(elem, PyAttribute) or isinstance(elem, PyGroup): continue lcen = elem.name if elem.abstract and lcen not in listed: - print("%s'%s': %s," % (INDENT, lcen, elem.class_name)) + print(f"{INDENT}'{lcen}': {elem.class_name},") listed.append(lcen) print("}") print @@ -1889,12 +1886,12 @@ def out(self): intro() for modul in self.add: - print("from %s import *" % modul) + print(f"from {modul} import *") for _namespace, (mod, namn) in self.impo.items(): if namn: - print("import %s as %s" % (mod, namn)) + print(f"import {mod} as {namn}") print() - print("NAMESPACE = '%s'" % self.target_namespace) + print(f"NAMESPACE = '{self.target_namespace}'") print for defs in self.defs: @@ -1925,12 +1922,12 @@ def out(self): print for attrgrp in self.attrgrp: - print("AG_%s = [" % attrgrp.name) + print(f"AG_{attrgrp.name} = [") for prop in attrgrp.properties[0]: if isinstance(prop.type, PyObj): - print("%s('%s', %s_, %s)," % (INDENT, prop.name, prop.type.name, prop.required)) + print(f"{INDENT}('{prop.name}', {prop.type.name}_, {prop.required}),") else: - print("%s('%s', '%s', %s)," % (INDENT, prop.name, prop.type, prop.required)) + print(f"{INDENT}('{prop.name}', '{prop.type}', {prop.required}),") print("]") print() @@ -1982,7 +1979,7 @@ def out(self): for nsp in NAMESPACE_BASE: for nskey, func in _MAP.items(): - ELEMENTFUNCTION["{%s}%s" % (nsp, nskey)] = func + ELEMENTFUNCTION[f"{{{nsp}}}{nskey}"] = func def evaluate(typ, elem): @@ -2084,12 +2081,12 @@ def find_and_replace(base, mods): def read_schema(doc, add, defs, impo, modul, ignore, sdir): for path in sdir: - fil = "%s%s" % (path, doc) + fil = f"{path}{doc}" try: fp = open(fil) fp.close() break - except IOError as e: + except OSError as e: if e.errno == errno.EACCES: continue else: @@ -2112,7 +2109,7 @@ def read_schema(doc, add, defs, impo, modul, ignore, sdir): elif namespace in ignore: continue else: - raise Exception("Undefined namespace: %s" % namespace) + raise Exception(f"Undefined namespace: {namespace}") _schema = Schema(tree._root, impo, add, modul, defs) _included_parts = [] @@ -2177,7 +2174,7 @@ def main(): elif opt in ("-I", "--ignore"): ignore.append(arg) else: - raise Exception("unhandled option %s" % opt) + raise Exception(f"unhandled option {opt}") if not args: print("No XSD-file specified") diff --git a/src/saml2/tools/sync_attrmaps.py b/src/saml2/tools/sync_attrmaps.py index 718508c03..1a3743de0 100644 --- a/src/saml2/tools/sync_attrmaps.py +++ b/src/saml2/tools/sync_attrmaps.py @@ -37,7 +37,7 @@ def intcmp(s1, s2): return 0 -class AMap(object): +class AMap: def __init__(self, head, tail, indent=4 * " "): self.mod = load(head, tail) self.variable = {} @@ -59,14 +59,14 @@ def sync(self): try: assert self.mod.MAP["to"][val] == key except KeyError: # missing value - print("# Added %s=%s" % (self.mod.MAP["to"][val], key)) + print(f"# Added {self.mod.MAP['to'][val]}={key}") self.mod.MAP["to"][val] = key except AssertionError: - raise Exception("Mismatch key:%s '%s' != '%s'" % (key, val, self.mod.MAP["to"][val])) + raise Exception(f"Mismatch key:{key} '{val}' != '{self.mod.MAP['to'][val]}'") for val in self.mod.MAP["to"].values(): if val not in self.mod.MAP["fro"]: - print("# Missing URN '%s'" % val) + print(f"# Missing URN '{val}'") def do_fro(self): txt = ["%s'fro': {" % self.indent] @@ -77,7 +77,7 @@ def do_fro(self): li = [k[len(_v) :] for k in _fro.keys() if k.startswith(_v)] li.sort(intcmp) for item in li: - txt.append("%s%s+'%s': '%s'," % (i2, var, item, _fro[_v + item])) + txt.append(f"{i2}{var}+'{item}': '{_fro[_v + item]}',") txt.append("%s}," % self.indent) return txt @@ -87,13 +87,13 @@ def do_to(self): _to = self.mod.MAP["to"] _keys = _to.keys() _keys.sort() - invmap = dict([(v, k) for k, v in self.variable.items()]) + invmap = {v: k for k, v in self.variable.items()} for key in _keys: val = _to[key] for _urn, _name in invmap.items(): if val.startswith(_urn): - txt.append("%s'%s': %s+'%s'," % (i2, key, _name, val[len(_urn) :])) + txt.append(f"{i2}'{key}': {_name}+'{val[len(_urn) :]}',") txt.append("%s}" % self.indent) return txt @@ -102,12 +102,12 @@ def __str__(self): self.sync() text = [] for key in self.vars: - text.append("%s = '%s'" % (key, self.variable[key])) + text.append(f"{key} = '{self.variable[key]}'") text.extend(["", ""]) text.append("MAP = {") - text.append("%s'identifier': '%s'," % (self.indent, self.mod.MAP["identifier"])) + text.append(f"{self.indent}'identifier': '{self.mod.MAP['identifier']}',") text.extend(self.do_fro()) text.extend(self.do_to()) @@ -122,7 +122,7 @@ def __str__(self): directory, fname = os.path.split(_name) amap = AMap(directory, fname, 4 * " ") f = open(_name, "w") - f.write("%s" % amap) + f.write(f"{amap}") f.close() elif os.path.isdir(_name): for fname in os.listdir(_name): @@ -133,5 +133,5 @@ def __str__(self): print(10 * "=" + fname + 10 * "=") amap = AMap(_name, fname, 4 * " ") f = open(fname, "w") - f.write("%s" % amap) + f.write(f"{amap}") f.close() diff --git a/src/saml2/userinfo/__init__.py b/src/saml2/userinfo/__init__.py index 9e5bccd47..1415d300d 100644 --- a/src/saml2/userinfo/__init__.py +++ b/src/saml2/userinfo/__init__.py @@ -3,7 +3,7 @@ import copy -class UserInfo(object): +class UserInfo: """Read only interface to a user info store""" def __init__(self): diff --git a/src/saml2/validate.py b/src/saml2/validate.py index 771635986..51a41b992 100644 --- a/src/saml2/validate.py +++ b/src/saml2/validate.py @@ -6,8 +6,7 @@ import re import struct import time - -from six.moves.urllib.parse import urlparse +from urllib.parse import urlparse from saml2 import time_util @@ -113,9 +112,7 @@ def validate_before(not_before, slack): nbefore = calendar.timegm(time_util.str_to_time(not_before)) if nbefore > now + slack: now_str = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(now)) - raise ToEarly( - "Can't use response yet: (now=%s + slack=%d) " "<= notbefore=%s" % (now_str, slack, not_before) - ) + raise ToEarly(f"Can't use response yet: (now={now_str} + slack={int(slack)}) <= notbefore={not_before}") return True @@ -334,9 +331,9 @@ def _valid_instance(instance, val): try: val.verify() except NotValid as exc: - raise NotValid("Class '%s' instance: %s" % (instance.__class__.__name__, exc.args[0])) + raise NotValid(f"Class '{instance.__class__.__name__}' instance: {exc.args[0]}") except OutsideCardinality as exc: - raise NotValid("Class '%s' instance cardinality error: %s" % (instance.__class__.__name__, exc.args[0])) + raise NotValid(f"Class '{instance.__class__.__name__}' instance cardinality error: {exc.args[0]}") ERROR_TEXT = "Wrong type of value '%s' on attribute '%s' expected it to be %s" @@ -355,13 +352,13 @@ def valid_instance(instance): try: validate_value_type(instance.text.strip(), instclass.c_value_type) except NotValid as exc: - raise NotValid("Class '%s' instance: %s" % (class_name, exc.args[0])) + raise NotValid(f"Class '{class_name}' instance: {exc.args[0]}") for (name, typ, required) in instclass.c_attributes.values(): value = getattr(instance, name, "") if required and not value: - txt = "Required value on property '%s' missing" % name - raise MustValueError("Class '%s' instance: %s" % (class_name, txt)) + txt = f"Required value on property '{name}' missing" + raise MustValueError(f"Class '{class_name}' instance: {txt}") if value: try: @@ -376,7 +373,7 @@ def valid_instance(instance): valid(typ, value) except (NotValid, ValueError) as exc: txt = ERROR_TEXT % (value, name, exc.args[0]) - raise NotValid("Class '%s' instance: %s" % (class_name, txt)) + raise NotValid(f"Class '{class_name}' instance: {txt}") for (name, _spec) in instclass.c_children.values(): value = getattr(instance, name, "") @@ -405,15 +402,9 @@ def valid_instance(instance): if _card: if _cmin is not None and _cmin > vlen: - raise NotValid( - "Class '%s' instance cardinality error: %s" - % (class_name, "less then min (%s<%s)" % (vlen, _cmin)) - ) + raise NotValid(f"Class '{class_name}' instance cardinality error: less then min ({vlen}<{_cmin})") if _cmax is not None and vlen > _cmax: - raise NotValid( - "Class '%s' instance cardinality error: %s" - % (class_name, "more then max (%s>%s)" % (vlen, _cmax)) - ) + raise NotValid(f"Class '{class_name}' instance cardinality error: more then max ({vlen}>{_cmax})") if _list: for val in value: @@ -423,9 +414,7 @@ def valid_instance(instance): _valid_instance(instance, value) else: if _cmin: - raise NotValid( - "Class '%s' instance cardinality error: %s" % (class_name, "too few values on %s" % name) - ) + raise NotValid(f"Class '{class_name}' instance cardinality error: too few values on {name}") return True diff --git a/src/saml2/virtual_org.py b/src/saml2/virtual_org.py index 375044b4d..d5d8dcbac 100644 --- a/src/saml2/virtual_org.py +++ b/src/saml2/virtual_org.py @@ -7,7 +7,7 @@ logger = logging.getLogger(__name__) -class VirtualOrg(object): +class VirtualOrg: def __init__(self, sp, vorg, cnf): self.sp = sp # The parent SP client instance self._name = vorg diff --git a/src/saml2/xmldsig/__init__.py b/src/saml2/xmldsig/__init__.py index 18c9eed4d..85f892632 100644 --- a/src/saml2/xmldsig/__init__.py +++ b/src/saml2/xmldsig/__init__.py @@ -75,8 +75,8 @@ } -class DefaultSignature(object): - class _DefaultSignature(object): +class DefaultSignature: + class _DefaultSignature: def __init__(self, sign_alg=None, digest_alg=None): if sign_alg is None: self.sign_alg = sig_default diff --git a/src/saml2test/__init__.py b/src/saml2test/__init__.py index 81eace7f4..e4f1d6bf6 100644 --- a/src/saml2test/__init__.py +++ b/src/saml2test/__init__.py @@ -88,9 +88,9 @@ def exception_trace(tag, exc, log=None): message = traceback.format_exception(*sys.exc_info()) try: - _exc = "Exception: %s" % exc + _exc = f"Exception: {exc}" except UnicodeEncodeError: - _exc = "Exception: %s" % exc.message.encode("utf-8", "replace") + _exc = f"Exception: {exc.message.encode('utf-8', 'replace')}" return {"status": CRITICAL, "message": _exc, "content": "".join(message)} diff --git a/src/saml2test/check.py b/src/saml2test/check.py index 7ef512790..158397fb5 100644 --- a/src/saml2test/check.py +++ b/src/saml2test/check.py @@ -1,8 +1,6 @@ import inspect import json -import six - __author__ = "rolandh" @@ -23,7 +21,7 @@ CONT_JWT = "application/jwt" -class Check(object): +class Check: """General test""" cid = "check" @@ -88,7 +86,7 @@ def _func(self, conv=None): self._status = self.status _msg = conv.last_content - if isinstance(_msg, six.string_types): + if isinstance(_msg, str): self._message = _msg else: self._message = _msg.to_dict() @@ -166,7 +164,7 @@ def _func(self, conv): try: assert item["error"] in self._kwargs["error"] except AssertionError: - self._message = "Wrong type of error, got %s" % item["error"] + self._message = f"Wrong type of error, got {item['error']}" self._status = self.status return {} @@ -259,7 +257,7 @@ def _func(self, conv=None): if conv.exception: self._status = self.status err = conv.exception - self._message = "%s: %s" % (err.__class__.__name__, err) + self._message = f"{err.__class__.__name__}: {err}" else: _rmsg = conv.response_message cname = _rmsg.type() @@ -267,7 +265,7 @@ def _func(self, conv=None): self._status = self.status self._message = ( "Didn't get a response of the type I expected:", - " '%s' instead of '%s', content:'%s'" % (cname, conv.response_type, _rmsg), + f" '{cname}' instead of '{conv.response_type}', content:'{_rmsg}'", ) return {"response_type": conv.response_type, "url": conv.position} diff --git a/src/saml2test/interaction.py b/src/saml2test/interaction.py index 9c1dad6ec..16378ffc5 100644 --- a/src/saml2test/interaction.py +++ b/src/saml2test/interaction.py @@ -8,7 +8,6 @@ from mechanize._form import AmbiguityError from mechanize._form import ControlNotFoundError from mechanize._form import ListControl -import six from urlparse import urlparse @@ -92,7 +91,7 @@ def read(self, size=0): return self.text -class Interaction(object): +class Interaction: def __init__(self, httpc, interactions=None): self.httpc = httpc self.interactions = interactions @@ -123,7 +122,7 @@ def pick_interaction(self, _base="", content="", req=None): _match += 1 else: _c = _bs.title.contents - if isinstance(_c, list) and not isinstance(_c, six.string_types): + if isinstance(_c, list) and not isinstance(_c, str): for _line in _c: if val in _line: _match += 1 @@ -183,7 +182,7 @@ def pick_form(self, response, url=None, **kwargs): _default = _ava["value"] try: orig_val = form[prop] - if isinstance(orig_val, six.string_types): + if isinstance(orig_val, str): if orig_val == _default: _form = form elif _default in orig_val: @@ -309,7 +308,7 @@ def chose(self, orig_response, path, **kwargs): _url = kwargs["location"] part = urlparse(_url) - url = "%s://%s%s" % (part[0], part[1], path) + url = f"{part[0]}://{part[1]}{path}" else: url = path @@ -361,7 +360,7 @@ def interaction(self, args): # ======================================================================== -class Action(object): +class Action: def __init__(self, args): self.args = args or {} self.request = None diff --git a/src/saml2test/opfunc.py b/src/saml2test/opfunc.py index 094917398..51b01b0cd 100644 --- a/src/saml2test/opfunc.py +++ b/src/saml2test/opfunc.py @@ -5,7 +5,6 @@ from mechanize._form import AmbiguityError from mechanize._form import ControlNotFoundError from mechanize._form import ListControl -import six from urlparse import urlparse @@ -164,7 +163,7 @@ def pick_form(response, content, url=None, **kwargs): _default = _ava["value"] try: orig_val = form[prop] - if isinstance(orig_val, six.string_types): + if isinstance(orig_val, str): if orig_val == _default: _form = form elif _default in orig_val: @@ -213,9 +212,7 @@ def do_click(client, form, **kwargs): else: _nr += 1 except ControlNotFoundError: - raise Exception( - "No submit control with the name='%s' and " "value='%s' could be found" % (_name, _val) - ) + raise Exception(f"No submit control with the name='{_name}' and value='{_val}' could be found") else: request = form.click() @@ -295,7 +292,7 @@ def chose(client, orig_response, content, path, **kwargs): _url = kwargs["location"] part = urlparse(_url) - url = "%s://%s%s" % (part[0], part[1], path) + url = f"{part[0]}://{part[1]}{path}" else: url = path @@ -339,7 +336,7 @@ def interaction(args): # ======================================================================== -class Operation(object): +class Operation: def __init__(self, conv, args=None, features=None): if args: self.function = interaction(args) diff --git a/src/saml2test/tool.py b/src/saml2test/tool.py index f87f0e2a5..fa600955f 100644 --- a/src/saml2test/tool.py +++ b/src/saml2test/tool.py @@ -3,7 +3,6 @@ import traceback import cookielib -import six from urlparse import parse_qs from saml2test import CheckError @@ -24,7 +23,7 @@ logger = logging.getLogger(__name__) -class Conversation(object): +class Conversation: """ :ivar response: The received HTTP messages :ivar protocol_response: List of the received protocol messages @@ -75,7 +74,7 @@ def check_severity(self, stat): raise CheckError def do_check(self, test, **kwargs): - if isinstance(test, six.string_types): + if isinstance(test, str): chk = self.check_factory(test)(**kwargs) else: chk = test(**kwargs) @@ -88,7 +87,7 @@ def err_check(self, test, err=None, bryt=True): chk = self.check_factory(test)() chk(self, self.test_output) if bryt: - e = FatalError("%s" % err) + e = FatalError(f"{err}") e.trace = "".join(traceback.format_exception(*sys.exc_info())) raise e @@ -126,7 +125,7 @@ def intermit(self): else: rdseq.append(url) if len(rdseq) > 8: - raise FatalError("Too long sequence of redirects: %s" % rdseq) + raise FatalError(f"Too long sequence of redirects: {rdseq}") logger.info("HTTP %d Location: %s", _response.status_code, url) # If back to me @@ -154,7 +153,7 @@ def intermit(self): logger.info("GET %s", url) _response = self.client.send(url, "GET") except Exception as err: - raise FatalError("%s" % err) + raise FatalError(f"{err}") content = _response.text logger.info("<-- CONTENT: %s", content) diff --git a/tests/_test_80_p11_backend.py b/tests/_test_80_p11_backend.py index 9dd1ad0bb..ea0ef4b4f 100644 --- a/tests/_test_80_p11_backend.py +++ b/tests/_test_80_p11_backend.py @@ -17,7 +17,6 @@ import traceback from pathutils import full_path -import pytest from saml2 import class_name from saml2 import saml @@ -60,7 +59,7 @@ def __init__(self, pub_key=PUB_KEY): self.only_use_keys_in_metadata = False self.metadata = None self.cert_file = pub_key - self.key_file = "pkcs11://%s:0/test?pin=secret1" % P11_MODULE + self.key_file = f"pkcs11://{P11_MODULE}:0/test?pin=secret1" self.debug = False self.cert_handler_extra_class = None self.generate_cert_info = False @@ -93,13 +92,13 @@ def setup_class(self): logging.debug("Generating softhsm.conf") with open(self.softhsm_conf, "w") as f: - f.write("#Generated by pysaml2 cryptobackend test\n0:%s\n" % self.softhsm_db) + f.write(f"#Generated by pysaml2 cryptobackend test\n0:{self.softhsm_db}\n") logging.debug("Initializing the token") self._p( ["softhsm", "--slot", "0", "--label", "test", "--init-token", "--pin", "secret1", "--so-pin", "secret2"] ) - logging.debug("Importing test key {!r} into SoftHSM".format(PRIV_KEY)) + logging.debug(f"Importing test key {PRIV_KEY!r} into SoftHSM") self._p( [ "softhsm", @@ -169,7 +168,7 @@ def setup_class(self): print("-" * 64) traceback.print_exc() print("-" * 64) - logging.warning("PKCS11 tests disabled: unable to initialize test token: %s" % ex) + logging.warning(f"PKCS11 tests disabled: unable to initialize test token: {ex}") raise def teardown_class(self): @@ -192,8 +191,8 @@ def _p(self, args): if self.softhsm_conf is not None: env["SOFTHSM_CONF"] = self.softhsm_conf # print("env SOFTHSM_CONF=%s " % softhsm_conf +" ".join(args)) - logging.debug("Environment {!r}".format(env)) - logging.debug("Executing {!r}".format(args)) + logging.debug(f"Environment {env!r}") + logging.debug(f"Executing {args!r}") args = ["ls"] proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) out, err = proc.communicate() @@ -203,7 +202,7 @@ def _p(self, args): logging.debug(out) rv = proc.wait() if rv: - raise RuntimeError("command exited with code != 0: %d" % rv) + raise RuntimeError(f"command exited with code != 0: {int(rv)}") def test_SAML_sign_with_pkcs11(self): """ @@ -213,7 +212,7 @@ def test_SAML_sign_with_pkcs11(self): ass = self._assertion print(ass) - sign_ass = self.sec.sign_assertion("%s" % ass, node_id=ass.id) + sign_ass = self.sec.sign_assertion(f"{ass}", node_id=ass.id) # print(sign_ass) sass = saml.assertion_from_string(sign_ass) # print(sass) @@ -222,7 +221,7 @@ def test_SAML_sign_with_pkcs11(self): assert sass.id == "11111" assert time_util.str_to_time(sass.issue_instant) - print("Crypto version : %s" % (self.sec.crypto.version())) + print(f"Crypto version : {self.sec.crypto.version()}") item = self.sec.check_signature(sass, class_name(sass), sign_ass) diff --git a/tests/aa_conf.py b/tests/aa_conf.py index 8f7289749..480591190 100644 --- a/tests/aa_conf.py +++ b/tests/aa_conf.py @@ -12,8 +12,8 @@ "service": { "aa": { "endpoints": { - "attribute_service": [(BASE + "as", BINDING_HTTP_REDIRECT)], - "single_logout_service": [(BASE + "slo", BINDING_SOAP)], + "attribute_service": [(f"{BASE}as", BINDING_HTTP_REDIRECT)], + "single_logout_service": [(f"{BASE}slo", BINDING_SOAP)], }, "release_policy": { "default": { @@ -25,7 +25,7 @@ "subject_data": full_path("aa.db"), } }, - "entityid": BASE + "aa", + "entityid": f"{BASE}aa", "name": "Rolands AA", "debug": 1, "key_file": full_path("test.key"), diff --git a/tests/attribute_statement_data.py b/tests/attribute_statement_data.py index dae085f10..e15bcdd20 100644 --- a/tests/attribute_statement_data.py +++ b/tests/attribute_statement_data.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """Testdata for attribute converters """ diff --git a/tests/attributemaps/saml_uri.py b/tests/attributemaps/saml_uri.py index 2055f016a..0520f4dd1 100644 --- a/tests/attributemaps/saml_uri.py +++ b/tests/attributemaps/saml_uri.py @@ -12,230 +12,230 @@ MAP = { "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "fro": { - EDUPERSON_OID + "2": "eduPersonNickname", - EDUPERSON_OID + "9": "eduPersonScopedAffiliation", - EDUPERSON_OID + "11": "eduPersonAssurance", - EDUPERSON_OID + "10": "eduPersonTargetedID", - EDUPERSON_OID + "4": "eduPersonOrgUnitDN", - NOREDUPERSON_OID + "6": "norEduOrgAcronym", - NOREDUPERSON_OID + "7": "norEduOrgUniqueIdentifier", - NOREDUPERSON_OID + "4": "norEduPersonLIN", - EDUPERSON_OID + "1": "eduPersonAffiliation", - NOREDUPERSON_OID + "2": "norEduOrgUnitUniqueNumber", - NETSCAPE_LDAP + "40": "userSMIMECertificate", - NOREDUPERSON_OID + "1": "norEduOrgUniqueNumber", - NETSCAPE_LDAP + "241": "displayName", - UCL_DIR_PILOT + "37": "associatedDomain", - EDUPERSON_OID + "6": "eduPersonPrincipalName", - NOREDUPERSON_OID + "8": "norEduOrgUnitUniqueIdentifier", - NOREDUPERSON_OID + "9": "federationFeideSchemaVersion", - X500ATTR_OID + "53": "deltaRevocationList", - X500ATTR_OID + "52": "supportedAlgorithms", - X500ATTR_OID + "51": "houseIdentifier", - X500ATTR_OID + "50": "uniqueMember", - X500ATTR_OID + "19": "physicalDeliveryOfficeName", - X500ATTR_OID + "18": "postOfficeBox", - X500ATTR_OID + "17": "postalCode", - X500ATTR_OID + "16": "postalAddress", - X500ATTR_OID + "15": "businessCategory", - X500ATTR_OID + "14": "searchGuide", - EDUPERSON_OID + "5": "eduPersonPrimaryAffiliation", - X500ATTR_OID + "12": "title", - X500ATTR_OID + "11": "ou", - X500ATTR_OID + "10": "o", - X500ATTR_OID + "37": "cACertificate", - X500ATTR_OID + "36": "userCertificate", - X500ATTR_OID + "31": "member", - X500ATTR_OID + "30": "supportedApplicationContext", - X500ATTR_OID + "33": "roleOccupant", - X500ATTR_OID + "32": "owner", - NETSCAPE_LDAP + "1": "carLicense", - PKCS_9 + "1": "email", - NETSCAPE_LDAP + "3": "employeeNumber", - NETSCAPE_LDAP + "2": "departmentNumber", - X500ATTR_OID + "39": "certificateRevocationList", - X500ATTR_OID + "38": "authorityRevocationList", - NETSCAPE_LDAP + "216": "userPKCS12", - EDUPERSON_OID + "8": "eduPersonPrimaryOrgUnitDN", - X500ATTR_OID + "9": "street", - X500ATTR_OID + "8": "st", - NETSCAPE_LDAP + "39": "preferredLanguage", - EDUPERSON_OID + "7": "eduPersonEntitlement", - X500ATTR_OID + "2": "knowledgeInformation", - X500ATTR_OID + "7": "l", - X500ATTR_OID + "6": "c", - X500ATTR_OID + "5": "serialNumber", - X500ATTR_OID + "4": "sn", - UCL_DIR_PILOT + "60": "jpegPhoto", - X500ATTR_OID + "65": "pseudonym", - NOREDUPERSON_OID + "5": "norEduPersonNIN", - UCL_DIR_PILOT + "3": "mail", - UCL_DIR_PILOT + "25": "dc", - X500ATTR_OID + "40": "crossCertificatePair", - X500ATTR_OID + "42": "givenName", - X500ATTR_OID + "43": "initials", - X500ATTR_OID + "44": "generationQualifier", - X500ATTR_OID + "45": "x500UniqueIdentifier", - X500ATTR_OID + "46": "dnQualifier", - X500ATTR_OID + "47": "enhancedSearchGuide", - X500ATTR_OID + "48": "protocolInformation", - X500ATTR_OID + "54": "dmdName", - NETSCAPE_LDAP + "4": "employeeType", - X500ATTR_OID + "22": "teletexTerminalIdentifier", - X500ATTR_OID + "23": "facsimileTelephoneNumber", - X500ATTR_OID + "20": "telephoneNumber", - X500ATTR_OID + "21": "telexNumber", - X500ATTR_OID + "26": "registeredAddress", - X500ATTR_OID + "27": "destinationIndicator", - X500ATTR_OID + "24": "x121Address", - X500ATTR_OID + "25": "internationaliSDNNumber", - X500ATTR_OID + "28": "preferredDeliveryMethod", - X500ATTR_OID + "29": "presentationAddress", - EDUPERSON_OID + "3": "eduPersonOrgDN", - NOREDUPERSON_OID + "3": "norEduPersonBirthDate", - UMICH + "57": "labeledURI", - UCL_DIR_PILOT + "1": "uid", - SCHAC + "1": "schacMotherTongue", - SCHAC + "2": "schacGender", - SCHAC + "3": "schacDateOfBirth", - SCHAC + "4": "schacPlaceOfBirth", - SCHAC + "5": "schacCountryOfCitizenship", - SCHAC + "6": "schacSn1", - SCHAC + "7": "schacSn2", - SCHAC + "8": "schacPersonalTitle", - SCHAC + "9": "schacHomeOrganization", - SCHAC + "10": "schacHomeOrganizationType", - SCHAC + "11": "schacCountryOfResidence", - SCHAC + "12": "schacUserPresenceID", - SCHAC + "13": "schacPersonalPosition", - SCHAC + "14": "schacPersonalUniqueCode", - SCHAC + "15": "schacPersonalUniqueID", - SCHAC + "17": "schacExpiryDate", - SCHAC + "18": "schacUserPrivateAttribute", - SCHAC + "19": "schacUserStatus", - SCHAC + "20": "schacProjectMembership", - SCHAC + "21": "schacProjectSpecificRole", + f"{EDUPERSON_OID}2": "eduPersonNickname", + f"{EDUPERSON_OID}9": "eduPersonScopedAffiliation", + f"{EDUPERSON_OID}11": "eduPersonAssurance", + f"{EDUPERSON_OID}10": "eduPersonTargetedID", + f"{EDUPERSON_OID}4": "eduPersonOrgUnitDN", + f"{NOREDUPERSON_OID}6": "norEduOrgAcronym", + f"{NOREDUPERSON_OID}7": "norEduOrgUniqueIdentifier", + f"{NOREDUPERSON_OID}4": "norEduPersonLIN", + f"{EDUPERSON_OID}1": "eduPersonAffiliation", + f"{NOREDUPERSON_OID}2": "norEduOrgUnitUniqueNumber", + f"{NETSCAPE_LDAP}40": "userSMIMECertificate", + f"{NOREDUPERSON_OID}1": "norEduOrgUniqueNumber", + f"{NETSCAPE_LDAP}241": "displayName", + f"{UCL_DIR_PILOT}37": "associatedDomain", + f"{EDUPERSON_OID}6": "eduPersonPrincipalName", + f"{NOREDUPERSON_OID}8": "norEduOrgUnitUniqueIdentifier", + f"{NOREDUPERSON_OID}9": "federationFeideSchemaVersion", + f"{X500ATTR_OID}53": "deltaRevocationList", + f"{X500ATTR_OID}52": "supportedAlgorithms", + f"{X500ATTR_OID}51": "houseIdentifier", + f"{X500ATTR_OID}50": "uniqueMember", + f"{X500ATTR_OID}19": "physicalDeliveryOfficeName", + f"{X500ATTR_OID}18": "postOfficeBox", + f"{X500ATTR_OID}17": "postalCode", + f"{X500ATTR_OID}16": "postalAddress", + f"{X500ATTR_OID}15": "businessCategory", + f"{X500ATTR_OID}14": "searchGuide", + f"{EDUPERSON_OID}5": "eduPersonPrimaryAffiliation", + f"{X500ATTR_OID}12": "title", + f"{X500ATTR_OID}11": "ou", + f"{X500ATTR_OID}10": "o", + f"{X500ATTR_OID}37": "cACertificate", + f"{X500ATTR_OID}36": "userCertificate", + f"{X500ATTR_OID}31": "member", + f"{X500ATTR_OID}30": "supportedApplicationContext", + f"{X500ATTR_OID}33": "roleOccupant", + f"{X500ATTR_OID}32": "owner", + f"{NETSCAPE_LDAP}1": "carLicense", + f"{PKCS_9}1": "email", + f"{NETSCAPE_LDAP}3": "employeeNumber", + f"{NETSCAPE_LDAP}2": "departmentNumber", + f"{X500ATTR_OID}39": "certificateRevocationList", + f"{X500ATTR_OID}38": "authorityRevocationList", + f"{NETSCAPE_LDAP}216": "userPKCS12", + f"{EDUPERSON_OID}8": "eduPersonPrimaryOrgUnitDN", + f"{X500ATTR_OID}9": "street", + f"{X500ATTR_OID}8": "st", + f"{NETSCAPE_LDAP}39": "preferredLanguage", + f"{EDUPERSON_OID}7": "eduPersonEntitlement", + f"{X500ATTR_OID}2": "knowledgeInformation", + f"{X500ATTR_OID}7": "l", + f"{X500ATTR_OID}6": "c", + f"{X500ATTR_OID}5": "serialNumber", + f"{X500ATTR_OID}4": "sn", + f"{UCL_DIR_PILOT}60": "jpegPhoto", + f"{X500ATTR_OID}65": "pseudonym", + f"{NOREDUPERSON_OID}5": "norEduPersonNIN", + f"{UCL_DIR_PILOT}3": "mail", + f"{UCL_DIR_PILOT}25": "dc", + f"{X500ATTR_OID}40": "crossCertificatePair", + f"{X500ATTR_OID}42": "givenName", + f"{X500ATTR_OID}43": "initials", + f"{X500ATTR_OID}44": "generationQualifier", + f"{X500ATTR_OID}45": "x500UniqueIdentifier", + f"{X500ATTR_OID}46": "dnQualifier", + f"{X500ATTR_OID}47": "enhancedSearchGuide", + f"{X500ATTR_OID}48": "protocolInformation", + f"{X500ATTR_OID}54": "dmdName", + f"{NETSCAPE_LDAP}4": "employeeType", + f"{X500ATTR_OID}22": "teletexTerminalIdentifier", + f"{X500ATTR_OID}23": "facsimileTelephoneNumber", + f"{X500ATTR_OID}20": "telephoneNumber", + f"{X500ATTR_OID}21": "telexNumber", + f"{X500ATTR_OID}26": "registeredAddress", + f"{X500ATTR_OID}27": "destinationIndicator", + f"{X500ATTR_OID}24": "x121Address", + f"{X500ATTR_OID}25": "internationaliSDNNumber", + f"{X500ATTR_OID}28": "preferredDeliveryMethod", + f"{X500ATTR_OID}29": "presentationAddress", + f"{EDUPERSON_OID}3": "eduPersonOrgDN", + f"{NOREDUPERSON_OID}3": "norEduPersonBirthDate", + f"{UMICH}57": "labeledURI", + f"{UCL_DIR_PILOT}1": "uid", + f"{SCHAC}1": "schacMotherTongue", + f"{SCHAC}2": "schacGender", + f"{SCHAC}3": "schacDateOfBirth", + f"{SCHAC}4": "schacPlaceOfBirth", + f"{SCHAC}5": "schacCountryOfCitizenship", + f"{SCHAC}6": "schacSn1", + f"{SCHAC}7": "schacSn2", + f"{SCHAC}8": "schacPersonalTitle", + f"{SCHAC}9": "schacHomeOrganization", + f"{SCHAC}10": "schacHomeOrganizationType", + f"{SCHAC}11": "schacCountryOfResidence", + f"{SCHAC}12": "schacUserPresenceID", + f"{SCHAC}13": "schacPersonalPosition", + f"{SCHAC}14": "schacPersonalUniqueCode", + f"{SCHAC}15": "schacPersonalUniqueID", + f"{SCHAC}17": "schacExpiryDate", + f"{SCHAC}18": "schacUserPrivateAttribute", + f"{SCHAC}19": "schacUserStatus", + f"{SCHAC}20": "schacProjectMembership", + f"{SCHAC}21": "schacProjectSpecificRole", }, "to": { - "roleOccupant": X500ATTR_OID + "33", - "gn": X500ATTR_OID + "42", - "norEduPersonNIN": NOREDUPERSON_OID + "5", - "title": X500ATTR_OID + "12", - "facsimileTelephoneNumber": X500ATTR_OID + "23", - "mail": UCL_DIR_PILOT + "3", - "postOfficeBox": X500ATTR_OID + "18", - "fax": X500ATTR_OID + "23", - "telephoneNumber": X500ATTR_OID + "20", - "norEduPersonBirthDate": NOREDUPERSON_OID + "3", - "rfc822Mailbox": UCL_DIR_PILOT + "3", - "dc": UCL_DIR_PILOT + "25", - "countryName": X500ATTR_OID + "6", - "emailAddress": PKCS_9 + "1", - "employeeNumber": NETSCAPE_LDAP + "3", - "organizationName": X500ATTR_OID + "10", - "eduPersonAssurance": EDUPERSON_OID + "11", - "norEduOrgAcronym": NOREDUPERSON_OID + "6", - "registeredAddress": X500ATTR_OID + "26", - "physicalDeliveryOfficeName": X500ATTR_OID + "19", - "associatedDomain": UCL_DIR_PILOT + "37", - "l": X500ATTR_OID + "7", - "stateOrProvinceName": X500ATTR_OID + "8", - "federationFeideSchemaVersion": NOREDUPERSON_OID + "9", - "pkcs9email": PKCS_9 + "1", - "givenName": X500ATTR_OID + "42", - "givenname": X500ATTR_OID + "42", - "x500UniqueIdentifier": X500ATTR_OID + "45", - "eduPersonNickname": EDUPERSON_OID + "2", - "houseIdentifier": X500ATTR_OID + "51", - "street": X500ATTR_OID + "9", - "supportedAlgorithms": X500ATTR_OID + "52", - "preferredLanguage": NETSCAPE_LDAP + "39", - "postalAddress": X500ATTR_OID + "16", - "email": PKCS_9 + "1", - "norEduOrgUnitUniqueIdentifier": NOREDUPERSON_OID + "8", - "eduPersonPrimaryOrgUnitDN": EDUPERSON_OID + "8", - "c": X500ATTR_OID + "6", - "teletexTerminalIdentifier": X500ATTR_OID + "22", - "o": X500ATTR_OID + "10", - "cACertificate": X500ATTR_OID + "37", - "telexNumber": X500ATTR_OID + "21", - "ou": X500ATTR_OID + "11", - "initials": X500ATTR_OID + "43", - "eduPersonOrgUnitDN": EDUPERSON_OID + "4", - "deltaRevocationList": X500ATTR_OID + "53", - "norEduPersonLIN": NOREDUPERSON_OID + "4", - "supportedApplicationContext": X500ATTR_OID + "30", - "eduPersonEntitlement": EDUPERSON_OID + "7", - "generationQualifier": X500ATTR_OID + "44", - "eduPersonAffiliation": EDUPERSON_OID + "1", - "edupersonaffiliation": EDUPERSON_OID + "1", - "eduPersonPrincipalName": EDUPERSON_OID + "6", - "edupersonprincipalname": EDUPERSON_OID + "6", - "localityName": X500ATTR_OID + "7", - "owner": X500ATTR_OID + "32", - "norEduOrgUnitUniqueNumber": NOREDUPERSON_OID + "2", - "searchGuide": X500ATTR_OID + "14", - "certificateRevocationList": X500ATTR_OID + "39", - "organizationalUnitName": X500ATTR_OID + "11", - "userCertificate": X500ATTR_OID + "36", - "preferredDeliveryMethod": X500ATTR_OID + "28", - "internationaliSDNNumber": X500ATTR_OID + "25", - "uniqueMember": X500ATTR_OID + "50", - "departmentNumber": NETSCAPE_LDAP + "2", - "enhancedSearchGuide": X500ATTR_OID + "47", - "userPKCS12": NETSCAPE_LDAP + "216", - "eduPersonTargetedID": EDUPERSON_OID + "10", - "norEduOrgUniqueNumber": NOREDUPERSON_OID + "1", - "x121Address": X500ATTR_OID + "24", - "destinationIndicator": X500ATTR_OID + "27", - "eduPersonPrimaryAffiliation": EDUPERSON_OID + "5", - "surname": X500ATTR_OID + "4", - "jpegPhoto": UCL_DIR_PILOT + "60", - "eduPersonScopedAffiliation": EDUPERSON_OID + "9", - "edupersonscopedaffiliation": EDUPERSON_OID + "9", - "protocolInformation": X500ATTR_OID + "48", - "knowledgeInformation": X500ATTR_OID + "2", - "employeeType": NETSCAPE_LDAP + "4", - "userSMIMECertificate": NETSCAPE_LDAP + "40", - "member": X500ATTR_OID + "31", - "streetAddress": X500ATTR_OID + "9", - "dmdName": X500ATTR_OID + "54", - "postalCode": X500ATTR_OID + "17", - "pseudonym": X500ATTR_OID + "65", - "dnQualifier": X500ATTR_OID + "46", - "crossCertificatePair": X500ATTR_OID + "40", - "eduPersonOrgDN": EDUPERSON_OID + "3", - "authorityRevocationList": X500ATTR_OID + "38", - "displayName": NETSCAPE_LDAP + "241", - "businessCategory": X500ATTR_OID + "15", - "serialNumber": X500ATTR_OID + "5", - "norEduOrgUniqueIdentifier": NOREDUPERSON_OID + "7", - "st": X500ATTR_OID + "8", - "carLicense": NETSCAPE_LDAP + "1", - "presentationAddress": X500ATTR_OID + "29", - "sn": X500ATTR_OID + "4", - "domainComponent": UCL_DIR_PILOT + "25", - "labeledURI": UMICH + "57", - "uid": UCL_DIR_PILOT + "1", - "schacMotherTongue": SCHAC + "1", - "schacGender": SCHAC + "2", - "schacDateOfBirth": SCHAC + "3", - "schacPlaceOfBirth": SCHAC + "4", - "schacCountryOfCitizenship": SCHAC + "5", - "schacSn1": SCHAC + "6", - "schacSn2": SCHAC + "7", - "schacPersonalTitle": SCHAC + "8", - "schacHomeOrganization": SCHAC + "9", - "schacHomeOrganizationType": SCHAC + "10", - "schacCountryOfResidence": SCHAC + "11", - "schacUserPresenceID": SCHAC + "12", - "schacPersonalPosition": SCHAC + "13", - "schacPersonalUniqueCode": SCHAC + "14", - "schacPersonalUniqueID": SCHAC + "15", - "schacExpiryDate": SCHAC + "17", - "schacUserPrivateAttribute": SCHAC + "18", - "schacUserStatus": SCHAC + "19", - "schacProjectMembership": SCHAC + "20", - "schacProjectSpecificRole": SCHAC + "21", + "roleOccupant": f"{X500ATTR_OID}33", + "gn": f"{X500ATTR_OID}42", + "norEduPersonNIN": f"{NOREDUPERSON_OID}5", + "title": f"{X500ATTR_OID}12", + "facsimileTelephoneNumber": f"{X500ATTR_OID}23", + "mail": f"{UCL_DIR_PILOT}3", + "postOfficeBox": f"{X500ATTR_OID}18", + "fax": f"{X500ATTR_OID}23", + "telephoneNumber": f"{X500ATTR_OID}20", + "norEduPersonBirthDate": f"{NOREDUPERSON_OID}3", + "rfc822Mailbox": f"{UCL_DIR_PILOT}3", + "dc": f"{UCL_DIR_PILOT}25", + "countryName": f"{X500ATTR_OID}6", + "emailAddress": f"{PKCS_9}1", + "employeeNumber": f"{NETSCAPE_LDAP}3", + "organizationName": f"{X500ATTR_OID}10", + "eduPersonAssurance": f"{EDUPERSON_OID}11", + "norEduOrgAcronym": f"{NOREDUPERSON_OID}6", + "registeredAddress": f"{X500ATTR_OID}26", + "physicalDeliveryOfficeName": f"{X500ATTR_OID}19", + "associatedDomain": f"{UCL_DIR_PILOT}37", + "l": f"{X500ATTR_OID}7", + "stateOrProvinceName": f"{X500ATTR_OID}8", + "federationFeideSchemaVersion": f"{NOREDUPERSON_OID}9", + "pkcs9email": f"{PKCS_9}1", + "givenName": f"{X500ATTR_OID}42", + "givenname": f"{X500ATTR_OID}42", + "x500UniqueIdentifier": f"{X500ATTR_OID}45", + "eduPersonNickname": f"{EDUPERSON_OID}2", + "houseIdentifier": f"{X500ATTR_OID}51", + "street": f"{X500ATTR_OID}9", + "supportedAlgorithms": f"{X500ATTR_OID}52", + "preferredLanguage": f"{NETSCAPE_LDAP}39", + "postalAddress": f"{X500ATTR_OID}16", + "email": f"{PKCS_9}1", + "norEduOrgUnitUniqueIdentifier": f"{NOREDUPERSON_OID}8", + "eduPersonPrimaryOrgUnitDN": f"{EDUPERSON_OID}8", + "c": f"{X500ATTR_OID}6", + "teletexTerminalIdentifier": f"{X500ATTR_OID}22", + "o": f"{X500ATTR_OID}10", + "cACertificate": f"{X500ATTR_OID}37", + "telexNumber": f"{X500ATTR_OID}21", + "ou": f"{X500ATTR_OID}11", + "initials": f"{X500ATTR_OID}43", + "eduPersonOrgUnitDN": f"{EDUPERSON_OID}4", + "deltaRevocationList": f"{X500ATTR_OID}53", + "norEduPersonLIN": f"{NOREDUPERSON_OID}4", + "supportedApplicationContext": f"{X500ATTR_OID}30", + "eduPersonEntitlement": f"{EDUPERSON_OID}7", + "generationQualifier": f"{X500ATTR_OID}44", + "eduPersonAffiliation": f"{EDUPERSON_OID}1", + "edupersonaffiliation": f"{EDUPERSON_OID}1", + "eduPersonPrincipalName": f"{EDUPERSON_OID}6", + "edupersonprincipalname": f"{EDUPERSON_OID}6", + "localityName": f"{X500ATTR_OID}7", + "owner": f"{X500ATTR_OID}32", + "norEduOrgUnitUniqueNumber": f"{NOREDUPERSON_OID}2", + "searchGuide": f"{X500ATTR_OID}14", + "certificateRevocationList": f"{X500ATTR_OID}39", + "organizationalUnitName": f"{X500ATTR_OID}11", + "userCertificate": f"{X500ATTR_OID}36", + "preferredDeliveryMethod": f"{X500ATTR_OID}28", + "internationaliSDNNumber": f"{X500ATTR_OID}25", + "uniqueMember": f"{X500ATTR_OID}50", + "departmentNumber": f"{NETSCAPE_LDAP}2", + "enhancedSearchGuide": f"{X500ATTR_OID}47", + "userPKCS12": f"{NETSCAPE_LDAP}216", + "eduPersonTargetedID": f"{EDUPERSON_OID}10", + "norEduOrgUniqueNumber": f"{NOREDUPERSON_OID}1", + "x121Address": f"{X500ATTR_OID}24", + "destinationIndicator": f"{X500ATTR_OID}27", + "eduPersonPrimaryAffiliation": f"{EDUPERSON_OID}5", + "surname": f"{X500ATTR_OID}4", + "jpegPhoto": f"{UCL_DIR_PILOT}60", + "eduPersonScopedAffiliation": f"{EDUPERSON_OID}9", + "edupersonscopedaffiliation": f"{EDUPERSON_OID}9", + "protocolInformation": f"{X500ATTR_OID}48", + "knowledgeInformation": f"{X500ATTR_OID}2", + "employeeType": f"{NETSCAPE_LDAP}4", + "userSMIMECertificate": f"{NETSCAPE_LDAP}40", + "member": f"{X500ATTR_OID}31", + "streetAddress": f"{X500ATTR_OID}9", + "dmdName": f"{X500ATTR_OID}54", + "postalCode": f"{X500ATTR_OID}17", + "pseudonym": f"{X500ATTR_OID}65", + "dnQualifier": f"{X500ATTR_OID}46", + "crossCertificatePair": f"{X500ATTR_OID}40", + "eduPersonOrgDN": f"{EDUPERSON_OID}3", + "authorityRevocationList": f"{X500ATTR_OID}38", + "displayName": f"{NETSCAPE_LDAP}241", + "businessCategory": f"{X500ATTR_OID}15", + "serialNumber": f"{X500ATTR_OID}5", + "norEduOrgUniqueIdentifier": f"{NOREDUPERSON_OID}7", + "st": f"{X500ATTR_OID}8", + "carLicense": f"{NETSCAPE_LDAP}1", + "presentationAddress": f"{X500ATTR_OID}29", + "sn": f"{X500ATTR_OID}4", + "domainComponent": f"{UCL_DIR_PILOT}25", + "labeledURI": f"{UMICH}57", + "uid": f"{UCL_DIR_PILOT}1", + "schacMotherTongue": f"{SCHAC}1", + "schacGender": f"{SCHAC}2", + "schacDateOfBirth": f"{SCHAC}3", + "schacPlaceOfBirth": f"{SCHAC}4", + "schacCountryOfCitizenship": f"{SCHAC}5", + "schacSn1": f"{SCHAC}6", + "schacSn2": f"{SCHAC}7", + "schacPersonalTitle": f"{SCHAC}8", + "schacHomeOrganization": f"{SCHAC}9", + "schacHomeOrganizationType": f"{SCHAC}10", + "schacCountryOfResidence": f"{SCHAC}11", + "schacUserPresenceID": f"{SCHAC}12", + "schacPersonalPosition": f"{SCHAC}13", + "schacPersonalUniqueCode": f"{SCHAC}14", + "schacPersonalUniqueID": f"{SCHAC}15", + "schacExpiryDate": f"{SCHAC}17", + "schacUserPrivateAttribute": f"{SCHAC}18", + "schacUserStatus": f"{SCHAC}19", + "schacProjectMembership": f"{SCHAC}20", + "schacProjectSpecificRole": f"{SCHAC}21", }, } diff --git a/tests/attributemaps/shibboleth_uri.py b/tests/attributemaps/shibboleth_uri.py index 30b31503d..992a2219e 100644 --- a/tests/attributemaps/shibboleth_uri.py +++ b/tests/attributemaps/shibboleth_uri.py @@ -9,182 +9,182 @@ MAP = { "identifier": "urn:mace:shibboleth:1.0:attributeNamespace:uri", "fro": { - EDUPERSON_OID + "2": "eduPersonNickname", - EDUPERSON_OID + "9": "eduPersonScopedAffiliation", - EDUPERSON_OID + "11": "eduPersonAssurance", - EDUPERSON_OID + "10": "eduPersonTargetedID", - EDUPERSON_OID + "4": "eduPersonOrgUnitDN", - NOREDUPERSON_OID + "6": "norEduOrgAcronym", - NOREDUPERSON_OID + "7": "norEduOrgUniqueIdentifier", - NOREDUPERSON_OID + "4": "norEduPersonLIN", - EDUPERSON_OID + "1": "eduPersonAffiliation", - NOREDUPERSON_OID + "2": "norEduOrgUnitUniqueNumber", - NETSCAPE_LDAP + "40": "userSMIMECertificate", - NOREDUPERSON_OID + "1": "norEduOrgUniqueNumber", - NETSCAPE_LDAP + "241": "displayName", - UCL_DIR_PILOT + "37": "associatedDomain", - EDUPERSON_OID + "6": "eduPersonPrincipalName", - NOREDUPERSON_OID + "8": "norEduOrgUnitUniqueIdentifier", - NOREDUPERSON_OID + "9": "federationFeideSchemaVersion", - X500ATTR + "53": "deltaRevocationList", - X500ATTR + "52": "supportedAlgorithms", - X500ATTR + "51": "houseIdentifier", - X500ATTR + "50": "uniqueMember", - X500ATTR + "19": "physicalDeliveryOfficeName", - X500ATTR + "18": "postOfficeBox", - X500ATTR + "17": "postalCode", - X500ATTR + "16": "postalAddress", - X500ATTR + "15": "businessCategory", - X500ATTR + "14": "searchGuide", - EDUPERSON_OID + "5": "eduPersonPrimaryAffiliation", - X500ATTR + "12": "title", - X500ATTR + "11": "ou", - X500ATTR + "10": "o", - X500ATTR + "37": "cACertificate", - X500ATTR + "36": "userCertificate", - X500ATTR + "31": "member", - X500ATTR + "30": "supportedApplicationContext", - X500ATTR + "33": "roleOccupant", - X500ATTR + "32": "owner", - NETSCAPE_LDAP + "1": "carLicense", - PKCS_9 + "1": "email", - NETSCAPE_LDAP + "3": "employeeNumber", - NETSCAPE_LDAP + "2": "departmentNumber", - X500ATTR + "39": "certificateRevocationList", - X500ATTR + "38": "authorityRevocationList", - NETSCAPE_LDAP + "216": "userPKCS12", - EDUPERSON_OID + "8": "eduPersonPrimaryOrgUnitDN", - X500ATTR + "9": "street", - X500ATTR + "8": "st", - NETSCAPE_LDAP + "39": "preferredLanguage", - EDUPERSON_OID + "7": "eduPersonEntitlement", - X500ATTR + "2": "knowledgeInformation", - X500ATTR + "7": "l", - X500ATTR + "6": "c", - X500ATTR + "5": "serialNumber", - X500ATTR + "4": "sn", - UCL_DIR_PILOT + "60": "jpegPhoto", - X500ATTR + "65": "pseudonym", - NOREDUPERSON_OID + "5": "norEduPersonNIN", - UCL_DIR_PILOT + "3": "mail", - UCL_DIR_PILOT + "25": "dc", - X500ATTR + "40": "crossCertificatePair", - X500ATTR + "42": "givenName", - X500ATTR + "43": "initials", - X500ATTR + "44": "generationQualifier", - X500ATTR + "45": "x500UniqueIdentifier", - X500ATTR + "46": "dnQualifier", - X500ATTR + "47": "enhancedSearchGuide", - X500ATTR + "48": "protocolInformation", - X500ATTR + "54": "dmdName", - NETSCAPE_LDAP + "4": "employeeType", - X500ATTR + "22": "teletexTerminalIdentifier", - X500ATTR + "23": "facsimileTelephoneNumber", - X500ATTR + "20": "telephoneNumber", - X500ATTR + "21": "telexNumber", - X500ATTR + "26": "registeredAddress", - X500ATTR + "27": "destinationIndicator", - X500ATTR + "24": "x121Address", - X500ATTR + "25": "internationaliSDNNumber", - X500ATTR + "28": "preferredDeliveryMethod", - X500ATTR + "29": "presentationAddress", - EDUPERSON_OID + "3": "eduPersonOrgDN", - NOREDUPERSON_OID + "3": "norEduPersonBirthDate", + f"{EDUPERSON_OID}2": "eduPersonNickname", + f"{EDUPERSON_OID}9": "eduPersonScopedAffiliation", + f"{EDUPERSON_OID}11": "eduPersonAssurance", + f"{EDUPERSON_OID}10": "eduPersonTargetedID", + f"{EDUPERSON_OID}4": "eduPersonOrgUnitDN", + f"{NOREDUPERSON_OID}6": "norEduOrgAcronym", + f"{NOREDUPERSON_OID}7": "norEduOrgUniqueIdentifier", + f"{NOREDUPERSON_OID}4": "norEduPersonLIN", + f"{EDUPERSON_OID}1": "eduPersonAffiliation", + f"{NOREDUPERSON_OID}2": "norEduOrgUnitUniqueNumber", + f"{NETSCAPE_LDAP}40": "userSMIMECertificate", + f"{NOREDUPERSON_OID}1": "norEduOrgUniqueNumber", + f"{NETSCAPE_LDAP}241": "displayName", + f"{UCL_DIR_PILOT}37": "associatedDomain", + f"{EDUPERSON_OID}6": "eduPersonPrincipalName", + f"{NOREDUPERSON_OID}8": "norEduOrgUnitUniqueIdentifier", + f"{NOREDUPERSON_OID}9": "federationFeideSchemaVersion", + f"{X500ATTR}53": "deltaRevocationList", + f"{X500ATTR}52": "supportedAlgorithms", + f"{X500ATTR}51": "houseIdentifier", + f"{X500ATTR}50": "uniqueMember", + f"{X500ATTR}19": "physicalDeliveryOfficeName", + f"{X500ATTR}18": "postOfficeBox", + f"{X500ATTR}17": "postalCode", + f"{X500ATTR}16": "postalAddress", + f"{X500ATTR}15": "businessCategory", + f"{X500ATTR}14": "searchGuide", + f"{EDUPERSON_OID}5": "eduPersonPrimaryAffiliation", + f"{X500ATTR}12": "title", + f"{X500ATTR}11": "ou", + f"{X500ATTR}10": "o", + f"{X500ATTR}37": "cACertificate", + f"{X500ATTR}36": "userCertificate", + f"{X500ATTR}31": "member", + f"{X500ATTR}30": "supportedApplicationContext", + f"{X500ATTR}33": "roleOccupant", + f"{X500ATTR}32": "owner", + f"{NETSCAPE_LDAP}1": "carLicense", + f"{PKCS_9}1": "email", + f"{NETSCAPE_LDAP}3": "employeeNumber", + f"{NETSCAPE_LDAP}2": "departmentNumber", + f"{X500ATTR}39": "certificateRevocationList", + f"{X500ATTR}38": "authorityRevocationList", + f"{NETSCAPE_LDAP}216": "userPKCS12", + f"{EDUPERSON_OID}8": "eduPersonPrimaryOrgUnitDN", + f"{X500ATTR}9": "street", + f"{X500ATTR}8": "st", + f"{NETSCAPE_LDAP}39": "preferredLanguage", + f"{EDUPERSON_OID}7": "eduPersonEntitlement", + f"{X500ATTR}2": "knowledgeInformation", + f"{X500ATTR}7": "l", + f"{X500ATTR}6": "c", + f"{X500ATTR}5": "serialNumber", + f"{X500ATTR}4": "sn", + f"{UCL_DIR_PILOT}60": "jpegPhoto", + f"{X500ATTR}65": "pseudonym", + f"{NOREDUPERSON_OID}5": "norEduPersonNIN", + f"{UCL_DIR_PILOT}3": "mail", + f"{UCL_DIR_PILOT}25": "dc", + f"{X500ATTR}40": "crossCertificatePair", + f"{X500ATTR}42": "givenName", + f"{X500ATTR}43": "initials", + f"{X500ATTR}44": "generationQualifier", + f"{X500ATTR}45": "x500UniqueIdentifier", + f"{X500ATTR}46": "dnQualifier", + f"{X500ATTR}47": "enhancedSearchGuide", + f"{X500ATTR}48": "protocolInformation", + f"{X500ATTR}54": "dmdName", + f"{NETSCAPE_LDAP}4": "employeeType", + f"{X500ATTR}22": "teletexTerminalIdentifier", + f"{X500ATTR}23": "facsimileTelephoneNumber", + f"{X500ATTR}20": "telephoneNumber", + f"{X500ATTR}21": "telexNumber", + f"{X500ATTR}26": "registeredAddress", + f"{X500ATTR}27": "destinationIndicator", + f"{X500ATTR}24": "x121Address", + f"{X500ATTR}25": "internationaliSDNNumber", + f"{X500ATTR}28": "preferredDeliveryMethod", + f"{X500ATTR}29": "presentationAddress", + f"{EDUPERSON_OID}3": "eduPersonOrgDN", + f"{NOREDUPERSON_OID}3": "norEduPersonBirthDate", }, "to": { - "roleOccupant": X500ATTR + "33", - "gn": X500ATTR + "42", - "norEduPersonNIN": NOREDUPERSON_OID + "5", - "title": X500ATTR + "12", - "facsimileTelephoneNumber": X500ATTR + "23", - "mail": UCL_DIR_PILOT + "3", - "postOfficeBox": X500ATTR + "18", - "fax": X500ATTR + "23", - "telephoneNumber": X500ATTR + "20", - "norEduPersonBirthDate": NOREDUPERSON_OID + "3", - "rfc822Mailbox": UCL_DIR_PILOT + "3", - "dc": UCL_DIR_PILOT + "25", - "countryName": X500ATTR + "6", - "emailAddress": PKCS_9 + "1", - "employeeNumber": NETSCAPE_LDAP + "3", - "organizationName": X500ATTR + "10", - "eduPersonAssurance": EDUPERSON_OID + "11", - "norEduOrgAcronym": NOREDUPERSON_OID + "6", - "registeredAddress": X500ATTR + "26", - "physicalDeliveryOfficeName": X500ATTR + "19", - "associatedDomain": UCL_DIR_PILOT + "37", - "l": X500ATTR + "7", - "stateOrProvinceName": X500ATTR + "8", - "federationFeideSchemaVersion": NOREDUPERSON_OID + "9", - "pkcs9email": PKCS_9 + "1", - "givenName": X500ATTR + "42", - "x500UniqueIdentifier": X500ATTR + "45", - "eduPersonNickname": EDUPERSON_OID + "2", - "houseIdentifier": X500ATTR + "51", - "street": X500ATTR + "9", - "supportedAlgorithms": X500ATTR + "52", - "preferredLanguage": NETSCAPE_LDAP + "39", - "postalAddress": X500ATTR + "16", - "email": PKCS_9 + "1", - "norEduOrgUnitUniqueIdentifier": NOREDUPERSON_OID + "8", - "eduPersonPrimaryOrgUnitDN": EDUPERSON_OID + "8", - "c": X500ATTR + "6", - "teletexTerminalIdentifier": X500ATTR + "22", - "o": X500ATTR + "10", - "cACertificate": X500ATTR + "37", - "telexNumber": X500ATTR + "21", - "ou": X500ATTR + "11", - "initials": X500ATTR + "43", - "eduPersonOrgUnitDN": EDUPERSON_OID + "4", - "deltaRevocationList": X500ATTR + "53", - "norEduPersonLIN": NOREDUPERSON_OID + "4", - "supportedApplicationContext": X500ATTR + "30", - "eduPersonEntitlement": EDUPERSON_OID + "7", - "generationQualifier": X500ATTR + "44", - "eduPersonAffiliation": EDUPERSON_OID + "1", - "eduPersonPrincipalName": EDUPERSON_OID + "6", - "localityName": X500ATTR + "7", - "owner": X500ATTR + "32", - "norEduOrgUnitUniqueNumber": NOREDUPERSON_OID + "2", - "searchGuide": X500ATTR + "14", - "certificateRevocationList": X500ATTR + "39", - "organizationalUnitName": X500ATTR + "11", - "userCertificate": X500ATTR + "36", - "preferredDeliveryMethod": X500ATTR + "28", - "internationaliSDNNumber": X500ATTR + "25", - "uniqueMember": X500ATTR + "50", - "departmentNumber": NETSCAPE_LDAP + "2", - "enhancedSearchGuide": X500ATTR + "47", - "userPKCS12": NETSCAPE_LDAP + "216", - "eduPersonTargetedID": EDUPERSON_OID + "10", - "norEduOrgUniqueNumber": NOREDUPERSON_OID + "1", - "x121Address": X500ATTR + "24", - "destinationIndicator": X500ATTR + "27", - "eduPersonPrimaryAffiliation": EDUPERSON_OID + "5", - "surname": X500ATTR + "4", - "jpegPhoto": UCL_DIR_PILOT + "60", - "eduPersonScopedAffiliation": EDUPERSON_OID + "9", - "protocolInformation": X500ATTR + "48", - "knowledgeInformation": X500ATTR + "2", - "employeeType": NETSCAPE_LDAP + "4", - "userSMIMECertificate": NETSCAPE_LDAP + "40", - "member": X500ATTR + "31", - "streetAddress": X500ATTR + "9", - "dmdName": X500ATTR + "54", - "postalCode": X500ATTR + "17", - "pseudonym": X500ATTR + "65", - "dnQualifier": X500ATTR + "46", - "crossCertificatePair": X500ATTR + "40", - "eduPersonOrgDN": EDUPERSON_OID + "3", - "authorityRevocationList": X500ATTR + "38", - "displayName": NETSCAPE_LDAP + "241", - "businessCategory": X500ATTR + "15", - "serialNumber": X500ATTR + "5", - "norEduOrgUniqueIdentifier": NOREDUPERSON_OID + "7", - "st": X500ATTR + "8", - "carLicense": NETSCAPE_LDAP + "1", - "presentationAddress": X500ATTR + "29", - "sn": X500ATTR + "4", - "domainComponent": UCL_DIR_PILOT + "25", + "roleOccupant": f"{X500ATTR}33", + "gn": f"{X500ATTR}42", + "norEduPersonNIN": f"{NOREDUPERSON_OID}5", + "title": f"{X500ATTR}12", + "facsimileTelephoneNumber": f"{X500ATTR}23", + "mail": f"{UCL_DIR_PILOT}3", + "postOfficeBox": f"{X500ATTR}18", + "fax": f"{X500ATTR}23", + "telephoneNumber": f"{X500ATTR}20", + "norEduPersonBirthDate": f"{NOREDUPERSON_OID}3", + "rfc822Mailbox": f"{UCL_DIR_PILOT}3", + "dc": f"{UCL_DIR_PILOT}25", + "countryName": f"{X500ATTR}6", + "emailAddress": f"{PKCS_9}1", + "employeeNumber": f"{NETSCAPE_LDAP}3", + "organizationName": f"{X500ATTR}10", + "eduPersonAssurance": f"{EDUPERSON_OID}11", + "norEduOrgAcronym": f"{NOREDUPERSON_OID}6", + "registeredAddress": f"{X500ATTR}26", + "physicalDeliveryOfficeName": f"{X500ATTR}19", + "associatedDomain": f"{UCL_DIR_PILOT}37", + "l": f"{X500ATTR}7", + "stateOrProvinceName": f"{X500ATTR}8", + "federationFeideSchemaVersion": f"{NOREDUPERSON_OID}9", + "pkcs9email": f"{PKCS_9}1", + "givenName": f"{X500ATTR}42", + "x500UniqueIdentifier": f"{X500ATTR}45", + "eduPersonNickname": f"{EDUPERSON_OID}2", + "houseIdentifier": f"{X500ATTR}51", + "street": f"{X500ATTR}9", + "supportedAlgorithms": f"{X500ATTR}52", + "preferredLanguage": f"{NETSCAPE_LDAP}39", + "postalAddress": f"{X500ATTR}16", + "email": f"{PKCS_9}1", + "norEduOrgUnitUniqueIdentifier": f"{NOREDUPERSON_OID}8", + "eduPersonPrimaryOrgUnitDN": f"{EDUPERSON_OID}8", + "c": f"{X500ATTR}6", + "teletexTerminalIdentifier": f"{X500ATTR}22", + "o": f"{X500ATTR}10", + "cACertificate": f"{X500ATTR}37", + "telexNumber": f"{X500ATTR}21", + "ou": f"{X500ATTR}11", + "initials": f"{X500ATTR}43", + "eduPersonOrgUnitDN": f"{EDUPERSON_OID}4", + "deltaRevocationList": f"{X500ATTR}53", + "norEduPersonLIN": f"{NOREDUPERSON_OID}4", + "supportedApplicationContext": f"{X500ATTR}30", + "eduPersonEntitlement": f"{EDUPERSON_OID}7", + "generationQualifier": f"{X500ATTR}44", + "eduPersonAffiliation": f"{EDUPERSON_OID}1", + "eduPersonPrincipalName": f"{EDUPERSON_OID}6", + "localityName": f"{X500ATTR}7", + "owner": f"{X500ATTR}32", + "norEduOrgUnitUniqueNumber": f"{NOREDUPERSON_OID}2", + "searchGuide": f"{X500ATTR}14", + "certificateRevocationList": f"{X500ATTR}39", + "organizationalUnitName": f"{X500ATTR}11", + "userCertificate": f"{X500ATTR}36", + "preferredDeliveryMethod": f"{X500ATTR}28", + "internationaliSDNNumber": f"{X500ATTR}25", + "uniqueMember": f"{X500ATTR}50", + "departmentNumber": f"{NETSCAPE_LDAP}2", + "enhancedSearchGuide": f"{X500ATTR}47", + "userPKCS12": f"{NETSCAPE_LDAP}216", + "eduPersonTargetedID": f"{EDUPERSON_OID}10", + "norEduOrgUniqueNumber": f"{NOREDUPERSON_OID}1", + "x121Address": f"{X500ATTR}24", + "destinationIndicator": f"{X500ATTR}27", + "eduPersonPrimaryAffiliation": f"{EDUPERSON_OID}5", + "surname": f"{X500ATTR}4", + "jpegPhoto": f"{UCL_DIR_PILOT}60", + "eduPersonScopedAffiliation": f"{EDUPERSON_OID}9", + "protocolInformation": f"{X500ATTR}48", + "knowledgeInformation": f"{X500ATTR}2", + "employeeType": f"{NETSCAPE_LDAP}4", + "userSMIMECertificate": f"{NETSCAPE_LDAP}40", + "member": f"{X500ATTR}31", + "streetAddress": f"{X500ATTR}9", + "dmdName": f"{X500ATTR}54", + "postalCode": f"{X500ATTR}17", + "pseudonym": f"{X500ATTR}65", + "dnQualifier": f"{X500ATTR}46", + "crossCertificatePair": f"{X500ATTR}40", + "eduPersonOrgDN": f"{EDUPERSON_OID}3", + "authorityRevocationList": f"{X500ATTR}38", + "displayName": f"{NETSCAPE_LDAP}241", + "businessCategory": f"{X500ATTR}15", + "serialNumber": f"{X500ATTR}5", + "norEduOrgUniqueIdentifier": f"{NOREDUPERSON_OID}7", + "st": f"{X500ATTR}8", + "carLicense": f"{NETSCAPE_LDAP}1", + "presentationAddress": f"{X500ATTR}29", + "sn": f"{X500ATTR}4", + "domainComponent": f"{UCL_DIR_PILOT}25", }, } diff --git a/tests/disco_conf.py b/tests/disco_conf.py index 0eafa7074..cb1197586 100644 --- a/tests/disco_conf.py +++ b/tests/disco_conf.py @@ -7,13 +7,13 @@ BASE = "http://localhost:8088" CONFIG = { - "entityid": "%s/disco.xml" % BASE, + "entityid": f"{BASE}/disco.xml", "name": "Rolands Discoserver", "service": { "ds": { "endpoints": { "disco_service": [ - ("%s/disco" % BASE, BINDING_DISCO), + (f"{BASE}/disco", BINDING_DISCO), ] }, }, diff --git a/tests/fakeIDP.py b/tests/fakeIDP.py index b7a78b335..00dda20ef 100644 --- a/tests/fakeIDP.py +++ b/tests/fakeIDP.py @@ -1,4 +1,4 @@ -from six.moves.urllib.parse import parse_qs +from urllib.parse import parse_qs from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT @@ -22,7 +22,7 @@ def unpack_form(_str, ver="SAMLRequest"): - SR_STR = 'name="%s" value="' % ver + SR_STR = f'name="{ver}" value="' RS_STR = 'name="RelayState" value="' i = _str.find(SR_STR) @@ -40,7 +40,7 @@ def unpack_form(_str, ver="SAMLRequest"): return {ver: sr, "RelayState": rs} -class DummyResponse(object): +class DummyResponse: def __init__(self, status, data, headers=None): self.status_code = status self.text = data @@ -118,7 +118,7 @@ def authn_request_endpoint(self, req, binding, relay_state): authn_resp = self.create_authn_response(identity, userid=userid, authn=AUTHN, **resp_args) - response = "%s" % authn_resp + response = f"{authn_resp}" _dict = pack.factory(_binding, response, resp_args["destination"], relay_state, "SAMLResponse") return DummyResponse(**_dict) @@ -147,9 +147,9 @@ def attribute_query_endpoint(self, xml_str, binding): # class_name(attr_resp), # nodeid=attr_resp.id) # soap_message = _signed - response = "%s" % soap_message + response = f"{soap_message}" else: # Just POST - response = "%s" % attr_resp + response = f"{attr_resp}" return DummyResponse(status=200, data=response) @@ -172,8 +172,8 @@ def logout_endpoint(self, xml_str, binding): # class_name(attr_resp), # nodeid=attr_resp.id) # soap_message = _signed - response = "%s" % soap_message + response = f"{soap_message}" else: # Just POST - response = "%s" % _resp + response = f"{_resp}" return DummyResponse(status=200, data=response) diff --git a/tests/idp_all_conf.py b/tests/idp_all_conf.py index 08050f244..b880b9eb7 100644 --- a/tests/idp_all_conf.py +++ b/tests/idp_all_conf.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from pathutils import full_path from saml2 import BINDING_HTTP_ARTIFACT @@ -18,37 +17,37 @@ "name": "Rolands IdP", "service": { "aa": { - "endpoints": {"attribute_service": [("%s/aap" % BASE, BINDING_HTTP_POST), ("%s/aas" % BASE, BINDING_SOAP)]}, + "endpoints": {"attribute_service": [(f"{BASE}/aap", BINDING_HTTP_POST), (f"{BASE}/aas", BINDING_SOAP)]}, }, "aq": { - "endpoints": {"authn_query_service": [("%s/aqs" % BASE, BINDING_SOAP)]}, + "endpoints": {"authn_query_service": [(f"{BASE}/aqs", BINDING_SOAP)]}, }, "idp": { "endpoints": { "single_sign_on_service": [ - ("%s/sso/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/sso/post" % BASE, BINDING_HTTP_POST), - ("%s/sso/art" % BASE, BINDING_HTTP_ARTIFACT), - ("%s/sso/paos" % BASE, BINDING_SOAP), + (f"{BASE}/sso/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/sso/post", BINDING_HTTP_POST), + (f"{BASE}/sso/art", BINDING_HTTP_ARTIFACT), + (f"{BASE}/sso/paos", BINDING_SOAP), ], "single_logout_service": [ - ("%s/slo/soap" % BASE, BINDING_SOAP), - ("%s/slo/post" % BASE, BINDING_HTTP_POST), + (f"{BASE}/slo/soap", BINDING_SOAP), + (f"{BASE}/slo/post", BINDING_HTTP_POST), ], - "artifact_resolution_service": [("%s/ars" % BASE, BINDING_SOAP)], - "assertion_id_request_service": [("%s/airs" % BASE, BINDING_URI)], - "authn_query_service": [("%s/aqs" % BASE, BINDING_SOAP)], + "artifact_resolution_service": [(f"{BASE}/ars", BINDING_SOAP)], + "assertion_id_request_service": [(f"{BASE}/airs", BINDING_URI)], + "authn_query_service": [(f"{BASE}/aqs", BINDING_SOAP)], "manage_name_id_service": [ - ("%s/mni/soap" % BASE, BINDING_SOAP), - ("%s/mni/post" % BASE, BINDING_HTTP_POST), - ("%s/mni/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/mni/art" % BASE, BINDING_HTTP_ARTIFACT), + (f"{BASE}/mni/soap", BINDING_SOAP), + (f"{BASE}/mni/post", BINDING_HTTP_POST), + (f"{BASE}/mni/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/mni/art", BINDING_HTTP_ARTIFACT), ], "name_id_mapping_service": [ - ("%s/nim/soap" % BASE, BINDING_SOAP), - ("%s/nim/post" % BASE, BINDING_HTTP_POST), - ("%s/nim/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/nim/art" % BASE, BINDING_HTTP_ARTIFACT), + (f"{BASE}/nim/soap", BINDING_SOAP), + (f"{BASE}/nim/post", BINDING_HTTP_POST), + (f"{BASE}/nim/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/nim/art", BINDING_HTTP_ARTIFACT), ], }, "policy": { diff --git a/tests/idp_conf.py b/tests/idp_conf.py index 9411554d9..4f76aba04 100644 --- a/tests/idp_conf.py +++ b/tests/idp_conf.py @@ -17,8 +17,8 @@ "service": { "idp": { "endpoints": { - "single_sign_on_service": [("%s/sso" % BASE, BINDING_HTTP_REDIRECT)], - "single_logout_service": [("%s/slo" % BASE, BINDING_SOAP), ("%s/slop" % BASE, BINDING_HTTP_POST)], + "single_sign_on_service": [(f"{BASE}/sso", BINDING_HTTP_REDIRECT)], + "single_logout_service": [(f"{BASE}/slo", BINDING_SOAP), (f"{BASE}/slop", BINDING_HTTP_POST)], }, "policy": { "default": { diff --git a/tests/idp_conf_ec.py b/tests/idp_conf_ec.py index 601b8b0b7..eef4d2c92 100644 --- a/tests/idp_conf_ec.py +++ b/tests/idp_conf_ec.py @@ -17,8 +17,8 @@ "service": { "idp": { "endpoints": { - "single_sign_on_service": [("%s/sso" % BASE, BINDING_HTTP_REDIRECT)], - "single_logout_service": [("%s/slo" % BASE, BINDING_SOAP), ("%s/slop" % BASE, BINDING_HTTP_POST)], + "single_sign_on_service": [(f"{BASE}/sso", BINDING_HTTP_REDIRECT)], + "single_logout_service": [(f"{BASE}/slo", BINDING_SOAP), (f"{BASE}/slop", BINDING_HTTP_POST)], }, "policy": { "default": { diff --git a/tests/idp_conf_mdb.py b/tests/idp_conf_mdb.py index 55016ea29..fb5d325d4 100644 --- a/tests/idp_conf_mdb.py +++ b/tests/idp_conf_mdb.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from pathutils import full_path from saml2 import BINDING_HTTP_ARTIFACT @@ -14,41 +13,41 @@ BASE = "http://localhost:8088" CONFIG = { - "entityid": "%s/saml/idp" % BASE, + "entityid": f"{BASE}/saml/idp", "name": "Rolands IdP", "service": { "aa": { - "endpoints": {"attribute_service": [("%s/aap" % BASE, BINDING_HTTP_POST), ("%s/aas" % BASE, BINDING_SOAP)]}, + "endpoints": {"attribute_service": [(f"{BASE}/aap", BINDING_HTTP_POST), (f"{BASE}/aas", BINDING_SOAP)]}, }, "aq": { - "endpoints": {"authn_query_service": [("%s/aqs" % BASE, BINDING_SOAP)]}, + "endpoints": {"authn_query_service": [(f"{BASE}/aqs", BINDING_SOAP)]}, }, "idp": { "endpoints": { "single_sign_on_service": [ - ("%s/sso/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/sso/post" % BASE, BINDING_HTTP_POST), - ("%s/sso/art" % BASE, BINDING_HTTP_ARTIFACT), - ("%s/sso/paos" % BASE, BINDING_SOAP), + (f"{BASE}/sso/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/sso/post", BINDING_HTTP_POST), + (f"{BASE}/sso/art", BINDING_HTTP_ARTIFACT), + (f"{BASE}/sso/paos", BINDING_SOAP), ], "single_logout_service": [ - ("%s/slo/soap" % BASE, BINDING_SOAP), - ("%s/slo/post" % BASE, BINDING_HTTP_POST), + (f"{BASE}/slo/soap", BINDING_SOAP), + (f"{BASE}/slo/post", BINDING_HTTP_POST), ], - "artifact_resolution_service": [("%s/ars" % BASE, BINDING_SOAP)], - "assertion_id_request_service": [("%s/airs" % BASE, BINDING_URI)], - "authn_query_service": [("%s/aqs" % BASE, BINDING_SOAP)], + "artifact_resolution_service": [(f"{BASE}/ars", BINDING_SOAP)], + "assertion_id_request_service": [(f"{BASE}/airs", BINDING_URI)], + "authn_query_service": [(f"{BASE}/aqs", BINDING_SOAP)], "manage_name_id_service": [ - ("%s/mni/soap" % BASE, BINDING_SOAP), - ("%s/mni/post" % BASE, BINDING_HTTP_POST), - ("%s/mni/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/mni/art" % BASE, BINDING_HTTP_ARTIFACT), + (f"{BASE}/mni/soap", BINDING_SOAP), + (f"{BASE}/mni/post", BINDING_HTTP_POST), + (f"{BASE}/mni/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/mni/art", BINDING_HTTP_ARTIFACT), ], "name_id_mapping_service": [ - ("%s/nim/soap" % BASE, BINDING_SOAP), - ("%s/nim/post" % BASE, BINDING_HTTP_POST), - ("%s/nim/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/nim/art" % BASE, BINDING_HTTP_ARTIFACT), + (f"{BASE}/nim/soap", BINDING_SOAP), + (f"{BASE}/nim/post", BINDING_HTTP_POST), + (f"{BASE}/nim/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/nim/art", BINDING_HTTP_ARTIFACT), ], }, "policy": { diff --git a/tests/idp_conf_mdb2.py b/tests/idp_conf_mdb2.py index ad766ee68..3a4b9e7dc 100644 --- a/tests/idp_conf_mdb2.py +++ b/tests/idp_conf_mdb2.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from pathutils import full_path from saml2 import BINDING_HTTP_ARTIFACT @@ -14,41 +13,41 @@ BASE = "http://localhost:8089" CONFIG = { - "entityid": "%s/saml/idp2" % BASE, + "entityid": f"{BASE}/saml/idp2", "name": "Rolands 2nd IdP", "service": { "aa": { - "endpoints": {"attribute_service": [("%s/aap" % BASE, BINDING_HTTP_POST), ("%s/aas" % BASE, BINDING_SOAP)]}, + "endpoints": {"attribute_service": [(f"{BASE}/aap", BINDING_HTTP_POST), (f"{BASE}/aas", BINDING_SOAP)]}, }, "aq": { - "endpoints": {"authn_query_service": [("%s/aqs" % BASE, BINDING_SOAP)]}, + "endpoints": {"authn_query_service": [(f"{BASE}/aqs", BINDING_SOAP)]}, }, "idp": { "endpoints": { "single_sign_on_service": [ - ("%s/sso/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/sso/post" % BASE, BINDING_HTTP_POST), - ("%s/sso/art" % BASE, BINDING_HTTP_ARTIFACT), - ("%s/sso/paos" % BASE, BINDING_SOAP), + (f"{BASE}/sso/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/sso/post", BINDING_HTTP_POST), + (f"{BASE}/sso/art", BINDING_HTTP_ARTIFACT), + (f"{BASE}/sso/paos", BINDING_SOAP), ], "single_logout_service": [ - ("%s/slo/soap" % BASE, BINDING_SOAP), - ("%s/slo/post" % BASE, BINDING_HTTP_POST), + (f"{BASE}/slo/soap", BINDING_SOAP), + (f"{BASE}/slo/post", BINDING_HTTP_POST), ], - "artifact_resolution_service": [("%s/ars" % BASE, BINDING_SOAP)], - "assertion_id_request_service": [("%s/airs" % BASE, BINDING_URI)], - "authn_query_service": [("%s/aqs" % BASE, BINDING_SOAP)], + "artifact_resolution_service": [(f"{BASE}/ars", BINDING_SOAP)], + "assertion_id_request_service": [(f"{BASE}/airs", BINDING_URI)], + "authn_query_service": [(f"{BASE}/aqs", BINDING_SOAP)], "manage_name_id_service": [ - ("%s/mni/soap" % BASE, BINDING_SOAP), - ("%s/mni/post" % BASE, BINDING_HTTP_POST), - ("%s/mni/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/mni/art" % BASE, BINDING_HTTP_ARTIFACT), + (f"{BASE}/mni/soap", BINDING_SOAP), + (f"{BASE}/mni/post", BINDING_HTTP_POST), + (f"{BASE}/mni/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/mni/art", BINDING_HTTP_ARTIFACT), ], "name_id_mapping_service": [ - ("%s/nim/soap" % BASE, BINDING_SOAP), - ("%s/nim/post" % BASE, BINDING_HTTP_POST), - ("%s/nim/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/nim/art" % BASE, BINDING_HTTP_ARTIFACT), + (f"{BASE}/nim/soap", BINDING_SOAP), + (f"{BASE}/nim/post", BINDING_HTTP_POST), + (f"{BASE}/nim/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/nim/art", BINDING_HTTP_ARTIFACT), ], }, "policy": { diff --git a/tests/idp_conf_sp_no_encrypt.py b/tests/idp_conf_sp_no_encrypt.py index 614b1a3e0..b47e4efef 100644 --- a/tests/idp_conf_sp_no_encrypt.py +++ b/tests/idp_conf_sp_no_encrypt.py @@ -16,8 +16,8 @@ "service": { "idp": { "endpoints": { - "single_sign_on_service": [("%s/sso" % BASE, BINDING_HTTP_REDIRECT)], - "single_logout_service": [("%s/slo" % BASE, BINDING_SOAP), ("%s/slop" % BASE, BINDING_HTTP_POST)], + "single_sign_on_service": [(f"{BASE}/sso", BINDING_HTTP_REDIRECT)], + "single_logout_service": [(f"{BASE}/slo", BINDING_SOAP), (f"{BASE}/slop", BINDING_HTTP_POST)], }, "policy": { "default": { diff --git a/tests/idp_conf_verify_cert.py b/tests/idp_conf_verify_cert.py index 1536385a8..e6c522993 100644 --- a/tests/idp_conf_verify_cert.py +++ b/tests/idp_conf_verify_cert.py @@ -27,8 +27,8 @@ def verify_encrypt_cert(cert_str): "verify_encrypt_cert_advice": verify_encrypt_cert, "verify_encrypt_cert_assertion": verify_encrypt_cert, "endpoints": { - "single_sign_on_service": [("%s/sso" % BASE, BINDING_HTTP_REDIRECT)], - "single_logout_service": [("%s/slo" % BASE, BINDING_SOAP), ("%s/slop" % BASE, BINDING_HTTP_POST)], + "single_sign_on_service": [(f"{BASE}/sso", BINDING_HTTP_REDIRECT)], + "single_logout_service": [(f"{BASE}/slo", BINDING_SOAP), (f"{BASE}/slop", BINDING_HTTP_POST)], }, "policy": { "default": { diff --git a/tests/idp_sp_conf.py b/tests/idp_sp_conf.py index e9f4466f2..32aecfa28 100644 --- a/tests/idp_sp_conf.py +++ b/tests/idp_sp_conf.py @@ -18,8 +18,8 @@ "service": { "idp": { "endpoints": { - "single_sign_on_service": [(BASE + "sso", BINDING_HTTP_REDIRECT)], - "single_logout_service": [(BASE + "slo", BINDING_SOAP), (BASE + "slop", BINDING_HTTP_POST)], + "single_sign_on_service": [(f"{BASE}sso", BINDING_HTTP_REDIRECT)], + "single_logout_service": [(f"{BASE}slo", BINDING_SOAP), (f"{BASE}slop", BINDING_HTTP_POST)], }, "policy": { "default": { diff --git a/tests/idp_test/target_idp.py b/tests/idp_test/target_idp.py index edb21689c..bafb538d6 100755 --- a/tests/idp_test/target_idp.py +++ b/tests/idp_test/target_idp.py @@ -7,8 +7,6 @@ import json from saml2 import xmldsig as ds -from saml2.saml import NAME_FORMAT_BASIC -from saml2.saml import NAME_FORMAT_UNSPECIFIED from saml2.saml import NAME_FORMAT_URI @@ -17,20 +15,20 @@ metadata = open("./idp/idp.xml").read() info = { - "entity_id": "%s/idp.xml" % BASE, + "entity_id": f"{BASE}/idp.xml", "interaction": [ { - "matches": {"url": "%s/sso/redirect" % BASE, "title": "IDP test login"}, + "matches": {"url": f"{BASE}/sso/redirect", "title": "IDP test login"}, "page-type": "login", "control": {"type": "form", "set": {"login": "roland", "password": "dianakra"}}, }, { - "matches": {"url": "%s/sso/post" % BASE, "title": "IDP test login"}, + "matches": {"url": f"{BASE}/sso/post", "title": "IDP test login"}, "page-type": "login", "control": {"type": "form", "set": {"login": "roland", "password": "dianakra"}}, }, { - "matches": {"url": "%s/sso/redirect" % BASE, "title": "SAML 2.0 POST"}, + "matches": {"url": f"{BASE}/sso/redirect", "title": "SAML 2.0 POST"}, "page-type": "other", "control": { "index": 0, @@ -38,12 +36,12 @@ }, }, { - "matches": {"url": "%s/sso/post" % BASE, "title": "SAML 2.0 POST"}, + "matches": {"url": f"{BASE}/sso/post", "title": "SAML 2.0 POST"}, "page-type": "other", "control": {"index": 0, "type": "form", "set": {}}, }, { - "matches": {"url": "%s/slo/post" % BASE, "title": "SAML 2.0 POST"}, + "matches": {"url": f"{BASE}/slo/post", "title": "SAML 2.0 POST"}, "page-type": "other", "control": {"index": 0, "type": "form", "set": {}}, }, diff --git a/tests/localhost.py b/tests/localhost.py index 1e715b8b3..762bd5b3f 100755 --- a/tests/localhost.py +++ b/tests/localhost.py @@ -12,25 +12,25 @@ metadata = open("idp_test/idp.xml").read() info = { - "entity_id": "%s/idp.xml" % BASE, + "entity_id": f"{BASE}/idp.xml", "interaction": [ { - "matches": {"url": "%s/login" % BASE, "title": "IDP test login"}, + "matches": {"url": f"{BASE}/login", "title": "IDP test login"}, "page-type": "login", "control": {"type": "form", "set": {"login": "roland", "password": "dianakra"}}, }, { - "matches": {"url": "%s/sso/redirect" % BASE, "title": "SAML 2.0 POST"}, + "matches": {"url": f"{BASE}/sso/redirect", "title": "SAML 2.0 POST"}, "page-type": "other", "control": {"index": 0, "type": "form", "set": {}}, }, { - "matches": {"url": "%s/sso/post" % BASE, "title": "SAML 2.0 POST"}, + "matches": {"url": f"{BASE}/sso/post", "title": "SAML 2.0 POST"}, "page-type": "other", "control": {"index": 0, "type": "form", "set": {}}, }, { - "matches": {"url": "%s/slo/post" % BASE, "title": "SAML 2.0 POST"}, + "matches": {"url": f"{BASE}/slo/post", "title": "SAML 2.0 POST"}, "page-type": "other", "control": {"index": 0, "type": "form", "set": {}}, }, diff --git a/tests/otest_61_makemeta.py b/tests/otest_61_makemeta.py index 581f20dd9..22a117763 100644 --- a/tests/otest_61_makemeta.py +++ b/tests/otest_61_makemeta.py @@ -2,7 +2,6 @@ from saml2 import BINDING_HTTP_POST from saml2 import extension_elements_to_elements from saml2 import md -from saml2 import mdstore from saml2.attribute_converter import ac_factory from saml2.config import IdPConfig from saml2.config import SPConfig diff --git a/tests/pathutils.py b/tests/pathutils.py index ce59bc969..1f10b0b95 100644 --- a/tests/pathutils.py +++ b/tests/pathutils.py @@ -10,7 +10,7 @@ def full_path(local_file): def dotname(module): if not BASEDIR.endswith("tests"): - return "tests." + module + return f"tests.{module}" else: return module diff --git a/tests/restrictive_idp_conf.py b/tests/restrictive_idp_conf.py index 67b4ec50b..70d78bced 100644 --- a/tests/restrictive_idp_conf.py +++ b/tests/restrictive_idp_conf.py @@ -14,8 +14,8 @@ "service": { "idp": { "endpoints": { - "single_sign_on_service": [(BASE + "sso", BINDING_HTTP_REDIRECT)], - "attribute_service": [(BASE + "aa", BINDING_SOAP)], + "single_sign_on_service": [(f"{BASE}sso", BINDING_HTTP_REDIRECT)], + "attribute_service": [(f"{BASE}aa", BINDING_SOAP)], }, "policy": { "default": {"lifetime": {"minutes": 15}, "name_form": NAME_FORMAT_URI}, diff --git a/tests/servera_conf.py b/tests/servera_conf.py index b7fb487d6..7277568c3 100644 --- a/tests/servera_conf.py +++ b/tests/servera_conf.py @@ -23,19 +23,19 @@ "sp": { "endpoints": { "assertion_consumer_service": [ - ("%s/" % BASE, BINDING_HTTP_POST), - ("%s/paos" % BASE, BINDING_PAOS), - ("%s/redirect" % BASE, BINDING_HTTP_REDIRECT), + (f"{BASE}/", BINDING_HTTP_POST), + (f"{BASE}/paos", BINDING_PAOS), + (f"{BASE}/redirect", BINDING_HTTP_REDIRECT), ], - "artifact_resolution_service": [("%s/ars" % BASE, BINDING_SOAP)], + "artifact_resolution_service": [(f"{BASE}/ars", BINDING_SOAP)], "manage_name_id_service": [ - ("%s/mni/soap" % BASE, BINDING_SOAP), - ("%s/mni/post" % BASE, BINDING_HTTP_POST), - ("%s/mni/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/mni/art" % BASE, BINDING_HTTP_ARTIFACT), + (f"{BASE}/mni/soap", BINDING_SOAP), + (f"{BASE}/mni/post", BINDING_HTTP_POST), + (f"{BASE}/mni/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/mni/art", BINDING_HTTP_ARTIFACT), ], - "single_logout_service": [("%s/sls" % BASE, BINDING_SOAP)], - "discovery_response": [("%s/disco" % BASE, BINDING_DISCO)], + "single_logout_service": [(f"{BASE}/sls", BINDING_SOAP)], + "discovery_response": [(f"{BASE}/disco", BINDING_DISCO)], }, "required_attributes": ["surName", "givenName", "mail"], "optional_attributes": ["title", "eduPersonAffiliation"], diff --git a/tests/sp_slo_redirect_conf.py b/tests/sp_slo_redirect_conf.py index fee16f7e8..696bee1db 100644 --- a/tests/sp_slo_redirect_conf.py +++ b/tests/sp_slo_redirect_conf.py @@ -2,8 +2,6 @@ from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT -from saml2.saml import NAME_FORMAT_URI -from saml2.saml import NAMEID_FORMAT_PERSISTENT HOME = "http://lingon.catalogix.se:8087/" @@ -15,7 +13,7 @@ "sp": { "endpoints": { "assertion_consumer_service": [(HOME, BINDING_HTTP_POST)], - "single_logout_service": [(HOME + "slo", BINDING_HTTP_REDIRECT)], + "single_logout_service": [(f"{HOME}slo", BINDING_HTTP_REDIRECT)], }, "required_attributes": ["surName", "givenName", "mail"], "optional_attributes": ["title"], diff --git a/tests/sp_test/config.py b/tests/sp_test/config.py index 0b3177a4f..d7ad0e41c 100644 --- a/tests/sp_test/config.py +++ b/tests/sp_test/config.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_URI @@ -23,24 +22,24 @@ BASE = "http://localhost:8088" CONFIG = { - "entityid": "%s/idp.xml" % BASE, + "entityid": f"{BASE}/idp.xml", "description": "My IDP", "service": { "idp": { "name": "Rolands IdP", "endpoints": { "single_sign_on_service": [ - ("%s/sso/redirect" % BASE, BINDING_HTTP_REDIRECT), - ("%s/sso/post" % BASE, BINDING_HTTP_POST), + (f"{BASE}/sso/redirect", BINDING_HTTP_REDIRECT), + (f"{BASE}/sso/post", BINDING_HTTP_POST), ], "single_logout_service": [ - ("%s/slo/post" % BASE, BINDING_HTTP_POST), - ("%s/slo/redirect" % BASE, BINDING_HTTP_REDIRECT), + (f"{BASE}/slo/post", BINDING_HTTP_POST), + (f"{BASE}/slo/redirect", BINDING_HTTP_REDIRECT), ], - "assertion_id_request_service": [("%s/airs" % BASE, BINDING_URI)], + "assertion_id_request_service": [(f"{BASE}/airs", BINDING_URI)], "manage_name_id_service": [ - ("%s/mni/post" % BASE, BINDING_HTTP_POST), - ("%s/mni/redirect" % BASE, BINDING_HTTP_REDIRECT), + (f"{BASE}/mni/post", BINDING_HTTP_POST), + (f"{BASE}/mni/redirect", BINDING_HTTP_REDIRECT), ], }, "policy": { diff --git a/tests/sp_test/targetsp.py b/tests/sp_test/targetsp.py index f47269dce..225930aea 100755 --- a/tests/sp_test/targetsp.py +++ b/tests/sp_test/targetsp.py @@ -16,7 +16,7 @@ info = { "start_page": BASE, - "entity_id": "%s/sp.xml" % BASE, + "entity_id": f"{BASE}/sp.xml", "result": { "matches": {"content": "

Your identity are"}, }, diff --git a/tests/test_00_xmldsig.py b/tests/test_00_xmldsig.py index 5f6ac2f30..059e8a049 100644 --- a/tests/test_00_xmldsig.py +++ b/tests/test_00_xmldsig.py @@ -7,12 +7,6 @@ import unittest - -try: - from xml.etree import ElementTree -except ImportError: - from elementtree import ElementTree - import ds_data import saml2.xmldsig as ds diff --git a/tests/test_02_saml.py b/tests/test_02_saml.py index b231a9c13..a090d89f2 100644 --- a/tests/test_02_saml.py +++ b/tests/test_02_saml.py @@ -1,15 +1,10 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """Tests for saml2.saml""" __author__ = "roland.hedberg@adm.umu.se (Roland Hedberg)" -try: - from xml.etree import ElementTree -except ImportError: - from elementtree import ElementTree import ds_data from pytest import raises @@ -1101,7 +1096,6 @@ def testAccessors(self): def testUsingTestData(self): """Test evidence_from_string() using test data""" # TODO: - pass class TestAuthzDecisionStatement: @@ -1126,7 +1120,6 @@ def testAccessors(self): def testUsingTestData(self): """Test authz_decision_statement_from_string() using test data""" # TODO: - pass class TestAdvice: @@ -1149,7 +1142,6 @@ def testAccessors(self): def testUsingTestData(self): """Test advice_from_string() using test data""" # TODO: - pass class TestAssertion: @@ -1190,7 +1182,6 @@ def testAccessors(self): def testUsingTestData(self): """Test assertion_from_string() using test data""" # TODO - pass if __name__ == "__main__": diff --git a/tests/test_03_saml2.py b/tests/test_03_saml2.py index 4ce554332..b96afd9c1 100644 --- a/tests/test_03_saml2.py +++ b/tests/test_03_saml2.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from defusedxml.common import EntitiesForbidden from pytest import raises import saml2_data @@ -9,7 +10,6 @@ from saml2 import make_vals from saml2 import md from saml2.saml import Attribute -from saml2.saml import AuthnContextClassRef from saml2.saml import Issuer from saml2.saml import NameID from saml2.saml import SubjectConfirmation @@ -17,17 +17,6 @@ from saml2.saml import SubjectLocality -try: - from xml.etree import cElementTree as ElementTree -except ImportError: - try: - import cElementTree as ElementTree - except ImportError: - from elementtree import ElementTree - -from defusedxml.common import EntitiesForbidden - - ITEMS = { NameID: [ """ diff --git a/tests/test_04_samlp.py b/tests/test_04_samlp.py index 421422893..97e6cdb9a 100644 --- a/tests/test_04_samlp.py +++ b/tests/test_04_samlp.py @@ -1,16 +1,10 @@ #!/usr/bin/env pythony -# -*- coding: utf-8 -*- # """Tests for saml2.samlp""" __author__ = "roland.hedberg@adm.umu.se (Roland Hedberg)" -try: - from xml.etree import ElementTree -except ImportError: - from elementtree import ElementTree - import samlp_data import saml2 @@ -58,7 +52,6 @@ def setup_class(self): def testAccessors(self): """Test for StatusDetail accessors""" # TODO: - pass class TestStatusMessage: @@ -68,7 +61,6 @@ def setup_class(self): def testAccessors(self): """Test for StatusMessage accessors""" # TODO: - pass class TestStatusCode: @@ -187,7 +179,6 @@ def testAccessors(self): def testUsingTestData(self): """Test for response_from_string() using test data""" # TODO: - pass class TestNameIDPolicy: diff --git a/tests/test_05_md.py b/tests/test_05_md.py index ebd88059b..a06723b14 100644 --- a/tests/test_05_md.py +++ b/tests/test_05_md.py @@ -1,19 +1,10 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # """Tests for saml2.md""" __author__ = "roland.hedberg@umu.se (Roland Hedberg)" -import unittest - - -try: - from xml.etree import ElementTree -except ImportError: - from elementtree import ElementTree - import ds_data import md_data diff --git a/tests/test_10_time_util.py b/tests/test_10_time_util.py index 12a2c1d43..80e77ac30 100644 --- a/tests/test_10_time_util.py +++ b/tests/test_10_time_util.py @@ -138,7 +138,7 @@ def test_instant(): def test_valid(): assert valid("2000-01-12T00:00:00Z") == False current_year = datetime.datetime.today().year - assert valid("%d-01-12T00:00:00Z" % (current_year + 1)) == True + assert valid(f"{int(current_year + 1)}-01-12T00:00:00Z") == True this_instance = instant() time.sleep(1) assert valid(this_instance) is False # unless on a very fast machine :-) @@ -154,26 +154,26 @@ def test_timeout(): def test_before(): current_year = datetime.datetime.today().year - assert before("%d-01-01T00:00:00Z" % (current_year - 1)) == False - assert before("%d-01-01T00:00:00Z" % (current_year + 1)) == True + assert before(f"{int(current_year - 1)}-01-01T00:00:00Z") == False + assert before(f"{int(current_year + 1)}-01-01T00:00:00Z") == True def test_after(): current_year = datetime.datetime.today().year - assert after("%d-01-01T00:00:00Z" % (current_year + 1)) == False - assert after("%d-01-01T00:00:00Z" % (current_year - 1)) == True + assert after(f"{int(current_year + 1)}-01-01T00:00:00Z") == False + assert after(f"{int(current_year - 1)}-01-01T00:00:00Z") == True def test_not_before(): current_year = datetime.datetime.today().year - assert not_before("%d-01-01T00:00:00Z" % (current_year + 1)) == False - assert not_before("%d-01-01T00:00:00Z" % (current_year - 1)) == True + assert not_before(f"{int(current_year + 1)}-01-01T00:00:00Z") == False + assert not_before(f"{int(current_year - 1)}-01-01T00:00:00Z") == True def test_not_on_or_after(): current_year = datetime.datetime.today().year - assert not_on_or_after("%d-01-01T00:00:00Z" % (current_year + 1)) == True - assert not_on_or_after("%d-01-01T00:00:00Z" % (current_year - 1)) == False + assert not_on_or_after(f"{int(current_year + 1)}-01-01T00:00:00Z") == True + assert not_on_or_after(f"{int(current_year - 1)}-01-01T00:00:00Z") == False if __name__ == "__main__": diff --git a/tests/test_12_s_utils.py b/tests/test_12_s_utils.py index be9b1d472..454cd0bb1 100644 --- a/tests/test_12_s_utils.py +++ b/tests/test_12_s_utils.py @@ -1,10 +1,8 @@ # !/usr/bin/env python -# -*- coding: utf-8 -*- import base64 from pathutils import full_path -import six from saml2 import s_utils as utils from saml2 import saml @@ -23,7 +21,7 @@ ":StatusCode " 'Value="urn:oasis:names:tc:SAML:2.0:status:Success" />' ) -SUCCESS_STATUS = "%s%s" % (XML_HEADER, SUCCESS_STATUS_NO_HEADER) +SUCCESS_STATUS = f"{XML_HEADER}{SUCCESS_STATUS_NO_HEADER}" ERROR_STATUS_NO_HEADER = ( '" ) -ERROR_STATUS = "%s%s" % (XML_HEADER, ERROR_STATUS_NO_HEADER) -ERROR_STATUS_EMPTY = "%s%s" % (XML_HEADER, ERROR_STATUS_NO_HEADER_EMPTY) +ERROR_STATUS = f"{XML_HEADER}{ERROR_STATUS_NO_HEADER}" +ERROR_STATUS_EMPTY = f"{XML_HEADER}{ERROR_STATUS_NO_HEADER_EMPTY}" def _eq(l1, l2): @@ -56,9 +54,9 @@ def _oeq(l1, l2): return False for item in l1: if item not in l2: - print("%s not in l2" % (item,)) + print(f"{item} not in l2") for ite in l2: - print("\t%s" % (ite,)) + print(f"\t{ite}") return False return True @@ -67,19 +65,19 @@ def test_inflate_then_deflate(): txt = """Selma Lagerlöf (1858-1940) was born in Östra Emterwik, Värmland, Sweden. She was brought up on Mårbacka, the family estate, which she did not leave until 1881, when she went to a teachers' college at Stockholm""" - if not isinstance(txt, six.binary_type): + if not isinstance(txt, bytes): txt = txt.encode("utf-8") interm = utils.deflate_and_base64_encode(txt) bis = utils.decode_base64_and_inflate(interm) - if not isinstance(bis, six.binary_type): + if not isinstance(bis, bytes): bis = bis.encode("utf-8") assert bis == txt def test_status_success(): status = utils.success_status_factory() - status_text = "%s" % status + status_text = f"{status}" assert status_text in (SUCCESS_STATUS_NO_HEADER, SUCCESS_STATUS) assert status.status_code.value == samlp.STATUS_SUCCESS @@ -89,7 +87,7 @@ def test_error_status(): "Error resolving principal", samlp.STATUS_UNKNOWN_PRINCIPAL, samlp.STATUS_RESPONDER ) - status_text = "%s" % status + status_text = f"{status}" print(status_text) assert status_text in (ERROR_STATUS_NO_HEADER, ERROR_STATUS) @@ -97,20 +95,20 @@ def test_error_status(): def test_status_from_exception(): e = utils.UnknownPrincipal("Error resolving principal") stat = utils.error_status_factory(e) - status_text = "%s" % stat + status_text = f"{stat}" print(status_text) assert status_text in (ERROR_STATUS_NO_HEADER, ERROR_STATUS) def test_status_from_tuple(): stat = utils.error_status_factory((samlp.STATUS_UNKNOWN_PRINCIPAL, "Error resolving principal")) - status_text = "%s" % stat + status_text = f"{stat}" assert status_text in (ERROR_STATUS_NO_HEADER, ERROR_STATUS) def test_status_from_tuple_empty_message(): stat = utils.error_status_factory((samlp.STATUS_UNKNOWN_PRINCIPAL, None)) - status_text = "%s" % stat + status_text = f"{stat}" assert status_text in (ERROR_STATUS_EMPTY, ERROR_STATUS_NO_HEADER_EMPTY) @@ -153,7 +151,7 @@ def test_attribute_onoff(): def test_attribute_base64(): txt = "Selma Lagerlöf" - if not isinstance(txt, six.binary_type): + if not isinstance(txt, bytes): txt = txt.encode("utf-8") b64sl = base64.b64encode(txt).decode("ascii") attr = utils.do_attributes({"name": (b64sl, "xs:base64Binary")}) diff --git a/tests/test_13_validate.py b/tests/test_13_validate.py index 91ce00527..05e63a192 100644 --- a/tests/test_13_validate.py +++ b/tests/test_13_validate.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from pytest import raises diff --git a/tests/test_19_attribute_converter.py b/tests/test_19_attribute_converter.py index f1db43af1..4f3a5fbc5 100644 --- a/tests/test_19_attribute_converter.py +++ b/tests/test_19_attribute_converter.py @@ -10,11 +10,8 @@ from saml2.attribute_converter import from_local from saml2.attribute_converter import to_local import saml2.attributemaps.saml_uri as saml_map -from saml2.saml import NAMEID_FORMAT_PERSISTENT -from saml2.saml import NameID from saml2.saml import attribute_from_string from saml2.saml import attribute_statement_from_string -from saml2.saml import name_id_from_string def _eq(l1, l2): diff --git a/tests/test_20_assertion.py b/tests/test_20_assertion.py index 3568b7a52..c40bde4bb 100644 --- a/tests/test_20_assertion.py +++ b/tests/test_20_assertion.py @@ -1,6 +1,3 @@ -# coding=utf-8 -import copy - from pathutils import full_path from pytest import raises diff --git a/tests/test_22_mdie.py b/tests/test_22_mdie.py index 6f7a9780b..f117ecd84 100644 --- a/tests/test_22_mdie.py +++ b/tests/test_22_mdie.py @@ -13,7 +13,7 @@ def _eq(l1, l2): def _class(cls): - return "%s&%s" % (cls.c_namespace, cls.c_tag) + return f"{cls.c_namespace}&{cls.c_tag}" def test_construct_contact(): diff --git a/tests/test_30_mdstore.py b/tests/test_30_mdstore.py index 81847b2ac..1c67a7018 100644 --- a/tests/test_30_mdstore.py +++ b/tests/test_30_mdstore.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from collections import OrderedDict import datetime import os @@ -7,11 +6,11 @@ from re import compile as regex_compile from unittest.mock import Mock from unittest.mock import patch +from urllib import parse from pathutils import full_path from pytest import raises import responses -from six.moves.urllib import parse from saml2 import BINDING_HTTP_ARTIFACT from saml2 import BINDING_HTTP_POST @@ -200,7 +199,7 @@ def _eq(l1, l2): def _fix_valid_until(xmlstring): new_date = datetime.datetime.now() + datetime.timedelta(days=1) new_date = new_date.strftime("%Y-%m-%dT%H:%M:%SZ") - return re.sub(r' validUntil=".*?"', ' validUntil="%s"' % new_date, xmlstring) + return re.sub(r' validUntil=".*?"', f' validUntil="{new_date}"', xmlstring) def test_invalid_metadata(): @@ -345,7 +344,7 @@ def test_metadata_file(): def test_mdx_service(): entity_id = "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php" - url = "http://mdx.example.com/entities/{}".format(parse.quote_plus(MetaDataMDX.sha1_entity_transform(entity_id))) + url = f"http://mdx.example.com/entities/{parse.quote_plus(MetaDataMDX.sha1_entity_transform(entity_id))}" responses.add(responses.GET, url, body=TEST_METADATA_STRING, status=200, content_type=SAML_METADATA_CONTENT_TYPE) mdx = MetaDataMDX("http://mdx.example.com") @@ -361,7 +360,7 @@ def test_mdx_service(): @patch("saml2.httpbase.requests.get") def test_mdx_service_request_timeout(mock_request): entity_id = "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php" - url = "http://mdx.example.com/entities/{}".format(MetaDataMDX.sha1_entity_transform(entity_id)) + url = f"http://mdx.example.com/entities/{MetaDataMDX.sha1_entity_transform(entity_id)}" mdx = MetaDataMDX("http://mdx.example.com", http_client_timeout=10) mdx.service(entity_id, "idpsso_descriptor", "single_sign_on_service") @@ -372,7 +371,7 @@ def test_mdx_service_request_timeout(mock_request): def test_mdx_single_sign_on_service(): entity_id = "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php" - url = "http://mdx.example.com/entities/{}".format(parse.quote_plus(MetaDataMDX.sha1_entity_transform(entity_id))) + url = f"http://mdx.example.com/entities/{parse.quote_plus(MetaDataMDX.sha1_entity_transform(entity_id))}" responses.add(responses.GET, url, body=TEST_METADATA_STRING, status=200, content_type=SAML_METADATA_CONTENT_TYPE) mdx = MetaDataMDX("http://mdx.example.com") @@ -385,7 +384,7 @@ def test_mdx_metadata_freshness_period_not_expired(): """Ensure that metadata is not refreshed if not expired.""" entity_id = "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php" - url = "http://mdx.example.com/entities/{}".format(parse.quote_plus(MetaDataMDX.sha1_entity_transform(entity_id))) + url = f"http://mdx.example.com/entities/{parse.quote_plus(MetaDataMDX.sha1_entity_transform(entity_id))}" responses.add( responses.GET, @@ -410,7 +409,7 @@ def test_mdx_metadata_freshness_period_expired(): """Ensure that metadata is not refreshed if not expired.""" entity_id = "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php" - url = "http://mdx.example.com/entities/{}".format(parse.quote_plus(MetaDataMDX.sha1_entity_transform(entity_id))) + url = f"http://mdx.example.com/entities/{parse.quote_plus(MetaDataMDX.sha1_entity_transform(entity_id))}" responses.add( responses.GET, diff --git a/tests/test_30_mdstore_old.py b/tests/test_30_mdstore_old.py index 44ed6c1f9..412d54c65 100644 --- a/tests/test_30_mdstore_old.py +++ b/tests/test_30_mdstore_old.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import datetime import os import re @@ -12,12 +11,9 @@ from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_SOAP from saml2 import config -from saml2 import md -from saml2 import saml from saml2 import sigver from saml2.attribute_converter import ac_factory from saml2.attribute_converter import d_to_local_name -from saml2.mdstore import MetaDataMDX from saml2.mdstore import MetadataStore from saml2.mdstore import locations from saml2.mdstore import name @@ -117,7 +113,7 @@ def _eq(l1, l2): def _fix_valid_until(xmlstring): new_date = datetime.datetime.now() + datetime.timedelta(days=1) new_date = new_date.strftime("%Y-%m-%dT%H:%M:%SZ") - return re.sub(r' validUntil=".*?"', ' validUntil="%s"' % new_date, xmlstring) + return re.sub(r' validUntil=".*?"', f' validUntil="{new_date}"', xmlstring) def test_swami_1(): diff --git a/tests/test_31_config.py b/tests/test_31_config.py index 21fe5a6f6..c7741c466 100644 --- a/tests/test_31_config.py +++ b/tests/test_31_config.py @@ -1,15 +1,11 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- -import logging -import sys from pathutils import dotname from pathutils import full_path from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_SOAP -from saml2 import logger from saml2.authn_context import PASSWORDPROTECTEDTRANSPORT as AUTHN_PASSWORD_PROTECTED from saml2.authn_context import TIMESYNCTOKEN as AUTHN_TIME_SYNC_TOKEN from saml2.config import Config diff --git a/tests/test_33_identifier.py b/tests/test_33_identifier.py index 959b9da3f..46d9ce41a 100644 --- a/tests/test_33_identifier.py +++ b/tests/test_33_identifier.py @@ -64,8 +64,8 @@ class TestIdentifier: def setup_class(self): for extension in (".db", ".dir", ".dat", ".bak"): try: - os.remove(full_path("subject.db{}".format(extension))) - except (OSError, IOError): + os.remove(full_path(f"subject.db{extension}")) + except OSError: pass self.id = IdentDB(full_path("subject.db"), "example.com", "example") diff --git a/tests/test_37_entity_categories.py b/tests/test_37_entity_categories.py index da7b6f4f0..10beb17d8 100644 --- a/tests/test_37_entity_categories.py +++ b/tests/test_37_entity_categories.py @@ -11,7 +11,6 @@ from saml2.mdie import to_dict from saml2.mdstore import MetadataStore from saml2.saml import NAME_FORMAT_URI -from saml2.saml import Attribute from saml2.server import Server diff --git a/tests/test_40_sigver.py b/tests/test_40_sigver.py index 446caba86..f026fa393 100644 --- a/tests/test_40_sigver.py +++ b/tests/test_40_sigver.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import base64 @@ -184,7 +183,7 @@ def test_non_verify_1(self): def test_sign_assertion(self): ass = self._assertion print(ass) - sign_ass = self.sec.sign_assertion("%s" % ass, node_id=ass.id) + sign_ass = self.sec.sign_assertion(f"{ass}", node_id=ass.id) # print(sign_ass) sass = saml.assertion_from_string(sign_ass) # print(sass) @@ -193,7 +192,7 @@ def test_sign_assertion(self): assert sass.id == "id-11111" assert time_util.str_to_time(sass.issue_instant) - print("Crypto version : %s" % (self.sec.crypto.version())) + print(f"Crypto version : {self.sec.crypto.version()}") item = self.sec.check_signature(sass, class_name(sass), sign_ass) @@ -210,7 +209,7 @@ def test_multiple_signatures_assertion(self): assert sass.id == "id-11111" assert time_util.str_to_time(sass.issue_instant) - print("Crypto version : %s" % (self.sec.crypto.version())) + print(f"Crypto version : {self.sec.crypto.version()}") item = self.sec.check_signature(sass, class_name(sass), sign_ass, must=True) @@ -489,7 +488,7 @@ def test_non_verify_1(self): def test_sign_assertion(self): ass = self._assertion print(ass) - sign_ass = self.sec.sign_assertion("%s" % ass, node_id=ass.id) + sign_ass = self.sec.sign_assertion(f"{ass}", node_id=ass.id) # print(sign_ass) sass = saml.assertion_from_string(sign_ass) # print(sass) @@ -499,7 +498,7 @@ def test_sign_assertion(self): assert sass.id == "id-11111" assert time_util.str_to_time(sass.issue_instant) - print("Crypto version : %s" % (self.sec.crypto.version())) + print(f"Crypto version : {self.sec.crypto.version()}") item = self.sec.check_signature(sass, class_name(sass), sign_ass) @@ -516,7 +515,7 @@ def test_multiple_signatures_assertion(self): assert sass.id == "id-11111" assert time_util.str_to_time(sass.issue_instant) - print("Crypto version : %s" % (self.sec.crypto.version())) + print(f"Crypto version : {self.sec.crypto.version()}") item = self.sec.check_signature(sass, class_name(sass), sign_ass, must=True) diff --git a/tests/test_41_response.py b/tests/test_41_response.py index 7e67fde78..2bf998bdf 100644 --- a/tests/test_41_response.py +++ b/tests/test_41_response.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from contextlib import closing import datetime @@ -83,7 +82,7 @@ def setup_class(self): self.conf = conf def test_1(self): - xml_response = "%s" % (self._resp_,) + xml_response = f"{self._resp_}" resp = response_factory( xml_response, self.conf, @@ -111,7 +110,7 @@ def test_2(self): assert isinstance(resp, AuthnResponse) def test_issuer_none(self): - xml_response = "%s" % (self._resp_issuer_none,) + xml_response = f"{self._resp_issuer_none}" resp = response_factory( xml_response, self.conf, diff --git a/tests/test_42_enc.py b/tests/test_42_enc.py index 63d73d825..8f15fe249 100644 --- a/tests/test_42_enc.py +++ b/tests/test_42_enc.py @@ -8,7 +8,6 @@ from saml2.server import Server from saml2.sigver import ASSERT_XPATH from saml2.sigver import CryptoBackendXmlSec1 -from saml2.sigver import EncryptError from saml2.sigver import pre_encrypt_assertion from saml2.sigver import pre_encryption_part diff --git a/tests/test_43_soap.py b/tests/test_43_soap.py index 1b222a298..91a45fda6 100755 --- a/tests/test_43_soap.py +++ b/tests/test_43_soap.py @@ -1,18 +1,6 @@ #!/usr/bin/env python -try: - from xml.etree import cElementTree as ElementTree - - if ElementTree.VERSION < "1.3.0": - # cElementTree has no support for register_namespace - # neither _namespace_map, thus we sacrify performance - # for correctness - from xml.etree import ElementTree -except ImportError: - try: - import cElementTree as ElementTree - except ImportError: - from elementtree import ElementTree +from xml.etree import ElementTree as ElementTree from defusedxml.common import EntitiesForbidden from pytest import raises diff --git a/tests/test_44_authnresp.py b/tests/test_44_authnresp.py index a741acd63..5be61d9b5 100644 --- a/tests/test_44_authnresp.py +++ b/tests/test_44_authnresp.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from contextlib import closing from datetime import datetime @@ -70,7 +69,7 @@ def setup_class(self): self.ar = authn_response(self.conf, "http://lingon.catalogix.se:8087/") def test_verify_1(self): - xml_response = "%s" % (self._resp_,) + xml_response = f"{self._resp_}" print(xml_response) self.ar.outstanding_queries = {"id12": "http://localhost:8088/sso"} self.ar.timeslack = 10000 @@ -118,7 +117,7 @@ def test_parse_2(self): assert self.ar.name_id def test_verify_w_authn(self): - xml_response = "%s" % (self._resp_authn,) + xml_response = f"{self._resp_authn}" self.ar.outstanding_queries = {"id12": "http://localhost:8088/sso"} self.ar.return_addr = "http://lingon.catalogix.se:8087/" self.ar.entity_id = "urn:mace:example.com:saml:roland:sp" diff --git a/tests/test_50_server.py b/tests/test_50_server.py index 5a3daf7c2..2784d172b 100644 --- a/tests/test_50_server.py +++ b/tests/test_50_server.py @@ -1,15 +1,14 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import base64 from contextlib import closing import copy import os import re +from urllib.parse import parse_qs import uuid from pathutils import full_path from pytest import raises -from six.moves.urllib.parse import parse_qs from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT @@ -21,7 +20,6 @@ from saml2 import s_utils from saml2 import saml from saml2 import samlp -from saml2 import sigver from saml2 import time_util from saml2.assertion import Policy from saml2.authn_context import INTERNETPROTOCOLPASSWORD @@ -219,7 +217,7 @@ def test_parse_faulty_request(self): # should raise an error because faulty spentityid binding = BINDING_HTTP_REDIRECT - htargs = self.client.apply_binding(binding, "%s" % authn_request, "http://www.example.com", "abcd") + htargs = self.client.apply_binding(binding, f"{authn_request}", "http://www.example.com", "abcd") _dict = parse_qs(htargs["headers"][0][1].split("?")[1]) print(_dict) with raises(OtherError): @@ -229,7 +227,7 @@ def test_parse_faulty_request_to_err_status(self): req_id, authn_request = self.client.create_authn_request(destination="http://www.example.com") binding = BINDING_HTTP_REDIRECT - htargs = self.client.apply_binding(binding, "%s" % authn_request, "http://www.example.com", "abcd") + htargs = self.client.apply_binding(binding, f"{authn_request}", "http://www.example.com", "abcd") _dict = parse_qs(htargs["headers"][0][1].split("?")[1]) print(_dict) @@ -258,7 +256,7 @@ def test_parse_ok_request(self): print(authn_request) binding = BINDING_HTTP_REDIRECT - htargs = self.client.apply_binding(binding, "%s" % authn_request, "http://www.example.com", "abcd") + htargs = self.client.apply_binding(binding, f"{authn_request}", "http://www.example.com", "abcd") _dict = parse_qs(htargs["headers"][0][1].split("?")[1]) print(_dict) @@ -626,7 +624,7 @@ def test_encrypted_signed_response_2(self): ) assert valid - decr_text_old = copy.deepcopy("%s" % signed_resp) + decr_text_old = copy.deepcopy(f"{signed_resp}") with raises(DecryptError): decr_text = self.server.sec.decrypt( @@ -771,7 +769,7 @@ def test_encrypted_response_1(self): encrypt_cert_advice=cert_str_advice, ) - _resp = "%s" % _resp + _resp = f"{_resp}" sresponse = response_from_string(_resp) @@ -891,7 +889,7 @@ def test_encrypted_response_5(self): pefim=True, ) - _resp = "%s" % _resp + _resp = f"{_resp}" sresponse = response_from_string(_resp) @@ -1295,7 +1293,7 @@ def test_parse_faulty_request(self): # should raise an error because faulty spentityid binding = BINDING_HTTP_REDIRECT - htargs = self.client.apply_binding(binding, "%s" % authn_request, "http://www.example.com", "abcd") + htargs = self.client.apply_binding(binding, f"{authn_request}", "http://www.example.com", "abcd") _dict = parse_qs(htargs["headers"][0][1].split("?")[1]) print(_dict) with raises(OtherError): @@ -1305,7 +1303,7 @@ def test_parse_faulty_request_to_err_status(self): req_id, authn_request = self.client.create_authn_request(destination="http://www.example.com") binding = BINDING_HTTP_REDIRECT - htargs = self.client.apply_binding(binding, "%s" % authn_request, "http://www.example.com", "abcd") + htargs = self.client.apply_binding(binding, f"{authn_request}", "http://www.example.com", "abcd") _dict = parse_qs(htargs["headers"][0][1].split("?")[1]) print(_dict) @@ -1334,7 +1332,7 @@ def test_parse_ok_request(self): print(authn_request) binding = BINDING_HTTP_REDIRECT - htargs = self.client.apply_binding(binding, "%s" % authn_request, "http://www.example.com", "abcd") + htargs = self.client.apply_binding(binding, f"{authn_request}", "http://www.example.com", "abcd") _dict = parse_qs(htargs["headers"][0][1].split("?")[1]) print(_dict) @@ -1702,7 +1700,7 @@ def test_encrypted_signed_response_2(self): ) assert valid - decr_text_old = copy.deepcopy("%s" % signed_resp) + decr_text_old = copy.deepcopy(f"{signed_resp}") with raises(DecryptError): decr_text = self.server.sec.decrypt( @@ -1847,7 +1845,7 @@ def test_encrypted_response_1(self): encrypt_cert_advice=cert_str_advice, ) - _resp = "%s" % _resp + _resp = f"{_resp}" sresponse = response_from_string(_resp) @@ -1967,7 +1965,7 @@ def test_encrypted_response_5(self): pefim=True, ) - _resp = "%s" % _resp + _resp = f"{_resp}" sresponse = response_from_string(_resp) @@ -2410,7 +2408,7 @@ def test_1(self): response = server.create_logout_response(request, bindings) binding, destination = server.pick_binding("single_logout_service", bindings, "spsso", request) - http_args = server.apply_binding(binding, "%s" % response, destination, "relay_state", response=True) + http_args = server.apply_binding(binding, f"{response}", destination, "relay_state", response=True) assert len(http_args) == 5 assert http_args["headers"][0][0] == "Location" @@ -2426,7 +2424,7 @@ def test_2(self): response = server.create_logout_response(request, bindings) binding, destination = server.pick_binding("single_logout_service", bindings, "spsso", request) - http_args = server.apply_binding(binding, "%s" % response, destination, "relay_state", response=True) + http_args = server.apply_binding(binding, f"{response}", destination, "relay_state", response=True) assert len(http_args) == 5 assert len(http_args["data"]) > 0 diff --git a/tests/test_51_client.py b/tests/test_51_client.py index 7913cc054..e1eb85ecb 100644 --- a/tests/test_51_client.py +++ b/tests/test_51_client.py @@ -1,8 +1,8 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from base64 import decodebytes as b64decode from base64 import encodebytes as b64encode +from urllib import parse import uuid from defusedxml.common import EntitiesForbidden @@ -10,8 +10,6 @@ from fakeIDP import unpack_form from pathutils import full_path from pytest import raises -import six -from six.moves.urllib import parse from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_REDIRECT @@ -90,10 +88,7 @@ def generate_cert(): def add_subelement(xmldoc, node_name, subelem): - if six.PY2: - _str = unicode - else: - _str = str + _str = str s = xmldoc.find(node_name) if s > 0: @@ -109,8 +104,8 @@ def add_subelement(xmldoc, node_name, subelem): if subelem_str[0:5].lower() == "" % (tag, node_name, spaces), - "<%s:%s%s>%s" % (tag, node_name, spaces, subelem_str, tag, node_name), + f"<{tag}:{node_name}{spaces}/>", + f"<{tag}:{node_name}{spaces}>{subelem_str}", ) return xmldoc @@ -164,7 +159,7 @@ def _leq(l1, l2): def list_values2simpletons(_dict): - return dict([(k, v[0]) for k, v in _dict.items()]) + return {k: v[0] for k, v in _dict.items()} class TestClient: @@ -188,7 +183,7 @@ def test_create_attribute_query1(self): format=saml.NAMEID_FORMAT_PERSISTENT, message_id="id1", ) - reqstr = "%s" % req.to_string().decode() + reqstr = f"{req.to_string().decode()}" assert req.destination == "https://idp.example.com/idp/" assert req.id == "id1" @@ -358,7 +353,7 @@ def test_create_auth_request_nameid_policy_allow_create(self): conf = config.SPConfig() conf.load_file("sp_conf_nameidpolicy") client = Saml2Client(conf) - ar_str = "%s" % client.create_authn_request("http://www.example.com/sso", message_id="id1")[1] + ar_str = f"{client.create_authn_request('http://www.example.com/sso', message_id='id1')[1]}" ar = samlp.authn_request_from_string(ar_str) assert ar.assertion_consumer_service_url == ("http://lingon.catalogix" ".se:8087/") @@ -400,7 +395,7 @@ def test_create_auth_request_vo(self): def test_sign_auth_request_0(self): req_id, areq = self.client.create_authn_request("http://www.example.com/sso", sign=True, message_id="id1") - ar_str = "%s" % areq + ar_str = f"{areq}" ar = samlp.authn_request_from_string(ar_str) assert ar @@ -482,7 +477,7 @@ def test_response_1(self): authn=AUTHN, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -567,7 +562,7 @@ def test_response_2(self): encrypt_cert_advice=cert_str, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -601,7 +596,7 @@ def test_response_3(self): pefim=True, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -635,7 +630,7 @@ def test_response_4(self): pefim=True, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -674,7 +669,7 @@ def test_response_5(self): encrypt_cert_assertion=cert_str, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -718,7 +713,7 @@ def test_response_6(self): encrypt_cert_advice=cert_advice_str, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -755,7 +750,7 @@ def test_response_7(self): encrypted_advice_attributes=True, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -793,7 +788,7 @@ def test_response_8(self): encrypt_cert_assertion=cert_str, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -942,7 +937,7 @@ def test_sign_then_encrypt_assertion(self): assers = extension_elements_to_elements(enc_ass.extension_elements, [saml, samlp]) for ass in assers: if ass.signature: - if not _csec.verify_signature("%s" % ass, sign_cert_file, node_name=class_name(ass)): + if not _csec.verify_signature(f"{ass}", sign_cert_file, node_name=class_name(ass)): continue resp_ass.append(ass) @@ -994,7 +989,7 @@ def test_sign_then_encrypt_assertion2(self): encrypted_assertion=EncryptedAssertion(), ) - xmldoc = "%s" % response + xmldoc = f"{response}" # strangely enough I get different tags if I run this test separately # or as part of a bunch of tests. xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) @@ -1084,7 +1079,7 @@ def test_sign_then_encrypt_assertion_advice_1(self): response.assertion.append(assertion) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion), key_file=self.client.sec.key_file, node_id=a_assertion.id + f"{response}", class_name(a_assertion), key_file=self.client.sec.key_file, node_id=a_assertion.id ) # xmldoc = "%s" % response @@ -1093,10 +1088,7 @@ def test_sign_then_encrypt_assertion_advice_1(self): # xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -1248,14 +1240,11 @@ def test_sign_then_encrypt_assertion_advice_2(self): ) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion_1), key_file=self.server.sec.key_file, node_id=a_assertion_1.id + f"{response}", class_name(a_assertion_1), key_file=self.server.sec.key_file, node_id=a_assertion_1.id ) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -1276,14 +1265,11 @@ def test_sign_then_encrypt_assertion_advice_2(self): ) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion_2), key_file=self.server.sec.key_file, node_id=a_assertion_2.id + f"{response}", class_name(a_assertion_2), key_file=self.server.sec.key_file, node_id=a_assertion_2.id ) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -1299,7 +1285,7 @@ def test_sign_then_encrypt_assertion_advice_2(self): response = response.get_xml_string_with_self_contained_assertion_within_encrypted_assertion(assertion_tag) response = _sec.sign_statement( - "%s" % response, class_name(assertion_1), key_file=self.server.sec.key_file, node_id=assertion_1.id + f"{response}", class_name(assertion_1), key_file=self.server.sec.key_file, node_id=assertion_1.id ) enctext = _sec.crypto.encrypt_assertion( @@ -1324,14 +1310,11 @@ def test_sign_then_encrypt_assertion_advice_2(self): ) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion_3), key_file=self.server.sec.key_file, node_id=a_assertion_3.id + f"{response}", class_name(a_assertion_3), key_file=self.server.sec.key_file, node_id=a_assertion_3.id ) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -1353,14 +1336,11 @@ def test_sign_then_encrypt_assertion_advice_2(self): ) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion_4), key_file=self.server.sec.key_file, node_id=a_assertion_4.id + f"{response}", class_name(a_assertion_4), key_file=self.server.sec.key_file, node_id=a_assertion_4.id ) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -1370,7 +1350,7 @@ def test_sign_then_encrypt_assertion_advice_2(self): response = samlp.response_from_string(enctext) response = _sec.sign_statement( - "%s" % response, + f"{response}", class_name(response.assertion[0]), key_file=self.server.sec.key_file, node_id=response.assertion[0].id, @@ -1870,7 +1850,7 @@ def test_create_attribute_query1(self): format=saml.NAMEID_FORMAT_PERSISTENT, message_id="id1", ) - reqstr = "%s" % req.to_string().decode() + reqstr = f"{req.to_string().decode()}" assert req.destination == "https://idp.example.com/idp/" assert req.id == "id1" @@ -2000,7 +1980,7 @@ def test_create_auth_request_nameid_policy_allow_create(self): conf = config.SPConfig() conf.load_file("sp_conf_nameidpolicy") client = Saml2Client(conf) - ar_str = "%s" % client.create_authn_request("http://www.example.com/sso", message_id="id1")[1] + ar_str = f"{client.create_authn_request('http://www.example.com/sso', message_id='id1')[1]}" ar = samlp.authn_request_from_string(ar_str) assert ar.assertion_consumer_service_url == ("http://lingon.catalogix" ".se:8087/") @@ -2042,7 +2022,7 @@ def test_create_auth_request_vo(self): def test_sign_auth_request_0(self): req_id, areq = self.client.create_authn_request("http://www.example.com/sso", sign=True, message_id="id1") - ar_str = "%s" % areq + ar_str = f"{areq}" ar = samlp.authn_request_from_string(ar_str) assert ar @@ -2094,7 +2074,7 @@ def test_response_1(self): authn=AUTHN, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode("utf-8")) @@ -2179,7 +2159,7 @@ def test_response_2(self): encrypt_cert_advice=cert_str, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -2213,7 +2193,7 @@ def test_response_3(self): pefim=True, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -2247,7 +2227,7 @@ def test_response_4(self): pefim=True, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -2286,7 +2266,7 @@ def test_response_5(self): encrypt_cert_assertion=cert_str, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -2330,7 +2310,7 @@ def test_response_6(self): encrypt_cert_advice=cert_advice_str, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -2367,7 +2347,7 @@ def test_response_7(self): encrypted_advice_attributes=True, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -2405,7 +2385,7 @@ def test_response_8(self): encrypt_cert_assertion=cert_str, ) - resp_str = "%s" % resp + resp_str = f"{resp}" resp_str = b64encode(resp_str.encode()) @@ -2419,10 +2399,7 @@ def test_response_no_name_id(self): """Test that the SP client can parse an authentication response from an IdP that does not contain a element.""" - if six.PY2: - _bytes = str - else: - _bytes = bytes + _bytes = bytes conf = config.SPConfig() conf.load_file("server_conf") @@ -2461,10 +2438,7 @@ def test_response_no_name_id(self): # Cast the response to a string and encode it to mock up the payload # the SP client is expected to receive via HTTP POST binding. - if six.PY2: - resp_str = b64encode(str(resp)) - else: - resp_str = b64encode(bytes(str(resp), "utf-8")) + resp_str = b64encode(bytes(str(resp), "utf-8")) # We do not need the client to verify a signature for this test. client.want_assertions_signed = False @@ -2494,10 +2468,7 @@ def test_response_error_status(self): # Cast the response to a string and encode it to mock up the payload # the SP client is expected to receive via HTTP POST binding. - if six.PY2: - resp_str = b64encode(str(resp)) - else: - resp_str = b64encode(bytes(str(resp), "utf-8")) + resp_str = b64encode(bytes(str(resp), "utf-8")) # We do not need the client to verify a signature for this test. client.want_assertions_signed = False @@ -2523,10 +2494,7 @@ def test_response_error_status_non_standard_status_code(self): # Cast the response to a string and encode it to mock up the payload # the SP client is expected to receive via HTTP POST binding. - if six.PY2: - resp_str = b64encode(str(resp)) - else: - resp_str = b64encode(bytes(str(resp), "utf-8")) + resp_str = b64encode(bytes(str(resp), "utf-8")) # We do not need the client to verify a signature for this test. client.want_assertions_signed = False @@ -2618,7 +2586,7 @@ def test_sign_then_encrypt_assertion(self): assers = extension_elements_to_elements(enc_ass.extension_elements, [saml, samlp]) for ass in assers: if ass.signature: - if not _csec.verify_signature("%s" % ass, sign_cert_file, node_name=class_name(ass)): + if not _csec.verify_signature(f"{ass}", sign_cert_file, node_name=class_name(ass)): continue resp_ass.append(ass) @@ -2670,7 +2638,7 @@ def test_sign_then_encrypt_assertion2(self): encrypted_assertion=EncryptedAssertion(), ) - xmldoc = "%s" % response + xmldoc = f"{response}" # strangely enough I get different tags if I run this test separately # or as part of a bunch of tests. xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) @@ -2760,7 +2728,7 @@ def test_sign_then_encrypt_assertion_advice_1(self): response.assertion.append(assertion) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion), key_file=self.client.sec.key_file, node_id=a_assertion.id + f"{response}", class_name(a_assertion), key_file=self.client.sec.key_file, node_id=a_assertion.id ) # xmldoc = "%s" % response @@ -2769,10 +2737,7 @@ def test_sign_then_encrypt_assertion_advice_1(self): # xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -2781,10 +2746,7 @@ def test_sign_then_encrypt_assertion_advice_1(self): # seresp = samlp.response_from_string(enctext) - if six.PY2: - resp_str = b64encode(enctext.encode("utf-8")) - else: - resp_str = b64encode(bytes(enctext, "utf-8")) + resp_str = b64encode(bytes(enctext, "utf-8")) # Now over to the client side resp = self.client.parse_authn_request_response( @@ -2926,14 +2888,11 @@ def test_sign_then_encrypt_assertion_advice_2(self): ) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion_1), key_file=self.server.sec.key_file, node_id=a_assertion_1.id + f"{response}", class_name(a_assertion_1), key_file=self.server.sec.key_file, node_id=a_assertion_1.id ) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -2954,14 +2913,11 @@ def test_sign_then_encrypt_assertion_advice_2(self): ) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion_2), key_file=self.server.sec.key_file, node_id=a_assertion_2.id + f"{response}", class_name(a_assertion_2), key_file=self.server.sec.key_file, node_id=a_assertion_2.id ) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -2977,7 +2933,7 @@ def test_sign_then_encrypt_assertion_advice_2(self): response = response.get_xml_string_with_self_contained_assertion_within_encrypted_assertion(assertion_tag) response = _sec.sign_statement( - "%s" % response, class_name(assertion_1), key_file=self.server.sec.key_file, node_id=assertion_1.id + f"{response}", class_name(assertion_1), key_file=self.server.sec.key_file, node_id=assertion_1.id ) enctext = _sec.crypto.encrypt_assertion( @@ -3002,14 +2958,11 @@ def test_sign_then_encrypt_assertion_advice_2(self): ) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion_3), key_file=self.server.sec.key_file, node_id=a_assertion_3.id + f"{response}", class_name(a_assertion_3), key_file=self.server.sec.key_file, node_id=a_assertion_3.id ) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -3031,14 +2984,11 @@ def test_sign_then_encrypt_assertion_advice_2(self): ) response = _sec.sign_statement( - "%s" % response, class_name(a_assertion_4), key_file=self.server.sec.key_file, node_id=a_assertion_4.id + f"{response}", class_name(a_assertion_4), key_file=self.server.sec.key_file, node_id=a_assertion_4.id ) node_xpath = "".join( - [ - '/*[local-name()="%s"]' % v - for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"] - ] + [f'/*[local-name()="{v}"]' for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]] ) enctext = _sec.crypto.encrypt_assertion( @@ -3048,7 +2998,7 @@ def test_sign_then_encrypt_assertion_advice_2(self): response = samlp.response_from_string(enctext) response = _sec.sign_statement( - "%s" % response, + f"{response}", class_name(response.assertion[0]), key_file=self.server.sec.key_file, node_id=response.assertion[0].id, @@ -3083,7 +3033,7 @@ def test_signed_redirect(self): # Revert configuration change to disallow unsinged responses self.client.want_response_signed = True - msg_str = "%s" % self.client.create_authn_request("http://localhost:8088/sso", message_id="id1")[1] + msg_str = f"{self.client.create_authn_request('http://localhost:8088/sso', message_id='id1')[1]}" info = self.client.apply_binding( BINDING_HTTP_REDIRECT, msg_str, destination="", relay_state="relay2", sign=True, sigalg=SIG_RSA_SHA256 @@ -3209,7 +3159,7 @@ def test_do_authn(self): IDP, "http://www.example.com/relay_state", binding=binding, response_binding=response_binding ) - assert isinstance(sid, six.string_types) + assert isinstance(sid, str) assert len(http_args) == 5 assert http_args["headers"][0][0] == "Location" assert http_args["data"] == [] @@ -3229,7 +3179,7 @@ def test_do_negotiated_authn(self): ) assert binding == auth_binding - assert isinstance(sid, six.string_types) + assert isinstance(sid, str) assert len(http_args) == 5 assert http_args["headers"][0][0] == "Location" assert http_args["data"] == [] diff --git a/tests/test_52_default_sign_alg.py b/tests/test_52_default_sign_alg.py index f0e96a50b..66fc572d7 100644 --- a/tests/test_52_default_sign_alg.py +++ b/tests/test_52_default_sign_alg.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import os from saml2 import client diff --git a/tests/test_60_sp.py b/tests/test_60_sp.py index c9fbf3fa7..9c8799646 100644 --- a/tests/test_60_sp.py +++ b/tests/test_60_sp.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from base64 import encodebytes as b64encode diff --git a/tests/test_63_ecp.py b/tests/test_63_ecp.py index a50a45ba2..94232a6c8 100644 --- a/tests/test_63_ecp.py +++ b/tests/test_63_ecp.py @@ -32,7 +32,7 @@ def _eq(l1, l2): return len(l1) == len(l2) -class DummyResponse(object): +class DummyResponse: def __init__(self, headers): self.headers = headers diff --git a/tests/test_64_artifact.py b/tests/test_64_artifact.py index 377fdfa72..25a191842 100644 --- a/tests/test_64_artifact.py +++ b/tests/test_64_artifact.py @@ -1,9 +1,8 @@ import base64 from contextlib import closing from hashlib import sha1 - -from six.moves.urllib.parse import parse_qs -from six.moves.urllib.parse import urlparse +from urllib.parse import parse_qs +from urllib.parse import urlparse from saml2 import BINDING_HTTP_ARTIFACT from saml2 import BINDING_HTTP_POST @@ -177,7 +176,7 @@ def test_artifact_flow(): }, name_id=name_id, authn=AUTHN, - **resp_args + **resp_args, ) print(response) @@ -190,7 +189,7 @@ def test_artifact_flow(): "single_sign_on_service", [BINDING_HTTP_ARTIFACT], entity_id=idp.config.entityid ) - hinfo = sp.apply_binding(binding, "%s" % artifact, destination, relay_state, response=True) + hinfo = sp.apply_binding(binding, f"{artifact}", destination, relay_state, response=True) # ========== SP ========= diff --git a/tests/test_65_authn_query.py b/tests/test_65_authn_query.py index 91426ed15..23faf47dd 100644 --- a/tests/test_65_authn_query.py +++ b/tests/test_65_authn_query.py @@ -1,7 +1,6 @@ from contextlib import closing - -from six.moves.urllib.parse import parse_qs -from six.moves.urllib.parse import urlparse +from urllib.parse import parse_qs +from urllib.parse import urlparse from saml2 import BINDING_HTTP_POST from saml2 import BINDING_SOAP @@ -16,8 +15,6 @@ from saml2.saml import NameID from saml2.saml import Subject from saml2.samlp import AuthnQuery -from saml2.samlp import AuthnRequest -from saml2.samlp import NameIDPolicy from saml2.server import Server @@ -88,7 +85,7 @@ def test_flow(): authn=AUTHN, ) - hinfo = idp.apply_binding(binding, "%s" % resp, destination, relay_state) + hinfo = idp.apply_binding(binding, f"{resp}", destination, relay_state) # ------- @SP ---------- @@ -110,7 +107,7 @@ def test_flow(): assert isinstance(aq, AuthnQuery) binding = BINDING_SOAP - hinfo = sp.apply_binding(binding, "%s" % aq, destination, "state2") + hinfo = sp.apply_binding(binding, f"{aq}", destination, "state2") # -------- @IDP ---------- @@ -125,7 +122,7 @@ def test_flow(): print(p_res) - hinfo = idp.apply_binding(binding, "%s" % p_res, "", "state2", response=True) + hinfo = idp.apply_binding(binding, f"{p_res}", "", "state2", response=True) # ------- @SP ---------- diff --git a/tests/test_67_manage_name_id.py b/tests/test_67_manage_name_id.py index 3a54f01e3..c41d8c0b2 100644 --- a/tests/test_67_manage_name_id.py +++ b/tests/test_67_manage_name_id.py @@ -23,7 +23,7 @@ def test_basic(): mid, mreq = sp.create_manage_name_id_request(destination, name_id=nameid, new_id=newid) print(mreq) - rargs = sp.apply_binding(binding, "%s" % mreq, destination, "") + rargs = sp.apply_binding(binding, f"{mreq}", destination, "") # --------- @IDP -------------- @@ -45,7 +45,7 @@ def test_flow(): mid, midq = sp.create_manage_name_id_request(destination, name_id=nameid, new_id=newid) print(midq) - rargs = sp.apply_binding(binding, "%s" % midq, destination, "") + rargs = sp.apply_binding(binding, f"{midq}", destination, "") # --------- @IDP -------------- @@ -60,7 +60,7 @@ def test_flow(): else: destination = "" - respargs = idp.apply_binding(binding, "%s" % mnir, destination, "") + respargs = idp.apply_binding(binding, f"{mnir}", destination, "") print(respargs) diff --git a/tests/test_68_assertion_id.py b/tests/test_68_assertion_id.py index 0ecfca614..34792efc4 100644 --- a/tests/test_68_assertion_id.py +++ b/tests/test_68_assertion_id.py @@ -1,7 +1,6 @@ from contextlib import closing - -from six.moves.urllib.parse import parse_qs -from six.moves.urllib.parse import urlparse +from urllib.parse import parse_qs +from urllib.parse import urlparse from saml2 import BINDING_HTTP_POST from saml2 import BINDING_SOAP @@ -76,7 +75,7 @@ def test_basic_flow(): authn=AUTHN, ) - hinfo = idp.apply_binding(binding, "%s" % resp, destination, relay_state) + hinfo = idp.apply_binding(binding, f"{resp}", destination, relay_state) # --------- @SP ------------- @@ -101,7 +100,7 @@ def test_basic_flow(): resp = idp.create_assertion_id_request_response(aid) - hinfo = idp.apply_binding(binding, "%s" % resp, None, "", response=True) + hinfo = idp.apply_binding(binding, f"{resp}", None, "", response=True) # ----------- @SP ------------- diff --git a/tests/test_69_discovery.py b/tests/test_69_discovery.py index 6bd559b00..bf5ce3883 100644 --- a/tests/test_69_discovery.py +++ b/tests/test_69_discovery.py @@ -60,7 +60,7 @@ def test_construct_deconstruct_response(): ) ds = DiscoveryServer(config_file=dotname("disco_conf")) dsr = ds.parse_discovery_service_request(url) - args = dict([(key, dsr[key]) for key in ["returnIDParam", "return"]]) + args = {key: dsr[key] for key in ["returnIDParam", "return"]} url = ds.create_discovery_service_response(entity_id="https://example.com/saml/idp.xml", **args) idp_id = sp.parse_discovery_service_response(url, returnIDParam="foo") diff --git a/tests/test_70_redirect_signing.py b/tests/test_70_redirect_signing.py index bb009e10a..27b167b1d 100644 --- a/tests/test_70_redirect_signing.py +++ b/tests/test_70_redirect_signing.py @@ -1,7 +1,7 @@ from contextlib import closing +from urllib.parse import parse_qs from pathutils import dotname -from six.moves.urllib.parse import parse_qs from saml2 import BINDING_HTTP_REDIRECT from saml2.client import Saml2Client @@ -9,7 +9,6 @@ from saml2.pack import http_redirect_message from saml2.server import Server from saml2.sigver import SIG_RSA_SHA1 -from saml2.sigver import import_rsa_key_from_file from saml2.sigver import verify_redirect_signature @@ -17,7 +16,7 @@ def list_values2simpletons(_dict): - return dict([(k, v[0]) for k, v in _dict.items()]) + return {k: v[0] for k, v in _dict.items()} def test(): diff --git a/tests/test_76_metadata_in_mdb.py b/tests/test_76_metadata_in_mdb.py index 7f22bd134..999c9382b 100644 --- a/tests/test_76_metadata_in_mdb.py +++ b/tests/test_76_metadata_in_mdb.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from pathutils import full_path from pymongo.errors import ConnectionFailure diff --git a/tests/test_77_authn_context.py b/tests/test_77_authn_context.py index e8dc62a72..b798720a9 100644 --- a/tests/test_77_authn_context.py +++ b/tests/test_77_authn_context.py @@ -20,11 +20,9 @@ from saml2.authn_context import authn_context_class_ref from saml2.authn_context import authn_context_decl_from_extension_elements from saml2.authn_context import authn_context_factory -from saml2.authn_context import ppt from saml2.authn_context import pword from saml2.authn_context import requested_authn_context from saml2.saml import AuthnContext -from saml2.saml import AuthnContextClassRef from saml2.saml import authn_context_from_string from saml2.samlp import RequestedAuthnContext @@ -56,7 +54,7 @@ def test_factory(): def test_authn_decl_in_authn_context(): authnctxt = AuthnContext(authn_context_decl=ACD) - acs = authn_context_from_string("%s" % authnctxt) + acs = authn_context_from_string(f"{authnctxt}") if acs.extension_elements: cacd = authn_context_decl_from_extension_elements(acs.extension_elements) if cacd: @@ -104,7 +102,7 @@ def test_authn_3(): level += 4 ac = authn_context_class_ref(ref) - authn.add(ac, REF2METHOD[ref], level, "https://www.example.com/%s" % "al%d" % level) + authn.add(ac, REF2METHOD[ref], level, f"https://www.example.com/{'al%d'}" % level) rac = requested_authn_context(AL1, "minimum") diff --git a/tests/test_81_certificates.py b/tests/test_81_certificates.py index bc32c5755..f02feea6e 100644 --- a/tests/test_81_certificates.py +++ b/tests/test_81_certificates.py @@ -36,7 +36,7 @@ def test_validate_with_root_cert(self): cert_info_ca, request=False, write_to_file=True, - cert_dir=os.path.dirname(os.path.abspath(__file__)) + "/pki", + cert_dir=f"{os.path.dirname(os.path.abspath(__file__))}/pki", ) req_cert_str, req_key_str = osw.create_certificate(cert_info, request=True) diff --git a/tests/test_82_pefim.py b/tests/test_82_pefim.py index abce6f586..ce223f272 100644 --- a/tests/test_82_pefim.py +++ b/tests/test_82_pefim.py @@ -39,7 +39,7 @@ # Get a certificate from an authn request -xml = "%s" % req +xml = f"{req}" parsed = authn_request_from_string(xml) diff --git a/tests/test_83_md_extensions.py b/tests/test_83_md_extensions.py index 9f6186f00..db4e08631 100644 --- a/tests/test_83_md_extensions.py +++ b/tests/test_83_md_extensions.py @@ -1,4 +1,3 @@ -from saml2 import create_class_from_element_tree as parse_element_as from saml2 import create_class_from_xml_string as parse_str_as from saml2.config import Config from saml2.extension.sp_type import SPType diff --git a/tests/test_88_nsprefix.py b/tests/test_88_nsprefix.py index 5b790f23e..d61e0d190 100644 --- a/tests/test_88_nsprefix.py +++ b/tests/test_88_nsprefix.py @@ -13,13 +13,13 @@ def test_nsprefix(): status_message = samlp.StatusMessage() status_message.text = "OK" - txt = "%s" % status_message + txt = f"{status_message}" assert "ns0:StatusMessage" in txt status_message.register_prefix({"saml2": saml.NAMESPACE, "saml2p": samlp.NAMESPACE}) - txt = "%s" % status_message + txt = f"{status_message}" assert "saml2p:StatusMessage" in txt @@ -39,7 +39,7 @@ def test_nsprefix2(): nsprefix={"saml2": saml.NAMESPACE, "saml2p": samlp.NAMESPACE}, ) - txt = "%s" % req + txt = f"{req}" assert "saml2p:AuthnRequest" in txt assert "saml2:Issuer" in txt diff --git a/tests/test_89_http_post_relay_state.py b/tests/test_89_http_post_relay_state.py index 9ec6b502c..f04b25cd5 100644 --- a/tests/test_89_http_post_relay_state.py +++ b/tests/test_89_http_post_relay_state.py @@ -16,12 +16,12 @@ ss:mem:ab1e6a31f3bd040ffd1d64a2d0e15d61ce517f5e1a94a41ea4fae32cc8d70a04""" -class RelayStateHTMLParser(HTMLParser, object): +class RelayStateHTMLParser(HTMLParser): """Class used to parse HTML from a HTTP-POST binding response and determine if the HTML includes the expected relay state.""" def __init__(self, expected_relay_state): - super(RelayStateHTMLParser, self).__init__() + super().__init__() self.expected_relay_state = expected_relay_state self.expected_relay_state_found = False @@ -65,7 +65,7 @@ def test_relay_state(): # typical from a Shibboleth SP to create the HTML that carries # the SAML response. relay_state = SHIB_SP_RELAY_STATE - html = idp.apply_binding(BINDING_HTTP_POST, "%s" % resp, destination, relay_state)["data"] + html = idp.apply_binding(BINDING_HTTP_POST, f"{resp}", destination, relay_state)["data"] # Parse the HTML and verify that it contains the correct relay state. parser = RelayStateHTMLParser(relay_state) @@ -74,7 +74,7 @@ def test_relay_state(): # Apply the HTTP_POST binding to the response with relay state None. relay_state = None - html = idp.apply_binding(BINDING_HTTP_POST, "%s" % resp, destination, relay_state)["data"] + html = idp.apply_binding(BINDING_HTTP_POST, f"{resp}", destination, relay_state)["data"] # Parse the HTML and verify that it does not contain a relay state. parser = RelayStateHTMLParser(relay_state) @@ -84,7 +84,7 @@ def test_relay_state(): # Apply the HTTP_POST binding to the response with empty # string relay state. relay_state = "" - html = idp.apply_binding(BINDING_HTTP_POST, "%s" % resp, destination, relay_state)["data"] + html = idp.apply_binding(BINDING_HTTP_POST, f"{resp}", destination, relay_state)["data"] # Parse the HTML and verify that it does not contain a relay state. parser = RelayStateHTMLParser(relay_state) diff --git a/tests/test_93_hok.py b/tests/test_93_hok.py index 2f215a2a0..aaf8ce0f3 100644 --- a/tests/test_93_hok.py +++ b/tests/test_93_hok.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from pathutils import dotname from pathutils import full_path from pytest import raises @@ -79,7 +78,7 @@ def _get_test_response(self, path): asynchop=False, allow_unsolicited=True, ) - with open(path, "r") as fp: + with open(path) as fp: authn_response_xml = fp.read() resp.loads(authn_response_xml, False) return resp diff --git a/tests/test_xmlsec1_key_data.py b/tests/test_xmlsec1_key_data.py index 414cb61e0..e8e9de85f 100644 --- a/tests/test_xmlsec1_key_data.py +++ b/tests/test_xmlsec1_key_data.py @@ -1,8 +1,6 @@ -from datetime import datetime from unittest.mock import Mock from unittest.mock import patch -from dateutil import parser from pathutils import dotname from pathutils import full_path from pytest import raises diff --git a/tests/test_xsw.py b/tests/test_xsw.py index 62d57cd3b..5d6ca1ac8 100644 --- a/tests/test_xsw.py +++ b/tests/test_xsw.py @@ -1,8 +1,6 @@ -from datetime import datetime from unittest.mock import Mock from unittest.mock import patch -from dateutil import parser from pathutils import dotname from pathutils import full_path from pytest import raises

%s%s{str(prop)}{valarr}%s\n" % (len(valarr), prop)) + txt.append(f"{prop}\n") else: txt.append("
%s{val}
%s{prop}\n") txt.extend(dict_to_table(valarr, lev + 1, width - 1)) txt.append("