pypiserver / pypiserver

Minimal PyPI server for uploading & downloading packages with pip/easy_install

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.