*/
#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);
/*
* 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...
*/
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...");
}
{
(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();
+}
+
puts(" httponly; secure;");
else
puts(" httponly;");
+
+ fflush(stdout);
}
* 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';
}
.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 {
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';
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))
{
*/
httpClearFields(con->http);
+ httpClearCookie(con->http);
if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE))
{
}
httpClearFields(con->http);
+ httpClearCookie(con->http);
httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
*/
httpClearFields(con->http);
+ httpClearCookie(con->http);
if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL,
CUPSD_AUTH_NONE))
*/
httpClearFields(con->http);
+ httpClearCookie(con->http);
httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
cupsdSendError(con, HTTP_STATUS_EXPECTATION_FAILED, CUPSD_AUTH_NONE);
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);
else if (!WebInterface)
{
httpClearFields(con->http);
+ httpClearCookie(con->http);
if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
{
*/
httpClearFields(con->http);
+ httpClearCookie(con->http);
if (!cupsdSendHeader(con, HTTP_STATUS_OK, "text/html", CUPSD_AUTH_NONE))
{
else
{
httpClearFields(con->http);
+ httpClearCookie(con->http);
if (!cupsdSendHeader(con, HTTP_STATUS_NOT_FOUND, "text/html", CUPSD_AUTH_NONE))
{
con->pipe_status = HTTP_STATUS_OK;
httpClearFields(con->http);
+ httpClearCookie(con->http);
if (fd >= 0)
close(fd);
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);
cupsCopyString(location, httpGetField(con->http, HTTP_FIELD_LOCATION), sizeof(location));
httpClearFields(con->http);
- httpClearCookie(con->http);
httpSetField(con->http, HTTP_FIELD_LOCATION, location);
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)
{
}
field = httpFieldValue(con->header);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "Script header: field=%d, value=\"%s\"", field, value);
if (field != HTTP_FIELD_UNKNOWN && value)
{
*/
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...
con->sent_header = 1;
httpClearFields(con->http);
+ httpClearCookie(con->http);
httpSetLength(con->http, (size_t)filestats->st_size);
/* 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 */
<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">
<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">
<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">
<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">
<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">
<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">
<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">
<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">
<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">
<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">