1 /*
2  * librest - RESTful web services access
3  * Copyright (c) 2012, Red Hat, Inc.
4  *
5  * Authors: Christophe Fergeau <cfergeau@redhat.com>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU Lesser General Public License,
9  * version 2.1, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  */
21 #include <config.h>
22 
23 #include <rest/rest-proxy-auth.h>
24 #include <rest/rest-proxy-auth-private.h>
25 #include "rest-private.h"
26 
27 G_DEFINE_TYPE (RestProxyAuth, rest_proxy_auth, G_TYPE_OBJECT)
28 
29 #define REST_PROXY_AUTH_GET_PRIVATE(o) \
30   (G_TYPE_INSTANCE_GET_PRIVATE ((o), REST_TYPE_PROXY_AUTH, RestProxyAuthPrivate))
31 
32 struct _RestProxyAuthPrivate {
33   /* used to hold state during async authentication */
34   RestProxy *proxy;
35   SoupSession *session;
36   SoupMessage *message;
37   SoupAuth *auth;
38   gboolean paused;
39 };
40 
41 static void
rest_proxy_auth_dispose(GObject * object)42 rest_proxy_auth_dispose (GObject *object)
43 {
44   RestProxyAuthPrivate *priv = ((RestProxyAuth*)object)->priv;
45 
46   g_clear_object (&priv->proxy);
47   g_clear_object (&priv->session);
48   g_clear_object (&priv->message);
49   g_clear_object (&priv->auth);
50 
51   G_OBJECT_CLASS (rest_proxy_auth_parent_class)->dispose (object);
52 }
53 
54 static void
rest_proxy_auth_class_init(RestProxyAuthClass * klass)55 rest_proxy_auth_class_init (RestProxyAuthClass *klass)
56 {
57   GObjectClass *object_class = G_OBJECT_CLASS (klass);
58 
59   g_type_class_add_private (klass, sizeof (RestProxyAuthPrivate));
60 
61   object_class->dispose = rest_proxy_auth_dispose;
62 }
63 
64 static void
rest_proxy_auth_init(RestProxyAuth * proxy)65 rest_proxy_auth_init (RestProxyAuth *proxy)
66 {
67   proxy->priv = REST_PROXY_AUTH_GET_PRIVATE (proxy);
68 }
69 
70 G_GNUC_INTERNAL RestProxyAuth*
rest_proxy_auth_new(RestProxy * proxy,SoupSession * session,SoupMessage * message,SoupAuth * soup_auth)71 rest_proxy_auth_new (RestProxy *proxy,
72                      SoupSession *session,
73                      SoupMessage *message,
74                      SoupAuth *soup_auth)
75 {
76   RestProxyAuth *rest_auth;
77 
78   g_return_val_if_fail (REST_IS_PROXY (proxy), NULL);
79   g_return_val_if_fail (SOUP_IS_SESSION (session), NULL);
80   g_return_val_if_fail (SOUP_IS_MESSAGE (message), NULL);
81   g_return_val_if_fail (SOUP_IS_AUTH (soup_auth), NULL);
82 
83   rest_auth = REST_PROXY_AUTH (g_object_new (REST_TYPE_PROXY_AUTH, NULL));
84   rest_auth->priv->proxy = g_object_ref(proxy);
85   rest_auth->priv->session = g_object_ref(session);
86   rest_auth->priv->message = g_object_ref(message);
87   rest_auth->priv->auth = g_object_ref(soup_auth);
88 
89   return rest_auth;
90 }
91 
92 /**
93  * rest_proxy_auth_pause:
94  * @auth: a #RestProxyAuth
95  *
96  * Pauses @auth.
97  *
98  * If @auth is already paused, this function does not
99  * do anything.
100  */
101 void
rest_proxy_auth_pause(RestProxyAuth * auth)102 rest_proxy_auth_pause (RestProxyAuth *auth)
103 {
104   g_return_if_fail (REST_IS_PROXY_AUTH (auth));
105 
106   if (auth->priv->paused)
107       return;
108 
109   auth->priv->paused = TRUE;
110   soup_session_pause_message (auth->priv->session, auth->priv->message);
111 }
112 
113 /**
114  * rest_proxy_auth_unpause:
115  * @auth: a paused #RestProxyAuth
116  *
117  * Unpauses a paused #RestProxyAuth instance.
118  */
119 void
rest_proxy_auth_unpause(RestProxyAuth * auth)120 rest_proxy_auth_unpause (RestProxyAuth *auth)
121 {
122   RestProxy *proxy;
123   gchar *username;
124   gchar *password;
125 
126   g_return_if_fail (REST_IS_PROXY_AUTH (auth));
127   g_return_if_fail (auth->priv->paused);
128 
129   proxy = REST_PROXY (auth->priv->proxy);
130   g_object_get (G_OBJECT (proxy), "username", &username, "password", &password, NULL);
131   soup_auth_authenticate (auth->priv->auth, username, password);
132   g_free (username);
133   g_free (password);
134   soup_session_unpause_message (auth->priv->session, auth->priv->message);
135   auth->priv->paused = FALSE;
136 }
137 
138 /**
139  * rest_proxy_auth_cancel:
140  * @auth: a #RestProxyAuth
141  *
142  * Cancel the authentication process
143  * by cancelling the associated #SoupMessage.
144  * It results in returning #GError REST_PROXY_ERROR_CANCELLED
145  * to the function that requested the authentication.
146  */
147 void
rest_proxy_auth_cancel(RestProxyAuth * auth)148 rest_proxy_auth_cancel (RestProxyAuth *auth)
149 {
150   g_return_if_fail (REST_IS_PROXY_AUTH (auth));
151 
152   soup_session_cancel_message (auth->priv->session, auth->priv->message, SOUP_STATUS_CANCELLED);
153 }
154 
rest_proxy_auth_is_paused(RestProxyAuth * auth)155 G_GNUC_INTERNAL gboolean rest_proxy_auth_is_paused (RestProxyAuth *auth)
156 {
157   g_return_val_if_fail (REST_IS_PROXY_AUTH (auth), FALSE);
158 
159   return auth->priv->paused;
160 }
161