-
Notifications
You must be signed in to change notification settings - Fork 238
Added ability to delete the default admin user #1131
Conversation
I would recommend that #1129 is merged before this. |
airsonic-main/src/main/java/org/airsonic/player/dao/UserDao.java
Outdated
Show resolved
Hide resolved
airsonic-main/src/main/java/org/airsonic/player/service/SecurityService.java
Outdated
Show resolved
Hide resolved
I'll test this one as soon as #1129 is merged :) |
Due to changes in another PR, this will probably have merge conflicts, but I'll fix them after #1129 is merged. |
fbbab4f
to
f166818
Compare
airsonic-main/src/main/java/org/airsonic/player/controller/GeneralSettingsController.java
Outdated
Show resolved
Hide resolved
airsonic-main/src/main/java/org/airsonic/player/validator/UserSettingsValidator.java
Outdated
Show resolved
Hide resolved
f166818
to
8f84733
Compare
This seems bizzare to me. What is the benefit of adding an AdminUser setting? IMO we should either go all the way to Roles where there can be multiple admin users or leave it as is. |
This PR just makes it so that the "primary admin" user can be any account rather than being hardcoded as the user with the username of Roles do already allow for multiple accounts to have "admin" privileges, but I think it still makes sense to have a special "primary" admin account that has special protections and actions, such as not being allowed to be deleted (even by other users with the admin role). For simplicity and a clean PR, this doesn't add anything additional, but I could see things like the primary admin account automatically having access to all media directories, whereas now individual accounts, even if they have the "admin" role do not. There may be other "special" things that would be useful as well. But if you would prefer not to have anything past the more general "admin" role, I can probably rework the PR to do that. |
@muff1nman Did you still want changes to this in order to merge it? |
My gut feeling is that we should either leave it as is or go all the way to an admin role that can be assigned. Having a |
179e3e4
to
b535324
Compare
I've updated this PR as @muff1nman has requested to not have a "special" admin account and instead use only roles for admin. A side effect of this change is that automatic playlist imports do not work any longer, since there is no "primary" user to own them, and there is not (yet) any way to auto-import playlists for individual users. One way of resolving this is described in #233 (comment) |
b535324
to
c3a571a
Compare
Fixed the merge conflicts from other merges. |
c3a571a
to
811a46e
Compare
airsonic-main/src/main/java/org/airsonic/player/controller/LoginController.java
Show resolved
Hide resolved
airsonic-main/src/main/java/org/airsonic/player/controller/SubsonicRESTController.java
Show resolved
Hide resolved
error(request, response, ErrorCode.NOT_FOUND, "No such user: " + username); | ||
return; | ||
} else if (user.getUsername().equals(username)) { | ||
error(request, response, ErrorCode.NOT_AUTHORIZED, "Not allowed to delete own user"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about "You're not allowed to delete your own user" instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since these messages are in the REST API, I kept them very terse, as no one should ever see them except developers.
airsonic-main/src/main/java/org/airsonic/player/service/PlaylistService.java
Outdated
Show resolved
Hide resolved
@@ -296,8 +295,11 @@ private void importPlaylistIfUpdated(File file, List<Playlist> allPlaylists) thr | |||
} | |||
InputStream in = new FileInputStream(file); | |||
try { | |||
importPlaylist(User.USERNAME_ADMIN, FilenameUtils.getBaseName(fileName), fileName, in, existingPlaylist); | |||
LOG.info("Auto-imported playlist " + file); | |||
// FIXME - With the transition away from a hardcoded admin account to Admin Roles, there is no longer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be fixed before merging this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No one has suggested a good solution to this issue, and I don't want fixing this security issue to wait on one. This side effect has only become a problem because @muff1nman wanted not to keep a "primary" admin user, so I've changed the PR to comply with that request. @muff1nman which would you prefer, keeping this version with this side effect, or going back to the original version of this PR that kept a "primary" admin user?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm probably going to work on the solution I proposed in #233 (comment) at some point which would resolve this playlist issue as well as many others, but that is almost certainly going to be a low priority, and again I don't want to wait on something like that for this to get merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now could you chose the first admin user found? Really I'd like to see the playlist owner field be nullable but that will probably take some work todo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not put in a half-baked hack, since it seems unlikely that playlist importing is all that usable in its current form anyway(*). I'd rather get the security regarding the hardcoded admin account fixed and merged, and then later get some focus on improving/fixing the playlist functionality.
(*) Is there even any documentation on how the playlist importing stuff is supposed to work that would help anyone actually use it? For instance, how are files in the playlist supposed to have their paths specified? How does it pick which media folder is used as the base? etc...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used it a year ago. I don't think the negligible security gained here is worth losing the feature over.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muff1nman So then would you prefer that I revert back to the original version of this PR that kept a "primary" admin user, in order to preserve the playlist functionality? I don't want to put playlist overhaul in as part of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope I'd prefer you kept it as is. For the playlist user you can:
- Use the first admin user
- Allow the playlist import user to be configurable
- Change the playlist to allow a nullable user field
Although I still think 3 would be ideal/workable, 1 or 2 would be considerably easier and be much better than straight out removing this functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As requested, PR has been modified to use the first admin account for playlist imports.
811a46e
to
3761340
Compare
This transitions to solely using Admin Roles rather than a hardcoded admin account. This allows for deleting the initial admin account, which had previously been a security weakness since the account name was not able to be changed. Fixes airsonic#640.
3761340
to
aa81d26
Compare
return user.getUsername(); | ||
} | ||
} | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd throw an exception here instead of returning null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like returning exceptions from simple lookup functions, especially when returning null for "not found" is such a universally accepted (and expected) pattern. I think it restricts potential use cases unnecessarily and violates separation of concerns. Why should this function need to enforce that the higher level system thinks not having a user with a particular role is an exception-worthy problem?
In any case, I believe that when this function returns null, the calling site will still generate an exception when it tries to use the null value, and does so without this function needing to have any concept of higher level user permissions concerns.
I also didn't want to rule out the possibility that someone might want to completely lock down their installation by disabling all admin accounts (even though doing so would require directly changing the db).
Returning null also allows for if/when someone changes the code to implement your suggestion number 3 above (making the owner of imported playlists nullable), although I admit that at that point this function might just be removed entirely, but who knows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muff1nman If throwing an exception is a requirement to get your approval, say so and I will change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like returning exceptions from simple lookup functions, especially when returning null for "not found" is such a universally accepted (and expected) pattern.
In Java land its not universally accepted. In other languages, go, c/c++, python, yes I would agree.
Why should this function need to enforce that the higher level system thinks not having a user with a particular role is an exception-worthy problem?
Its in the SecurityService and warrants a bit more checking around assumptions to ensure we fail fast. With this change we still have an assumption that there should always be at least one admin user. When that assumption changes, we should get this exception and we can change the code to deal with the new assumptions then.
I also didn't want to rule out the possibility that someone might want to completely lock down their installation by disabling all admin accounts (even though doing so would require directly changing the db)
In the case the user does this anything that uses this function should rightly be broken. If the calling code can be robust in the scenario of no admin users, its on the function to handle the exception.
Returning null also allows for if/when someone changes the code to implement your suggestion number 3 above (making the owner of imported playlists nullable), although I admit that at that point this function might just be removed entirely, but who knows?
And when that happens we can change/remove this code too :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be noted that the other user lookup functions already in SecurityService (e.g. getUserByName()
, getUserByEmail()
) also use returning null to indicate "not found", so throwing an exception rather than returning null would be inconsistent with those.
* @return username of admin user | ||
*/ | ||
public String getAdminUsername() { | ||
for (User user : userDao.getAllUsers()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor thing: we should probably make sure the order is consistent (order by id or user name), I'm not sure of the behavior of all databases, and this might be confusing if the order somehow changes between runs.
I'm seeing no issue for now in my instance after removing the |
I haven't see any issue, this sounds good to go! |
Let's go ahead and merge it. Thanks for the lot of work on this y'al! |
This transitions to solely using Admin Roles rather than a hardcoded admin
account. This allows for deleting the initial admin account, which had
previously been a security weakness since the account name was not able to
be changed. Fixes #640.