]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Save work on OAuth login/logout workflow (still having some difficulties)
authorMichael R Sweet <msweet@msweet.org>
Fri, 2 May 2025 18:21:44 +0000 (14:21 -0400)
committerMichael R Sweet <msweet@msweet.org>
Fri, 2 May 2025 18:21:44 +0000 (14:21 -0400)
16 files changed:
cgi-bin/home.c
cgi-bin/var.c
doc/cups.css
scheduler/auth.c
scheduler/client.c
scheduler/client.h
templates/da/header.tmpl.in
templates/de/header.tmpl.in
templates/es/header.tmpl.in
templates/fr/header.tmpl.in
templates/header.tmpl.in
templates/ja/header.tmpl.in
templates/pl/header.tmpl.in
templates/pt_BR/header.tmpl.in
templates/ru/header.tmpl.in
templates/sv/header.tmpl.in

index 0067f66377b30f4877e9605acde5c00bbfe2e081..d4b781d64f7c7c535b5e19c817570c951e2b7c3e 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "cgi-private.h"
+#include <cups/oauth.h>
 #include <errno.h>
 
 
  */
 
 static void    do_dashboard(void);
+static void    do_login(void);
+static void    do_logout(void);
+static void    do_redirect(const char *url);
 static void    do_search(char *query);
+static void    finish_login(void);
+static void    show_error(const char *title, const char *message, const char *error);
 
 
 /*
@@ -46,15 +52,17 @@ main(void)
   * Show the home page...
   */
 
-  cgiStartHTML(cgiText(_("Home")));
-
   if ((query = cgiGetVariable("QUERY")) != NULL)
     do_search(query);
+  else if (cgiGetSize("LOGIN"))
+    do_login();
+  else if (cgiGetSize("LOGOUT"))
+    do_logout();
+  else if (!cgiIsPOST() && (cgiGetSize("code") || cgiGetSize("error")))
+    finish_login();
   else
     do_dashboard();
 
-  cgiEndHTML();
-
  /*
   * Return with no errors...
   */
