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.

801 lines
22 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
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
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
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
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
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
Add single sign-on support via SSPI on Windows (#8463) * Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
5 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
7 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package models
  6. import (
  7. "crypto/tls"
  8. "encoding/json"
  9. "errors"
  10. "fmt"
  11. "net/smtp"
  12. "net/textproto"
  13. "regexp"
  14. "strings"
  15. "code.gitea.io/gitea/modules/auth/ldap"
  16. "code.gitea.io/gitea/modules/auth/oauth2"
  17. "code.gitea.io/gitea/modules/auth/pam"
  18. "code.gitea.io/gitea/modules/log"
  19. "code.gitea.io/gitea/modules/setting"
  20. "code.gitea.io/gitea/modules/timeutil"
  21. "github.com/unknwon/com"
  22. "xorm.io/core"
  23. "xorm.io/xorm"
  24. )
  25. // LoginType represents an login type.
  26. type LoginType int
  27. // Note: new type must append to the end of list to maintain compatibility.
  28. const (
  29. LoginNoType LoginType = iota
  30. LoginPlain // 1
  31. LoginLDAP // 2
  32. LoginSMTP // 3
  33. LoginPAM // 4
  34. LoginDLDAP // 5
  35. LoginOAuth2 // 6
  36. LoginSSPI // 7
  37. )
  38. // LoginNames contains the name of LoginType values.
  39. var LoginNames = map[LoginType]string{
  40. LoginLDAP: "LDAP (via BindDN)",
  41. LoginDLDAP: "LDAP (simple auth)", // Via direct bind
  42. LoginSMTP: "SMTP",
  43. LoginPAM: "PAM",
  44. LoginOAuth2: "OAuth2",
  45. LoginSSPI: "SPNEGO with SSPI",
  46. }
  47. // SecurityProtocolNames contains the name of SecurityProtocol values.
  48. var SecurityProtocolNames = map[ldap.SecurityProtocol]string{
  49. ldap.SecurityProtocolUnencrypted: "Unencrypted",
  50. ldap.SecurityProtocolLDAPS: "LDAPS",
  51. ldap.SecurityProtocolStartTLS: "StartTLS",
  52. }
  53. // Ensure structs implemented interface.
  54. var (
  55. _ core.Conversion = &LDAPConfig{}
  56. _ core.Conversion = &SMTPConfig{}
  57. _ core.Conversion = &PAMConfig{}
  58. _ core.Conversion = &OAuth2Config{}
  59. _ core.Conversion = &SSPIConfig{}
  60. )
  61. // LDAPConfig holds configuration for LDAP login source.
  62. type LDAPConfig struct {
  63. *ldap.Source
  64. }
  65. // FromDB fills up a LDAPConfig from serialized format.
  66. func (cfg *LDAPConfig) FromDB(bs []byte) error {
  67. return json.Unmarshal(bs, &cfg)
  68. }
  69. // ToDB exports a LDAPConfig to a serialized format.
  70. func (cfg *LDAPConfig) ToDB() ([]byte, error) {
  71. return json.Marshal(cfg)
  72. }
  73. // SecurityProtocolName returns the name of configured security
  74. // protocol.
  75. func (cfg *LDAPConfig) SecurityProtocolName() string {
  76. return SecurityProtocolNames[cfg.SecurityProtocol]
  77. }
  78. // SMTPConfig holds configuration for the SMTP login source.
  79. type SMTPConfig struct {
  80. Auth string
  81. Host string
  82. Port int
  83. AllowedDomains string `xorm:"TEXT"`
  84. TLS bool
  85. SkipVerify bool
  86. }
  87. // FromDB fills up an SMTPConfig from serialized format.
  88. func (cfg *SMTPConfig) FromDB(bs []byte) error {
  89. return json.Unmarshal(bs, cfg)
  90. }
  91. // ToDB exports an SMTPConfig to a serialized format.
  92. func (cfg *SMTPConfig) ToDB() ([]byte, error) {
  93. return json.Marshal(cfg)
  94. }
  95. // PAMConfig holds configuration for the PAM login source.
  96. type PAMConfig struct {
  97. ServiceName string // pam service (e.g. system-auth)
  98. }
  99. // FromDB fills up a PAMConfig from serialized format.
  100. func (cfg *PAMConfig) FromDB(bs []byte) error {
  101. return json.Unmarshal(bs, &cfg)
  102. }
  103. // ToDB exports a PAMConfig to a serialized format.
  104. func (cfg *PAMConfig) ToDB() ([]byte, error) {
  105. return json.Marshal(cfg)
  106. }
  107. // OAuth2Config holds configuration for the OAuth2 login source.
  108. type OAuth2Config struct {
  109. Provider string
  110. ClientID string
  111. ClientSecret string
  112. OpenIDConnectAutoDiscoveryURL string
  113. CustomURLMapping *oauth2.CustomURLMapping
  114. }
  115. // FromDB fills up an OAuth2Config from serialized format.
  116. func (cfg *OAuth2Config) FromDB(bs []byte) error {
  117. return json.Unmarshal(bs, cfg)
  118. }
  119. // ToDB exports an SMTPConfig to a serialized format.
  120. func (cfg *OAuth2Config) ToDB() ([]byte, error) {
  121. return json.Marshal(cfg)
  122. }
  123. // SSPIConfig holds configuration for SSPI single sign-on.
  124. type SSPIConfig struct {
  125. AutoCreateUsers bool
  126. AutoActivateUsers bool
  127. StripDomainNames bool
  128. SeparatorReplacement string
  129. DefaultLanguage string
  130. }
  131. // FromDB fills up an SSPIConfig from serialized format.
  132. func (cfg *SSPIConfig) FromDB(bs []byte) error {
  133. return json.Unmarshal(bs, cfg)
  134. }
  135. // ToDB exports an SSPIConfig to a serialized format.
  136. func (cfg *SSPIConfig) ToDB() ([]byte, error) {
  137. return json.Marshal(cfg)
  138. }
  139. // LoginSource represents an external way for authorizing users.
  140. type LoginSource struct {
  141. ID int64 `xorm:"pk autoincr"`
  142. Type LoginType
  143. Name string `xorm:"UNIQUE"`
  144. IsActived bool `xorm:"INDEX NOT NULL DEFAULT false"`
  145. IsSyncEnabled bool `xorm:"INDEX NOT NULL DEFAULT false"`
  146. Cfg core.Conversion `xorm:"TEXT"`
  147. CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
  148. UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
  149. }
  150. // Cell2Int64 converts a xorm.Cell type to int64,
  151. // and handles possible irregular cases.
  152. func Cell2Int64(val xorm.Cell) int64 {
  153. switch (*val).(type) {
  154. case []uint8:
  155. log.Trace("Cell2Int64 ([]uint8): %v", *val)
  156. return com.StrTo(string((*val).([]uint8))).MustInt64()
  157. }
  158. return (*val).(int64)
  159. }
  160. // BeforeSet is invoked from XORM before setting the value of a field of this object.
  161. func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
  162. if colName == "type" {
  163. switch LoginType(Cell2Int64(val)) {
  164. case LoginLDAP, LoginDLDAP:
  165. source.Cfg = new(LDAPConfig)
  166. case LoginSMTP:
  167. source.Cfg = new(SMTPConfig)
  168. case LoginPAM:
  169. source.Cfg = new(PAMConfig)
  170. case LoginOAuth2:
  171. source.Cfg = new(OAuth2Config)
  172. case LoginSSPI:
  173. source.Cfg = new(SSPIConfig)
  174. default:
  175. panic("unrecognized login source type: " + com.ToStr(*val))
  176. }
  177. }
  178. }
  179. // TypeName return name of this login source type.
  180. func (source *LoginSource) TypeName() string {
  181. return LoginNames[source.Type]
  182. }
  183. // IsLDAP returns true of this source is of the LDAP type.
  184. func (source *LoginSource) IsLDAP() bool {
  185. return source.Type == LoginLDAP
  186. }
  187. // IsDLDAP returns true of this source is of the DLDAP type.
  188. func (source *LoginSource) IsDLDAP() bool {
  189. return source.Type == LoginDLDAP
  190. }
  191. // IsSMTP returns true of this source is of the SMTP type.
  192. func (source *LoginSource) IsSMTP() bool {
  193. return source.Type == LoginSMTP
  194. }
  195. // IsPAM returns true of this source is of the PAM type.
  196. func (source *LoginSource) IsPAM() bool {
  197. return source.Type == LoginPAM
  198. }
  199. // IsOAuth2 returns true of this source is of the OAuth2 type.
  200. func (source *LoginSource) IsOAuth2() bool {
  201. return source.Type == LoginOAuth2
  202. }
  203. // IsSSPI returns true of this source is of the SSPI type.
  204. func (source *LoginSource) IsSSPI() bool {
  205. return source.Type == LoginSSPI
  206. }
  207. // HasTLS returns true of this source supports TLS.
  208. func (source *LoginSource) HasTLS() bool {
  209. return ((source.IsLDAP() || source.IsDLDAP()) &&
  210. source.LDAP().SecurityProtocol > ldap.SecurityProtocolUnencrypted) ||
  211. source.IsSMTP()
  212. }
  213. // UseTLS returns true of this source is configured to use TLS.
  214. func (source *LoginSource) UseTLS() bool {
  215. switch source.Type {
  216. case LoginLDAP, LoginDLDAP:
  217. return source.LDAP().SecurityProtocol != ldap.SecurityProtocolUnencrypted
  218. case LoginSMTP:
  219. return source.SMTP().TLS
  220. }
  221. return false
  222. }
  223. // SkipVerify returns true if this source is configured to skip SSL
  224. // verification.
  225. func (source *LoginSource) SkipVerify() bool {
  226. switch source.Type {
  227. case LoginLDAP, LoginDLDAP:
  228. return source.LDAP().SkipVerify
  229. case LoginSMTP:
  230. return source.SMTP().SkipVerify
  231. }
  232. return false
  233. }
  234. // LDAP returns LDAPConfig for this source, if of LDAP type.
  235. func (source *LoginSource) LDAP() *LDAPConfig {
  236. return source.Cfg.(*LDAPConfig)
  237. }
  238. // SMTP returns SMTPConfig for this source, if of SMTP type.
  239. func (source *LoginSource) SMTP() *SMTPConfig {
  240. return source.Cfg.(*SMTPConfig)
  241. }
  242. // PAM returns PAMConfig for this source, if of PAM type.
  243. func (source *LoginSource) PAM() *PAMConfig {
  244. return source.Cfg.(*PAMConfig)
  245. }
  246. // OAuth2 returns OAuth2Config for this source, if of OAuth2 type.
  247. func (source *LoginSource) OAuth2() *OAuth2Config {
  248. return source.Cfg.(*OAuth2Config)
  249. }
  250. // SSPI returns SSPIConfig for this source, if of SSPI type.
  251. func (source *LoginSource) SSPI() *SSPIConfig {
  252. return source.Cfg.(*SSPIConfig)
  253. }
  254. // CreateLoginSource inserts a LoginSource in the DB if not already
  255. // existing with the given name.
  256. func CreateLoginSource(source *LoginSource) error {
  257. has, err := x.Get(&LoginSource{Name: source.Name})
  258. if err != nil {
  259. return err
  260. } else if has {
  261. return ErrLoginSourceAlreadyExist{source.Name}
  262. }
  263. // Synchronization is only aviable with LDAP for now
  264. if !source.IsLDAP() {
  265. source.IsSyncEnabled = false
  266. }
  267. _, err = x.Insert(source)
  268. if err == nil && source.IsOAuth2() && source.IsActived {
  269. oAuth2Config := source.OAuth2()
  270. err = oauth2.RegisterProvider(source.Name, oAuth2Config.Provider, oAuth2Config.ClientID, oAuth2Config.ClientSecret, oAuth2Config.OpenIDConnectAutoDiscoveryURL, oAuth2Config.CustomURLMapping)
  271. err = wrapOpenIDConnectInitializeError(err, source.Name, oAuth2Config)
  272. if err != nil {
  273. // remove the LoginSource in case of errors while registering OAuth2 providers
  274. if _, err := x.Delete(source); err != nil {
  275. log.Error("CreateLoginSource: Error while wrapOpenIDConnectInitializeError: %v", err)
  276. }
  277. return err
  278. }
  279. }
  280. return err
  281. }
  282. // LoginSources returns a slice of all login sources found in DB.
  283. func LoginSources() ([]*LoginSource, error) {
  284. auths := make([]*LoginSource, 0, 6)
  285. return auths, x.Find(&auths)
  286. }
  287. // LoginSourcesByType returns all sources of the specified type
  288. func LoginSourcesByType(loginType LoginType) ([]*LoginSource, error) {
  289. sources := make([]*LoginSource, 0, 1)
  290. if err := x.Where("type = ?", loginType).Find(&sources); err != nil {
  291. return nil, err
  292. }
  293. return sources, nil
  294. }
  295. // ActiveLoginSources returns all active sources of the specified type
  296. func ActiveLoginSources(loginType LoginType) ([]*LoginSource, error) {
  297. sources := make([]*LoginSource, 0, 1)
  298. if err := x.Where("is_actived = ? and type = ?", true, loginType).Find(&sources); err != nil {
  299. return nil, err
  300. }
  301. return sources, nil
  302. }
  303. // IsSSPIEnabled returns true if there is at least one activated login
  304. // source of type LoginSSPI
  305. func IsSSPIEnabled() bool {
  306. if !HasEngine {
  307. return false
  308. }
  309. sources, err := ActiveLoginSources(LoginSSPI)
  310. if err != nil {
  311. log.Error("ActiveLoginSources: %v", err)
  312. return false
  313. }
  314. return len(sources) > 0
  315. }
  316. // GetLoginSourceByID returns login source by given ID.
  317. func GetLoginSourceByID(id int64) (*LoginSource, error) {
  318. source := new(LoginSource)
  319. has, err := x.ID(id).Get(source)
  320. if err != nil {
  321. return nil, err
  322. } else if !has {
  323. return nil, ErrLoginSourceNotExist{id}
  324. }
  325. return source, nil
  326. }
  327. // UpdateSource updates a LoginSource record in DB.
  328. func UpdateSource(source *LoginSource) error {
  329. var originalLoginSource *LoginSource
  330. if source.IsOAuth2() {
  331. // keep track of the original values so we can restore in case of errors while registering OAuth2 providers
  332. var err error
  333. if originalLoginSource, err = GetLoginSourceByID(source.ID); err != nil {
  334. return err
  335. }
  336. }
  337. _, err := x.ID(source.ID).AllCols().Update(source)
  338. if err == nil && source.IsOAuth2() && source.IsActived {
  339. oAuth2Config := source.OAuth2()
  340. err = oauth2.RegisterProvider(source.Name, oAuth2Config.Provider, oAuth2Config.ClientID, oAuth2Config.ClientSecret, oAuth2Config.OpenIDConnectAutoDiscoveryURL, oAuth2Config.CustomURLMapping)
  341. err = wrapOpenIDConnectInitializeError(err, source.Name, oAuth2Config)
  342. if err != nil {
  343. // restore original values since we cannot update the provider it self
  344. if _, err := x.ID(source.ID).AllCols().Update(originalLoginSource); err != nil {
  345. log.Error("UpdateSource: Error while wrapOpenIDConnectInitializeError: %v", err)
  346. }
  347. return err
  348. }
  349. }
  350. return err
  351. }
  352. // DeleteSource deletes a LoginSource record in DB.
  353. func DeleteSource(source *LoginSource) error {
  354. count, err := x.Count(&User{LoginSource: source.ID})
  355. if err != nil {
  356. return err
  357. } else if count > 0 {
  358. return ErrLoginSourceInUse{source.ID}
  359. }
  360. count, err = x.Count(&ExternalLoginUser{LoginSourceID: source.ID})
  361. if err != nil {
  362. return err
  363. } else if count > 0 {
  364. return ErrLoginSourceInUse{source.ID}
  365. }
  366. if source.IsOAuth2() {
  367. oauth2.RemoveProvider(source.Name)
  368. }
  369. _, err = x.ID(source.ID).Delete(new(LoginSource))
  370. return err
  371. }
  372. // CountLoginSources returns number of login sources.
  373. func CountLoginSources() int64 {
  374. count, _ := x.Count(new(LoginSource))
  375. return count
  376. }
  377. // .____ ________ _____ __________
  378. // | | \______ \ / _ \\______ \
  379. // | | | | \ / /_\ \| ___/
  380. // | |___ | ` \/ | \ |
  381. // |_______ \/_______ /\____|__ /____|
  382. // \/ \/ \/
  383. func composeFullName(firstname, surname, username string) string {
  384. switch {
  385. case len(firstname) == 0 && len(surname) == 0:
  386. return username
  387. case len(firstname) == 0:
  388. return surname
  389. case len(surname) == 0:
  390. return firstname
  391. default:
  392. return firstname + " " + surname
  393. }
  394. }
  395. var (
  396. alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
  397. )
  398. // LoginViaLDAP queries if login/password is valid against the LDAP directory pool,
  399. // and create a local user if success when enabled.
  400. func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
  401. sr := source.Cfg.(*LDAPConfig).SearchEntry(login, password, source.Type == LoginDLDAP)
  402. if sr == nil {
  403. // User not in LDAP, do nothing
  404. return nil, ErrUserNotExist{0, login, 0}
  405. }
  406. var isAttributeSSHPublicKeySet = len(strings.TrimSpace(source.LDAP().AttributeSSHPublicKey)) > 0
  407. // Update User admin flag if exist
  408. if isExist, err := IsUserExist(0, sr.Username); err != nil {
  409. return nil, err
  410. } else if isExist &&
  411. !user.ProhibitLogin && len(source.LDAP().AdminFilter) > 0 && user.IsAdmin != sr.IsAdmin {
  412. // Change existing admin flag only if AdminFilter option is set
  413. user.IsAdmin = sr.IsAdmin
  414. err = UpdateUserCols(user, "is_admin")
  415. if err != nil {
  416. return nil, err
  417. }
  418. }
  419. if !autoRegister {
  420. if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(user, source, sr.SSHPublicKey) {
  421. return user, RewriteAllPublicKeys()
  422. }
  423. return user, nil
  424. }
  425. // Fallback.
  426. if len(sr.Username) == 0 {
  427. sr.Username = login
  428. }
  429. // Validate username make sure it satisfies requirement.
  430. if alphaDashDotPattern.MatchString(sr.Username) {
  431. return nil, fmt.Errorf("Invalid pattern for attribute 'username' [%s]: must be valid alpha or numeric or dash(-_) or dot characters", sr.Username)
  432. }
  433. if len(sr.Mail) == 0 {
  434. sr.Mail = fmt.Sprintf("%s@localhost", sr.Username)
  435. }
  436. user = &User{
  437. LowerName: strings.ToLower(sr.Username),
  438. Name: sr.Username,
  439. FullName: composeFullName(sr.Name, sr.Surname, sr.Username),
  440. Email: sr.Mail,
  441. LoginType: source.Type,
  442. LoginSource: source.ID,
  443. LoginName: login,
  444. IsActive: true,
  445. IsAdmin: sr.IsAdmin,
  446. }
  447. err := CreateUser(user)
  448. if err == nil && isAttributeSSHPublicKeySet && addLdapSSHPublicKeys(user, source, sr.SSHPublicKey) {
  449. err = RewriteAllPublicKeys()
  450. }
  451. return user, err
  452. }
  453. // _________ __________________________
  454. // / _____/ / \__ ___/\______ \
  455. // \_____ \ / \ / \| | | ___/
  456. // / \/ Y \ | | |
  457. // /_______ /\____|__ /____| |____|
  458. // \/ \/
  459. type smtpLoginAuth struct {
  460. username, password string
  461. }
  462. func (auth *smtpLoginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
  463. return "LOGIN", []byte(auth.username), nil
  464. }
  465. func (auth *smtpLoginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
  466. if more {
  467. switch string(fromServer) {
  468. case "Username:":
  469. return []byte(auth.username), nil
  470. case "Password:":
  471. return []byte(auth.password), nil
  472. }
  473. }
  474. return nil, nil
  475. }
  476. // SMTP authentication type names.
  477. const (
  478. SMTPPlain = "PLAIN"
  479. SMTPLogin = "LOGIN"
  480. )
  481. // SMTPAuths contains available SMTP authentication type names.
  482. var SMTPAuths = []string{SMTPPlain, SMTPLogin}
  483. // SMTPAuth performs an SMTP authentication.
  484. func SMTPAuth(a smtp.Auth, cfg *SMTPConfig) error {
  485. c, err := smtp.Dial(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port))
  486. if err != nil {
  487. return err
  488. }
  489. defer c.Close()
  490. if err = c.Hello("gogs"); err != nil {
  491. return err
  492. }
  493. if cfg.TLS {
  494. if ok, _ := c.Extension("STARTTLS"); ok {
  495. if err = c.StartTLS(&tls.Config{
  496. InsecureSkipVerify: cfg.SkipVerify,
  497. ServerName: cfg.Host,
  498. }); err != nil {
  499. return err
  500. }
  501. } else {
  502. return errors.New("SMTP server unsupports TLS")
  503. }
  504. }
  505. if ok, _ := c.Extension("AUTH"); ok {
  506. return c.Auth(a)
  507. }
  508. return ErrUnsupportedLoginType
  509. }
  510. // LoginViaSMTP queries if login/password is valid against the SMTP,
  511. // and create a local user if success when enabled.
  512. func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPConfig, autoRegister bool) (*User, error) {
  513. // Verify allowed domains.
  514. if len(cfg.AllowedDomains) > 0 {
  515. idx := strings.Index(login, "@")
  516. if idx == -1 {
  517. return nil, ErrUserNotExist{0, login, 0}
  518. } else if !com.IsSliceContainsStr(strings.Split(cfg.AllowedDomains, ","), login[idx+1:]) {
  519. return nil, ErrUserNotExist{0, login, 0}
  520. }
  521. }
  522. var auth smtp.Auth
  523. if cfg.Auth == SMTPPlain {
  524. auth = smtp.PlainAuth("", login, password, cfg.Host)
  525. } else if cfg.Auth == SMTPLogin {
  526. auth = &smtpLoginAuth{login, password}
  527. } else {
  528. return nil, errors.New("Unsupported SMTP auth type")
  529. }
  530. if err := SMTPAuth(auth, cfg); err != nil {
  531. // Check standard error format first,
  532. // then fallback to worse case.
  533. tperr, ok := err.(*textproto.Error)
  534. if (ok && tperr.Code == 535) ||
  535. strings.Contains(err.Error(), "Username and Password not accepted") {
  536. return nil, ErrUserNotExist{0, login, 0}
  537. }
  538. return nil, err
  539. }
  540. if !autoRegister {
  541. return user, nil
  542. }
  543. username := login
  544. idx := strings.Index(login, "@")
  545. if idx > -1 {
  546. username = login[:idx]
  547. }
  548. user = &User{
  549. LowerName: strings.ToLower(username),
  550. Name: strings.ToLower(username),
  551. Email: login,
  552. Passwd: password,
  553. LoginType: LoginSMTP,
  554. LoginSource: sourceID,
  555. LoginName: login,
  556. IsActive: true,
  557. }
  558. return user, CreateUser(user)
  559. }
  560. // __________ _____ _____
  561. // \______ \/ _ \ / \
  562. // | ___/ /_\ \ / \ / \
  563. // | | / | \/ Y \
  564. // |____| \____|__ /\____|__ /
  565. // \/ \/
  566. // LoginViaPAM queries if login/password is valid against the PAM,
  567. // and create a local user if success when enabled.
  568. func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMConfig, autoRegister bool) (*User, error) {
  569. if err := pam.Auth(cfg.ServiceName, login, password); err != nil {
  570. if strings.Contains(err.Error(), "Authentication failure") {
  571. return nil, ErrUserNotExist{0, login, 0}
  572. }
  573. return nil, err
  574. }
  575. if !autoRegister {
  576. return user, nil
  577. }
  578. user = &User{
  579. LowerName: strings.ToLower(login),
  580. Name: login,
  581. Email: login,
  582. Passwd: password,
  583. LoginType: LoginPAM,
  584. LoginSource: sourceID,
  585. LoginName: login,
  586. IsActive: true,
  587. }
  588. return user, CreateUser(user)
  589. }
  590. // ExternalUserLogin attempts a login using external source types.
  591. func ExternalUserLogin(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
  592. if !source.IsActived {
  593. return nil, ErrLoginSourceNotActived
  594. }
  595. var err error
  596. switch source.Type {
  597. case LoginLDAP, LoginDLDAP:
  598. user, err = LoginViaLDAP(user, login, password, source, autoRegister)
  599. case LoginSMTP:
  600. user, err = LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig), autoRegister)
  601. case LoginPAM:
  602. user, err = LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig), autoRegister)
  603. default:
  604. return nil, ErrUnsupportedLoginType
  605. }
  606. if err != nil {
  607. return nil, err
  608. }
  609. // WARN: DON'T check user.IsActive, that will be checked on reqSign so that
  610. // user could be hint to resend confirm email.
  611. if user.ProhibitLogin {
  612. return nil, ErrUserProhibitLogin{user.ID, user.Name}
  613. }
  614. return user, nil
  615. }
  616. // UserSignIn validates user name and password.
  617. func UserSignIn(username, password string) (*User, error) {
  618. var user *User
  619. if strings.Contains(username, "@") {
  620. user = &User{Email: strings.ToLower(strings.TrimSpace(username))}
  621. // check same email
  622. cnt, err := x.Count(user)
  623. if err != nil {
  624. return nil, err
  625. }
  626. if cnt > 1 {
  627. return nil, ErrEmailAlreadyUsed{
  628. Email: user.Email,
  629. }
  630. }
  631. } else {
  632. trimmedUsername := strings.TrimSpace(username)
  633. if len(trimmedUsername) == 0 {
  634. return nil, ErrUserNotExist{0, username, 0}
  635. }
  636. user = &User{LowerName: strings.ToLower(trimmedUsername)}
  637. }
  638. hasUser, err := x.Get(user)
  639. if err != nil {
  640. return nil, err
  641. }
  642. if hasUser {
  643. switch user.LoginType {
  644. case LoginNoType, LoginPlain, LoginOAuth2:
  645. if user.IsPasswordSet() && user.ValidatePassword(password) {
  646. // Update password hash if server password hash algorithm have changed
  647. if user.PasswdHashAlgo != setting.PasswordHashAlgo {
  648. user.HashPassword(password)
  649. if err := UpdateUserCols(user, "passwd", "passwd_hash_algo"); err != nil {
  650. return nil, err
  651. }
  652. }
  653. // WARN: DON'T check user.IsActive, that will be checked on reqSign so that
  654. // user could be hint to resend confirm email.
  655. if user.ProhibitLogin {
  656. return nil, ErrUserProhibitLogin{user.ID, user.Name}
  657. }
  658. return user, nil
  659. }
  660. return nil, ErrUserNotExist{user.ID, user.Name, 0}
  661. default:
  662. var source LoginSource
  663. hasSource, err := x.ID(user.LoginSource).Get(&source)
  664. if err != nil {
  665. return nil, err
  666. } else if !hasSource {
  667. return nil, ErrLoginSourceNotExist{user.LoginSource}
  668. }
  669. return ExternalUserLogin(user, user.LoginName, password, &source, false)
  670. }
  671. }
  672. sources := make([]*LoginSource, 0, 5)
  673. if err = x.Where("is_actived = ?", true).Find(&sources); err != nil {
  674. return nil, err
  675. }
  676. for _, source := range sources {
  677. if source.IsOAuth2() || source.IsSSPI() {
  678. // don't try to authenticate against OAuth2 and SSPI sources here
  679. continue
  680. }
  681. authUser, err := ExternalUserLogin(nil, username, password, source, true)
  682. if err == nil {
  683. return authUser, nil
  684. }
  685. log.Warn("Failed to login '%s' via '%s': %v", username, source.Name, err)
  686. }
  687. return nil, ErrUserNotExist{user.ID, user.Name, 0}
  688. }