cannot propose a member to a team through launchpadlib

Bug #498181 reported by Pedro Villavicencio
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Launchpad itself
Fix Released
High
Edwin Grubbs

Bug Description

I've created a script to propose members to a team the script is located here:

http://paste.ubuntu.com/343748/

We managed to propose two members (dwstirton and a-s-techgeek) to the bugsquad-mentorship team but as of today is not working anymore and we're getting 401 errors:

/lp-propose-mship.py mahen
The authorization page:
   (https://staging.launchpad.net/+authorize-token?oauth_token=hXjs4Mhct2JDT36qpv4V)
should be opening in your browser. After you have authorized
this program to access Launchpad on your behalf you should come
back here and press <Enter> to finish the authentication process.

mahen
Traceback (most recent call last):
  File "./lp-propose-mship.py", line 24, in <module>
    team.addMember (person=student, status='Proposed', comment='proposing a new student to the bugsquad mentorship group')
  File "/usr/lib/python2.6/dist-packages/lazr/restfulclient/resource.py", line 460, in __call__
    url, in_representation, http_method, extra_headers=extra_headers)
  File "/usr/lib/python2.6/dist-packages/lazr/restfulclient/_browser.py", line 204, in _request
    raise HTTPError(response, content)
lazr.restfulclient.errors.HTTPError: HTTP Error 401: Unauthorized

Tags: lp-registry

Related branches

Revision history for this message
Eleanor Berger (intellectronica) wrote :

I can reproduce this on staging.

Revision history for this message
Eleanor Berger (intellectronica) wrote :

Also, the same works fine using the web UI.

Revision history for this message
Eleanor Berger (intellectronica) wrote :

Actually, after removing my cache (and saved credentials) I can run on staging without a problem. Pedro, can you please try again with clear cache and new credentials?

Revision history for this message
Curtis Hovey (sinzui) wrote :

Hi Edwin.

I know you are working or an ajax version of adding a team member that will change the API a bit. Please review this script because it illustrates a use case we want to support. It is still unclear if the issue is launchpad or stale client-caches, but we know this scenario is one that must work.

Changed in launchpad-registry:
status: New → Triaged
importance: Undecided → High
milestone: none → 3.1.13
assignee: nobody → Edwin Grubbs (edwin-grubbs)
Revision history for this message
Pedro Villavicencio (pedro) wrote :

Hello Tom, I've cleaned up my cache and credentials, but i'm getting the same error.

Revision history for this message
C de-Avillez (hggdh2) wrote :

I had:

* deleted the ~.launchpadlib directory completely
* deleted *all* OAUTHs registered in EDGE and STAGING

Then I ran the script against both EDGE and STAGING, both failed with 401. New credentials were (or seemed to have been) created successfully.

I will try again.

Please note that -- different from Pedro's original hack -- I am *not* specifying a cache directory, so the lib is defaulting to ~/.launchpadlib.

Revision history for this message
Markus Korn (thekorn) wrote :

I can reproduce this problem, this is the error I get (please see the attached log for complete debug output):
I'm using a tempdir as cache/for credentials, so I don't have possibly broken stuff around.

HTTPError: HTTP Error 401: Unauthorized
---------------------------------------------------------------------------
Response: {'content-length': '108',
 'content-type': 'text/plain',
 'date': 'Fri, 18 Dec 2009 14:36:19 GMT',
 'server': 'zope.server.http (HTTP)',
 'status': '401',
 'via': '1.1 wildcard.staging.launchpad.net',
 'x-lazr-oopsid': 'OOPS-1448S169',
 'x-powered-by': 'Zope (www.zope.org), Python (www.python.org)'}
Content: "(<EmailAddress at 0x97bdd50 <email address hidden> [Preferred Email Address]>, 'email', 'launchpad.View')"
---------------------------------------------------------------------------

Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

There is a separate join() method that needs to be exposed on the api. join() is called on the team that will become a new member, whereas addMember() is called on the team that will get a new member; therefore, you the team you need to be an admin on changes depending on which method you call. The need for separate methods is caused by zope's security wrapper.