@@ -70,7 +78,130 @@ main(void)
 static void
 do_dashboard(void)
 {
+  // TOOD: Gather alerts
+
+  // Show the home page (dashboard) content...
+  cgiStartHTML(cgiText(_("Home")));
   cgiCopyTemplateLang("home.tmpl");
+  cgiEndHTML();
+}
+
+
+/*
+ * 'do_login()' - Redirect to the OAuth server's authorization endpoint.
+ */
+
+static void
+do_login(void)
+{
+  const char   *oauth_uri = getenv("CUPS_OAUTH_SERVER"),
+                                       // OAuth authorization server URL
+               *server_name = getenv("SERVER_NAME"),
+                                       // SERVER_NAME value
+               *server_port = getenv("SERVER_PORT");
+                                       // SERVER_PORT value
+  char         *client_id = NULL,      // Client ID value
+               *code_verifier = NULL,  // Code verifier string
+               *nonce = NULL,          // Nonce string
+               redirect_uri[1024],     // redirect_uri value
+               *state = NULL,          // State string
+               *url = NULL;            // Authorization URL
+  cups_json_t  *metadata = NULL;       // OAuth metadata
+
+
+  fputs("DEBUG2: do_login()\n", stderr);
+
+  // Get the metadata...
+  oauth_uri = getenv("CUPS_OAUTH_SERVER");
+  if ((metadata = cupsOAuthGetMetadata(oauth_uri)) == NULL)
+  {
+    show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to get authorization server information")), cupsGetErrorString());
+    goto done;
+  }
+
+  // Get the redirect URL...
+  if (!strcmp(server_name, "localhost"))
+    snprintf(redirect_uri, sizeof(redirect_uri), "http://127.0.0.1:%s/", server_port);
+  else
+    snprintf(redirect_uri, sizeof(redirect_uri), "%s://%s:%s/", getenv("HTTPS") ? "https" : "http", server_name, server_port);
+
+  fprintf(stderr, "DEBUG2: do_login: redirect_uri=\"%s\"\n", redirect_uri);
+
+  // Get the client ID...
+  if ((client_id = cupsOAuthCopyClientId(oauth_uri, redirect_uri)) == NULL)
+  {
+    // Nothing saved, try to dynamically register one...
+    if ((client_id = cupsOAuthGetClientId(oauth_uri, metadata, redirect_uri, /*logo_uri*/NULL, /*tos_uri*/NULL)) == NULL)
+    {
+      // Nope, show an error...
+      show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to get authorization URL")), cgiText(_("No client ID configured for this server.")));
+      goto done;
+    }
+  }
+
+  fprintf(stderr, "DEBUG2: do_login: client_id=\"%s\"\n", client_id);
+
+  // Make state and code verification strings...
+  code_verifier = cupsOAuthMakeBase64Random(128);
+  nonce         = cupsOAuthMakeBase64Random(16);
+  state         = cupsOAuthMakeBase64Random(16);
+
+  // Get the authorization URL
+  if ((url = cupsOAuthMakeAuthorizationURL(oauth_uri, metadata, /*resource_uri*/NULL, getenv("CUPS_OAUTH_SCOPES"), client_id, code_verifier, nonce, redirect_uri, state)) == NULL)
+  {
+    show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to get authorization URL")), cupsGetErrorString());
+    goto done;
+  }
+
+  // Redirect...
+  cgiSetCookie("CUPS_OAUTH_STATE", state, /*path*/NULL, /*domain*/NULL, time(NULL) + 300, /*secure*/0);
+  cgiSetCookie("CUPS_REFERRER", getenv("HTTP_REFERER"), /*path*/NULL, /*domain*/NULL, time(NULL) + 300, /*secure*/0);
+
+  do_redirect(url);
+
+  done:
+
+  // Free memory...
+  free(client_id);
+  free(code_verifier);
+  cupsJSONDelete(metadata);
+  free(nonce);
+  free(state);
+  free(url);
+}
+
+
+/*
+ * 'do_logout()' - Clear the OAuth bearer token cookie.
+ */
+
+static void
+do_logout(void)
+{
+  // Clear the CUPS_BEARER cookie...
+  cgiSetCookie("CUPS_BEARER", "", /*path*/NULL, /*domain*/NULL, time(NULL) - 1, /*secure*/0);
+
+  // Redirect back to the referrer...
+  do_redirect(getenv("HTTP_REFERER"));
+}
+
+
+/*
+ * 'do_redirect()' - Redirect to another web page...
+ */
+
+static void
+do_redirect(const char *url)           // URL or NULL for home page
+{
+  fprintf(stderr, "DEBUG2: do_redirect(url=\"%s\")\n", url);
+
+  if (url && (!strncmp(url, "http://", 7) || !strncmp(url, "https://", 8)))
+    printf("Location: %s\n\n", url);
+  else
+    printf("Location: %s://%s:%s%s\n\n", getenv("HTTPS") ? "https" : "http", getenv("SERVER_NAME"), getenv("SERVER_PORT"), url ? url : "/");
+
+  puts("Content-Type: text/plain\n");
+  puts("Redirecting...");
 }
 
 
@@ -83,3 +214,117 @@ do_search(char *query)                     /* I - Search string */
 {
   (void)query;
 }
