zorn-v / nextcloud-social-login

GNU Affero General Public License v3.0
199 stars 138 forks source link

Redirect URI causes SQL error "lastval is not yet defined" #308

Closed hirunatan closed 2 years ago

hirunatan commented 2 years ago

Hello. I have set up login with google in my nextcloud instance. It works OK except that, when google calls back to the redirect_uri after connecting an existing account, it shows a 500 error page. Looking at server logs, I see an error with this message in the php log of the nextcloud app:

"An exception occurred while executing a query: SQLSTATE[55000]: Object not in prerequisite state: 7 ERROR: lastval is not yet defined in this session"

These are my versions: nextcloud 22.2.0 social-login 4.8.10 postgresql 12.5

Any clue? Thanks very much!

This is the full error trace (i have removed personal info and keys):

{
  "reqId": "zsV4ky2SClwDHATqXukg",
  "level": 3,
  "time": "2021-10-29T06:53:07+00:00",
  "remoteAddr": "82.158.62.139",
  "user": "hirunatan",
  "app": "index",
  "method": "GET",
  "url": "/apps/sociallogin/oauth/google?state=<state>&code=<code>&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.profile%20openid%20https://www.googleapis.com/auth/userinfo.email&authuser=1&hd=<domain>&prompt=none",
  "message": "An exception occurred while executing a query: SQLSTATE[55000]: Object not in prerequisite state: 7 ERROR: lastval is not yet defined in this session",
  "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
  "version": "22.2.0.2",
  "exception": {
    "Exception": "OC\\\\DB\\\\Exceptions\\\\DbalException",
    "Message": "An exception occurred while executing a query: SQLSTATE[55000]: Object not in prerequisite state: 7 ERROR: lastval is not yet defined in this session",
    "Code": 7,
    "Trace": [
      {
        "file": "/app/code/lib/private/DB/ConnectionAdapter.php",
        "line": 93,
        "function": "wrap",
        "class": "OC\\\\DB\\\\Exceptions\\\\DbalException",
        "type": "::"
      },
      {
        "file": "/app/code/lib/private/DB/QueryBuilder/QueryBuilder.php",
        "line": 1293,
        "function": "lastInsertId",
        "class": "OC\\\\DB\\\\ConnectionAdapter",
        "type": "->"
      },
      {
        "file": "/app/code/lib/public/AppFramework/Db/QBMapper.php",
        "line": 143,
        "function": "getLastInsertId",
        "class": "OC\\\\DB\\\\QueryBuilder\\\\QueryBuilder",
        "type": "->"
      },
      {
        "file": "/app/data/apps/sociallogin/lib/Db/ConnectedLoginMapper.php",
        "line": 56,
        "function": "insert",
        "class": "OCP\\\\AppFramework\\\\Db\\\\QBMapper",
        "type": "->"
      },
      {
        "file": "/app/data/apps/sociallogin/lib/Service/ProviderService.php",
        "line": 396,
        "function": "connectLogin",
        "class": "OCA\\\\SocialLogin\\\\Db\\\\ConnectedLoginMapper",
        "type": "->"
      },
      {
        "file": "/app/data/apps/sociallogin/lib/Service/ProviderService.php",
        "line": 378,
        "function": "login",
        "class": "OCA\\\\SocialLogin\\\\Service\\\\ProviderService",
        "type": "->",
        "args": [
          "*** sensitive parameters replaced ***"
        ]
      },
      {
        "file": "/app/data/apps/sociallogin/lib/Service/ProviderService.php",
        "line": 251,
        "function": "auth",
        "class": "OCA\\\\SocialLogin\\\\Service\\\\ProviderService",
        "type": "->"
      },
      {
        "file": "/app/data/apps/sociallogin/lib/Controller/LoginController.php",
        "line": 28,
        "function": "handleDefault",
        "class": "OCA\\\\SocialLogin\\\\Service\\\\ProviderService",
        "type": "->"
      },
      {
        "file": "/app/code/lib/private/AppFramework/Http/Dispatcher.php",
        "line": 217,
        "function": "oauth",
        "class": "OCA\\\\SocialLogin\\\\Controller\\\\LoginController",
        "type": "->"
      },
      {
        "file": "/app/code/lib/private/AppFramework/Http/Dispatcher.php",
        "line": 126,
        "function": "executeController",
        "class": "OC\\\\AppFramework\\\\Http\\\\Dispatcher",
        "type": "->"
      },
      {
        "file": "/app/code/lib/private/AppFramework/App.php",
        "line": 156,
        "function": "dispatch",
        "class": "OC\\\\AppFramework\\\\Http\\\\Dispatcher",
        "type": "->"
      },
      {
        "file": "/app/code/lib/private/Route/Router.php",
        "line": 301,
        "function": "main",
        "class": "OC\\\\AppFramework\\\\App",
        "type": "::"
      },
      {
        "file": "/app/code/lib/base.php",
        "line": 1000,
        "function": "match",
        "class": "OC\\\\Route\\\\Router",
        "type": "->"
      },
      {
        "file": "/app/code/index.php",
        "line": 36,
        "function": "handleRequest",
        "class": "OC",
        "type": "::"
      }
    ],
    "File": "/app/code/lib/private/DB/Exceptions/DbalException.php",
    "Line": 71,
    "Previous": {
      "Exception": "Doctrine\\\\DBAL\\\\Exception\\\\DriverException",
      "Message": "An exception occurred while executing a query: SQLSTATE[55000]: Object not in prerequisite state: 7 ERROR: lastval is not yet defined in this session",
      "Code": 7,
      "Trace": [
        {
          "file": "/app/code/3rdparty/doctrine/dbal/src/Connection.php",
          "line": 1728,
          "function": "convert",
          "class": "Doctrine\\\\DBAL\\\\Driver\\\\API\\\\PostgreSQL\\\\ExceptionConverter",
          "type": "->"
        },
        {
          "file": "/app/code/3rdparty/doctrine/dbal/src/Connection.php",
          "line": 1667,
          "function": "handleDriverException",
          "class": "Doctrine\\\\DBAL\\\\Connection",
          "type": "->"
        },
        {
          "file": "/app/code/3rdparty/doctrine/dbal/src/Connection.php",
          "line": 1040,
          "function": "convertExceptionDuringQuery",
          "class": "Doctrine\\\\DBAL\\\\Connection",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/DB/Connection.php",
          "line": 231,
          "function": "executeQuery",
          "class": "Doctrine\\\\DBAL\\\\Connection",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/DB/AdapterPgSql.php",
          "line": 33,
          "function": "executeQuery",
          "class": "OC\\\\DB\\\\Connection",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/DB/Connection.php",
          "line": 282,
          "function": "lastInsertId",
          "class": "OC\\\\DB\\\\AdapterPgSql",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/DB/ConnectionAdapter.php",
          "line": 91,
          "function": "lastInsertId",
          "class": "OC\\\\DB\\\\Connection",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/DB/QueryBuilder/QueryBuilder.php",
          "line": 1293,
          "function": "lastInsertId",
          "class": "OC\\\\DB\\\\ConnectionAdapter",
          "type": "->"
        },
        {
          "file": "/app/code/lib/public/AppFramework/Db/QBMapper.php",
          "line": 143,
          "function": "getLastInsertId",
          "class": "OC\\\\DB\\\\QueryBuilder\\\\QueryBuilder",
          "type": "->"
        },
        {
          "file": "/app/data/apps/sociallogin/lib/Db/ConnectedLoginMapper.php",
          "line": 56,
          "function": "insert",
          "class": "OCP\\\\AppFramework\\\\Db\\\\QBMapper",
          "type": "->"
        },
        {
          "file": "/app/data/apps/sociallogin/lib/Service/ProviderService.php",
          "line": 396,
          "function": "connectLogin",
          "class": "OCA\\\\SocialLogin\\\\Db\\\\ConnectedLoginMapper",
          "type": "->"
        },
        {
          "file": "/app/data/apps/sociallogin/lib/Service/ProviderService.php",
          "line": 378,
          "function": "login",
          "class": "OCA\\\\SocialLogin\\\\Service\\\\ProviderService",
          "type": "->",
          "args": [
            "*** sensitive parameters replaced ***"
          ]
        },
        {
          "file": "/app/data/apps/sociallogin/lib/Service/ProviderService.php",
          "line": 251,
          "function": "auth",
          "class": "OCA\\\\SocialLogin\\\\Service\\\\ProviderService",
          "type": "->"
        },
        {
          "file": "/app/data/apps/sociallogin/lib/Controller/LoginController.php",
          "line": 28,
          "function": "handleDefault",
          "class": "OCA\\\\SocialLogin\\\\Service\\\\ProviderService",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/AppFramework/Http/Dispatcher.php",
          "line": 217,
          "function": "oauth",
          "class": "OCA\\\\SocialLogin\\\\Controller\\\\LoginController",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/AppFramework/Http/Dispatcher.php",
          "line": 126,
          "function": "executeController",
          "class": "OC\\\\AppFramework\\\\Http\\\\Dispatcher",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/AppFramework/App.php",
          "line": 156,
          "function": "dispatch",
          "class": "OC\\\\AppFramework\\\\Http\\\\Dispatcher",
          "type": "->"
        },
        {
          "file": "/app/code/lib/private/Route/Router.php",
          "line": 301,
          "function": "main",
          "class": "OC\\\\AppFramework\\\\App",
          "type": "::"
        },
        {
          "file": "/app/code/lib/base.php",
          "line": 1000,
          "function": "match",
          "class": "OC\\\\Route\\\\Router",
          "type": "->"
        },
        {
          "file": "/app/code/index.php",
          "line": 36,
          "function": "handleRequest",
          "class": "OC",
          "type": "::"
        }
      ],
      "File": "/app/code/3rdparty/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php",
      "Line": 83,
      "Previous": {
        "Exception": "Doctrine\\\\DBAL\\\\Driver\\\\PDO\\\\Exception",
        "Message": "SQLSTATE[55000]: Object not in prerequisite state: 7 ERROR: lastval is not yet defined in this session",
        "Code": 7,
        "Trace": [
          {
            "file": "/app/code/3rdparty/doctrine/dbal/src/Driver/PDO/Connection.php",
            "line": 87,
            "function": "new",
            "class": "Doctrine\\\\DBAL\\\\Driver\\\\PDO\\\\Exception",
            "type": "::"
          },
          {
            "file": "/app/code/3rdparty/doctrine/dbal/src/Connection.php",
            "line": 1035,
            "function": "query",
            "class": "Doctrine\\\\DBAL\\\\Driver\\\\PDO\\\\Connection",
            "type": "->"
          },
          {
            "file": "/app/code/lib/private/DB/Connection.php",
            "line": 231,
            "function": "executeQuery",
            "class": "Doctrine\\\\DBAL\\\\Connection",
            "type": "->"
          },
          {
            "file": "/app/code/lib/private/DB/AdapterPgSql.php",
            "line": 33,
            "function": "executeQuery",
            "class": "OC\\\\DB\\\\Connection",
            "type": "->"
          },
          {
            "file": "/app/code/lib/private/DB/Connection.php",
            "line": 282,
            "function": "lastInsertId",
            "class": "OC\\\\DB\\\\AdapterPgSql",
            "type": "->"
          },
          {
            "file": "/app/code/lib/private/DB/ConnectionAdapter.php",
            "line": 91,
            "function": "lastInsertId",
            "class": "OC\\\\DB\\\\Connection",
            "type": "->"
          },
          {
            "file": "/app/code/lib/private/DB/QueryBuilder/QueryBuilder.php",
            "line": 1293,
            "function": "lastInsertId",
            "class": "OC\\\\DB\\\\ConnectionAdapter",
            "type": "->"
          }
        ]
      }
    }
  }
}
zorn-v commented 2 years ago

