#include <string.h>
+#include <libzakformini/libzakformini.h>
+
#include "session.h"
+ enum
+ {
+ PROP_0,
+ PROP_MINUTES,
+ };
+
static void zak_cgi_session_class_init (ZakCgiSessionClass *class);
static void zak_cgi_session_init (ZakCgiSession *zak_cgi_session);
gchar *sid;
GFile *gfile;
GKeyFile *kfile;
+ ZakFormIniProvider *zakformini;
+
+ gint minutes;
};
G_DEFINE_TYPE (ZakCgiSession, zak_cgi_session, G_TYPE_OBJECT)
priv->path = NULL;
priv->gfile = NULL;
priv->kfile = NULL;
+ priv->zakformini = NULL;
+
+ priv->minutes = MINUTES_DEFAULT;
}
/**
* Returns: the newly created #ZakCgiSession object.
*/
ZakCgiSession
- *zak_cgi_session_new (ZakCgiMain *zakcgimain,
- const gchar *base_uri,
- const gchar *path)
+ *zak_cgi_session_new_minutes (ZakCgiMain *zakcgimain,
+ const gchar *base_uri,
+ const gchar *path,
+ gint minutes)
{
- GError *error;
- gchar *val;
- GHashTable *ht_cookies;
-
+ GDateTime *gdt_now;
ZakCgiSession *zak_cgi_session;
ZakCgiSessionPrivate *priv;
priv->path = g_strdup (path);
}
+ priv->sid = g_strdup ((gchar *)g_value_get_string (zak_cgi_main_get_cookie (priv->zakcgimain, "ZAKCGISID")));
+ priv->minutes = MAX (-1, minutes);
- if (priv->sid != NULL)
- ht_cookies = zak_cgi_main_get_cookies (priv->zakcgimain);
- priv->sid = g_strdup (g_value_get_string (g_hash_table_lookup (ht_cookies, "ZAKCGISID")));
-
+ if (zak_cgi_session_is_valid (zak_cgi_session))
{
- /* open the file */
- priv->gfile = g_file_new_for_path (g_build_filename (priv->path != NULL ? priv->path : g_get_tmp_dir (), priv->sid, NULL));
-
- error = NULL;
-
- /* check the content */
- priv->kfile = g_key_file_new ();
- if (!g_key_file_load_from_file (priv->kfile,
- g_file_get_path (priv->gfile),
- G_KEY_FILE_NONE,
- &error)
- || error != NULL)
+ /* update timestamp */
+ gdt_now = g_date_time_new_now_local ();
+ g_key_file_set_string (priv->kfile, "ZAKCGI", "TIMESTAMP", g_date_time_format (gdt_now, "%FT%T"));
+ g_key_file_save_to_file (priv->kfile, g_file_get_path (priv->gfile), NULL);
+ g_date_time_unref (gdt_now);
+ }
+ else
+ {
+ if (priv->sid != NULL)
{
- /* TODO */
+ zak_cgi_session_close (zak_cgi_session);
}
- else
- {
- val = g_key_file_get_string (priv->kfile, "ZAKCGI", "REMOTE_ADDR", NULL);
- if (val == NULL
- || g_strcmp0 (val, g_getenv ("REMOTE_ADDR")) != 0)
- {
- zak_cgi_session_close (zak_cgi_session);
- }
- val = g_key_file_get_string (priv->kfile, "ZAKCGI", "TIMESTAMP", NULL);
- if (val == NULL)
- {
- zak_cgi_session_close (zak_cgi_session);
- }
- else
- {
- GTimeVal tval;
-
- if (g_time_val_from_iso8601 (val, &tval))
- {
- GDateTime *gdt;
- GDateTime *gdt_now;
- GDateTime *gdt_plus;
+ zak_cgi_session_create_file (zak_cgi_session);
+ }
- gdt = g_date_time_new_from_timeval_local (&tval);
- if (gdt == NULL)
- {
- zak_cgi_session_close (zak_cgi_session);
- }
- else
- {
- /* TODO
- * add a property for minutes number */
- gdt_plus = g_date_time_add_minutes (gdt, 5);
- gdt_now = g_date_time_new_now_local ();
- if (g_date_time_compare (gdt_plus, gdt_now) == -1)
- {
- /* session expired */
- zak_cgi_session_close (zak_cgi_session);
- }
- else
- {
- /* update timestamp */
- g_key_file_set_string (priv->kfile, "ZAKCGI", "TIMESTAMP", g_date_time_format (gdt_now, "%FT%T"));
- g_key_file_save_to_file (priv->kfile, g_file_get_path (priv->gfile), NULL);
- }
+ return zak_cgi_session;
+ }
- g_date_time_unref (gdt_plus);
- g_date_time_unref (gdt_now);
- }
+ /**
+ * zak_cgi_session_new:
+ * @zakcgimain:
+ * @base_uri:
+ * @path:
+ *
+ * Returns: the newly created #ZakCgiSession object.
+ */
+ ZakCgiSession
+ *zak_cgi_session_new (ZakCgiMain *zakcgimain,
+ const gchar *base_uri,
+ const gchar *path)
+ {
+ return zak_cgi_session_new_minutes (zakcgimain, base_uri, path, MINUTES_DEFAULT);
+ }
- g_date_time_unref (gdt);
- }
- else
- {
- zak_cgi_session_close (zak_cgi_session);
- }
- }
- }
- }
+ /**
+ * zak_cgi_session_get_minutes:
+ * @session:
+ *
+ */
+ gint
+ zak_cgi_session_get_minutes (ZakCgiSession *session)
+ {
+ ZakCgiSessionPrivate *priv = ZAK_CGI_SESSION_GET_PRIVATE (session);
- return zak_cgi_session;
+ return priv->minutes;
}
/**
if (priv->sid == NULL)
{
- /* create new random name */
-
- i = g_random_int ();
-
- tmp = g_strdup_printf ("%d", i);
-
- priv->sid = g_compute_checksum_for_string (G_CHECKSUM_MD5,
- tmp,
- strlen (tmp));
-
- g_free (tmp);
-
- /* see if file already exists */
- priv->gfile = g_file_new_for_path (g_build_filename (priv->path != NULL ? priv->path : g_get_tmp_dir (), priv->sid, NULL));
- error = NULL;
- iostream = g_file_replace_readwrite (priv->gfile, NULL, FALSE, G_FILE_CREATE_PRIVATE, NULL, &error);
- if (iostream == NULL
- || error != NULL)
- {
- /* TODO */
- g_warning ("Unable to write new session file: %s.",
- error != NULL && error->message != NULL ? error->message : "no details");
- }
- else
- {
- g_io_stream_close (G_IO_STREAM (iostream), NULL, NULL);
- g_object_unref (iostream);
-
- priv->kfile = g_key_file_new ();
- if (!g_key_file_load_from_file (priv->kfile,
- g_file_get_path (priv->gfile),
- G_KEY_FILE_NONE,
- &error)
- || error != NULL)
- {
- /* TODO */
- g_warning ("Unable to read session file: %s.",
- error != NULL && error->message != NULL ? error->message : "no details");
- }
- else
- {
- /* write REMOTE_ADDR and creation timestamp */
- GDateTime *gdt;
-
- gdt = g_date_time_new_now_local ();
-
- g_key_file_set_string (priv->kfile, "ZAKCGI", "REMOTE_ADDR", g_getenv ("REMOTE_ADDR"));
- g_key_file_set_string (priv->kfile, "ZAKCGI", "TIMESTAMP", g_date_time_format (gdt, "%FT%T"));
- g_key_file_save_to_file (priv->kfile, g_file_get_path (priv->gfile), NULL);
+ zak_cgi_session_create_file (session);
+ }
- g_date_time_unref (gdt);
- }
- }
+ if (priv->sid != NULL)
+ {
+ ht_env = zak_cgi_main_get_env (priv->zakcgimain);
ret = zak_cgi_main_set_cookie ("ZAKCGISID", priv->sid, NULL, NULL,
- priv->base_uri != NULL ? priv->base_uri : (gchar *)g_hash_table_lookup (ht_env, "CONTEXT_PREFIX"),
+ priv->base_uri != NULL ? priv->base_uri : (gchar *)g_value_get_string (zak_cgi_main_get_env_field (priv->zakcgimain, "CONTEXT_PREFIX")),
FALSE, FALSE);
}
else
return ret;
}
+/**
+ * zak_cgi_session_set_value:
+ * @session:
+ * @name:
+ * @value:
+ *
+ */
+void
+zak_cgi_session_set_value (ZakCgiSession *session, const gchar *name, const gchar *value)
+{
+ zak_cgi_session_set_value_full (session, "SESSION", name, value);
+}
+
+/**
+ * zak_cgi_session_get_value:
+ * @session:
+ * @name:
+ *
+ * Returns: a value from session.
+ */
+gchar
+*zak_cgi_session_get_value (ZakCgiSession *session, const gchar *name)
+{
+ return zak_cgi_session_get_value_full (session, "SESSION", name);
+}
+
+/**
+ * zak_cgi_session_set_value_full_int:
+ * @session:
+ * @group:
+ * @name:
+ * @value:
+ *
+ */
+void
+zak_cgi_session_set_value_full_int (ZakCgiSession *session, const gchar *group, const gchar *name, gint value)
+{
+ gchar *str;
+
+ str = g_strdup_printf ("%d", value);
+ zak_cgi_session_set_value_full (session, group, name, str);
+ g_free (str);
+}
+
+/**
+ * zak_cgi_session_set_value_full_double:
+ * @session:
+ * @group:
+ * @name:
+ * @value:
+ *
+ */
+void
+zak_cgi_session_set_value_full_double (ZakCgiSession *session, const gchar *group, const gchar *name, gdouble value)
+{
+ gchar *str;
+
+ str = g_strdup_printf ("%f", value);
+ zak_cgi_session_set_value_full (session, group, name, str);
+ g_free (str);
+}
+
+/**
+ * zak_cgi_session_set_value_full_boolean:
+ * @session:
+ * @group:
+ * @name:
+ * @value:
+ *
+ */
+void
+zak_cgi_session_set_value_full_boolean (ZakCgiSession *session, const gchar *group, const gchar *name, gboolean value)
+{
+ zak_cgi_session_set_value_full_int (session, group, name, (gint)value);
+}
+
+/**
+ * zak_cgi_session_get_value_full_int:
+ * @session:
+ * @group:
+ * @name:
+ *
+ * Returns:
+ */
+gint
+zak_cgi_session_get_value_full_int (ZakCgiSession *session, const gchar *group, const gchar *name)
+{
+ gchar *str;
+ gint ret;
+
+ str = zak_cgi_session_get_value_full (session, group, name);
+ ret = strtol (str, NULL, 10);
+ g_free (str);
+
+ return ret;
+}
+
+/**
+ * zak_cgi_session_get_value_full_double:
+ * @session:
+ * @group:
+ * @name:
+ *
+ * Returns:
+ */
+gdouble
+zak_cgi_session_get_value_full_double (ZakCgiSession *session, const gchar *group, const gchar *name)
+{
+ gchar *str;
+ gdouble ret;
+
+ str = zak_cgi_session_get_value_full (session, group, name);
+ ret = g_strtod (str, NULL);
+ g_free (str);
+
+ return ret;
+}
+
+/**
+ * zak_cgi_session_get_value_full_boolean:
+ * @session:
+ * @group:
+ * @name:
+ *
+ * Returns:
+ */
+gboolean
+zak_cgi_session_get_value_full_boolean (ZakCgiSession *session, const gchar *group, const gchar *name)
+{
+ return (gboolean)zak_cgi_session_get_value_full_int (session, group, name);
+}
+
+static ZakFormIniProvider
+*zak_cgi_session_get_form_ini_provider (ZakCgiSession *session)
+{
+ ZakCgiSessionPrivate *priv = ZAK_CGI_SESSION_GET_PRIVATE (session);
+
+ if (priv->zakformini == NULL)
+ {
+ priv->zakformini = zak_form_ini_provider_new_from_gkeyfile (priv->kfile, g_file_get_path (priv->gfile));
+ }
+
+ return priv->zakformini;
+}
+
+/**
+ * zak_cgi_session_set_from_form:
+ * @session:
+ * @form:
+ *
+ */
+void
+zak_cgi_session_set_from_form (ZakCgiSession *session, ZakFormForm *form)
+{
+ zak_form_form_insert (ZAK_FORM_FORM (form), ZAK_FORM_IPROVIDER (zak_cgi_session_get_form_ini_provider (session)));
+}
+
+/**
+ * zak_cgi_session_fill_form:
+ * @session:
+ * @form:
+ *
+ */
+void
+zak_cgi_session_fill_form (ZakCgiSession *session, ZakFormForm *form)
+{
+ ZakCgiSessionPrivate *priv = ZAK_CGI_SESSION_GET_PRIVATE (session);
+
+ zak_cgi_session_get_form_ini_provider (session);
+ zak_form_form_load (ZAK_FORM_FORM (form), ZAK_FORM_IPROVIDER (priv->zakformini));
+}
+
+ /**
+ * zak_cgi_session_is_valid:
+ * @session:
+ *
+ */
+ gboolean
+ zak_cgi_session_is_valid (ZakCgiSession *session)
+ {
+ gboolean ret;
+
+ GError *error;
+
+ gchar *filename;
+ gchar *val;
+
+ GTimeVal tval;
+ GDateTime *gdt;
+ GDateTime *gdt_now;
+ GDateTime *gdt_plus;
+
+ ZakCgiSessionPrivate *priv = ZAK_CGI_SESSION_GET_PRIVATE (session);
+
+ ret = FALSE;
+
+ if (priv->sid != NULL)
+ {
+ /* open the file */
+ filename = zak_cgi_session_build_filename (session);
+ priv->gfile = g_file_new_for_path (filename);
+ g_free (filename);
+
+ error = NULL;
+
+ /* check the content */
+ priv->kfile = g_key_file_new ();
+ if (g_key_file_load_from_file (priv->kfile,
+ g_file_get_path (priv->gfile),
+ G_KEY_FILE_NONE,
+ &error)
+ && error == NULL)
+ {
+ val = g_key_file_get_string (priv->kfile, "ZAKCGI", "REMOTE_ADDR", NULL);
+ if (val != NULL
+ && g_strcmp0 (val, g_getenv ("REMOTE_ADDR")) == 0)
+ {
+ /* if priv->minutes <= -1 the session never expires */
+ if (priv->minutes > -1)
+ {
+ val = g_key_file_get_string (priv->kfile, "ZAKCGI", "TIMESTAMP", NULL);
+ if (val != NULL)
+ {
+ if (g_time_val_from_iso8601 (val, &tval))
+ {
+ gdt = g_date_time_new_from_timeval_local (&tval);
+ if (gdt != NULL)
+ {
+ gdt_plus = g_date_time_add_minutes (gdt, priv->minutes);
+ gdt_now = g_date_time_new_now_local ();
+ if (g_date_time_compare (gdt_plus, gdt_now) > -1)
+ {
+ ret = TRUE;
+ }
+ else
+ {
+ g_warning ("Session expired.");
+ }
+
+ g_date_time_unref (gdt_plus);
+ g_date_time_unref (gdt_now);
+ }
+ else
+ {
+ g_warning ("Session expired.");
+ }
+
+ g_date_time_unref (gdt);
+ }
+ else
+ {
+ g_warning ("Session expired.");
+ }
+ }
+ else
+ {
+ g_warning ("Session expired.");
+ }
+ }
+ }
+ else
+ {
+ g_warning ("Possibile session hijackin: right addr %s; current addr %s",
+ val, g_getenv ("REMOTE_ADDR"));
+ }
+ }
+ else
+ {
+ g_warning ("Unable to open session file «%s»: %s.",
+ g_file_get_path (priv->gfile),
+ error != NULL && error->message != NULL ? error->message : "no details");
+ }
+ }
+
+ return ret;
+ }
+
/**
* zak_cgi_session_close:
* @session: