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.

742 lines
20 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
10 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
10 years ago
10 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
10 years ago
10 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
10 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
10 years ago
10 years ago
8 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
8 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
8 years ago
8 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
8 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
Oauth2 consumer (#679) * initial stuff for oauth2 login, fails on: * login button on the signIn page to start the OAuth2 flow and a callback for each provider Only GitHub is implemented for now * show login button only when the OAuth2 consumer is configured (and activated) * create macaron group for oauth2 urls * prevent net/http in modules (other then oauth2) * use a new data sessions oauth2 folder for storing the oauth2 session data * add missing 2FA when this is enabled on the user * add password option for OAuth2 user , for use with git over http and login to the GUI * add tip for registering a GitHub OAuth application * at startup of Gitea register all configured providers and also on adding/deleting of new providers * custom handling of errors in oauth2 request init + show better tip * add ExternalLoginUser model and migration script to add it to database * link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed * remove the linked external account from the user his settings * if user is unknown we allow him to register a new account or link it to some existing account * sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers) * from gorilla/sessions docs: "Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!" (we're using gorilla/sessions for storing oauth2 sessions) * use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
7 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package models
  5. import (
  6. "crypto/tls"
  7. "encoding/json"
  8. "errors"
  9. "fmt"
  10. "net/smtp"
  11. "net/textproto"
  12. "strings"
  13. "time"
  14. "github.com/Unknwon/com"
  15. "github.com/go-macaron/binding"
  16. "github.com/go-xorm/core"
  17. "github.com/go-xorm/xorm"
  18. "code.gitea.io/gitea/modules/auth/ldap"
  19. "code.gitea.io/gitea/modules/auth/oauth2"
  20. "code.gitea.io/gitea/modules/auth/pam"
  21. "code.gitea.io/gitea/modules/log"
  22. )
  23. // LoginType represents an login type.
  24. type LoginType int
  25. // Note: new type must append to the end of list to maintain compatibility.
  26. const (
  27. LoginNoType LoginType = iota
  28. LoginPlain // 1
  29. LoginLDAP // 2
  30. LoginSMTP // 3
  31. LoginPAM // 4
  32. LoginDLDAP // 5
  33. LoginOAuth2 // 6
  34. )
  35. // LoginNames contains the name of LoginType values.
  36. var LoginNames = map[LoginType]string{
  37. LoginLDAP: "LDAP (via BindDN)",
  38. LoginDLDAP: "LDAP (simple auth)", // Via direct bind
  39. LoginSMTP: "SMTP",
  40. LoginPAM: "PAM",
  41. LoginOAuth2: "OAuth2",
  42. }
  43. // SecurityProtocolNames contains the name of SecurityProtocol values.
  44. var SecurityProtocolNames = map[ldap.SecurityProtocol]string{
  45. ldap.SecurityProtocolUnencrypted: "Unencrypted",
  46. ldap.SecurityProtocolLDAPS: "LDAPS",
  47. ldap.SecurityProtocolStartTLS: "StartTLS",
  48. }
  49. // Ensure structs implemented interface.
  50. var (
  51. _ core.Conversion = &LDAPConfig{}
  52. _ core.Conversion = &SMTPConfig{}
  53. _ core.Conversion = &PAMConfig{}
  54. _ core.Conversion = &OAuth2Config{}
  55. )
  56. // LDAPConfig holds configuration for LDAP login source.
  57. type LDAPConfig struct {
  58. *ldap.Source
  59. }
  60. // FromDB fills up a LDAPConfig from serialized format.
  61. func (cfg *LDAPConfig) FromDB(bs []byte) error {
  62. return json.Unmarshal(bs, &cfg)
  63. }
  64. // ToDB exports a LDAPConfig to a serialized format.
  65. func (cfg *LDAPConfig) ToDB() ([]byte, error) {
  66. return json.Marshal(cfg)
  67. }
  68. // SecurityProtocolName returns the name of configured security
  69. // protocol.
  70. func (cfg *LDAPConfig) SecurityProtocolName() string {
  71. return SecurityProtocolNames[cfg.SecurityProtocol]
  72. }
  73. // SMTPConfig holds configuration for the SMTP login source.
  74. type SMTPConfig struct {
  75. Auth string
  76. Host string
  77. Port int
  78. AllowedDomains string `xorm:"TEXT"`
  79. TLS bool
  80. SkipVerify bool
  81. }
  82. // FromDB fills up an SMTPConfig from serialized format.
  83. func (cfg *SMTPConfig) FromDB(bs []byte) error {
  84. return json.Unmarshal(bs, cfg)
  85. }
  86. // ToDB exports an SMTPConfig to a serialized format.
  87. func (cfg *SMTPConfig) ToDB() ([]byte, error) {
  88. return json.Marshal(cfg)
  89. }
  90. // PAMConfig holds configuration for the PAM login source.
  91. type PAMConfig struct {
  92. ServiceName string // pam service (e.g. system-auth)
  93. }
  94. // FromDB fills up a PAMConfig from serialized format.
  95. func (cfg *PAMConfig) FromDB(bs []byte) error {
  96. return json.Unmarshal(bs, &cfg)
  97. }
  98. // ToDB exports a PAMConfig to a serialized format.
  99. func (cfg *PAMConfig) ToDB() ([]byte, error) {
  100. return json.Marshal(cfg)
  101. }
  102. // OAuth2Config holds configuration for the OAuth2 login source.
  103. type OAuth2Config struct {
  104. Provider string
  105. ClientID string
  106. ClientSecret string
  107. }
  108. // FromDB fills up an OAuth2Config from serialized format.
  109. func (cfg *OAuth2Config) FromDB(bs []byte) error {
  110. return json.Unmarshal(bs, cfg)
  111. }
  112. // ToDB exports an SMTPConfig to a serialized format.
  113. func (cfg *OAuth2Config) ToDB() ([]byte, error) {
  114. return json.Marshal(cfg)
  115. }
  116. // LoginSource represents an external way for authorizing users.
  117. type LoginSource struct {
  118. ID int64 `xorm:"pk autoincr"`
  119. Type LoginType
  120. Name string `xorm:"UNIQUE"`
  121. IsActived bool `xorm:"INDEX NOT NULL DEFAULT false"`
  122. Cfg core.Conversion `xorm:"TEXT"`
  123. Created time.Time `xorm:"-"`
  124. CreatedUnix int64 `xorm:"INDEX"`
  125. Updated time.Time `xorm:"-"`
  126. UpdatedUnix int64 `xorm:"INDEX"`
  127. }
  128. // BeforeInsert is invoked from XORM before inserting an object of this type.
  129. func (source *LoginSource) BeforeInsert() {
  130. source.CreatedUnix = time.Now().Unix()
  131. source.UpdatedUnix = source.CreatedUnix
  132. }
  133. // BeforeUpdate is invoked from XORM before updating this object.
  134. func (source *LoginSource) BeforeUpdate() {
  135. source.UpdatedUnix = time.Now().Unix()
  136. }
  137. // Cell2Int64 converts a xorm.Cell type to int64,
  138. // and handles possible irregular cases.
  139. func Cell2Int64(val xorm.Cell) int64 {
  140. switch (*val).(type) {
  141. case []uint8:
  142. log.Trace("Cell2Int64 ([]uint8): %v", *val)
  143. return com.StrTo(string((*val).([]uint8))).MustInt64()
  144. }
  145. return (*val).(int64)
  146. }
  147. // BeforeSet is invoked from XORM before setting the value of a field of this object.
  148. func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
  149. switch colName {
  150. case "type":
  151. switch LoginType(Cell2Int64(val)) {
  152. case LoginLDAP, LoginDLDAP:
  153. source.Cfg = new(LDAPConfig)
  154. case LoginSMTP:
  155. source.Cfg = new(SMTPConfig)
  156. case LoginPAM:
  157. source.Cfg = new(PAMConfig)
  158. case LoginOAuth2:
  159. source.Cfg = new(OAuth2Config)
  160. default:
  161. panic("unrecognized login source type: " + com.ToStr(*val))
  162. }
  163. }
  164. }
  165. // AfterSet is invoked from XORM after setting the value of a field of this object.
  166. func (source *LoginSource) AfterSet(colName string, _ xorm.Cell) {
  167. switch colName {
  168. case "created_unix":
  169. source.Created = time.Unix(source.CreatedUnix, 0).Local()
  170. case "updated_unix":
  171. source.Updated = time.Unix(source.UpdatedUnix, 0).Local()
  172. }
  173. }
  174. // TypeName return name of this login source type.
  175. func (source *LoginSource) TypeName() string {
  176. return LoginNames[source.Type]
  177. }
  178. // IsLDAP returns true of this source is of the LDAP type.
  179. func (source *LoginSource) IsLDAP() bool {
  180. return source.Type == LoginLDAP
  181. }
  182. // IsDLDAP returns true of this source is of the DLDAP type.
  183. func (source *LoginSource) IsDLDAP() bool {
  184. return source.Type == LoginDLDAP
  185. }
  186. // IsSMTP returns true of this source is of the SMTP type.
  187. func (source *LoginSource) IsSMTP() bool {
  188. return source.Type == LoginSMTP
  189. }
  190. // IsPAM returns true of this source is of the PAM type.
  191. func (source *LoginSource) IsPAM() bool {
  192. return source.Type == LoginPAM
  193. }
  194. // IsOAuth2 returns true of this source is of the OAuth2 type.
  195. func (source *LoginSource) IsOAuth2() bool {
  196. return source.Type == LoginOAuth2
  197. }
  198. // HasTLS returns true of this source supports TLS.
  199. func (source *LoginSource) HasTLS() bool {
  200. return ((source.IsLDAP() || source.IsDLDAP()) &&
  201. source.LDAP().SecurityProtocol > ldap.SecurityProtocolUnencrypted) ||
  202. source.IsSMTP()
  203. }
  204. // UseTLS returns true of this source is configured to use TLS.
  205. func (source *LoginSource) UseTLS() bool {
  206. switch source.Type {
  207. case LoginLDAP, LoginDLDAP:
  208. return source.LDAP().SecurityProtocol != ldap.SecurityProtocolUnencrypted
  209. case LoginSMTP:
  210. return source.SMTP().TLS
  211. }
  212. return false
  213. }
  214. // SkipVerify returns true if this source is configured to skip SSL
  215. // verification.
  216. func (source *LoginSource) SkipVerify() bool {
  217. switch source.Type {
  218. case LoginLDAP, LoginDLDAP:
  219. return source.LDAP().SkipVerify
  220. case LoginSMTP:
  221. return source.SMTP().SkipVerify
  222. }
  223. return false
  224. }
  225. // LDAP returns LDAPConfig for this source, if of LDAP type.
  226. func (source *LoginSource) LDAP() *LDAPConfig {
  227. return source.Cfg.(*LDAPConfig)
  228. }
  229. // SMTP returns SMTPConfig for this source, if of SMTP type.
  230. func (source *LoginSource) SMTP() *SMTPConfig {
  231. return source.Cfg.(*SMTPConfig)
  232. }
  233. // PAM returns PAMConfig for this source, if of PAM type.
  234. func (source *LoginSource) PAM() *PAMConfig {
  235. return source.Cfg.(*PAMConfig)
  236. }
  237. // OAuth2 returns OAuth2Config for this source, if of OAuth2 type.
  238. func (source *LoginSource) OAuth2() *OAuth2Config {
  239. return source.Cfg.(*OAuth2Config)
  240. }
  241. // CreateLoginSource inserts a LoginSource in the DB if not already
  242. // existing with the given name.
  243. func CreateLoginSource(source *LoginSource) error {
  244. has, err := x.Get(&LoginSource{Name: source.Name})
  245. if err != nil {
  246. return err
  247. } else if has {
  248. return ErrLoginSourceAlreadyExist{source.Name}
  249. }
  250. _, err = x.Insert(source)
  251. if err == nil && source.IsOAuth2() {
  252. oAuth2Config := source.OAuth2()
  253. oauth2.RegisterProvider(source.Name, oAuth2Config.Provider, oAuth2Config.ClientID, oAuth2Config.ClientSecret)
  254. }
  255. return err
  256. }
  257. // LoginSources returns a slice of all login sources found in DB.
  258. func LoginSources() ([]*LoginSource, error) {
  259. auths := make([]*LoginSource, 0, 6)
  260. return auths, x.Find(&auths)
  261. }
  262. // GetLoginSourceByID returns login source by given ID.
  263. func GetLoginSourceByID(id int64) (*LoginSource, error) {
  264. source := new(LoginSource)
  265. has, err := x.Id(id).Get(source)
  266. if err != nil {
  267. return nil, err
  268. } else if !has {
  269. return nil, ErrLoginSourceNotExist{id}
  270. }
  271. return source, nil
  272. }
  273. // UpdateSource updates a LoginSource record in DB.
  274. func UpdateSource(source *LoginSource) error {
  275. _, err := x.Id(source.ID).AllCols().Update(source)
  276. if err == nil && source.IsOAuth2() {
  277. oAuth2Config := source.OAuth2()
  278. oauth2.RemoveProvider(source.Name)
  279. oauth2.RegisterProvider(source.Name, oAuth2Config.Provider, oAuth2Config.ClientID, oAuth2Config.ClientSecret)
  280. }
  281. return err
  282. }
  283. // DeleteSource deletes a LoginSource record in DB.
  284. func DeleteSource(source *LoginSource) error {
  285. count, err := x.Count(&User{LoginSource: source.ID})
  286. if err != nil {
  287. return err
  288. } else if count > 0 {
  289. return ErrLoginSourceInUse{source.ID}
  290. }
  291. count, err = x.Count(&ExternalLoginUser{LoginSourceID: source.ID})
  292. if err != nil {
  293. return err
  294. } else if count > 0 {
  295. return ErrLoginSourceInUse{source.ID}
  296. }
  297. if source.IsOAuth2() {
  298. oauth2.RemoveProvider(source.Name)
  299. }
  300. _, err = x.Id(source.ID).Delete(new(LoginSource))
  301. return err
  302. }
  303. // CountLoginSources returns number of login sources.
  304. func CountLoginSources() int64 {
  305. count, _ := x.Count(new(LoginSource))
  306. return count
  307. }
  308. // .____ ________ _____ __________
  309. // | | \______ \ / _ \\______ \
  310. // | | | | \ / /_\ \| ___/
  311. // | |___ | ` \/ | \ |
  312. // |_______ \/_______ /\____|__ /____|
  313. // \/ \/ \/
  314. func composeFullName(firstname, surname, username string) string {
  315. switch {
  316. case len(firstname) == 0 && len(surname) == 0:
  317. return username
  318. case len(firstname) == 0:
  319. return surname
  320. case len(surname) == 0:
  321. return firstname
  322. default:
  323. return firstname + " " + surname
  324. }
  325. }
  326. // LoginViaLDAP queries if login/password is valid against the LDAP directory pool,
  327. // and create a local user if success when enabled.
  328. func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
  329. username, fn, sn, mail, isAdmin, succeed := source.Cfg.(*LDAPConfig).SearchEntry(login, password, source.Type == LoginDLDAP)
  330. if !succeed {
  331. // User not in LDAP, do nothing
  332. return nil, ErrUserNotExist{0, login, 0}
  333. }
  334. if !autoRegister {
  335. return user, nil
  336. }
  337. // Fallback.
  338. if len(username) == 0 {
  339. username = login
  340. }
  341. // Validate username make sure it satisfies requirement.
  342. if binding.AlphaDashDotPattern.MatchString(username) {
  343. return nil, fmt.Errorf("Invalid pattern for attribute 'username' [%s]: must be valid alpha or numeric or dash(-_) or dot characters", username)
  344. }
  345. if len(mail) == 0 {
  346. mail = fmt.Sprintf("%s@localhost", username)
  347. }
  348. user = &User{
  349. LowerName: strings.ToLower(username),
  350. Name: username,
  351. FullName: composeFullName(fn, sn, username),
  352. Email: mail,
  353. LoginType: source.Type,
  354. LoginSource: source.ID,
  355. LoginName: login,
  356. IsActive: true,
  357. IsAdmin: isAdmin,
  358. }
  359. return user, CreateUser(user)
  360. }
  361. // _________ __________________________
  362. // / _____/ / \__ ___/\______ \
  363. // \_____ \ / \ / \| | | ___/
  364. // / \/ Y \ | | |
  365. // /_______ /\____|__ /____| |____|
  366. // \/ \/
  367. type smtpLoginAuth struct {
  368. username, password string
  369. }
  370. func (auth *smtpLoginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
  371. return "LOGIN", []byte(auth.username), nil
  372. }
  373. func (auth *smtpLoginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
  374. if more {
  375. switch string(fromServer) {
  376. case "Username:":
  377. return []byte(auth.username), nil
  378. case "Password:":
  379. return []byte(auth.password), nil
  380. }
  381. }
  382. return nil, nil
  383. }
  384. // SMTP authentication type names.
  385. const (
  386. SMTPPlain = "PLAIN"
  387. SMTPLogin = "LOGIN"
  388. )
  389. // SMTPAuths contains available SMTP authentication type names.
  390. var SMTPAuths = []string{SMTPPlain, SMTPLogin}
  391. // SMTPAuth performs an SMTP authentication.
  392. func SMTPAuth(a smtp.Auth, cfg *SMTPConfig) error {
  393. c, err := smtp.Dial(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port))
  394. if err != nil {
  395. return err
  396. }
  397. defer c.Close()
  398. if err = c.Hello("gogs"); err != nil {
  399. return err
  400. }
  401. if cfg.TLS {
  402. if ok, _ := c.Extension("STARTTLS"); ok {
  403. if err = c.StartTLS(&tls.Config{
  404. InsecureSkipVerify: cfg.SkipVerify,
  405. ServerName: cfg.Host,
  406. }); err != nil {
  407. return err
  408. }
  409. } else {
  410. return errors.New("SMTP server unsupports TLS")
  411. }
  412. }
  413. if ok, _ := c.Extension("AUTH"); ok {
  414. if err = c.Auth(a); err != nil {
  415. return err
  416. }
  417. return nil
  418. }
  419. return ErrUnsupportedLoginType
  420. }
  421. // LoginViaSMTP queries if login/password is valid against the SMTP,
  422. // and create a local user if success when enabled.
  423. func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPConfig, autoRegister bool) (*User, error) {
  424. // Verify allowed domains.
  425. if len(cfg.AllowedDomains) > 0 {
  426. idx := strings.Index(login, "@")
  427. if idx == -1 {
  428. return nil, ErrUserNotExist{0, login, 0}
  429. } else if !com.IsSliceContainsStr(strings.Split(cfg.AllowedDomains, ","), login[idx+1:]) {
  430. return nil, ErrUserNotExist{0, login, 0}
  431. }
  432. }
  433. var auth smtp.Auth
  434. if cfg.Auth == SMTPPlain {
  435. auth = smtp.PlainAuth("", login, password, cfg.Host)
  436. } else if cfg.Auth == SMTPLogin {
  437. auth = &smtpLoginAuth{login, password}
  438. } else {
  439. return nil, errors.New("Unsupported SMTP auth type")
  440. }
  441. if err := SMTPAuth(auth, cfg); err != nil {
  442. // Check standard error format first,
  443. // then fallback to worse case.
  444. tperr, ok := err.(*textproto.Error)
  445. if (ok && tperr.Code == 535) ||
  446. strings.Contains(err.Error(), "Username and Password not accepted") {
  447. return nil, ErrUserNotExist{0, login, 0}
  448. }
  449. return nil, err
  450. }
  451. if !autoRegister {
  452. return user, nil
  453. }
  454. username := login
  455. idx := strings.Index(login, "@")
  456. if idx > -1 {
  457. username = login[:idx]
  458. }
  459. user = &User{
  460. LowerName: strings.ToLower(username),
  461. Name: strings.ToLower(username),
  462. Email: login,
  463. Passwd: password,
  464. LoginType: LoginSMTP,
  465. LoginSource: sourceID,
  466. LoginName: login,
  467. IsActive: true,
  468. }
  469. return user, CreateUser(user)
  470. }
  471. // __________ _____ _____
  472. // \______ \/ _ \ / \
  473. // | ___/ /_\ \ / \ / \
  474. // | | / | \/ Y \
  475. // |____| \____|__ /\____|__ /
  476. // \/ \/
  477. // LoginViaPAM queries if login/password is valid against the PAM,
  478. // and create a local user if success when enabled.
  479. func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMConfig, autoRegister bool) (*User, error) {
  480. if err := pam.Auth(cfg.ServiceName, login, password); err != nil {
  481. if strings.Contains(err.Error(), "Authentication failure") {
  482. return nil, ErrUserNotExist{0, login, 0}
  483. }
  484. return nil, err
  485. }
  486. if !autoRegister {
  487. return user, nil
  488. }
  489. user = &User{
  490. LowerName: strings.ToLower(login),
  491. Name: login,
  492. Email: login,
  493. Passwd: password,
  494. LoginType: LoginPAM,
  495. LoginSource: sourceID,
  496. LoginName: login,
  497. IsActive: true,
  498. }
  499. return user, CreateUser(user)
  500. }
  501. // ________ _____ __ .__ ________
  502. // \_____ \ / _ \ __ ___/ |_| |__ \_____ \
  503. // / | \ / /_\ \| | \ __\ | \ / ____/
  504. // / | \/ | \ | /| | | Y \/ \
  505. // \_______ /\____|__ /____/ |__| |___| /\_______ \
  506. // \/ \/ \/ \/
  507. // OAuth2Provider describes the display values of a single OAuth2 provider
  508. type OAuth2Provider struct {
  509. Name string
  510. DisplayName string
  511. Image string
  512. }
  513. // OAuth2Providers contains the map of registered OAuth2 providers in Gitea (based on goth)
  514. // key is used to map the OAuth2Provider with the goth provider type (also in LoginSource.OAuth2Config.Provider)
  515. // value is used to store display data
  516. var OAuth2Providers = map[string]OAuth2Provider{
  517. "github": {Name: "github", DisplayName: "GitHub", Image: "/img/github.png"},
  518. }
  519. // ExternalUserLogin attempts a login using external source types.
  520. func ExternalUserLogin(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
  521. if !source.IsActived {
  522. return nil, ErrLoginSourceNotActived
  523. }
  524. switch source.Type {
  525. case LoginLDAP, LoginDLDAP:
  526. return LoginViaLDAP(user, login, password, source, autoRegister)
  527. case LoginSMTP:
  528. return LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig), autoRegister)
  529. case LoginPAM:
  530. return LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig), autoRegister)
  531. }
  532. return nil, ErrUnsupportedLoginType
  533. }
  534. // UserSignIn validates user name and password.
  535. func UserSignIn(username, password string) (*User, error) {
  536. var user *User
  537. if strings.Contains(username, "@") {
  538. user = &User{Email: strings.ToLower(strings.TrimSpace(username))}
  539. // check same email
  540. cnt, err := x.Count(user)
  541. if err != nil {
  542. return nil, err
  543. }
  544. if cnt > 1 {
  545. return nil, ErrEmailAlreadyUsed{
  546. Email: user.Email,
  547. }
  548. }
  549. } else {
  550. user = &User{LowerName: strings.ToLower(strings.TrimSpace(username))}
  551. }
  552. hasUser, err := x.Get(user)
  553. if err != nil {
  554. return nil, err
  555. }
  556. if hasUser {
  557. switch user.LoginType {
  558. case LoginNoType, LoginPlain, LoginOAuth2:
  559. if user.ValidatePassword(password) {
  560. return user, nil
  561. }
  562. return nil, ErrUserNotExist{user.ID, user.Name, 0}
  563. default:
  564. var source LoginSource
  565. hasSource, err := x.Id(user.LoginSource).Get(&source)
  566. if err != nil {
  567. return nil, err
  568. } else if !hasSource {
  569. return nil, ErrLoginSourceNotExist{user.LoginSource}
  570. }
  571. return ExternalUserLogin(user, user.LoginName, password, &source, false)
  572. }
  573. }
  574. sources := make([]*LoginSource, 0, 5)
  575. if err = x.UseBool().Find(&sources, &LoginSource{IsActived: true}); err != nil {
  576. return nil, err
  577. }
  578. for _, source := range sources {
  579. if source.IsOAuth2() {
  580. // don't try to authenticate against OAuth2 sources
  581. continue
  582. }
  583. authUser, err := ExternalUserLogin(nil, username, password, source, true)
  584. if err == nil {
  585. return authUser, nil
  586. }
  587. log.Warn("Failed to login '%s' via '%s': %v", username, source.Name, err)
  588. }
  589. return nil, ErrUserNotExist{user.ID, user.Name, 0}
  590. }
  591. // GetActiveOAuth2ProviderLoginSources returns all actived LoginOAuth2 sources
  592. func GetActiveOAuth2ProviderLoginSources() ([]*LoginSource, error) {
  593. sources := make([]*LoginSource, 0, 1)
  594. if err := x.UseBool().Find(&sources, &LoginSource{IsActived: true, Type: LoginOAuth2}); err != nil {
  595. return nil, err
  596. }
  597. return sources, nil
  598. }
  599. // GetActiveOAuth2LoginSourceByName returns a OAuth2 LoginSource based on the given name
  600. func GetActiveOAuth2LoginSourceByName(name string) (*LoginSource, error) {
  601. loginSource := &LoginSource{
  602. Name: name,
  603. Type: LoginOAuth2,
  604. IsActived: true,
  605. }
  606. has, err := x.UseBool().Get(loginSource)
  607. if !has || err != nil {
  608. return nil, err
  609. }
  610. return loginSource, nil
  611. }
  612. // GetActiveOAuth2Providers returns the map of configured active OAuth2 providers
  613. // key is used as technical name (like in the callbackURL)
  614. // values to display
  615. func GetActiveOAuth2Providers() (map[string]OAuth2Provider, error) {
  616. // Maybe also separate used and unused providers so we can force the registration of only 1 active provider for each type
  617. loginSources, err := GetActiveOAuth2ProviderLoginSources()
  618. if err != nil {
  619. return nil, err
  620. }
  621. providers := make(map[string]OAuth2Provider)
  622. for _, source := range loginSources {
  623. providers[source.Name] = OAuth2Providers[source.OAuth2().Provider]
  624. }
  625. return providers, nil
  626. }
  627. // InitOAuth2 initialize the OAuth2 lib and register all active OAuth2 providers in the library
  628. func InitOAuth2() {
  629. oauth2.Init()
  630. loginSources, _ := GetActiveOAuth2ProviderLoginSources()
  631. for _, source := range loginSources {
  632. oAuth2Config := source.OAuth2()
  633. oauth2.RegisterProvider(source.Name, oAuth2Config.Provider, oAuth2Config.ClientID, oAuth2Config.ClientSecret)
  634. }
  635. }