Allow only certain users to upload
Rizhiy opened this issue · comments
Hi, I'm trying to run a private server and I understand that I can restrict access with -P
and -a
.
The way I currently understand it is that the same permissions are set for all users.
Is it possible to have different permissions for different users?
I need two types of users:
- "standard" user, which will be able to only list & download/install packages.
- "admin" user which will be able to upload packages as well.
If a request does not provide a valid username & password, it should be denied completely.
How can I achieve this?
@Rizhiy I've written a proxy application to do this, that implements a per group and per user access controls for list/download/upload. That sat in front of the simple APIs and filtered out the results as needed. Unfortunately this isn't currently a open source project.
This is functionality I'm looking for too. I'm not against making a pull request, but could use some guidance on how authorizing could be handled per user.
I'm inclined to introduce a new property to the config called authorizer
and use that authorizer function to handle the per-user authorization. It's a little weird cause it is so similar to the auther
function, but it seems like a larger breaking change if the auther
function is updated to take an action in addition to the user name and password it already takes.
More concretely, once an authorizer
function was available, I'd change the logic here to look like this so that both the auther
and authorizer
functions would be applied to each request to authenticate/authorize the requested action:
if (
config.auther(*request.auth)
and config.authorizer(request.auth[0], request.auth[1], self.action)
):
return method(*args, **kwargs)
raise HTTPError(403)
I made a draft PR of this notion here, but it is untested and there is still more work to do before the PR would be mergable (e.g. tests)
I made another PR to try to support this feature here: #483 . This PR is more of a breaking change, but is simpler then adding another auth function.
Just making an enquiry as this is a feature that I am interested in. Do you want a helping hand with this?
hey @tdg5 and @ghinks, sorry for quite some silence on this feature proposal! I do really like the idea but didn't get to get to reviewing it yet indeed, sorry about this 😔 If you are both interested, I'd of course really appreciate any help in getting this forward!
As a quick question to brush up my mind, @tdg5, which of the two proposed solutions do you like more yourself? 😊 As far as I understand one of them is more breaking but more ready to merge and the other gives a good sample of the idea but might need some more work in finalizing - sorry if I get something wrong but am I on a correct line?
@ghinks if you're interested in taking a look at both PRs, please go ahead, I'd be very happy to hear your input too! And in the meantime I'll also try to dive a little deeper into them both.
@vEpiphyte thank you for the post above suggesting an nginx solution. I am looking at all angles for a solution to providing upload access to only certain users. Please may I ask your approach with nginx? What I want to know is how you approached this. Did you use 2 different auth_basic_user_files one for regular auth and one for enhanced access to upload? If you did how did you map the different request_methods in nginx to the same base route "/". From my reading of the nginx documents you can map different auth_basic_user_file ( something like .httpasswd & .adminhttpw ) to different location routes but not the same route on different request methods? A code snippet from you may help my understanding.
Sorry for the radio silence. I've been using a branch with this commit that adds action
as an argument to the auther
function. I've found that it works well for my purposes and I haven't had any need to change it. I think adding action
as an argument to auther
is the simplest solution, but wasn't sure how y'all typically handle breaking API changes, so wasn't sure how y'all'd want to proceed. I, personally, prefer a python approach over an nginx approach since I'm handling JWT tokens and I think that kind of setup would be cumbersome with nginx, but I could be mistaken.
Let me know if there's anything I can do to help make this behavior part of pypiserver
so I can kill that branch 😀
Thank you. Let me look into the changes you have on this branch. Offering an Nginx docker-compose as the skeleton of a solution is not mutually exclusive of also having a python based solution as Nginx offers other directives such as slowing down 401 responses to maker attacks harder etc. I'll follow up and get to understand your changes now.