Notifikcations preview over HTTPs
authorZdeněk Šustr <sustr4@cesnet.cz>
Wed, 22 Feb 2012 16:27:12 +0000 (16:27 +0000)
committerZdeněk Šustr <sustr4@cesnet.cz>
Wed, 22 Feb 2012 16:27:12 +0000 (16:27 +0000)
- Handling query strings in HTTP requests completely refactored
- convenience function used for admin recognition
- new query strings (?all, ?foreign) implemented to allow admin users to list all/foreign notifications on top of their own.

org.glite.lb.server/src/lb_html.c
org.glite.lb.server/src/lb_html.h
org.glite.lb.server/src/lb_proto.c
org.glite.lb.server/src/lb_proto.h

index 69e16a7..aeddbf9 100644 (file)
@@ -130,8 +130,9 @@ int edg_wll_UserInfoToHTML(edg_wll_Context ctx UNUSED_VAR, edg_wlc_JobId *jobsOu
         return 0;
 }
 
-int edg_wll_UserNotifsToHTML(edg_wll_Context ctx UNUSED_VAR, char **notifids, char **message){
+int edg_wll_UserNotifsToHTML(edg_wll_Context ctx UNUSED_VAR, char **notifids, char **message, http_admin_option option, int adm) {
        char *pomA = NULL, *pomB = NULL;
+       char *mylink = NULL, *alllink = NULL, *foreignlink = NULL, *heading = NULL;
         pomB = strdup("");
 
        int i = 0;
@@ -146,15 +147,39 @@ int edg_wll_UserNotifsToHTML(edg_wll_Context ctx UNUSED_VAR, char **notifids, ch
                 i++;
         }
 
+       if (adm) {
+               asprintf(&mylink,"<BR>%s just your registrations%s",
+                       option != HTTP_ADMIN_OPTION_MY ? "<A HREF=\"/NOTIF:\">View" : "<B>Viewing",
+                       option != HTTP_ADMIN_OPTION_MY ? "</A>" : "</B>");
+               asprintf(&alllink,"<BR>%s all registrations%s",
+                       option != HTTP_ADMIN_OPTION_ALL ? "<A HREF=\"/NOTIF:?all\">View" : "<B>Viewing",
+                       option != HTTP_ADMIN_OPTION_ALL ? "</A>" : "</B>");
+               if (option == HTTP_ADMIN_OPTION_ALL) asprintf(&heading,"All notifications");
+               asprintf(&foreignlink,"<BR>%s registrations by other users%s",
+                       option != HTTP_ADMIN_OPTION_FOREIGN ? "<A HREF=\"/NOTIF:?foreign\">View" : "<B>Viewing",
+                       option != HTTP_ADMIN_OPTION_FOREIGN ? "</A>" : "</B>");
+               if (option == HTTP_ADMIN_OPTION_FOREIGN) asprintf(&heading,"Other users' notifications");
+       }
+       if (!heading) asprintf(&heading,"Your notifications");
+
        char *ret;
         asprintf(&ret, "<html>\r\n\t<body>\r\n");
        asprintf(&ret, "<html>\r\n\t<body>\r\n"
-                       "<h2><B>User notifications</B></h2>\r\n"
+                       "<h2><B>%s</B></h2>\r\n"
                         "<ul>%s</ul>"
+                       "<P>%s%s%s"
                        "\t</body>\r\n</html>",
-                        pomA
+                       heading,
+                        pomA, 
+                       mylink ? mylink : "",
+                       alllink ? alllink : "",
+                       foreignlink ? foreignlink : ""
         );
         free(pomA);
+       free(mylink);
+       free(alllink);
+       free(foreignlink);
+       free(heading);
 
        *message = ret;
 
index a1bb1f7..682662d 100644 (file)
@@ -29,7 +29,7 @@ int edg_wll_QueryToHTML(edg_wll_Context,edg_wll_Event *,char **);
 int edg_wll_GeneralJobStatusToHTML(edg_wll_Context, edg_wll_JobStat, char **);
 int edg_wll_CreamJobStatusToHTML(edg_wll_Context, edg_wll_JobStat, char **);
 int edg_wll_UserInfoToHTML(edg_wll_Context, edg_wlc_JobId *, edg_wll_JobStat *, char **);
-int edg_wll_UserNotifsToHTML(edg_wll_Context ctx, char **notifids, char **message);
+int edg_wll_UserNotifsToHTML(edg_wll_Context ctx, char **notifids, char **message, http_admin_option option, int adm);
 int edg_wll_NotificationToHTML(edg_wll_Context ctx, notifInfo *ni, char **message);
 char *edg_wll_ErrorToHTML(edg_wll_Context,int);
 int edg_wll_FileTransferStatusToHTML(edg_wll_Context ctx, edg_wll_JobStat stat, char **message);
index 5a63f47..e32adab 100644 (file)
@@ -50,6 +50,7 @@ limitations under the License.
 #include "db_supp.h"
 #include "server_notification.h"
 #include "authz_policy.h"
+#include "lb_authz.h"
 
 
 #define METHOD_GET      "GET "
@@ -212,31 +213,44 @@ static int outputHTML(char **headers)
 }
 
 
-static int drain_text_request(char *request){
-       int i = 0;
-       while (!isspace(request[i])) i++;
-       if (i < 5) 
-               return 0;
-       if (! strncmp(request+i-5, "?text", 5)){
-               if (i == 5)
-                       strcpy(request+i-4, request+i); // keep '/'
-               else
-                       strcpy(request+i-5, request+i);
-               return 1;
+static int check_request_for_query(char *request, char *query) {
+       char *found = strstr(request, query);
+
+       if (found && (!strcspn(found+strlen(query),"? \f\n\r\t\v"))) return 1;
+       else return 0;
+}
+
+static int strip_request_of_queries(char *request) {
+       int front, back;
+       char *tail;
+
+       front = strcspn(request, "?");
+       if (front < strlen(request)) {
+               back = strcspn(request+front, " \f\n\r\t\v"); //POSIX set of whitespaces
+               tail = strdup(request+front+back);
+               strcpy(request+front, tail);
+               free(tail);
        }
-       else
-               return 0;
+
+       return 0;
 }
 
-static int getUserNotifications(edg_wll_Context ctx, char *user, char ***notifids){
+static int getUserNotifications(edg_wll_Context ctx, char *user, char ***notifids, http_admin_option option, int adm_output){
         char *q = NULL;
+       char *where_clause = NULL;
         glite_lbu_Statement notifs = NULL;
         char *notifc[1] = {NULL};
 
+       if ((option != HTTP_ADMIN_OPTION_MY) && adm_output) {
+               if (option == HTTP_ADMIN_OPTION_ALL) asprintf(&where_clause, "1");
+               else if (option == HTTP_ADMIN_OPTION_FOREIGN) asprintf(&where_clause, "userid!='%s'", user);
+       }
+       if (!where_clause) asprintf(&where_clause, "userid='%s'", user);
+
         trio_asprintf(&q, "select notifid "
                 "from notif_registrations "
-                "where userid='%s'",
-                user);
+               "where %s",
+                where_clause);
        glite_common_log_msg(LOG_CATEGORY_LB_SERVER_DB, LOG_PRIORITY_DEBUG, q);
         if (edg_wll_ExecSQL(ctx, q, &notifs) < 0) goto err;
         free(q); q = NULL;
@@ -266,7 +280,6 @@ static int getNotifInfo(edg_wll_Context ctx, char *notifId, notifInfo *ni){
        char *notifc[5] = {NULL, NULL, NULL, NULL, NULL};
 
        char *can_peername = NULL;
-        struct _edg_wll_GssPrincipal_data principal;
        int retval = HTTP_OK;
 
        trio_asprintf(&q, "select n.destination, n.valid, n.conditions, n.flags, u.cert_subj "
@@ -277,13 +290,10 @@ static int getNotifInfo(edg_wll_Context ctx, char *notifId, notifInfo *ni){
         free(q); q = NULL;
 
        can_peername = edg_wll_gss_normalize_subj(ctx->peerName, 0);
-        memset(&principal, 0, sizeof principal);
-        principal.name = can_peername;
-        principal.fqans = ctx->fqans;
 
        if (edg_wll_FetchRow(ctx, notif, sizeof(notifc)/sizeof(notifc[0]), NULL, notifc)){
 
-               if (edg_wll_gss_equal_subj(principal.name, notifc[4]) || ctx->noAuth || check_authz_policy(&ctx->authz_policy, &principal, ADMIN_ACCESS)) {
+               if (edg_wll_gss_equal_subj(can_peername, notifc[4]) || ctx->noAuth || edg_wll_amIroot(can_peername, ctx->fqans, &ctx->authz_policy)) {
                        ni->notifid = strdup(notifId);
                        ni->destination = notifc[0];
                        ni->valid = notifc[1];
@@ -636,6 +646,8 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
        int     html = outputHTML(headers);
        int     text = 0; //XXX: Plain text communication is special case of html here, hence when text=1, html=1 too
        int     i;
+       int     isadm;
+       http_admin_option adm_opt = HTTP_ADMIN_OPTION_MY;
 
        edg_wll_ResetError(ctx);
 
@@ -674,7 +686,12 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
        if (!strncmp(request, METHOD_GET, sizeof(METHOD_GET)-1)) {
                
                requestPTR = strdup(request + sizeof(METHOD_GET)-1);
-               if (html) text = drain_text_request(requestPTR);
+               if (html) {
+                       text = check_request_for_query(requestPTR, "?text");
+                       if (check_request_for_query(requestPTR, "?all")) adm_opt = HTTP_ADMIN_OPTION_ALL;
+                       else if (check_request_for_query(requestPTR, "?foreign")) adm_opt = HTTP_ADMIN_OPTION_FOREIGN;
+                       strip_request_of_queries(requestPTR);
+               }
 
 
        /* Is user authorised? */
@@ -792,14 +809,17 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
                        char **notifids = NULL;
                        char *can_peername = edg_wll_gss_normalize_subj(ctx->peerName, 0);
                         char *userid = strmd5(can_peername, NULL);
-                       getUserNotifications(ctx, userid, &notifids);
+
+                       isadm = ctx->noAuth || edg_wll_amIroot(ctx->peerName, ctx->fqans,&ctx->authz_policy);
+
+                       getUserNotifications(ctx, userid, &notifids, adm_opt, isadm);
                        free(can_peername);
                        if (text) {
                                edg_wll_UserNotifsToText(ctx, notifids, &message);
                                edg_wll_ServerStatisticsIncrement(ctx, SERVER_STATS_TEXT_VIEWS);
                        }
                         else if (html) {
-                               edg_wll_UserNotifsToHTML(ctx, notifids, &message);
+                               edg_wll_UserNotifsToHTML(ctx, notifids, &message, adm_opt, isadm);
                                edg_wll_ServerStatisticsIncrement(ctx, SERVER_STATS_HTML_VIEWS);
                        }
                         else ret = HTTP_OK;
@@ -904,7 +924,8 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
        } else if (!strncmp(request,METHOD_POST,sizeof(METHOD_POST)-1)) {
 
                requestPTR = strdup(request + sizeof(METHOD_POST)-1);
-               if (html) text = drain_text_request(requestPTR);
+               if (html) text = check_request_for_query(requestPTR, "?text");
+               strip_request_of_queries(requestPTR);
        
                if (!strncmp(requestPTR,KEY_QUERY_EVENTS,sizeof(KEY_QUERY_EVENTS)-1)) { 
                        edg_wll_Event *eventsOut = NULL;
index 63496d9..f8765e4 100644 (file)
@@ -49,6 +49,13 @@ typedef struct _notifInfo{
        char *owner;
 } notifInfo;
 
+typedef enum _http_admin_option{
+       HTTP_ADMIN_OPTION_MY,
+       HTTP_ADMIN_OPTION_ALL,
+       HTTP_ADMIN_OPTION_FOREIGN,
+       HTTP_ADMIN_OPTION_LAST
+} http_admin_option;
+
 extern char *edg_wll_HTTPErrorMessage(int);
 
 extern int edg_wll_UserJobsServer(edg_wll_Context ctx, int flags, edg_wlc_JobId  **jobs, edg_wll_JobStat **states);