sundawg_contacts 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ windows_live:
2
+ appid: your_app_id
3
+ secret: your_app_secret_key
4
+ security_algorithm: wsignin1.0
5
+ return_url: http://yourserver.com/your_return_url
6
+ policy_url: http://yourserver.com/you_policy_url
7
+
8
+ yahoo:
9
+ appid: i%3DB%26p%3DUw70JGIdHWVRbpqYItcMw--
10
+ secret: a34f389cbd135de4618eed5e23409d34450
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <frob>934-746563215463214621</frob>
4
+ </rsp>
@@ -0,0 +1,5 @@
1
+ <auth>
2
+ <token>45-76598454353455</token>
3
+ <perms>read</perms>
4
+ <user nsid="12037949754@N01" username="Bees" fullname="Cal H" />
5
+ </auth>
@@ -0,0 +1,48 @@
1
+ <feed>
2
+ <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
3
+ <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/>
4
+ <title>Elizabeth Bennet</title>
5
+ <content>My good friend, Liz. A little quick to judge sometimes, but nice girl.</content>
6
+ <gd:email rel='http://schemas.google.com/g/2005#work' primary='true' address='liz@gmail.com'/>
7
+ <gd:email rel='http://schemas.google.com/g/2005#home' address='liz@example.org'/>
8
+ <gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>
9
+ (206)555-1212
10
+ </gd:phoneNumber>
11
+ <gd:phoneNumber rel='http://schemas.google.com/g/2005#home'>
12
+ (206)555-1213
13
+ </gd:phoneNumber>
14
+ <gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>
15
+ (206) 555-1212
16
+ </gd:phoneNumber>
17
+ <gd:im rel='http://schemas.google.com/g/2005#home'
18
+ protocol='http://schemas.google.com/g/2005#GOOGLE_TALK'
19
+ address='liz@gmail.com'/>
20
+ <gd:postalAddress rel='http://schemas.google.com/g/2005#work' primary='true'>
21
+ 1600 Amphitheatre Pkwy
22
+ Mountain View, CA 94043
23
+ </gd:postalAddress>
24
+ <gd:postalAddress rel='http://schemas.google.com/g/2005#home'>
25
+ 800 Main Street
26
+ Mountain View, CA 94041
27
+ </gd:postalAddress>
28
+ <gd:organization>
29
+ <gd:orgName>Google, Inc.</gd:orgName>
30
+ <gd:orgTitle>Tech Writer</gd:orgTitle>
31
+ </gd:organization>
32
+ </entry>
33
+
34
+ <entry>
35
+ <title>Poor Jack</title>
36
+ <content>Poor Jack doesn't have an e-mail address</content>
37
+ </entry>
38
+
39
+ <entry>
40
+ <title>William Paginate</title>
41
+ <gd:email address='will_paginate@googlegroups.com' />
42
+ </entry>
43
+
44
+ <entry>
45
+ <content>This guy doesn't have a name</content>
46
+ <gd:email address='anonymous@example.com' />
47
+ </entry>
48
+ </feed>
@@ -0,0 +1,46 @@
1
+ <!-- source: http://code.google.com/apis/contacts/developers_guide_protocol.html -->
2
+ <feed xmlns='http://www.w3.org/2005/Atom'
3
+ xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
4
+ xmlns:gd='http://schemas.google.com/g/2005'>
5
+ <id>http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base</id>
6
+ <updated>2008-03-05T12:36:38.836Z</updated>
7
+ <category scheme='http://schemas.google.com/g/2005#kind'
8
+ term='http://schemas.google.com/contact/2008#contact' />
9
+ <title type='text'>Contacts</title>
10
+ <link rel='http://schemas.google.com/g/2005#feed'
11
+ type='application/atom+xml'
12
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base' />
13
+ <link rel='http://schemas.google.com/g/2005#post'
14
+ type='application/atom+xml'
15
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base' />
16
+ <link rel='self' type='application/atom+xml'
17
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base?max-results=25' />
18
+ <author>
19
+ <name>Elizabeth Bennet</name>
20
+ <email>liz@gmail.com</email>
21
+ </author>
22
+ <generator version='1.0' uri='http://www.google.com/m8/feeds/contacts'>
23
+ Contacts
24
+ </generator>
25
+ <openSearch:totalResults>1</openSearch:totalResults>
26
+ <openSearch:startIndex>1</openSearch:startIndex>
27
+ <openSearch:itemsPerPage>25</openSearch:itemsPerPage>
28
+ <entry>
29
+ <id>
30
+ http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de
31
+ </id>
32
+ <updated>2008-03-05T12:36:38.835Z</updated>
33
+ <category scheme='http://schemas.google.com/g/2005#kind'
34
+ term='http://schemas.google.com/contact/2008#contact' />
35
+ <title type='text'>Fitzgerald</title>
36
+ <link rel='self' type='application/atom+xml'
37
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de' />
38
+ <link rel='edit' type='application/atom+xml'
39
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de/1204720598835000' />
40
+ <gd:phoneNumber rel='http://schemas.google.com/g/2005#home'
41
+ primary='true'>
42
+ 456
43
+ </gd:phoneNumber>
44
+ <gd:email label="Personal" rel="http://schemas.google.com/g/2005#home" address="fubar@gmail.com" primary="true" />
45
+ </entry>
46
+ </feed>
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <LiveContacts>
3
+ <Owner>
4
+ <WindowsLiveID>hugo@hotmail.com</WindowsLiveID>
5
+ </Owner>
6
+ <Contacts>
7
+ <Contact>
8
+ <Profiles>
9
+ <Personal />
10
+ </Profiles>
11
+ <PreferredEmail>froz@gmail.com</PreferredEmail>
12
+ </Contact>
13
+ <Contact>
14
+ <Profiles>
15
+ <Personal>
16
+ <FirstName>Rafael</FirstName>
17
+ <LastName>Timbo</LastName>
18
+ </Personal>
19
+ </Profiles>
20
+ <PreferredEmail>timbo@hotmail.com</PreferredEmail>
21
+ </Contact>
22
+ <Contact>
23
+ <Profiles>
24
+ <Personal />
25
+ </Profiles>
26
+ <PreferredEmail>betinho@hotmail.com</PreferredEmail>
27
+ </Contact>
28
+ </Contacts>
29
+ </LiveContacts>
@@ -0,0 +1,119 @@
1
+ {
2
+ "type":"search_response",
3
+ "contacts":[
4
+ {
5
+ "type":"contact",
6
+ "fields":[
7
+ {
8
+ "type":"email",
9
+ "data":"hugo.barauna@gmail.com",
10
+ "fid":2,
11
+ "categories":[
12
+ ]
13
+ },
14
+ {
15
+ "type":"name",
16
+ "first":"Hugo",
17
+ "last":"Barauna",
18
+ "fid":1,
19
+ "categories":[
20
+ ]
21
+ }
22
+ ],
23
+ "cid":4,
24
+ "categories":[
25
+ ]
26
+ },
27
+ {
28
+ "type":"contact",
29
+ "fields":[
30
+ {
31
+ "type":"email",
32
+ "data":"nina@hotmail.com",
33
+ "fid":5,
34
+ "categories":[
35
+ ]
36
+ },
37
+ {
38
+ "type":"name",
39
+ "first":"Nina",
40
+ "last":"Benchimol",
41
+ "fid":4,
42
+ "categories":[
43
+ ]
44
+ }
45
+ ],
46
+ "cid":5,
47
+ "categories":[
48
+ ]
49
+ },
50
+ {
51
+ "type":"contact",
52
+ "fields":[
53
+ {
54
+ "type":"email",
55
+ "data":"and@yahoo.com",
56
+ "fid":7,
57
+ "categories":[
58
+ ]
59
+ },
60
+ {
61
+ "type":"name",
62
+ "first":"Andrea",
63
+ "last":"Dimitri",
64
+ "fid":6,
65
+ "categories":[
66
+ ]
67
+ }
68
+ ],
69
+ "cid":1,
70
+ "categories":[
71
+ ]
72
+ },
73
+ {
74
+ "type":"contact",
75
+ "fields":[
76
+ {
77
+ "type":"email",
78
+ "data":"ricardo@poli.usp.br",
79
+ "fid":11,
80
+ "categories":[
81
+ ]
82
+ },
83
+ {
84
+ "type":"name",
85
+ "first":"Ricardo",
86
+ "last":"Fiorelli",
87
+ "fid":10,
88
+ "categories":[
89
+ ]
90
+ }
91
+ ],
92
+ "cid":3,
93
+ "categories":[
94
+ ]
95
+ },
96
+ {
97
+ "type":"contact",
98
+ "fields":[
99
+ {
100
+ "type":"email",
101
+ "data":"pizinha@yahoo.com.br",
102
+ "fid":14,
103
+ "categories":[
104
+ ]
105
+ },
106
+ {
107
+ "type":"name",
108
+ "first":"Priscila",
109
+ "fid":13,
110
+ "categories":[
111
+ ]
112
+ }
113
+ ],
114
+ "cid":2,
115
+ "categories":[
116
+ ]
117
+ }
118
+ ]
119
+ }
@@ -0,0 +1,28 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2
+ <BBAuthTokenLoginResponse
3
+ xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
4
+ xmlns:yahooauth='urn:yahoo:auth'>
5
+ <Success>
6
+ <Cookie>
7
+ Y=cdunlEx76ZEeIdWyeJNOegxfy.jkeoULJCnc7Q0Vr8D5P.u.EE2vCa7G2MwBoULuZhvDZuJNqhHwF3v5RJ4dnsWsEDGOjYV1k6snoln3RlQmx0Ggxs0zAYgbaA4BFQk5ieAkpipq19l6GoD_k8IqXRfJN0Q54BbekC_O6Tj3zl2wV3YQK6Mi2MWBQFSBsO26Tw_1yMAF8saflF9EX1fQl4N.1yBr8UXb6LLDiPQmlISq1_c6S6rFbaOhSZMgO78f2iqZmUAk9RmCHrqPJiHEo.mJlxxHaQsuqTMf7rwLEHqK__Gi_bLypGtaslqeWyS0h2J.B5xwRC8snfEs3ct_kLXT3ngP_pK3MeMf2pe1TiJ4JXVciY9br.KJFUgNd4J6rmQsSFj4wPLoMGCETfVc.M8KLiaFHasZqXDyCE7tvd1khAjQ_xLfQKlg1GlBOWmbimQ1FhdHnsVj3svXjEGquRh8JI2sHIQrzoiqAPBf9WFKQcH0t_1dxf4MOH.7gJaYDPEozCW5EcCsYjuHup9xJKxyTddh5pk8yUg5bURzA.TwPalExMKsbv.RWFBhzWKuTp5guNcqjmUHcCoT19_qFENHX41Xf3texAnsDDGj
8
+ </Cookie>
9
+ <WSSID>tr.jZsW/ulc</WSSID>
10
+ <Timeout>3600</Timeout>
11
+ <YahooSOAPAuthHeader>
12
+ <wsse:Security>
13
+ <yahooauth:YahooAuthToken>
14
+ <yahooauth:Cookies>Y=cdunlEx76ZEeIdWyeJNOegxfy.jkeoULJCnc7Q0Vr8D5P.u.EE2vCa7G2MwBoULuZhvDZuJNqhHwF3v5RJ4dnsWsEDGOjYV1k6snoln3RlQmx0Ggxs0zAYgbaA4BFQk5ieAkpipq19l6GoD_k8IqXRfJN0Q54BbekC_O6Tj3zl2wV3YQK6Mi2MWBQFSBsO26Tw_1yMAF8saflF9EX1fQl4N.1yBr8UXb6LLDiPQmlISq1_c6S6rFbaOhSZMgO78f2iqZmUAk9RmCHrqPJiHEo.mJlxxHaQsuqTMf7rwLEHqK__Gi_bLypGtaslqeWyS0h2J.B5xwRC8snfEs3ct_kLXT3ngP_pK3MeMf2pe1TiJ4JXVciY9br.KJFUgNd4J6rmQsSFj4wPLoMGCETfVc.M8KLiaFHasZqXDyCE7tvd1khAjQ_xLfQKlg1GlBOWmbimQ1FhdHnsVj3svXjEGquRh8JI2sHIQrzoiqAPBf9WFKQcH0t_1dxf4MOH.7gJaYDPEozCW5EcCsYjuHup9xJKxyTddh5pk8yUg5bURzA.TwPalExMKsbv.RWFBhzWKuTp5guNcqjmUHcCoT19_qFENHX41Xf3texAnsDDGj
15
+ </yahooauth:Cookies>
16
+ <yahooauth:AppID>
17
+ jjmaQ37IkY0JH18hDRbVIbZ0r6BGYrbaQnm-
18
+ </yahooauth:AppID>
19
+ <yahooauth:WSSID>
20
+ tr.jZsW/ulc
21
+ </yahooauth:WSSID>
22
+ </yahooauth:YahooAuthToken>
23
+ </wsse:Security>
24
+ </YahooSOAPAuthHeader>
25
+ </Success>
26
+ </BBAuthTokenLoginResponse>
27
+ <!-- apil02.member.re3.yahoo.com uncompressed/chunked Mon Aug 11 19:00:37 PDT 2008 -->
28
+
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'contacts/flickr'
3
+ require 'uri'
4
+
5
+ describe Contacts::Flickr, "authentication" do
6
+
7
+ before(:each) do
8
+ @f = Contacts::Flickr
9
+ end
10
+
11
+ describe "authentication for desktop apps" do
12
+ # Key, secret and signature come from the Flickr API docs.
13
+ # http://www.flickr.com/services/api/auth.howto.desktop.html
14
+ it "should generate a correct url to retrieve a frob" do
15
+ path, query = Contacts::Flickr.frob_url('9a0554259914a86fb9e7eb014e4e5d52', '000005fab4534d05').split('?')
16
+ path.should == '/services/rest/'
17
+
18
+ hsh = hash_from_query(query)
19
+ hsh[:method].should == 'flickr.auth.getFrob'
20
+ hsh[:api_key].should == '9a0554259914a86fb9e7eb014e4e5d52'
21
+ hsh[:api_sig].should == '8ad70cd3888ce493c8dde4931f7d6bd0'
22
+ hsh[:secret].should be_nil
23
+ end
24
+
25
+ it "should generate an authentication url from a response with a frob" do
26
+ response = mock_response
27
+ response.stubs(:body).returns sample_xml('flickr/auth.getFrob')
28
+ Contacts::Flickr.frob_from_response(response).should == '934-746563215463214621'
29
+ end
30
+
31
+ # The :api_sig parameter is documented wronly in the Flickr API docs. It says the string
32
+ # to sign ends in 'permswread', but this should be 'permsread' of course. Therefore
33
+ # the :api_sig here does not correspond to the Flickr docs, but it makes the spec valid.
34
+ it "should return an url to authenticate to containing a frob" do
35
+ response = mock_response
36
+ response.stubs(:body).returns sample_xml('flickr/auth.getFrob')
37
+ @f.expects(:http_start).returns(response)
38
+ uri = URI.parse @f.authentication_url('9a0554259914a86fb9e7eb014e4e5d52', '000005fab4534d05')
39
+
40
+ uri.host.should == 'www.flickr.com'
41
+ uri.scheme.should == 'http'
42
+ uri.path.should == '/services/auth/'
43
+ hsh = hash_from_query(uri.query)
44
+ hsh[:api_key].should == '9a0554259914a86fb9e7eb014e4e5d52'
45
+ hsh[:api_sig].should == '0d08a9522d152d2e43daaa2a932edf67'
46
+ hsh[:frob].should == '934-746563215463214621'
47
+ hsh[:perms].should == 'read'
48
+ hsh[:secret].should be_nil
49
+ end
50
+
51
+ it "should get a token from a frob" do
52
+ response = mock_response
53
+ response.stubs(:body).returns sample_xml('flickr/auth.getToken')
54
+ connection = mock('Connection')
55
+ connection.expects(:get).with do |value|
56
+ path, query = value.split('?')
57
+ path.should == '/services/rest/'
58
+
59
+ hsh = hash_from_query(query)
60
+ hsh[:method].should == 'flickr.auth.getToken'
61
+ hsh[:api_key].should == '9a0554259914a86fb9e7eb014e4e5d52'
62
+ hsh[:api_sig].should == 'a5902059792a7976d03be67bdb1e98fd'
63
+ hsh[:frob].should == '934-746563215463214621'
64
+ hsh[:secret].should be_nil
65
+ true
66
+ end
67
+ @f.expects(:http_start).returns(response).yields(connection)
68
+ @f.get_token_from_frob('9a0554259914a86fb9e7eb014e4e5d52', '000005fab4534d05', '934-746563215463214621').should == '45-76598454353455'
69
+ end
70
+
71
+ end
72
+
73
+ def hash_from_query(str)
74
+ str.split('&').inject({}) do |hsh, pair|
75
+ key, value = pair.split('=')
76
+ hsh[key.to_sym] = value
77
+ hsh
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+ require 'contacts/google'
3
+ require 'uri'
4
+
5
+ describe Contacts::Google, '.authentication_url' do
6
+
7
+ after :each do
8
+ FakeWeb.clean_registry
9
+ end
10
+
11
+ it 'generates a URL for target with default parameters' do
12
+ uri = parse_authentication_url('http://example.com/invite')
13
+
14
+ uri.host.should == 'www.google.com'
15
+ uri.scheme.should == 'https'
16
+ uri.query.split('&').sort.should == [
17
+ 'next=http%3A%2F%2Fexample.com%2Finvite',
18
+ 'scope=https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2Fcontacts%2F',
19
+ 'secure=0',
20
+ 'session=0'
21
+ ]
22
+ end
23
+
24
+ it 'should handle boolean parameters' do
25
+ pairs = parse_authentication_url(nil, :secure => true, :session => true).query.split('&')
26
+
27
+ pairs.should include('secure=1')
28
+ pairs.should include('session=1')
29
+ end
30
+
31
+ it 'skips parameters that have nil value' do
32
+ query = parse_authentication_url(nil, :secure => nil).query
33
+ query.should_not include('next')
34
+ query.should_not include('secure')
35
+ end
36
+
37
+ it 'should be able to exchange one-time for session token' do
38
+ FakeWeb::register_uri(:get, 'https://www.google.com/accounts/AuthSubSessionToken',
39
+ :body => "Token=G25aZ-v_8B\nExpiration=20061004T123456Z",
40
+ :verify => lambda { |req|
41
+ req['Authorization'].should == %(AuthSub token="dummytoken")
42
+ }
43
+ )
44
+
45
+ Contacts::Google.session_token('dummytoken').should == 'G25aZ-v_8B'
46
+ end
47
+
48
+ it "should support client login" do
49
+ FakeWeb::register_uri(:post, 'https://www.google.com/accounts/ClientLogin',
50
+ :method => 'POST',
51
+ :query => {
52
+ 'accountType' => 'GOOGLE', 'service' => 'cp', 'source' => 'Contacts-Ruby',
53
+ 'Email' => 'mislav@example.com', 'Passwd' => 'dummyPassword'
54
+ },
55
+ :body => "SID=klw4pHhL_ry4jl6\nLSID=Ij6k-7Ypnc1sxm\nAuth=EuoqMSjN5uo-3B"
56
+ )
57
+
58
+ Contacts::Google.client_login('mislav@example.com', 'dummyPassword').should == 'EuoqMSjN5uo-3B'
59
+ end
60
+
61
+ it "should support token authentication after client login" do
62
+ @gmail = Contacts::Google.new('dummytoken', 'default', true)
63
+ @gmail.headers['Authorization'].should == 'GoogleLogin auth="dummytoken"'
64
+ end
65
+
66
+ def parse_authentication_url(*args)
67
+ URI.parse Contacts::Google.authentication_url(*args)
68
+ end
69
+
70
+ end