+
+
+//
+// 'finish_login()' - Finish OAuth login and then redirect back to the original page.
+//
+
+static void
+finish_login(void)
+{
+  const char   *oauth_uri = getenv("CUPS_OAUTH_SERVER"),
+                                       // OAuth authorization server URL
+               *server_name = getenv("SERVER_NAME"),
+                                       // SERVER_NAME value
+               *server_port = getenv("SERVER_PORT");
+                                       // SERVER_PORT value
+  char         *bearer = NULL,         // Bearer token
+               *client_id = NULL,      // Client ID value
+               *error,                 // Error string
+               redirect_uri[1024];     // redirect_uri value
+  const char   *code,                  // Authorization code
+               *state_cookie,          // State cookie
+               *state_var;             // State variable
+  cups_json_t  *metadata = NULL;       // OAuth metadata
+  time_t       access_expires;         // When the bearer token expires
+
+
+  // Show any error from authorization...
+  if ((error = cgiGetVariable("error_description")) == NULL)
+    error = cgiGetVariable("error");
+
+  if (error)
+  {
+    show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to authorize access")), error);
+    return;
+  }
+
+  // Get the metadata...
+  oauth_uri = getenv("CUPS_OAUTH_SERVER");
+  if ((metadata = cupsOAuthGetMetadata(oauth_uri)) == NULL)
+  {
+    show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to get authorization server information")), cupsGetErrorString());
+    goto done;
+  }
+
+  // Get the redirect URL...
+  if (!strcmp(server_name, "localhost"))
+    snprintf(redirect_uri, sizeof(redirect_uri), "http://127.0.0.1:%s/", server_port);
+  else
+    snprintf(redirect_uri, sizeof(redirect_uri), "%s://%s:%s/", getenv("HTTPS") ? "https" : "http", server_name, server_port);
+
+  fprintf(stderr, "DEBUG2: finish_login: redirect_uri=\"%s\"\n", redirect_uri);
+
+  // Get the client ID...
+  if ((client_id = cupsOAuthCopyClientId(oauth_uri, redirect_uri)) == NULL)
+  {
+    // Nope, show an error...
+    show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to authorize access")), cgiText(_("No client ID configured for this server.")));
+    goto done;
+  }
+
+  fprintf(stderr, "DEBUG2: finish_login: client_id=\"%s\"\n", client_id);
+
+  // Get the state and code strings...
+  code         = cgiGetVariable("code");
+  state_cookie = cgiGetCookie("CUPS_OAUTH_STATE");
+  state_var    = cgiGetVariable("state");
+
+  if (!state_cookie || !state_var || strcmp(state_cookie, state_var))
+  {
+    show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to authorize access")), cgiText(_("Bad client state value in response.")));
+    goto done;
+  }
+
+  // Get the access token...
+  if ((bearer = cupsOAuthGetTokens(oauth_uri, metadata, /*resource_uri*/NULL, code, CUPS_OGRANT_AUTHORIZATION_CODE, redirect_uri, &access_expires)) == NULL)
+  {
+    show_error(cgiText(_("OAuth Login")), cgiText(_("Unable to authorize access")), cupsGetErrorString());
+    goto done;
+  }
+
+  // Save it as a cookie...
+  cgiSetCookie("CUPS_BEARER", bearer, /*path*/NULL, /*domain*/NULL, access_expires, /*secure*/0);
+
+  // Redirect...
+  do_redirect(cgiGetCookie("CUPS_REFERRER"));
+
+  done:
+
+  // Free memory...
+  free(bearer);
+  free(client_id);
+  cupsJSONDelete(metadata);
+}
+
+
+//
+// 'show_error()' - Show an error message.
+//
+
+static void
+show_error(const char *title,          // I - Page title
+           const char *message,                // I - Initial message
+           const char *error)          // I - Error message
+{
+  cgiStartHTML(title);
+
+  cgiSetVariable("title", title);
+  cgiSetVariable("message", message);
+  cgiSetVariable("error", error);
+  cgiCopyTemplateLang("error.tmpl");
+
+  cgiEndHTML();
+}
+
index ff13e9f719db7db456cb406759952326c0ce7b42..66a5a8e70bd0275a0c1768e3d6bd34a625c77f0b 100644 (file)
@@ -522,6 +522,8 @@ cgiSetCookie(const char *name,              /* I - Name */
     puts(" httponly; secure;");
   else
     puts(" httponly;");
+
+  fflush(stdout);
 }
 
 
@@ -1243,6 +1245,8 @@ cgi_initialize_string(const char *data)   /* I - Form data string */
     * Add the string to the variable "database"...
     */
 
+    fprintf(stderr, "DEBUG2: cgi_initialize_string: name=\"%s\", value=\"%s\"\n", name, value);
+
     if ((s = strrchr(name, '-')) != NULL && isdigit(s[1] & 255))
     {
       *s++ = '\0';
index d6b277a9b3b2b368e615cfa50994945b5d06d6b2..34cfe33427f459bb8d86c04dace4ceb6c93e4ae0 100644 (file)
 }
 .cups-header form {
   display: block;
-  margin: 0px 30px;
-  padding: 15px 0px !important;
+  padding: 15px 15px !important;
 }
 .cups-header span.label {
   color: #ccc;
   display: block;
   font-style: italic;
-  margin: 0px 30px;
-  padding: 15px 0px !important;
+  padding: 15px 0 !important;
 }
 
 .cups-body {
index 6efafe47d9d9bf071ae745b883e0ac16cfb9608d..1702d1f8c8c142ac3404cea5652018ffa886c81b 100644 (file)
@@ -351,7 +351,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
 
   authorization = httpGetField(con->http, HTTP_FIELD_AUTHORIZATION);
 
-  if (!*authorization && type == CUPSD_AUTH_BEARER && httpGetCookieValue(con->http, "CUPS_BEARER", bearer, sizeof(bearer)))
+  if (!*authorization && type == CUPSD_AUTH_BEARER && httpGetCookieValue(con->http, "CUPS_BEARER", bearer, sizeof(bearer)) && bearer[0])
     authorization = "Bearer COOKIE";
 
   username[0] = '\0';
index 469569839a161b520a8749d432417a498920d845..bf1b0d1ed373a5bbb2799b11a866f46bb31dbb4b 100644 (file)
@@ -916,6 +916,7 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
       if (con->best && con->best->type != CUPSD_AUTH_NONE)
       {
         httpClearFields(con->http);
+        httpClearCookie(con->http);
 
        if (!cupsdSendHeader(con, HTTP_STATUS_UNAUTHORIZED, NULL, CUPSD_AUTH_NONE))
        {
@@ -931,6 +932,7 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
        */
 
         httpClearFields(con->http);
+        httpClearCookie(con->http);
 
        if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE))
        {
@@ -946,6 +948,7 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
       }
 
       httpClearFields(con->http);
+      httpClearCookie(con->http);
       httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
 
       if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
@@ -979,6 +982,7 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
        */
 
         httpClearFields(con->http);
+        httpClearCookie(con->http);
 
        if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL,
                             CUPSD_AUTH_NONE))