Revision history for this message
Markus Korn (thekorn) wrote :
Revision history for this message
C de-Avillez (hggdh2) wrote :

In this case all of us (Markus, Pedro, and myself) are admins on the bugsquad-mentorship team, and we are just proposing members (not really adding):

team = launchpad.people['bugsquad-mentorship']
people = launchpad.people

for arg in sys.argv[1:]:
    student = people [arg]
    team.addMember (person=student, status='Proposed', comment='proposing a new student to the bugsquad mentorship group')

so it is indeed the [busquad-memtorship].addMember method we should use.

Changed in launchpad-registry:
status: Triaged → In Progress
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

The join() named operation is already exposed. I don't know how I missed that before. Be aware of bug 504297 that prevents you from calling named operations on launchpad.me if you are using launchpadlib as the client.

Instead of
  launchpad.me.join(team=launchpad.people['foo'])
use
  launchpad.people[launchpad.me.name].join(team=launchpad.people['foo'])
or
  launchpad.load(launchpad.me.self_link).join(team=launchpad.people['foo'])

Changed in launchpad-registry:
status: In Progress → Invalid
Revision history for this message
C de-Avillez (hggdh2) wrote :

I am not sure about join(), since we were using addMember() -- the single method, to my knowledge, that allows for *proposing* somebody else (than launchpad.me).

join() does not allow for that, so we are still stuck.

Reopening. Issue still exists.

Changed in launchpad-registry:
status: Invalid → New
Curtis Hovey (sinzui)
Changed in launchpad-registry:
status: New → In Progress
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

Hi C de-Avillez,

I'm sorry for the confusion. It appears you are using the PROPOSED status in a way that is completely different from how the UI uses it. I would like to get more information from you so we can determine the best solution going forward.

For example, with Team Alpha with Owner Alpha and Team Beta with Owner Beta:
  * Owner Beta can propose Team Beta as a member of Team Alpha.
  * Owner Beta can propose himself as a member of Team Alpha.
  * Owner Alpha can invite Team Beta as a member of Team Alpha.

I am assuming that an admin of the bugsquad-membership team is authenticating via launchpadlib and trying to propose someone else. Is there a reason that you aren't adding a new member with APPROVED status? In some ways, the INVITED status might make more sense, although that status was only intended for use with teams.

Currently, when a user proposes themself as a member of a team, they are revealing there email address to the admins of that team, so the admins can ask them why they want to become a member. If we removed the current error, an admin of any team could harvest hidden email addresses from users just by proposing them. Therefore, we must be careful in how we solve this problem.

Revision history for this message
C de-Avillez (hggdh2) wrote :

Hi Edwin,

Yes, given what you describe above, we are most certainly abusing the API -- but, in our defence, this is not documented :-)

First of all -- this was a hack. When we started the bug-squad mentorship programme (which, BTW, still needs a lot of details worked out), we were asking the cadidates to email the ML asking for it. Eventually we decided this was not working, and moved over to a LP team, where the candidates would propose themselves (very much like you expected). When a candidate is accepted for mentorship, the mentor would them accept this candidate into the team.

But we were left with a number of candidates, waiting for a response to their ML request. So Pedro and I went on with this hack, with the idea of getting these candidates, and proposing them to the team -- where they would wait for a mentor to pick them up. This was done mostly out of respect with them (they *did* follow the procedures in place; if we changed the procedures later on, the then-currently pending candidates should not be penalised).

Since, it seems, we are the first to try it (and Pedro actually *did* succeed when he first tried, then we had a new LP deployment, and both Pedro and I could not do it anymore), then I guess this is not a critical issue. I still see benefits if this is allowed, though.

But.

I just went and looked at some of the currently proposed members, via the UI (on edge). I still cannot see the email address(es) of those that set it as private, and I am one of the team admins.

