Deprecate UserIdMapper and just use an HMAC#10926
Deprecate UserIdMapper and just use an HMAC#10926NotMyFault merged 7 commits intojenkinsci:masterfrom
UserIdMapper and just use an HMAC#10926Conversation
| or greater issues in the realm change, could affect currently logged | ||
| in users and even the user making the change. */ |
There was a problem hiding this comment.
Not sure rekey has any real test coverage.
jenkins/test/src/test/java/hudson/model/UserTest.java
Lines 223 to 266 in eab026b
There was a problem hiding this comment.
(Interactive testing with mock-security-realm seems fine: switching the id strategy renames the dir of a user whose id contains uppercase letters.)
| return new File(Jenkins.get().getRootDir(), "users"); | ||
| } | ||
|
|
||
| private static final int PREFIX_MAX = 14; |
There was a problem hiding this comment.
Original version in UserIdMapper set this to 15 but then subtracted one for the _. I find this a bit clearer. Of course the size is arbitrary; here it allows directory names up to 79 (ASCII) characters, which I think is safe on all operating systems. The bigger concern on Windows is a total path length approaching (IIRC) 254, when not using the UNC \\?\ trick, but if you control the %JENKINS_HOME% length, this should not be too bad: C:\Jenkins\users\quixotichacker_01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b\config.xml is only 107.
There was a problem hiding this comment.
The bigger concern on Windows is a total path length approaching (IIRC) 254, when not using the UNC \?\ trick, but if you control the %JENKINS_HOME% length, this should not be too bad:
Java has been using the unicode API with \\?\ for a loooong time.
https://github.com/openjdk/jdk21u-dev/blame/d90297a828dff468afc34e2767439e51379f4f95/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java#L174-L178
There was a problem hiding this comment.
OK, I just recall problems with branch-api on Windows.
There was a problem hiding this comment.
with
branch-apion Windows.
🤔 it should have only been an issue with other tools (like git.exe) and the like, nothing directly inside the JVM (calling cmd.exe from a durable task for example in a long directory would be fun).
There was a problem hiding this comment.
an issue with other tools (like
git.exe) and the like
Ah, perhaps so, in which case that would indeed not be a concern here.
| return userDetails.getUsername(); | ||
| } catch (UsernameNotFoundException x) { | ||
| LOGGER.log(Level.FINE, "not sure whether " + idOrFullName + " is a valid username or not", x); | ||
| LOGGER.log(Level.FINER, "not sure whether " + idOrFullName + " is a valid username or not", x); |
| XSTREAM.alias("user", User.class); | ||
| } | ||
|
|
||
| private User() {} |
There was a problem hiding this comment.
There is a subtle difference between calling the no-arg ctor and unmarshalling into that object, vs. deserializing a new object: whether properties (and, if anyone cares, version) are initialized.
| var d = getUserFolderFor(id); | ||
| return d.isDirectory() ? d : null; |
There was a problem hiding this comment.
Dubious (normally you would just want to get the File unconditionally whether it currently exists or not), but following the existing nullability annotation and semantics.
| if (!migratedUserIdMapper) { | ||
| try { | ||
| UserIdMapper.migrate(); |
There was a problem hiding this comment.
May happen prior to scanAll if JCasC defines users in the built-in realm (mostly useful for demos).
jtnord
left a comment
There was a problem hiding this comment.
Seems reasonable but appears to be lacking any test coverage for the older data migration?
| user.id = idKey; // not quite right but hoping for the best | ||
| userXml.write(user); | ||
| } | ||
| var newDirectory = User.getUserFolderFor(user.id); |
There was a problem hiding this comment.
seems weired that the users folder uses the normalized user id, but we don;t actually store that in the User.id here or when creating a new User?
There was a problem hiding this comment.
Sorry, I am not following this comment.
There was a problem hiding this comment.
not related (directly) to this change.
if you say log in first with "JOE" then your user.id can be JOE (but the keyfor will create this file as it if is for "joe". if you later log in with "joe" (your user will load, but your user.id will be "JOE") (yes its the same user, but there is no normalisation going on).
There was a problem hiding this comment.
Indeed the first login will store $JENKINS_HOME/users/joe_deadbeef1234/config.xml with
<id>JOE</id>and I suppose that will be your id henceforth, even if User.getById("joe", …) is called. I think nothing in this PR is changing that; the previous format would have written the same XML content to $JENKINS_HOME/users/JOE_11772365/config.xml and an entry joe → JOE_11772365 to $JENKINS_HOME/users.xml but otherwise behaved the same.
| private final int version = 1; // Not currently used, but it may be helpful in the future to store a version. | ||
|
|
||
| private transient File usersDirectory; | ||
| // contrary to the name, the keys were actually IdStrategy.keyFor, not necessarily ids |
There was a problem hiding this comment.
Not sure what this comment is trying to imply, keyFor creates the normalized id. If you are saying that this can also contain Names (when the id is not known and this is from say an SCM commit) then that should not be persisted so should not have a directory Name?
There was a problem hiding this comment.
keyForcreates the normalizedid
Right, which is not necessarily the id. So the map should really have been named something like idKeyToDirectoryName. That is all.
No newly written coverage currently, though various cases are in fact tested implicitly via |
… `UserIdMigratorTest/migrateMultipleUsers/users/foo$002fbar/config.xml`
|
/label ready-for-merge This PR is now ready for merge, after ~24 hours, we will merge it if there's no negative feedback. Thanks! |
|
Hello, I am encountering a problem when using the latest version of Jenkins in my company. Jenkins is deployed in a k3s cluster as a pod. Each Jenkins pod is customised using the as code plugin. We back up the user folder and the jov folder so that we do not lose our data. Thanks, J. Pallier (Team CI from Lectra) |
|
Token migration problems from this PR are tracked in https://issues.jenkins.io/browse/JENKINS-76269. |
|
please check #16840 (comment) |
Subsumes both #10870 and #10871, following @daniel-beck’s suggestion recorded in #10871 (comment). With this change, the logic of managing
Users is simplified in most respects: everyidgets a predictable directory name determined by a secure hash of the currentIdStrategyand a per-controller secret, so no index is needed. The directory names are also strictly sanitized against dangerous characters (asUserIdMapperdid), and it should not be possible to construct anidwhich would hash to a given directory name.Testing done
A 2.516.x version passes CloudBees CI PCT & ATH. 2d18199 passed
bomPCT. Light interactive testing withmock-security-realm.Proposed changelog entries
$JENKINS_HOME/users/.$JENKINS_HOME/users/users.xml.Proposed changelog category
/label removed
Proposed upgrade guidelines
No action is necessary when upgrading. Downgrading past this version (without restoring from backup) may lose user records including configuration such as API tokens.
Maintainer checklist
upgrade-guide-neededlabel is set and there is a Proposed upgrade guidelines section in the pull request title (see example).lts-candidateto be considered (see query).