@@ -1023,6 +1027,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
          */
 
           httpClearFields(con->http);
+         httpClearCookie(con->http);
          httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
 
          cupsdSendError(con, HTTP_STATUS_EXPECTATION_FAILED, CUPSD_AUTH_NONE);
@@ -1480,6 +1485,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
                  snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
 
                httpClearFields(con->http);
+               httpClearCookie(con->http);
 
                httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED, httpGetDateString(filestats.st_mtime));
                httpSetLength(con->http, (size_t)filestats.st_size);
@@ -1496,6 +1502,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
            else if (!WebInterface)
            {
               httpClearFields(con->http);
+             httpClearCookie(con->http);
 
               if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
              {
@@ -1514,6 +1521,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              */
 
               httpClearFields(con->http);
+             httpClearCookie(con->http);
 
               if (!cupsdSendHeader(con, HTTP_STATUS_OK, "text/html", CUPSD_AUTH_NONE))
              {
@@ -1526,6 +1534,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
            else
            {
               httpClearFields(con->http);
+             httpClearCookie(con->http);
 
              if (!cupsdSendHeader(con, HTTP_STATUS_NOT_FOUND, "text/html", CUPSD_AUTH_NONE))
              {
@@ -1929,6 +1938,7 @@ cupsdSendCommand(
   con->pipe_status = HTTP_STATUS_OK;
 
   httpClearFields(con->http);
+  httpClearCookie(con->http);
 
   if (fd >= 0)
     close(fd);
@@ -1963,7 +1973,7 @@ cupsdSendError(cupsd_client_t *con,       /* I - Connection */
                http_status_t  code,    /* I - Error code */
               int            auth_type)/* I - Authentication type */
 {
-  char location[HTTP_MAX_VALUE];       /* Location field */
+  char location[2048];                 /* Location field */
 
 
   cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cupsdSendError code=%d, auth_type=%d", code, auth_type);
@@ -1998,7 +2008,6 @@ cupsdSendError(cupsd_client_t *con,       /* I - Connection */
   cupsCopyString(location, httpGetField(con->http, HTTP_FIELD_LOCATION), sizeof(location));
 
   httpClearFields(con->http);
-  httpClearCookie(con->http);
 
   httpSetField(con->http, HTTP_FIELD_LOCATION, location);
 
@@ -2418,6 +2427,7 @@ cupsdWriteClient(cupsd_client_t *con)     /* I - Client connection */
   else if ((bytes = read(con->file, con->header + con->header_used, (size_t)bytes)) > 0)
   {
     con->header_used += bytes;
+    cupsdLogClient(con, CUPSD_LOG_DEBUG2, "Script header: BEFORE header_used=%lu", (unsigned long)con->header_used);
 
     if (con->pipe_pid && !con->got_fields)
     {
@@ -2460,6 +2470,7 @@ cupsdWriteClient(cupsd_client_t *con)     /* I - Client connection */
            }
 
            field = httpFieldValue(con->header);
+            cupsdLogClient(con, CUPSD_LOG_DEBUG2, "Script header: field=%d, value=\"%s\"", field, value);
 
            if (field != HTTP_FIELD_UNKNOWN && value)
            {
@@ -2479,11 +2490,13 @@ cupsdWriteClient(cupsd_client_t *con)   /* I - Client connection */
          */
 
          con->header_used -= bufptr - con->header;
+         cupsdLogClient(con, CUPSD_LOG_DEBUG2, "Script header: AFTER header_used=%lu", (unsigned long)con->header_used);
 
          if (con->header_used > 0)
            memmove(con->header, bufptr, (size_t)con->header_used);
 
          bufptr = con->header - 1;
+         bufend = con->header + con->header_used;
 
          /*
          * See if the line was empty...
@@ -3812,6 +3825,7 @@ write_file(cupsd_client_t *con,           /* I - Client connection */
   con->sent_header = 1;
 
   httpClearFields(con->http);
+  httpClearCookie(con->http);
 
   httpSetLength(con->http, (size_t)filestats->st_size);
 
index bd979bfc02d0e67fae14b4fe035d810dd7ea03fb..33b2f6ec96dd416dfc2553f89cee5a033d8d3568 100644 (file)
@@ -40,8 +40,7 @@ struct cupsd_client_s
                                        /* Real name from OAuth Bearer token */
                        autherror[HTTP_MAX_VALUE],
                                        /* Authorization error, if any */
-                       uri[HTTP_MAX_URI],
-                                       /* Localized URL/URI for GET/PUT */
+                       uri[2048],      /* Localized URL/URI for GET/PUT */
                        *filename,      /* Filename of output file */
                        *command,       /* Command to run */
                        *options,       /* Options for command */
index a824d611d1cf39b3a50c3de53cb68547a10a1fd9..107b3ba289d03346b11b48fbd50f6f4e6323e616 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Hjælp</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Jobs</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Printere</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index 2bb6a91f30a3a732d79a48543b1c2aa4c7e6d3f2..274f7a25935a5881f3897d71acd968f531c3e587 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Hilfe</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Aufträge</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Drucker</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index b1e07a1344822f258a1ac0ef66fb7d21c5f789a1..7baac36fa9825d5b53e4ec234cd4203de1bdba71 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Ayuda</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Trabajos</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Impresoras</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index 860b030c9ef665b9b53c456e7cb9a17052a703dc..769bba471722fcac02cb7f6fa5beb7cf21cfdd88 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Aide</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Tâches</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Imprimantes</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index 6808a4667a3563d72b40caa3881a51970bce668e..633aacf13a90b792599a51c2bc6f1934a4185a99 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Help</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Jobs</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Printers</a></li>
-       <li class="right">{?ENV:REMOTE_USER=?<i>Guest</i>:{ENV:REMOTE_USER}}
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index 35a600af49562f063604d5d0e9730963f40f93f9..ef35655a00c3f433ff1924b2451ad4226a581cb9 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">ヘルプ</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">ジョブ</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">プリンター</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index f45ce523affe7e34a2dd29ca01fcbe063df599de..316327d1096301ce1d981571eff378f7f3296e84 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Pomoc</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Kolejka</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Drukarki</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index 51332bd3b9d7facdd94aa82b10c532904d2910b9..9f1361ebb7a6b900e67f6372b6513b4e9008580b 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Ajuda</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Trabalhos</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Impressoras</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index ce208d79cce77a248981a06a3064b75353fd79b9..ff2a0c7c98fe973692826b47b9ef53a1f61a2a01 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Справка</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Задания</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Принтеры</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">
index e4a62eee8354cee0e90f959475815b60bbc8fc83..ddb03a74733a4516d70a435da5ad049bc1f14173 100644 (file)
        <li><a {SECTION=help?class="active" :}href="/help/">Hjälp</a></li>
        <li><a {SECTION=jobs?class="active" :}href="/jobs/">Jobb</a></li>
        <li><a {SECTION=printers?class="active" :}href="/printers/">Skrivare</a></li>
-       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span>
-       {?ENV:CUPS_OAUTH_SERVER=?:<form action="/loginout/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" value="{?ENV:CUPS_OAUTH_USERNAME=?Login:Logout}"></form>}
-       </li>
-       <li class="right"><form action="/help/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.help" results="20"><input type="submit" value="Search"></form></li>
+       <li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="search" name="QUERY" value="{?QUERY}" size="10" placeholder="" autosave="org.cups.site" results="20"><input type="submit" name="SEARCH" value="Search"></form></li>
+       {?ENV:CUPS_OAUTH_SERVER=?:<li class="right"><form action="/" method="POST"><input type="hidden" name="org.cups.sid" value="{$org.cups.sid}"><input type="submit" name="{?ENV:REMOTE_USER=?LOGIN:LOGOUT}" value="{?ENV:REMOTE_USER=?Login:Logout}"></form></li>}
+       <li class="right"><span class="label">{?ENV:REMOTE_NAME=?Guest:{ENV:REMOTE_NAME}}</span></li>
       </ul>
     </div>
     <div class="cups-body">