Why you think that my app is reason of your problem ?

hirunatan commented 2 years ago

From the trace call stack:

    {
        "file": "/app/data/apps/sociallogin/lib/Db/ConnectedLoginMapper.php",
        "line": 56,
        "function": "insert",
        "class": "OCP\\\\AppFramework\\\\Db\\\\QBMapper",
        "type": "->"
      },

The error seems to occur inside the sociallogin app. And also it happens while processing the redirect_api call at /apps/sociallogin/oauth/google url, that is also likely to be from this app. Isn't it?

zorn-v commented 2 years ago

You configure my app, your DB can not insert record, and I am guilty ? Just disable my app if you think so.

zorn-v commented 2 years ago

Or tell what EXACTLY you does.

zorn-v commented 2 years ago

Sorry was nervous. Are you using DB in container that may be restarted after login flow is started and before it finished ?

hirunatan commented 2 years ago

Ok, no problem. Anyone may have a bad day, if this does not happen very often it doesn't matter :smiley:

I use nextcloud with the social-login app inside a docker container, and I think that it does not restart any time. I use PostgreSQL as the database.

I have investigated it a bit further. The error occurs in sociallogin/lib/Db/ConnectedLoginMapper.php, the function is

public function connectLogin($uid, $identifier)
{
    $l = new ConnectedLogin();
    $l->setUid($uid);
    $l->setIdentifier($identifier);
    $this->insert($l);
}

This executes an insert, that at some point calls lastInsertId function, that is defined here in the PgSql adapter:

    public function lastInsertId($table) {
        $result = $this->conn->executeQuery('SELECT lastval()');
        $val = $result->fetchOne();
        $result->free();
        return (int)$val;
    }

The insert function uses lastInsertId to return the id of the newly inserted row. BUT this lastval() function used assume that the table we are on has a PK that is a serial sequence field. If there is no serial field in the table, it causes the given error "lastval is not yet defined".

I'm not sure, but it seems that the table being used for social login (I think 'sociallogin_connect' is the name) perhaps has a PK that is not a serial sequence. Could it be? I don't understand the code very well so I can't state it firmly. But perhaps you have any clue about this, you know well the app. Do you think this could be the cause of the failure?

Thanks for your patience and your help!

zorn-v commented 2 years ago

Check v4.9.1 Thanks for investigations, it helps.

hirunatan commented 2 years ago

Ey, thanks very much! It seems to work well now, after updating to new version. Good work!