Zum Inhalt springen
Menü
Sie müssen registriert sein, um mit der Community zu interagieren.
Diese Frage wurde gekennzeichnet
1 Antworten
1383 Ansichten

I have configured Google Oauth, to allow 
1. allready pre-registred internal users to log in via google Oauth - works Ok
2. new external users to be registred via google Oauth as PUBLIC/Portal users(without pre-registration from backend) - doesnt work. 


They get error : "You do not have access to this database or your invitation has expired. Please ask for an invitation and be sure to follow the link in your invitation email." 


The google OAuth works ok for all odoo internal users (employess created in advance)
Seems this message is more "focused on internal users " I am not sure if I have something misconfigured or why I get this message.
One thing is sure : I dont want to manually register all public users, this doesnt give sense. Instead : Any gmail user should be able to log in to Odoo, not as internal user but at least as public user  (or portal user.... whatever)
Registration with username + password works OK off course, the problem I have is with Oauth.
Anybody can help?
odoo v16

Avatar
Verwerfen
Beste Antwort

Hi everyone!

In my case, with Odoo 18 with Nginx and despite having the web.base.url set to HTTPS, the Google OAuth authentication wasn't working. After analyzing and updating the code to make it more flexible, I've created a fixed version of the auth_oauth module that solves the common issues.


🔧 Issues Resolved:

🔒 HTTP URLs being sent to Google OAuth2

👤 Authentication failure with existing users

🌐 Google's redirect_uri_mismatch error

✉️ Duplicate email handling


💻 Code Improvements and changes made:

In controllers/main.py - list_providers method:


Added logic to force HTTPS on redirect URL Prevents Google rejection for HTTP use Maintains compatibility with existing configurations


  • Changes made in file main.py


  def list_providers(self):

      try:

          providers = request.env['auth.oauth.provider'].sudo().search_read([('enabled', '=', True)])

      except Exception:

          providers = []

      for provider in providers:

          # Force HTTPS in redirect URL

          base_url = request.httprequest.url_root

          if base_url.startswith('http://'):

              base_url = base_url.replace('http://', 'https://', 1)

          return_url = base_url + 'auth_oauth/signin'

          state = self.get_state(provider)

          params = dict(

              response_type='token',

              client_id=provider['client_id'],

              redirect_uri=return_url,

              scope=provider['scope'],

              state=json.dumps(state),

              # nonce=base64.urlsafe_b64encode(os.urandom(16)),

          )

          provider['auth_link'] = "%s?%s" % (provider['auth_endpoint'], werkzeug.urls.url_encode(params))

      return providers


  • Changes made in /models/res_users.py

 _auth_oauth_validate method:

Added detailed logging of the validation process Better error handling and response validation Clearer information about the authentication process


 _auth_oauth_signin method:

User search by email was implemented in addition to oauth_uid Automatic management of existing users Updating OAuth credentials for existing users Improved logging for diagnostics


@api.model

  def _auth_oauth_validate(self, provider, access_token):

          """ return the validation data corresponding to the access token """

          oauth_provider = self.env['auth.oauth.provider'].browse(provider)

          validation = self._auth_oauth_rpc(oauth_provider.validation_endpoint, access_token)

          if validation.get("error"):

              _logger.error("OAuth validation error: %s", validation['error'])

              raise Exception(validation['error'])

          if oauth_provider.data_endpoint:

              data = self._auth_oauth_rpc(oauth_provider.data_endpoint, access_token)

              validation.update(data)

          # Logging the validation data

          subject = next(filter(None, [

              validation.pop(key, None)

              for key in [

                  'sub',  # standard

                  'id',  # google v1 userinfo, facebook opengraph

                  'user_id',  # google tokeninfo, odoo (tokeninfo)

              ]

          ]), None)

          if not subject:

              _logger.error("Missing subject identity in validation data")

              raise AccessDenied('Missing subject identity')

          validation['user_id'] = subject

          return validation


  @api.model

  def _auth_oauth_signin(self, provider, validation, params):

          """ retrieve and sign in the user corresponding to provider and validated access token

              :param provider: oauth provider id (int)

              :param validation: result of validation of access token (dict)

              :param params: oauth parameters (dict)

              :return: user login (str)

              :raise: AccessDenied if signin failed

              This method can be overridden to add alternative signin methods.

          """

          oauth_uid = validation['user_id']

          email = validation.get('email')

          try:

              # First search for oauth_uid

              oauth_user = self.search([("oauth_uid", "=", oauth_uid), ('oauth_provider_id', '=', provider)])

              if not oauth_user and email:

                  # If not found, search by email.

                  oauth_user = self.search([("login", "=", email)])

                  if oauth_user:

                      # If the user with that email exists, we update their OAuth data

                      oauth_user.write({

                          'oauth_provider_id': provider,

                          'oauth_uid': oauth_uid,

                          'oauth_access_token': params['access_token']

                      })

              if not oauth_user:

                  raise AccessDenied()

              assert len(oauth_user) == 1

              oauth_user.write({'oauth_access_token': params['access_token']})

              return oauth_user.login

          except AccessDenied as access_denied_exception:

              if self.env.context.get('no_user_creation'):

                  return None

              state = json.loads(params['state'])

              token = state.get('t')

              values = self._generate_signup_values(provider, validation, params)

              try:

                  login, _ = self.signup(values, token)

                  return login

              except (SignupError, UserError) as e:

                  _logger.error("Failed to create new user: %s", str(e))

                  raise access_denied_exception

You can find it on github:

(Sorry but I can't post links yet.)


diegonaranjo/odoo-addons-auth_oauth


Please make sure to backup your existing module before making any changes. If you encounter any issues or need help, feel free to open an issue on the GitHub repository.

Hope this helps!

Avatar
Verwerfen
Verknüpfte Beiträge Antworten Ansichten Aktivität
1
Jan. 25
1851
2
Okt. 24
33
2
Mai 24
3016
2
Okt. 23
3987
1
Juli 23
3575