~ubuntu-branches/ubuntu/trusty/syncevolution/trusty-proposed

« back to all changes in this revision

Viewing changes to src/backends/webdav/WebDAVSourceRegister.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Tino Keitel
  • Date: 2011-07-20 16:02:02 UTC
  • mfrom: (3.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110720160202-e8uf7ogw4vh0q0f3
Tags: 1.1.99.5a-1
* New upstream version 1.1.99.5a, first release candiate for 1.2
* Added python-openssl dependency, the HTTP server needs it for HTTPS support
* Added versioned dependency on libsynthesis0 to get required features
* Fixed .orig.tar.gz generation in get-orig-source target
* Added myself to Uploaders:, thanks to David for sponsoring
* Use updated upstream tag for source package generation
* Removed 0001-Replace-with-in-call-to-PKG_CHECK_MODULES.patch, fixed upstream
* Renamed NEWS.Debian to NEWS so that it is actually used
* Updated NEWS for 1.1.99.5a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 Intel Corporation
 
3
 */
 
4
 
 
5
#include "WebDAVSource.h"
 
6
#include "CalDAVSource.h"
 
7
#include "CardDAVSource.h"
 
8
#include <syncevo/SyncSource.h>
 
9
#ifdef ENABLE_UNIT_TESTS
 
10
#include "test.h"
 
11
#endif
 
12
 
 
13
#include <boost/bind.hpp>
 
14
#include <boost/tokenizer.hpp>
 
15
 
 
16
#include <syncevo/declarations.h>
 
17
SE_BEGIN_CXX
 
18
 
 
19
static SyncSource *createSource(const SyncSourceParams &params)
 
20
{
 
21
    SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
 
22
    bool isMe;
 
23
 
 
24
    isMe = sourceType.m_backend == "CalDAV";
 
25
    if (isMe) {
 
26
        if (sourceType.m_format == "" ||
 
27
            sourceType.m_format == "text/calendar" ||
 
28
            sourceType.m_format == "text/x-calendar" ||
 
29
            sourceType.m_format == "text/x-vcalendar") {
 
30
#ifdef ENABLE_DAV
 
31
            boost::shared_ptr<Neon::Settings> settings;
 
32
            boost::shared_ptr<SubSyncSource> sub(new CalDAVSource(params, settings));
 
33
            return new MapSyncSource(params, sub);
 
34
#else
 
35
            return RegisterSyncSource::InactiveSource;
 
36
#endif
 
37
        }
 
38
    }
 
39
 
 
40
    isMe = sourceType.m_backend == "CardDAV";
 
41
    if (isMe) {
 
42
        if (sourceType.m_format == "" ||
 
43
            sourceType.m_format == "text/x-vcard" ||
 
44
            sourceType.m_format == "text/vcard") {
 
45
#ifdef ENABLE_DAV
 
46
            boost::shared_ptr<Neon::Settings> settings;
 
47
            return new CardDAVSource(params, settings);
 
48
#else
 
49
            return RegisterSyncSource::InactiveSource;
 
50
#endif
 
51
        }
 
52
    }
 
53
 
 
54
    return NULL;
 
55
}
 
56
 
 
57
static class RegisterWebDAVSyncSource : public RegisterSyncSource
 
58
{
 
59
public:
 
60
    RegisterWebDAVSyncSource() :
 
61
        RegisterSyncSource("DAV",
 
62
#ifdef ENABLE_DAV
 
63
                           true,
 
64
#else
 
65
                           false,
 
66
#endif
 
67
                           createSource,
 
68
                           "CalDAV\n"
 
69
                           "CardDAV\n"
 
70
                           ,
 
71
                           Values() +
 
72
                           Aliases("CalDAV")
 
73
                           + Aliases("CardDAV")
 
74
                           )
 
75
    {
 
76
        // configure and register our own property;
 
77
        // do this regardless whether the backend is enabled,
 
78
        // so that config migration always includes this property
 
79
        WebDAVCredentialsOkay.setHidden(true);
 
80
        SyncConfig::getRegistry().push_back(&WebDAVCredentialsOkay);
 
81
    }
 
82
} registerMe;
 
83
 
 
84
#ifdef ENABLE_DAV
 
85
#ifdef ENABLE_UNIT_TESTS
 
86
 
 
87
class WebDAVTest : public CppUnit::TestFixture {
 
88
    CPPUNIT_TEST_SUITE(WebDAVTest);
 
89
    CPPUNIT_TEST(testInstantiate);
 
90
    CPPUNIT_TEST(testHTMLEntities);
 
91
    CPPUNIT_TEST_SUITE_END();
 
92
 
 
93
protected:
 
94
    void testInstantiate() {
 
95
        boost::shared_ptr<TestingSyncSource> source;
 
96
        source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV", true));
 
97
        source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/calendar", true));
 
98
        source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/x-vcalendar", true));
 
99
        source.reset((TestingSyncSource *)SyncSource::createTestingSource("CardDAV", "CardDAV", true));
 
100
        source.reset((TestingSyncSource *)SyncSource::createTestingSource("CardDAV", "CardDAV:text/vcard", true));
 
101
        source.reset((TestingSyncSource *)SyncSource::createTestingSource("CardDAV", "CardDAV:text/x-vcard", true));
 
102
    }
 
103
 
 
104
    std::string decode(const char *item) {
 
105
        std::string buffer = item;
 
106
        CardDAVSource::replaceHTMLEntities(buffer);
 
107
        return buffer;
 
108
    }
 
109
 
 
110
    void testHTMLEntities() {
 
111
        // named entries
 
112
        CPPUNIT_ASSERT_EQUAL(std::string("\" & ' < >"),
 
113
                             decode("&quot; &amp; &apos; &lt; &gt;"));
 
114
        // decimal and hex, encoded in different ways
 
115
        CPPUNIT_ASSERT_EQUAL(std::string("\" & ' < >"),
 
116
                             decode("&#x22; &#0038; &#x0027; &#x3C; &#x3e;"));
 
117
        // no translation needed
 
118
        CPPUNIT_ASSERT_EQUAL(std::string("hello world"),
 
119
                             decode("hello world"));
 
120
        // entity at start
 
121
        CPPUNIT_ASSERT_EQUAL(std::string("< "),
 
122
                             decode("&lt; "));
 
123
        // entity at end
 
124
        CPPUNIT_ASSERT_EQUAL(std::string(" <"),
 
125
                             decode(" &lt;"));
 
126
        // double quotation
 
127
        CPPUNIT_ASSERT_EQUAL(std::string("\\"),
 
128
                             decode("&amp;#92;"));
 
129
        CPPUNIT_ASSERT_EQUAL(std::string("ampersand entity & less-than entity <"),
 
130
                             decode("ampersand entity &amp; less-than entity &amp;lt;"));
 
131
 
 
132
        // invalid entities
 
133
        CPPUNIT_ASSERT_EQUAL(std::string(" &"),
 
134
                             decode(" &"));
 
135
        CPPUNIT_ASSERT_EQUAL(std::string("&"),
 
136
                             decode("&"));
 
137
        CPPUNIT_ASSERT_EQUAL(std::string("& "),
 
138
                             decode("& "));
 
139
        CPPUNIT_ASSERT_EQUAL(std::string("&;"),
 
140
                             decode("&;"));
 
141
        CPPUNIT_ASSERT_EQUAL(std::string("&; "),
 
142
                             decode("&; "));
 
143
        CPPUNIT_ASSERT_EQUAL(std::string(" &; "),
 
144
                             decode(" &; "));
 
145
        CPPUNIT_ASSERT_EQUAL(std::string(" &;"),
 
146
                             decode(" &;"));
 
147
        CPPUNIT_ASSERT_EQUAL(std::string("&xyz;"),
 
148
                             decode("&xyz;"));
 
149
        CPPUNIT_ASSERT_EQUAL(std::string("&#1f;"),
 
150
                             decode("&#1f;"));
 
151
        CPPUNIT_ASSERT_EQUAL(std::string("&#1f;"),
 
152
                             decode("&#1f;"));
 
153
        CPPUNIT_ASSERT_EQUAL(std::string("&#x1f ;"),
 
154
                             decode("&#x1f ;"));
 
155
        CPPUNIT_ASSERT_EQUAL(std::string("&#quot ;"),
 
156
                             decode("&#quot ;"));
 
157
    }
 
158
};
 
159
 
 
160
SYNCEVOLUTION_TEST_SUITE_REGISTRATION(WebDAVTest);
 
161
 
 
162
#endif // ENABLE_UNIT_TESTS
 
163
 
 
164
namespace {
 
165
#if 0
 
166
}
 
167
#endif
 
168
 
 
169
 
 
170
 
 
171
/**
 
172
 * implements one specific source for local testing;
 
173
 * creates "target-config@client-test-<server>" peer config
 
174
 * and <type> source inside it before instantiating the
 
175
 * source
 
176
 */
 
177
class WebDAVTest : public RegisterSyncSourceTest {
 
178
    std::string m_server;
 
179
    std::string m_type;
 
180
    ConfigProps m_props;
 
181
 
 
182
public:
 
183
    /**
 
184
     * @param server      for example, "yahoo", "google"
 
185
     * @param type        "caldav" or "carddav"
 
186
     * @param props       sync properties (username, password, syncURL, ...)
 
187
     *                    or key/value parameters for the testing (testcases)
 
188
     */
 
189
    WebDAVTest(const std::string &server,
 
190
               const std::string &type,
 
191
               const ConfigProps &props) :
 
192
        RegisterSyncSourceTest(server + "_" + type, // for example, google_caldav
 
193
                               props.get(type + "/testconfig",
 
194
                                         props.get("testconfig",
 
195
                                                   type == "caldav" ? "eds_event" :
 
196
                                                   type == "carddav" ? "eds_contact" :
 
197
                                                   type))),
 
198
        m_server(server),
 
199
        m_type(type),
 
200
        m_props(props)
 
201
    {}
 
202
 
 
203
    virtual void updateConfig(ClientTestConfig &config) const
 
204
    {
 
205
        config.type = m_type.c_str();
 
206
        config.createSourceA = boost::bind(&WebDAVTest::createSource, this, _3);
 
207
        config.createSourceB = boost::bind(&WebDAVTest::createSource, this, _3);
 
208
        ConfigProps::const_iterator it = m_props.find(m_type + "/testcases");
 
209
        if (it != m_props.end() ||
 
210
            (it = m_props.find("testcases")) != m_props.end()) {
 
211
            config.testcases = it->second.c_str();
 
212
        }
 
213
    }
 
214
 
 
215
    TestingSyncSource *createSource(bool isSourceA) const
 
216
    {
 
217
        boost::shared_ptr<SyncConfig> context(new SyncConfig(string("target-config@client-test-") + m_server));
 
218
        SyncSourceNodes nodes = context->getSyncSourceNodes(m_type,
 
219
                                                            /* string("_") m_clientID + */
 
220
                                                            string("_") + (isSourceA ? "A" : "B"));
 
221
 
 
222
        // always set properties taken from the environment;
 
223
        // TODO: "database" property (currently always uses the default)
 
224
        nodes.getProperties()->setProperty("backend", m_type);
 
225
        BOOST_FOREACH(const StringPair &propval, m_props) {
 
226
            boost::shared_ptr<FilterConfigNode> node = context->getNode(propval.first);
 
227
            if (node) {
 
228
                node->setProperty(propval.first, propval.second);
 
229
            } else if (!boost::ends_with(propval.first, "testconfig") &&
 
230
                       !boost::ends_with(propval.first, "testcases")) {
 
231
                SE_THROW(StringPrintf("invalid property %s=%s set in CLIENT_TEST_WEBDAV for %s %s",
 
232
                                      propval.first.c_str(), propval.second.c_str(),
 
233
                                      m_server.c_str(), m_type.c_str()));
 
234
            }
 
235
        }
 
236
        context->flush();
 
237
 
 
238
        SyncSourceParams params(m_type,
 
239
                                nodes,
 
240
                                context);
 
241
        SyncSource *ss = SyncSource::createSource(params);
 
242
        return static_cast<TestingSyncSource *>(ss);
 
243
    }
 
244
};
 
245
 
 
246
 
 
247
/**
 
248
 * creates WebDAV sources by parsing
 
249
 * CLIENT_TEST_WEBDAV=<server> [caldav] [carddav] <prop>=<val> ...; ...
 
250
 */
 
251
static class WebDAVTestSingleton {
 
252
    list< boost::shared_ptr<WebDAVTest> > m_sources;
 
253
 
 
254
public:
 
255
    WebDAVTestSingleton()
 
256
    {
 
257
        const char *env = getenv("CLIENT_TEST_WEBDAV");
 
258
        if (!env) {
 
259
            return;
 
260
        }
 
261
 
 
262
        std::string settings(env);
 
263
        boost::char_separator<char> sep1(";");
 
264
        boost::char_separator<char> sep2("\t ");
 
265
        BOOST_FOREACH(const std::string &entry,
 
266
                      boost::tokenizer< boost::char_separator<char> >(settings, boost::char_separator<char>(";"))) {
 
267
            std::string server;
 
268
            bool caldav = false, carddav = false;
 
269
            ConfigProps props;
 
270
            BOOST_FOREACH(const std::string &token,
 
271
                          boost::tokenizer< boost::char_separator<char> >(entry, boost::char_separator<char>("\t "))) {
 
272
                if (server.empty()) {
 
273
                    server = token;
 
274
                } else if (token == "caldav") {
 
275
                    caldav = true;
 
276
                } else if (token == "carddav") {
 
277
                    carddav = true;
 
278
                } else {
 
279
                    size_t pos = token.find('=');
 
280
                    if (pos == token.npos) {
 
281
                        SE_THROW(StringPrintf("CLIENT_TEST_WEBDAV: unknown keyword %s", token.c_str()));
 
282
                    }
 
283
                    props[token.substr(0,pos)] = token.substr(pos + 1);
 
284
                }
 
285
            }
 
286
            if (caldav) {
 
287
                boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "caldav", props));
 
288
                m_sources.push_back(ptr);
 
289
            }
 
290
            if (carddav) {
 
291
                boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "carddav", props));
 
292
                m_sources.push_back(ptr);
 
293
            }
 
294
        }
 
295
    }
 
296
} WebDAVTestSingleton;
 
297
 
 
298
}
 
299
 
 
300
#endif // ENABLE_DAV
 
301
 
 
302
SE_END_CXX