~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
Using BugTracker Login Tokens
=============================

# XXX: sinzui 2011-09-28 bug=861510: This test is disabled because it does
# not tear down all the way, breaking subsequent tests that use feature flags.

Launchpad offers an XML-RPC interface for generating bug tracker tokens.

    >>> import xmlrpclib
    >>> from zope.component import getUtility
    >>> from lp.testing.xmlrpc import XMLRPCTestTransport
    >>> from lp.services.verification.interfaces.logintoken import (
    ...     ILoginTokenSet)
    >>> bugtracker_api = xmlrpclib.ServerProxy(
    ...     'http://xmlrpc-private.launchpad.dev:8087/bugs',
    ...     transport=XMLRPCTestTransport())

    >>> token_string = bugtracker_api.newBugTrackerToken()
    >>> token = getUtility(ILoginTokenSet)[token_string]

These LoginTokens are used by Launchpad to authenticate with external
bug trackers. We pass the token to the bug tracker and it then makes a
POST request to the token's canonical URL to validate it.

    >>> from lp.services.webapp import canonical_url
    >>> from lp.services.webapp.servers import (
    ...     LaunchpadTestRequest)
    >>> test_request = LaunchpadTestRequest(method='POST')
    >>> token_url = canonical_url(
    ...     token, request=test_request, rootsite='mainsite',
    ...     view_name='+bugtracker-handshake')

    >>> print token_url
    http://launchpad.dev/token/.../+bugtracker-handshake

Visiting the token's +bugtracker-handshake URL will result in an HTTP
200 response if the token is valid.

    >>> from zope.component import getMultiAdapter
    >>> view = getMultiAdapter(
    ...     (token, test_request), name='+bugtracker-handshake')
    >>> view()
    'Handshake token validated.'

    >>> print test_request.response.getStatus()
    200

The token has now been consumed.

    >>> token = getUtility(ILoginTokenSet)[token_string]
    >>> print token.date_consumed is not None
    True

If we try to access the +bugtracker-handshake URL again, we will receive
an HTTP 410 (Gone) response.

    >>> view = getMultiAdapter(
    ...     (token, test_request), name='+bugtracker-handshake')
    >>> view()
    'Token has already been used or is invalid.'

    >>> print test_request.response.getStatus()
    410

Only POST requests are valid when accessing a +bugtracker-handshake URL.
If we attempt another request method, such as a GET, we will receive an
HTTP 405 (Method Not Allowed) response.

    >>> token_string = bugtracker_api.newBugTrackerToken()
    >>> token = getUtility(ILoginTokenSet)[token_string]
    >>> test_request = LaunchpadTestRequest(method='GET')

    >>> view = getMultiAdapter(
    ...     (token, test_request), name='+bugtracker-handshake')
    >>> view()
    'Only POST requests are accepted for bugtracker handshakes.'

    >>> print test_request.response.getStatus()
    405

However, since the request was invalid the token will not have been
consumed.

    >>> token = getUtility(ILoginTokenSet)[token_string]
    >>> print token.date_consumed
    None