Base the task model around an auth object, so we can make the model reflect the
[milk] / src / milk-auth.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License as
4  * published by the Free Software Foundation; either version 2 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  * General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public
13  * License along with this program; if not, write to the
14  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
15  * Boston, MA  02110-1301  USA
16  *
17  * Authors: Travis Reitter <treitter@gmail.com>
18  */
19
20 #include <config.h>
21
22 #include <glib.h>
23 #include <glib/gi18n.h>
24 #include <gtk/gtk.h>
25 #include <hildon/hildon.h>
26
27 #include <rtm-glib/rtm-error.h>
28 #include <rtm-glib/rtm-glib.h>
29
30 #include "milk-auth.h"
31 #include "milk-dialogs.h"
32
33 G_DEFINE_TYPE (MilkAuth, milk_auth, G_TYPE_OBJECT);
34
35 /* less expensive than G_TYPE_INSTANCE_GET_PRIVATE */
36 #define MILK_AUTH_PRIVATE(o) ((MILK_AUTH ((o)))->priv)
37
38 #define RTM_API_KEY "81f5c6c904aeafbbc914d9845d250ea8"
39 #define RTM_SHARED_SECRET "b08b15419378f913"
40
41 struct _MilkAuthPrivate
42 {
43         RtmGlib *rtm_glib;
44         char *api_key;
45         char *shared_secret;
46         char *frob;
47 };
48
49 enum {
50         PROP_API_KEY = 1,
51         PROP_SHARED_SECRET,
52 };
53
54 static MilkAuth *default_auth = NULL;
55
56
57 static void
58 milk_auth_get_property (GObject    *object,
59                         guint       property_id,
60                         GValue     *value,
61                         GParamSpec *pspec)
62 {
63         MilkAuthPrivate *priv = MILK_AUTH_PRIVATE (object);
64
65         switch (property_id)
66         {
67                 case PROP_API_KEY:
68                         g_value_set_string (value, priv->api_key);
69                 break;
70
71                 case PROP_SHARED_SECRET:
72                         g_value_set_string (value, priv->shared_secret);
73                 break;
74
75                 default:
76                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
77                                         pspec);
78         }
79 }
80
81 static void
82 milk_auth_set_property (GObject      *object,
83                         guint         property_id,
84                         const GValue *value,
85                         GParamSpec   *pspec)
86 {
87         MilkAuthPrivate *priv;
88         MilkAuth *auth;
89
90         auth = MILK_AUTH (object);
91         priv = MILK_AUTH_PRIVATE (auth);
92
93         switch (property_id)
94         {
95                 case PROP_API_KEY:
96                         priv->api_key = g_value_dup_string (value);
97                 break;
98
99                 case PROP_SHARED_SECRET:
100                         priv->shared_secret = g_value_dup_string (value);
101                 break;
102
103                 default:
104                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
105                                         pspec);
106         }
107 }
108
109 static void
110 auth_response_cb (GtkWidget *dialog,
111                   int        response,
112                   MilkAuth  *auth)
113
114 {
115         MilkAuthPrivate *priv;
116
117         GError *error = NULL;
118         gchar *auth_token;
119         gchar *username;
120
121         priv = MILK_AUTH_PRIVATE (auth);
122
123         auth_token = rtm_glib_auth_get_token (priv->rtm_glib, priv->frob,
124                         &error);
125         if (error != NULL) {
126                 g_error ("%s", rtm_error_get_message (error));
127                 goto auth_response_cb_OUT;
128         }
129
130         if (!rtm_glib_auth_check_token (priv->rtm_glib, auth_token, NULL)) {
131                 g_error ("auth_token not valid!\n");
132                 goto auth_response_cb_error_OUT;
133         }
134         if (error != NULL) {
135                 g_error ("%s", rtm_error_get_message (error));
136                 goto auth_response_cb_OUT;
137         }
138         username = rtm_glib_test_login (priv->rtm_glib, auth_token, &error);
139
140         g_free (auth_token);
141
142         if (error != NULL) {
143                 g_error ("%s", rtm_error_get_message (error));
144                 goto auth_response_cb_OUT;
145         }
146
147         /* FIXME: work this in where appropriate */
148 #if 0
149         glist = rtm_glib_tasks_get_list (priv->rtm_glib, NULL, NULL, NULL, &error);
150         if (error != NULL) {
151                 g_error ("%s", rtm_error_get_message (error));
152         }
153         for (item = glist; item; item = g_list_next (item)) {
154                 task = (RtmTask *) item->data;
155                 g_print ("%s", rtm_task_to_string (task));
156         }
157         g_list_free (glist);
158
159         glist = rtm_glib_lists_get_list (priv->rtm_glib, &error);
160         if (error != NULL) {
161                 g_error ("%s", rtm_error_get_message (error));
162                 goto auth_response_cb_OUT;
163         }
164         for (item = glist; item; item = g_list_next (item)) {
165                 rtm_list = (RtmList *) item->data;
166                 if (g_strcmp0 (rtm_list_get_name (rtm_list), "Sent") == 0) {
167                         list_id_sent = rtm_list_get_id (rtm_list);
168                 }
169                 g_print ("%s", rtm_list_to_string (rtm_list));
170         }
171         g_list_free (glist);
172
173         timeline = rtm_glib_timelines_create (priv->rtm_glib, &error);
174         if (error != NULL) {
175                 g_error ("%s", rtm_error_get_message (error));
176         }
177         g_print ("timeline: %s", timeline);
178
179         task = rtm_glib_tasks_add (priv->rtm_glib, timeline, "test-rtm-glib", NULL, FALSE, &error);
180         if (error != NULL) {
181                 g_error ("%s", rtm_error_get_message (error));
182                 goto auth_response_cb_OUT;
183         }
184         if (task != NULL) {
185                 g_print ("First task added! task_id: %s\n", rtm_task_get_id (task));
186         } else {
187                 g_print ("First task NOT added!\n");
188                 goto auth_response_cb_OUT;
189         }
190
191 #endif
192
193 auth_response_cb_OUT:
194         gtk_widget_destroy (dialog);
195 }
196
197 void
198 milk_auth_log_in (MilkAuth *auth)
199 {
200         MilkAuthPrivate *priv;
201
202         GError *error = NULL;
203         gchar *url;
204         GtkDialog *dialog;
205
206         priv = MILK_AUTH_PRIVATE (auth);
207
208         if (rtm_glib_test_echo (priv->rtm_glib, &error)) {
209                 g_print ("Test echo OK!\n");
210         } else {
211                 g_print ("Test echo FAIL!\n");
212                 return;
213         }
214         if (error != NULL) {
215                 g_error ("%s", rtm_error_get_message (error));
216                 return;
217         }
218
219         /* FIXME: relocate this */
220         if (priv->frob)
221                 g_free (priv->frob);
222
223         priv->frob = rtm_glib_auth_get_frob (priv->rtm_glib, &error);
224         if (error != NULL) {
225                 g_error ("%s", rtm_error_get_message (error));
226                 return;
227         }
228         g_print ("Frob: %s\n", priv->frob);
229
230         url = rtm_glib_auth_get_login_url (priv->rtm_glib, priv->frob,
231                         "delete");
232         g_print ("URL: %s\n", url);
233
234         dialog = milk_dialogs_auth_prompt (NULL, url);
235
236         g_signal_connect (dialog, "response", G_CALLBACK (auth_response_cb),
237                         auth);
238 }
239
240
241 static void
242 milk_auth_constructed (GObject *object)
243 {
244         MilkAuthPrivate *priv = MILK_AUTH_PRIVATE (object);
245
246         priv->rtm_glib = rtm_glib_new (priv->api_key, priv->shared_secret);
247 }
248
249 static void
250 milk_auth_finalize (GObject *object)
251 {
252         MilkAuthPrivate *priv = MILK_AUTH_PRIVATE (object);
253
254         g_object_unref (priv->rtm_glib);
255
256         g_free (priv->api_key);
257         g_free (priv->shared_secret);
258         g_free (priv->frob);
259 }
260
261 static void
262 milk_auth_class_init (MilkAuthClass *klass)
263 {
264         GObjectClass *object_class = G_OBJECT_CLASS (klass);
265
266         g_type_class_add_private (klass, sizeof (MilkAuthPrivate));
267
268         object_class->get_property = milk_auth_get_property;
269         object_class->set_property = milk_auth_set_property;
270         object_class->constructed = milk_auth_constructed;
271         object_class->finalize = milk_auth_finalize;
272
273         /* FIXME: make these read-only */
274         g_object_class_install_property
275                 (object_class,
276                  PROP_API_KEY,
277                  g_param_spec_string
278                          ("api-key",
279                           "API authentication key",
280                           "Milk's API authentication key.",
281                           RTM_API_KEY,
282                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
283                           G_PARAM_STATIC_STRINGS));
284
285         g_object_class_install_property
286                 (object_class,
287                  PROP_SHARED_SECRET,
288                  g_param_spec_string
289                          ("shared-secret",
290                           "Shared secret",
291                           "Milk's shared secret with the server.",
292                           RTM_SHARED_SECRET,
293                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
294                           G_PARAM_STATIC_STRINGS));
295 }
296
297 static void
298 milk_auth_init (MilkAuth *self)
299 {
300         MilkAuthPrivate *priv;
301
302         self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (
303                         self, MILK_TYPE_AUTH, MilkAuthPrivate);
304 }
305
306 MilkAuth*
307 milk_auth_get_default ()
308 {
309         if (!default_auth)
310                 default_auth = g_object_new (MILK_TYPE_AUTH, NULL);
311
312         return default_auth;
313 }