We are using MavenArtifactRepository to wire our d...
# community-support
e
We are using MavenArtifactRepository to wire our dependencies to our own internal Artifactory instance. User provide their id and artifactory token via their gradle.properties file ... everything pretty standard. But thing is. it happens quite often that the users have an invalid artifactory token. And if that happens and gradle needs to download from our artifactory server, the error that users see looks like this:
Copy code
* What went wrong:
Plugin [id: 'org.gradle.kotlin.kotlin-dsl', version: '6.6.4'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Included Builds (No included builds contain this plugin)
- Plugin Repositories (could not resolve plugin artifact 'org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:6.6.4')
  Searched in the following repositories:
    maven(<https://eu.artifactory.whatever.com/artifactory/foobarblub>)
Token invalid , download not possible, but a "not found error" In order to make our tooling more user friendly, we added a "ping" check to our toplevel settings.gradle file. Artifactory servers have a "ping" endpoint, so do a GET request ... and if that fails with a 401 or 403, the token is not valid, and we can print a nice error message. But: this means that any single gradle invocation sends such a "ping" to the Artifactory servers. And now we regularly see failures on our CI build servers with Artifactory complaining about "too many requests". Before we had this "ping" solution, we tried to somehow "catch" the actual "not found error" that I showed above, but I couldn't get that to work reliably. Any idea if/how we can reliably give "good" error messages when Artifactory downloads fail (because of that bad token), without hammering the servers with every gradle invocation?
p
With Gradle 9.8, you can return Problem Details: https://www.rfc-editor.org/rfc/rfc9457.html. But you should also return a 403 instead of a 404.
e
Is there any example code how to do that with gradle 9.8? I assume this is functionality works with the RC, too?
p
Yes, the RC does work. Your artifactory “just” needs to return Problem details.
e
How would that "manifest" on the gradle side? Would it simply show up in the stack trace? Is there a way to process that those Problems Details?
p
Yeah, the details will be shown to the user by default, via the Gradle Problem API.
v
Not too familiar with Artifactory, but I guess the intention is to not give information out. If you for example have a login dialog somewhere or is usually considered a security flaw if you say "login is wrong" or "password is wrong" as an attacker then at least knows when he found a valid login but not yet the correct password. Same might be the case here. If someone does not have a valid login, he just gets 404 always instead of the proper 403 to not spoil the information that the requested artifact exists, which in the case of Gradle as consumer is ... unlucky. If that is the case, then Artifactory will also not use the problem details RFC, or it could right away return 403 which is all information you need here. One possible proper solution would be use a different server. Maybe Nexus for example has a different behavior. Another possible proper solution would be a proxy in front that in 404 uses the ping everyone to decide whether it is a real 404 or potentially a 403 and then return 403 no matter whether the requested artifact exists. Better would maybe be, if Artifactory always returned 403 for an invalid token, whether the artist exists or not, then the proxy is not necessary. Maybe Artifactory can be configured to do so or you can get a feature request done for that.
👍 1
hideUnauthorizedResources
probably is the Artifactory setting you are after
l
Why not check the tokens BEFORE doing calls to Artifactory. If its a JWT, just do a quick check. Then run the build. IF the build fails, look for instances of
MultiCauseException
to figure out which repo calls failed and ping only the failed ones. Fix whatever the issue was (network, bad token....) Re-run the build.
e
That is what we implemented. So, any gradle invocation taps the "ping" API endpoint of the artifactory server. Leading to "too many requests" on those.
p
If the token is a JWT, you could check the expiration date locally.
e
That's true. That won't catch situations where people invalidated their token by mistake, but it would be a good starting point.
l
CHecking the JWT token shouldn't require a ping like @Philip W mentioned (you should check locally). Only resort to a remote check if it fails.
v
If it fails you shouldn't need a remote check, should you? If it fails it cannot be remotely valid, can it? The point was, if it is locally valid, but remote rejects it. Then you would have the same behavior and to also catch that, you would again need a remote ping each time.
e
Yes, I think the local check would catch 90+% of most user errors. For those remaining, it might be an option to do the "ping" on request.
Follow up question ... is there any robust way to simply detect that artifactory failed. I don't care for the actual reason ... but if I code run code after a download failed, I could run the "ping" in that scenario.