<p dir="auto">I've changed the directory of caravel.db to a local path.<br>
When I restarted the machine and exeuted the "pip install caravel --upgrade",<br>
input the "caravel db upgrade", the error is "sqlalchemy.exc.OperationalError: (pysqlite2.dbapi2.OperationalError) duplicate column name: verbose_name [SQL: u'ALTER TABLE table_columns ADD COLUMN verbose_name VARCHAR(1024)']"</p>
<p dir="auto">then I input the "caravel init", and error is "sqlalchemy.exc.OperationalError: (pysqlite2.dbapi2.OperationalError) no such column: sql_metrics.is_restricted [SQL: u'SELECT sql_metrics.created_on AS sql_metrics_created_on, sql_metrics.changed_on AS sql_metrics_changed_on, sql_metrics.id AS sql_metrics_id, sql_metrics.metric_name AS sql_metrics_metric_name, sql_metrics.verbose_name AS sql_metrics_verbose_name, sql_metrics.metric_type AS sql_metrics_metric_type, sql_metrics.table_id AS sql_metrics_table_id, sql_metrics.expression AS sql_metrics_expression, sql_metrics.description AS sql_metrics_description, sql_metrics.is_restricted AS sql_metrics_is_restricted, sql_metrics.changed_by_fk AS sql_metrics_changed_by_fk, sql_metrics.created_by_fk AS sql_metrics_created_by_fk \nFROM sql_metrics']"</p>
<p dir="auto">I tried many ways to solve this problem, but none of them worked.</p>
<p dir="auto">Thanks for your solution,<br>
best</p>
<p dir="auto">Can't login via OAuth2 LDAP with some issues.</p>
<ol dir="auto">
<li>Error with <code class="notranslate">client_id=None</code></li>
<li>Error <code class="notranslate">ERROR:flask_appbuilder.security.views:Error returning OAuth user info: name 'logging' is not defined</code></li>
</ol>
<p dir="auto">First issue is docs-based, because with config:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="'consumer_key':'SOME_CLIENT_ID',
'consumer_secret':'SOME_SECRET'"><pre class="notranslate"><code class="notranslate">'consumer_key':'SOME_CLIENT_ID',
'consumer_secret':'SOME_SECRET'
</code></pre></div>
<p dir="auto">says Keycloak this: <code class="notranslate">... type=LOGIN_ERROR, realmId=SOME_REALM, clientId=None, userId=null, ...</code>, so Superset don't care about <code class="notranslate">client_id</code>.<br>
When I've duplicated <code class="notranslate">consumer_key</code> as <code class="notranslate">client_id</code> it started working up to the second problem.</p>
<p dir="auto">Second problem is Error written above. Keycloak says:<br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/11560794/109177050-b243a500-7787-11eb-97af-b6d0a4cfcabe.png"><img src="https://user-images.githubusercontent.com/11560794/109177050-b243a500-7787-11eb-97af-b6d0a4cfcabe.png" alt="image" style="max-width: 100%;"></a><br>
and <code class="notranslate">ERROR:flask_appbuilder.security.views:Error returning OAuth user info: name 'logging' is not defined</code>. IDK what to do :/</p>
<h3 dir="auto">Expected results</h3>
<p dir="auto">Successful OAuth2 login</p>
<h3 dir="auto">Actual results</h3>
<p dir="auto">Lying docs, can't easily setup OAuth2</p>
<h4 dir="auto">How to reproduce the bug</h4>
<ol dir="auto">
<li>Try to setup OAuth2 with keycloak provider</li>
</ol>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>superset version: <code class="notranslate">1.0.1</code></li>
<li>python version: <code class="notranslate">3.8.7</code></li>
<li>node.js version: <code class="notranslate">v12.18.4</code></li>
</ul>
<h3 dir="auto">Checklist</h3>
<p dir="auto">Make sure to follow these steps before submitting your issue - thank you!</p>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the superset logs for python stacktraces and included it here as text if there are any.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have reproduced the issue with at least the latest released version of superset.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the issue tracker for the same issue and I haven't found one similar.</li>
</ul>
<h3 dir="auto">Additional context</h3>
<p dir="auto"><em>superset_config.py</em></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="...
#---------------------------------------------------------
# OAuth Config
#---------------------------------------------------------
from custom_sso_security_manager import CustomSsoSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager

AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [
    {   'name':'SSO',
        'token_key':'access_token', # Name of the token in the response of access_token_url
        'icon':'fa-address-card',   # Icon for the provider
        'remote_app': {
            'consumer_key':'SOME_CLIENT_ID',  # Client Id (Identify Superset application)
            'client_id':'SOME_CLIENT_ID',  # Client Id (Identify Superset application)
            'consumer_secret':'SOME_CLIENT_SECRET', # Secret for this Client Id (Identify Superset application)
            'client_secret':'SOME_CLIENT_SECRET', # Secret for this Client Id (Identify Superset application)
            'request_token_params':{
                'scope': 'email profile'               # Scope for the Authorization
            },
            'access_token_method':'POST',    # HTTP Method to call access_token_url
            'access_token_params':{        # Additional parameters for calls to access_token_url
                'client_id':'SOME_CLIENT_ID'
            },
            'access_token_headers':{    # Additional headers for calls to access_token_url
                'Authorization': 'Basic Base64EncodedClientIdAndSecret'
            },
            'base_url':'https://&lt;KEYCLOAK_URL&gt;/auth/realms/&lt;REALM&gt;',
            'access_token_url':'https://&lt;KEYCLOAK_URL&gt;/auth/realms/&lt;REALM&gt;/protocol/openid-connect/token',
            'authorize_url':'https://&lt;KEYCLOAK_URL&gt;/auth/realms/&lt;REALM&gt;/protocol/openid-connect/auth'
        }
    }
]
..."><pre class="notranslate"><code class="notranslate">...
#---------------------------------------------------------
# OAuth Config
#---------------------------------------------------------
from custom_sso_security_manager import CustomSsoSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager

AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [
    {   'name':'SSO',
        'token_key':'access_token', # Name of the token in the response of access_token_url
        'icon':'fa-address-card',   # Icon for the provider
        'remote_app': {
            'consumer_key':'SOME_CLIENT_ID',  # Client Id (Identify Superset application)
            'client_id':'SOME_CLIENT_ID',  # Client Id (Identify Superset application)
            'consumer_secret':'SOME_CLIENT_SECRET', # Secret for this Client Id (Identify Superset application)
            'client_secret':'SOME_CLIENT_SECRET', # Secret for this Client Id (Identify Superset application)
            'request_token_params':{
                'scope': 'email profile'               # Scope for the Authorization
            },
            'access_token_method':'POST',    # HTTP Method to call access_token_url
            'access_token_params':{        # Additional parameters for calls to access_token_url
                'client_id':'SOME_CLIENT_ID'
            },
            'access_token_headers':{    # Additional headers for calls to access_token_url
                'Authorization': 'Basic Base64EncodedClientIdAndSecret'
            },
            'base_url':'https://&lt;KEYCLOAK_URL&gt;/auth/realms/&lt;REALM&gt;',
            'access_token_url':'https://&lt;KEYCLOAK_URL&gt;/auth/realms/&lt;REALM&gt;/protocol/openid-connect/token',
            'authorize_url':'https://&lt;KEYCLOAK_URL&gt;/auth/realms/&lt;REALM&gt;/protocol/openid-connect/auth'
        }
    }
]
...
</code></pre></div>
<p dir="auto"><em>custom_sso_security_manager.py</em></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="from superset.security import SupersetSecurityManager

class CustomSsoSecurityManager(SupersetSecurityManager):

    def oauth_user_info(self, provider, response=None):
        logging.debug(&quot;Oauth2 provider: {0}.&quot;.format(provider))
        if provider == 'SSO':
            # As example, this line request a GET to base_url + '/' + userDetails with Bearer  Authentication,
    # and expects that authorization server checks the token, and response with user details
            me = self.appbuilder.sm.oauth_remotes[provider].get('userDetails').data
            logging.debug(&quot;user_data: {0}&quot;.format(me))
            return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''}
    ..."><pre class="notranslate"><code class="notranslate">from superset.security import SupersetSecurityManager

class CustomSsoSecurityManager(SupersetSecurityManager):

    def oauth_user_info(self, provider, response=None):
        logging.debug("Oauth2 provider: {0}.".format(provider))
        if provider == 'SSO':
            # As example, this line request a GET to base_url + '/' + userDetails with Bearer  Authentication,
    # and expects that authorization server checks the token, and response with user details
            me = self.appbuilder.sm.oauth_remotes[provider].get('userDetails').data
            logging.debug("user_data: {0}".format(me))
            return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''}
    ...
</code></pre></div>
<p dir="auto">It's configured exactly as in <a href="https://superset.apache.org/docs/installation/configuring-superset#custom-oauth2-configuration" rel="nofollow">docs</a> <em>(except the client ID that's not working as in docs)</em></p>