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.

64 lines
1.9 KiB

  1. package openid
  2. import (
  3. "errors"
  4. "net/url"
  5. "strings"
  6. )
  7. func Normalize(id string) (string, error) {
  8. id = strings.TrimSpace(id)
  9. if len(id) == 0 {
  10. return "", errors.New("No id provided")
  11. }
  12. // 7.2 from openID 2.0 spec.
  13. //If the user's input starts with the "xri://" prefix, it MUST be
  14. //stripped off, so that XRIs are used in the canonical form.
  15. if strings.HasPrefix(id, "xri://") {
  16. id = id[6:]
  17. return id, errors.New("XRI identifiers not supported")
  18. }
  19. // If the first character of the resulting string is an XRI
  20. // Global Context Symbol ("=", "@", "+", "$", "!") or "(", as
  21. // defined in Section 2.2.1 of [XRI_Syntax_2.0], then the input
  22. // SHOULD be treated as an XRI.
  23. if b := id[0]; b == '=' || b == '@' || b == '+' || b == '$' || b == '!' {
  24. return id, errors.New("XRI identifiers not supported")
  25. }
  26. // Otherwise, the input SHOULD be treated as an http URL; if it
  27. // does not include a "http" or "https" scheme, the Identifier
  28. // MUST be prefixed with the string "http://". If the URL
  29. // contains a fragment part, it MUST be stripped off together
  30. // with the fragment delimiter character "#". See Section 11.5.2 for
  31. // more information.
  32. if !strings.HasPrefix(id, "http://") && !strings.HasPrefix(id,
  33. "https://") {
  34. id = "http://" + id
  35. }
  36. if fragmentIndex := strings.Index(id, "#"); fragmentIndex != -1 {
  37. id = id[0:fragmentIndex]
  38. }
  39. if u, err := url.ParseRequestURI(id); err != nil {
  40. return "", err
  41. } else {
  42. if u.Host == "" {
  43. return "", errors.New("Invalid address provided as id")
  44. }
  45. if u.Path == "" {
  46. u.Path = "/"
  47. }
  48. id = u.String()
  49. }
  50. // URL Identifiers MUST then be further normalized by both
  51. // following redirects when retrieving their content and finally
  52. // applying the rules in Section 6 of [RFC3986] to the final
  53. // destination URL. This final URL MUST be noted by the Relying
  54. // Party as the Claimed Identifier and be used when requesting
  55. // authentication.
  56. return id, nil
  57. }