Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

uri.py 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. """
  2. """
  3. # Created on 2014.09.08
  4. #
  5. # Author: Giovanni Cannata
  6. #
  7. # Copyright 2014 - 2018 Giovanni Cannata
  8. #
  9. # This file is part of ldap3.
  10. #
  11. # ldap3 is free software: you can redistribute it and/or modify
  12. # it under the terms of the GNU Lesser General Public License as published
  13. # by the Free Software Foundation, either version 3 of the License, or
  14. # (at your option) any later version.
  15. #
  16. # ldap3 is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU Lesser General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU Lesser General Public License
  22. # along with ldap3 in the COPYING and COPYING.LESSER files.
  23. # If not, see <http://www.gnu.org/licenses/>.
  24. try:
  25. from urllib.parse import unquote # Python3
  26. except ImportError:
  27. from urllib import unquote # Python 2
  28. from .. import SUBTREE, BASE, LEVEL
  29. def parse_uri(uri):
  30. """
  31. Decode LDAP URI as specified in RFC 4516 relaxing specifications
  32. permitting 'ldaps' as scheme for ssl-ldap
  33. """
  34. # ldapurl = scheme COLON SLASH SLASH [host [COLON port]]
  35. # [SLASH dn [QUESTION [attributes]
  36. # [QUESTION [scope] [QUESTION [filter]
  37. # [QUESTION extensions]]]]]
  38. # ; <host> and <port> are defined
  39. # ; in Sections 3.2.2 and 3.2.3
  40. # ; of [RFC3986].
  41. # ; <filter> is from Section 3 of
  42. # ; [RFC4515], subject to the
  43. # ; provisions of the
  44. # ; "Percent-Encoding" section
  45. # ; below.
  46. #
  47. # scheme = "ldap" / "ldaps" <== not RFC4516 compliant (original is 'scheme = "ldap"')
  48. # dn = distinguishedName ; From Section 3 of [RFC4514],
  49. # ; subject to the provisions of
  50. # ; the "Percent-Encoding"
  51. # ; section below.
  52. #
  53. # attributes = attrdesc *(COMMA attrdesc)
  54. # attrdesc = selector *(COMMA selector)
  55. # selector = attributeSelector ; From Section 4.5.1 of
  56. # ; [RFC4511], subject to the
  57. # ; provisions of the
  58. # ; "Percent-Encoding" section
  59. # ; below.
  60. #
  61. # scope = "base" / "one" / "sub"
  62. # extensions = extension *(COMMA extension)
  63. # extension = [EXCLAMATION] extype [EQUALS exvalue]
  64. # extype = oid ; From section 1.4 of [RFC4512].
  65. #
  66. # exvalue = LDAPString ; From section 4.1.2 of
  67. # ; [RFC4511], subject to the
  68. # ; provisions of the
  69. # ; "Percent-Encoding" section
  70. # ; below.
  71. #
  72. # EXCLAMATION = %x21 ; exclamation mark ("!")
  73. # SLASH = %x2F ; forward slash ("/")
  74. # COLON = %x3A ; colon (":")
  75. # QUESTION = %x3F ; question mark ("?")
  76. uri_components = dict()
  77. parts = unquote(uri).split('?') # encoding defaults to utf-8 in Python 3
  78. scheme, sep, remain = parts[0].partition('://')
  79. if sep != '://' or scheme not in ['ldap', 'ldaps']:
  80. return None
  81. address, _, uri_components['base'] = remain.partition('/')
  82. uri_components['ssl'] = True if scheme == 'ldaps' else False
  83. uri_components['host'], sep, uri_components['port'] = address.partition(':')
  84. if sep != ':':
  85. if uri_components['ssl']:
  86. uri_components['port'] = 636
  87. else:
  88. uri_components['port'] = None
  89. else:
  90. if not uri_components['port'].isdigit() or not (0 < int(uri_components['port']) < 65536):
  91. return None
  92. else:
  93. uri_components['port'] = int(uri_components['port'])
  94. uri_components['attributes'] = parts[1].split(',') if len(parts) > 1 else None
  95. uri_components['scope'] = parts[2] if len(parts) > 2 else None
  96. if uri_components['scope'] == 'base':
  97. uri_components['scope'] = BASE
  98. elif uri_components['scope'] == 'sub':
  99. uri_components['scope'] = SUBTREE
  100. elif uri_components['scope'] == 'one':
  101. uri_components['scope'] = LEVEL
  102. elif uri_components['scope']:
  103. return None
  104. uri_components['filter'] = parts[3] if len(parts) > 3 else None
  105. uri_components['extensions'] = parts[4].split(',') if len(parts) > 4 else None
  106. return uri_components