How is it the email address gets revealed? This is actually a relevant question, since a team admin can always contact a candidate via standard UI (via the ./+contactuser), like anybody else. And, if someone decided to set email to private, this setting should be respected everywhere.

Oooh, I see now where this is done -- on the LP email sent of behalf of the team, the proponent is CC-ed. I humbly suggest this is wrong (either always, or if email is set to private, the proponent should be BCC-ed).

Revision history for this message
Curtis Hovey (sinzui) wrote :

This is an interesting workflow. I hope we can make this work well.

HIdden email address can be seen and used by the Launchpad admins only. Registry Admins can see hidden email addresses on the user's profile page, but cannot use them (we get errors trying to access them in scripts). In the case of Contact-the-user, the person who is sending the message is choosing to reveal his address to the other person. The person who receives the message may also have a hidden address, and he must decide how to reply--he could reveal his email address, or reply from another email address, or use Contact-this-user.

In the case of joining a team, the team admins and the user get separate emails because their actions are different. PROPOSED means that the admins get an email to approve the proosed user. Yhe user has no idea he is now proposed because the pupose of PROPSED is intended for the user. Since the mailing code "knows" that the user doing the PROPOSING can see his own address there are no security checks. We could add a security check to the email code because the users are getting separate emails--the team admins will not see this PROPOSED user's email address.

The question is should we allow this inverted process. Someone could use it to add me to a thousand team. That would be very bad for me.

Revision history for this message
C de-Avillez (hggdh2) wrote :

Thank you for your explanation.

Now, supposing this is considered A Good Thing To Do (TM):

First, on your last point -- the most that can be done is *proposing* you to a team. Of course, most probably LP Registry will simply *add* a proposed person to an open group (caveat: I have not looked this up in the code).

Anyway, this could be controlled quite effectively by allowing proposals only from self or an admin of the target group. Then, standard abuse control can be used (a request to answers.lp stating the abuse, or a ping on #launchpad, etc). Also, as far as I can understand, ADD requests are restricted to self or the target team admin(s), so this should not cause unexpected grief.

Now, the emailing piece: if I understand it correctly, we *do* have a potential breach of privacy here: suppose we have UserA and UserB, both with private email addresses, and no other recorded means of communication. Now UserA needs to contact UserB. If UserA sends UserB an email via ./+contactuser, then UserA will have her/his email sent to UserB. In other words, LP offers a communication path (./+contactuser), but does not respect privacy settings. It would be better -- for example -- to have LP interface between both UserA and UserB: UserA uses ./+contactuser, LP sends an email on behalf of UserA (https://lp.net~UserA), but does not add UserA's email address to the headers. UserB, then, can respond to UserA using https://lp.net/~UserA (by clicking on the Contact User link).

Finally: I do not know if this should be allowed or not. I see not big nefarious consequences if it is implemented with the controls I point above. And existing capabilities are better than existing (or future) needs ;-)

Note that this does not matter for me -- my email is public on LP.

Revision history for this message
Curtis Hovey (sinzui) wrote :

The Contact-this-user scenario is not a security breach. It is a design descion that when a user chooses to communicate, he cannot hide. Launchpad, and teams in particular, are designed to facilate communication. We do honour a user's desire to not display email addresses in the UI, but we do not want to allow users to work anonymously. Users must be willing to share their contact their information when they choose to contact other users.

Revision history for this message
C de-Avillez (hggdh2) wrote :

Heh. I did not say it was a security breach -- it is not. I stated it was a potential privacy breach, which is not quite the same. But the design decision and the the reasoning (if I want to contact another user I must be willing to disclose some data -- i.e, email address --) shows this was considered and accepted. And there is a clear warning on the pane. I consider myself corrected ;-)

summary: - cannot propose a member to a team trough launchpadlib
+ cannot propose a member to a team through launchpadlib
Revision history for this message
Curtis Hovey (sinzui) wrote :

Fixed in Launchpad devel r10169.

Changed in launchpad-registry:
status: In Progress → Fix Committed
Curtis Hovey (sinzui)
Changed in launchpad-registry:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.