repman icon indicating copy to clipboard operation
repman copied to clipboard

GitLab sync issue

Open amrography opened this issue 2 years ago • 15 comments

I can't sync gitlab projects or add new one.

Screen Shot 2022-05-19 at 12 21 53 PM Screen Shot 2022-05-19 at 12 22 02 PM

amrography avatar May 19 '22 10:05 amrography

What version of GitLab are you running?

I had an issue after the upgrade to GitLab 15, but somehow managed to sort it by trying to Add Projects twice until I got redirected to GitLab, then projects seemed to sync again.

giggsey avatar May 27 '22 10:05 giggsey

@giggsey It happens on the last version of gitlab.com. They published a new release that expires Oauth tokens. So every time we'll need to unlink Gitlab and link again to refresh the token.

hugodeaguiar avatar May 27 '22 10:05 hugodeaguiar

Take a look: https://about.gitlab.com/blog/2022/04/18/gitlab-releases-15-breaking-changes/#oauth-tokens-without-an-expiration

hugodeaguiar avatar May 27 '22 10:05 hugodeaguiar

Can you enhance the token refresh mechanism in repman so we can access gitlab again?

kristofnk avatar May 27 '22 20:05 kristofnk

@giggsey Yes, I am doing this now. Thanks for the tip.

amrography avatar May 28 '22 18:05 amrography

@giggsey Yes, I am doing this now. Thanks for the tip.

I need to retest, as I expect it'll be erroring again due to the token expiring

Edit:

Now getting the same as OP Error: An error occurred while refreshing the access token: Bad Request

giggsey avatar May 28 '22 18:05 giggsey

any updates on this?

trace:

RuntimeException:
An error occurred while refreshing the access token: Bad Request

  at src/Entity/User/OAuthToken.php:102
  at Buddy\Repman\Entity\User\OAuthToken->accessToken(object(UserOAuthTokenRefresher))
     (src/Service/User/UserOAuthTokenProvider.php:31)
  at Buddy\Repman\Service\User\UserOAuthTokenProvider->findAccessToken('2648dada-XXXX-4f08-XXXX-b6240d1e71c7', 'gitlab')
     (src/Controller/Organization/PackageController.php:253)
  at Buddy\Repman\Controller\Organization\PackageController->packageNewFromGitLab(object(Form), object(Organization), object(Request))
     (src/Controller/Organization/PackageController.php:87)
  at Buddy\Repman\Controller\Organization\PackageController->packageNew(object(Organization), object(Request), 'gitlab')
     (vendor/symfony/http-kernel/HttpKernel.php:152)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:74)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:202)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (public/index.php:48)                

Fahl-Design avatar Jun 07 '22 09:06 Fahl-Design

+1

tecbird avatar Jun 08 '22 09:06 tecbird

FYI: I found the root cause, the "redirect_uri" must always be the same when requesting a new token with a refresh token

  • at registration redirect_uri .../register/gitlab/check is used
  • when this token expires and an UpdateMessage is trigger a refresh a token is requested with redirect_uri: ../user/token/gitlab/check
  • this will result in:
{
  "error": "invalid_grant",
  "error_description": "The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
}

Fahl-Design avatar Jun 09 '22 17:06 Fahl-Design

@amrography any chance we can get a refactored oauth flow (with a single redirect uri in any case) any time soon? Is a pain to fix it in a running container ;)

Fahl-Design avatar Jun 15 '22 12:06 Fahl-Design

Hi @Fahl-Design, can you write a small summary how to fix it in a running container? Would be very helpful until this issue is fixed in repman itself.

KSauter avatar Jun 20 '22 11:06 KSauter

@KSauter yes, my boss may found an other hotfix:

  • remove current token(s) from database table "user_oauth_token"
  • relink the user you want to use
  • open vendor/league/oauth2-client/src/Provider/AbstractProvider.php and goto \League\OAuth2\Client\Provider\AbstractProvider::getAccessToken
  • force .../register/gitlab/check url for "refresh_token" requests like:
if ($params['grant_type'] === 'refresh_token') {
  $params['redirect_uri'] = 'https://<YOUR_REPMAN_URI>/register/gitlab/check';
}

to verify:

  • change token expire date in database and try to update a package
  • see if token/expire date gets updated

Fahl-Design avatar Jun 20 '22 11:06 Fahl-Design

@Fahl-Design Thanks for the update! I updated the expires_at to be in the past, and the update was successful without any code change

update user_oauth_token set expires_at = '2022-06-20 10:10:10' where id = 'xxx';

KSauter avatar Jun 20 '22 12:06 KSauter

@KSauter yes it will work when the token was generated with redirect_uri "/user/token/gitlab/check" (which is the case when you generate the user token by adding a package. when you link the account first, it will fail later

you can see it with some hacky style debug logging (remove tmp fix first)

public function getAccessToken($grant, array $options = [])
    {
        $grant = $this->verifyGrant($grant);

        $params = [
            'client_id'     => $this->clientId,
            'client_secret' => $this->clientSecret,
            'redirect_uri'  => $this->redirectUri,
        ];

        $params   = $grant->prepareRequestParameters($params, $options);
// tmp fix
if ($params['grant_type'] === 'refresh_token') {
  $params['redirect_uri'] = 'https://<YOUR_REPMAN_URI>/register/gitlab/check';
}
        try {
            file_put_contents('/tmp/repman.log', var_export($params, true) ."\n".var_export($options, true) , FILE_APPEND | LOCK_EX);
            $request  = $this->getAccessTokenRequest($params);
        } catch (\Throwable $e) {
            dd($e);
        }

        $response = $this->getParsedResponse($request);
        if (false === is_array($response)) {
            throw new UnexpectedValueException(
                'Invalid response received from Authorization Server. Expected JSON.'
            );
        }
        $prepared = $this->prepareAccessTokenResponse($response);
        $token    = $this->createAccessToken($prepared, $grant);

        return $token;
    }

Fahl-Design avatar Jun 20 '22 12:06 Fahl-Design

@Fahl-Design i checked further and found that the refresh-token isn't updated by the token refresh. This will invalidate the refresh token for the next use.

See PR https://github.com/repman-io/repman/pull/596

KSauter avatar Jun 20 '22 16:06 KSauter