diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2012-12-31 20:08:30 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2012-12-31 20:08:30 +0100 |
| commit | 95b85be502f639fb2080ae92d4d33c013b18aa94 (patch) | |
| tree | 7ca15af789198da9021937269eda023946b69221 /src | |
| parent | 571790ba31a48c108e42c4ae10f8e63ae734c376 (diff) | |
| download | cataract-95b85be502f639fb2080ae92d4d33c013b18aa94.tar.xz | |
Add support for password protected albums
This adds support for simple password protected areas (albums and
all subalbums) through webserver HTTP authentication. CGG simply
generates .htaccess and password files and it's up to the user to
set up the rest on server side.
No UI changes at this point. Limited to one user per album for
the moment.
Diffstat (limited to 'src')
| -rw-r--r-- | src/generators.c | 76 | ||||
| -rw-r--r-- | src/generators.h | 12 | ||||
| -rw-r--r-- | src/items.c | 17 | ||||
| -rw-r--r-- | src/items.h | 9 | ||||
| -rw-r--r-- | src/job-manager.c | 26 |
5 files changed, 140 insertions, 0 deletions
diff --git a/src/generators.c b/src/generators.c index d5f1837..ac641d4 100644 --- a/src/generators.c +++ b/src/generators.c @@ -33,6 +33,7 @@ #include "replace-table.h" #include "block-parser.h" #include "stats.h" +#include "generators.h" #define IS_NOFULLSIZE(item,parent_items,setup) \ @@ -959,3 +960,78 @@ write_html_image (TGallerySetup *setup, return res; } + +/* + * write_auth_passwd_file, write_auth_htaccess_file: setup authentication files for the current album + * + */ +gboolean +write_auth_passwd_file (TGallerySetup *setup, + const gchar *dst, + TAlbum *items) +{ + GError *error = NULL; + const gchar *argv[8]; + + argv[0] = "htpasswd"; + argv[1] = "-b"; + argv[2] = "-c"; + argv[3] = "-m"; + argv[4] = dst; + argv[5] = items->auth_username; + argv[6] = items->auth_passwd; + argv[7] = NULL; + + if (! g_spawn_sync (NULL, + (gchar **) argv, + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, + NULL, NULL, + NULL, + &error)) + { + log_error ("Error writing password file: %s\n", error->message); + g_error_free (error); + return FALSE; + } + + return TRUE; +} + +gboolean +write_auth_htaccess_file (TGallerySetup *setup, + const gchar *dst, + const gchar *passwd_file_name, + TAlbum *items) +{ + FILE* f; + + f = fopen (dst, "a"); + if (f == NULL) { + log_error ("Error writing htaccess file: %s\n", strerror (errno)); + return FALSE; + } + + fprintf (f, "\n"); + fprintf (f, "# CGG auth data\n"); + switch (items->auth_type) { + case AUTH_TYPE_NONE: + g_assert_not_reached(); + break; + case AUTH_TYPE_BASIC: + fprintf (f, "AuthType Basic\n"); + fprintf (f, "AuthName \"%s\"\n", items->auth_realm); + fprintf (f, "AuthBasicProvider file\n"); + fprintf (f, "AuthUserFile %s\n", passwd_file_name); + fprintf (f, "Require user %s\n", items->auth_username); + break; + } + + if (fclose (f) != 0) { + log_error ("Error writing htaccess file: %s\n", strerror (errno)); + return FALSE; + } + + return TRUE; +} diff --git a/src/generators.h b/src/generators.h index c284f37..bff6cde 100644 --- a/src/generators.h +++ b/src/generators.h @@ -70,6 +70,18 @@ gboolean write_html_image (TGallerySetup *setup, TIndexItem *item, TAlbum *parent_items); +/* + * write_auth_passwd_file, write_auth_htaccess_file: setup authentication files for the current album + * + */ +gboolean write_auth_passwd_file (TGallerySetup *setup, + const gchar *dst, + TAlbum *items); +gboolean write_auth_htaccess_file (TGallerySetup *setup, + const gchar *dst, + const gchar *passwd_file_name, + TAlbum *items); + G_END_DECLS diff --git a/src/items.c b/src/items.c index 68ae66d..8692b65 100644 --- a/src/items.c +++ b/src/items.c @@ -140,6 +140,20 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info) } } + /* Authentication */ + index->auth_type = AUTH_TYPE_NONE; + s = xml_file_get_node_value (xml, "/gallery/general/auth/type/text()"); + if (g_strcmp0 (s, "Basic") == 0) + index->auth_type = AUTH_TYPE_BASIC; + g_free (s); + index->auth_realm = xml_file_get_node_value (xml, "/gallery/general/auth/realm/text()"); + index->auth_username = xml_file_get_node_value (xml, "/gallery/general/auth/username/text()"); + index->auth_passwd = xml_file_get_node_value (xml, "/gallery/general/auth/password/text()"); + if (index->auth_type != AUTH_TYPE_NONE && (index->auth_realm == NULL || index->auth_username == NULL || index->auth_passwd == NULL)) { + log_error ("Authentication requested but not all information provided. Ignoring.\n"); + index->auth_type = AUTH_TYPE_NONE; + } + /* Section Items */ count = xml_file_node_get_children_count (xml, "/gallery/items/*"); index->items = g_ptr_array_new (); @@ -276,6 +290,9 @@ free_album_data (TAlbum *album) g_free (album->meta_author); g_free (album->meta_description); g_free (album->meta_keywords); + g_free (album->auth_realm); + g_free (album->auth_username); + g_free (album->auth_passwd); g_strfreev (album->extra_files); if (album->items) { diff --git a/src/items.h b/src/items.h index 2a7179c..5b350b9 100644 --- a/src/items.h +++ b/src/items.h @@ -34,6 +34,11 @@ typedef enum { INDEX_ITEM_TYPE_INTERSPACE = 1 << 2 } TIndexItemType; +typedef enum { + AUTH_TYPE_NONE, + AUTH_TYPE_BASIC +} TAuthType; + typedef struct { TGalleryType type; gchar *ID; @@ -55,6 +60,10 @@ typedef struct { gboolean nofullsize; gboolean fullsize; gchar **extra_files; + gchar *auth_realm; + gchar *auth_username; + gchar *auth_passwd; + TAuthType auth_type; } TAlbum; typedef struct { diff --git a/src/job-manager.c b/src/job-manager.c index bf3b0df..8044b7f 100644 --- a/src/job-manager.c +++ b/src/job-manager.c @@ -35,6 +35,7 @@ #define DEFAULT_DATA_DIR_MODE S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH +#define AUTH_PASSWD_FILE ".htpasswd" typedef struct { @@ -268,9 +269,34 @@ build_tree (TGallerySetup *setup, } } + /* Cleanup for auth */ + if (items->auth_type != AUTH_TYPE_NONE) { + /* We're appending by default to preserve user .htaccess file supplied as an extra file. + * Let's remove the target file to prevent endless appending when overwriting the dst structure. */ + s1 = g_build_filename (path_info->dest_dir, ".htaccess", NULL); + unlink (s1); + g_free (s1); + } + /* Copy extra files */ mirror_files (setup, items->extra_files, path_info->src_dir, path_info->dest_dir, " Copying extra files: "); + /* Write auth files */ + if (items->auth_type != AUTH_TYPE_NONE) { + if (setup->verbose) printf (" Writing auth files: "); + s1 = g_build_filename (path_info->dest_dir, AUTH_PASSWD_FILE, NULL); + if (write_auth_passwd_file (setup, s1, items) && setup->verbose) + printf ("%s ", AUTH_PASSWD_FILE); + g_free (s1); + s1 = g_build_filename (path_info->dest_dir, ".htaccess", NULL); + s2 = g_build_filename (setup->location_local_path, path_info->album_path, AUTH_PASSWD_FILE, NULL); + if (write_auth_htaccess_file (setup, s1, s2, items) && setup->verbose) + printf ("%s ", ".htaccess"); + g_free (s2); + g_free (s1); + if (setup->verbose) printf ("\n"); + } + /* Prepare target image directories */ for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) { image_size = l->data; |
