<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[163213] trunk/Tools</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/163213">163213</a></dd>
<dt>Author</dt> <dd>dbates@webkit.org</dd>
<dt>Date</dt> <dd>2014-01-31 15:31:00 -0800 (Fri, 31 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>WebKit Bot Watcher's Dashboard: Access restricted queue should only prompt for HTTP credentials once per page load
https://bugs.webkit.org/show_bug.cgi?id=127849

Reviewed by Alexey Proskuryakov.

Currently whenever the dashboard updates the status of a queue whose Buildbot requires authentication
it will cause a browser to prompt for credentials once per update until valid credentials are provided.
Instead we should keep track of Buildbots that respond with an HTTP 401 Unauthorized status code to avoid
subsequently querying them and hence cause a browser to prompt for credentials. Together with an optional
hint provided when instantiating a Buildbot object as to whether it requires authentication, we can make
the dashboard prompt for HTTP credentials exactly once per page load for each queue whose associated
Buildbot requires authentication.

Queues whose Buildbot wasn't authenticated will show in the dashboard as &quot;unauthorized&quot;. Clicking on
this status message will cause the browser to prompt for credentials.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Buildbot.js:
(Buildbot): Initialize instance variable authenticationStatus to Buildbot.AuthenticationStatus.Unauthenticated.
(Buildbot.prototype.get needsAuthentication): Added.
(Buildbot.prototype.get authenticationStatus): Added.
(Buildbot.prototype.get isAuthenticated): Added.
(Buildbot.prototype.set isAuthenticated): Added.
(Buildbot.prototype.updateQueues): Added.
* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js:
(BuildbotBuilderQueueView.prototype.update.appendBuilderQueueStatus): Modified to call
BuildbotQueueView.prototype._appendUnauthorizedLineView() to update the view and show status of the queue as
&quot;unauthorized&quot; if the Buildbot associated with the queue is either unauthenticated or was given invalid credentials.
* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js:
(BuildbotQueue.prototype.update): Return immediately if the associated Buildbot requires authentication.
Additionally, if the JSON load fails with an HTTP 401 Unauthorized access error (say, credentials were
invalidated) then update the authentication status of the Buildbot to avoid subsequently prompting a
person for credentials the next time the queue update timer fires.
* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js:
(BuildbotQueueView): Register as a listener for event BuildbotQueue.Event.UnauthorizedAccess on each queue
so that the view can be updated to show status &quot;unauthorized&quot;.
(BuildbotQueueView.prototype._appendUnauthorizedLineView): Added.
* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js:
(BuildbotTesterQueueView.prototype.update.appendBuilderQueueStatus):
* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/StatusLineView.js: Added new status, StatusLineView.Status.Unauthorized.
* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/StatusLineView.css:
(.status-line.unauthorized .bubble): Added.
(.status-line.unauthorized .bubble.pictogram): Added.
(.status-line.unauthorized .message): Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotjs">trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Buildbot.js</a></li>
<li><a href="#trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotBuilderQueueViewjs">trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js</a></li>
<li><a href="#trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotQueuejs">trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js</a></li>
<li><a href="#trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotQueueViewjs">trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js</a></li>
<li><a href="#trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotTesterQueueViewjs">trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js</a></li>
<li><a href="#trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsStatusLineViewjs">trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/StatusLineView.js</a></li>
<li><a href="#trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardStylesStatusLineViewcss">trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/StatusLineView.css</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Buildbot.js (163212 => 163213)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Buildbot.js        2014-01-31 23:28:44 UTC (rev 163212)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Buildbot.js        2014-01-31 23:31:00 UTC (rev 163213)
</span><span class="lines">@@ -32,14 +32,29 @@
</span><span class="cx"> 
</span><span class="cx">     this.baseURL = baseURL;
</span><span class="cx">     this.queues = {};
</span><del>-    this.needsAuthentication = typeof options === &quot;object&quot; &amp;&amp; options.needsAuthentication === true;
</del><span class="cx"> 
</span><ins>+    // We regard _needsAuthentication as a hint whether this Buildbot requires authentication so that we can show
+    // an appropriate initial status message (say, an &quot;unauthorized&quot; status if the Buildbot requires authentication)
+    // for its associated queues before we make the actual HTTP request for the status of each queue.
+    this._needsAuthentication = typeof options === &quot;object&quot; &amp;&amp; options.needsAuthentication === true;
+    this._authenticationStatus = Buildbot.AuthenticationStatus.Unauthenticated;
+
</ins><span class="cx">     for (var id in queuesInfo)
</span><span class="cx">         this.queues[id] = new BuildbotQueue(this, id, queuesInfo[id]);
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> BaseObject.addConstructorFunctions(Buildbot);
</span><span class="cx"> 
</span><ins>+Buildbot.AuthenticationStatus = {
+    Unauthenticated: &quot;unauthenticated&quot;,
+    Authenticated: &quot;authenticated&quot;,
+    InvalidCredentials: &quot;invalid-credentials&quot;
+};
+
+Buildbot.UpdateReason = {
+    Reauthenticate: &quot;reauthenticate&quot;
+};
+
</ins><span class="cx"> // Ordered importance.
</span><span class="cx"> Buildbot.TestCategory = {
</span><span class="cx">     WebKit2: &quot;webkit-2&quot;,
</span><span class="lines">@@ -57,6 +72,42 @@
</span><span class="cx">     constructor: Buildbot,
</span><span class="cx">     __proto__: BaseObject.prototype,
</span><span class="cx"> 
</span><ins>+    get needsAuthentication()
+    {
+        return this._needsAuthentication;
+    },
+
+    get authenticationStatus()
+    {
+        return this._authenticationStatus;
+    },
+
+    get isAuthenticated()
+    {
+        return this._authenticationStatus === Buildbot.AuthenticationStatus.Authenticated;
+    },
+
+    set isAuthenticated(value)
+    {
+        this._authenticationStatus = value ? Buildbot.AuthenticationStatus.Authenticated : Buildbot.AuthenticationStatus.InvalidCredentials;
+    },
+
+    updateQueues: function(updateReason)
+    {
+        var shouldReauthenticate = updateReason === Buildbot.UpdateReason.Reauthenticate;
+        if (shouldReauthenticate) {
+            var savedAuthenticationStatus = this._authenticationStatus;
+            this._authenticationStatus = Buildbot.AuthenticationStatus.Unauthenticated;
+        }
+        for (var id in this.queues)
+            this.queues[id].update();
+        if (shouldReauthenticate) {
+            // Assert status wasn't changed synchronously. Otherwise, we will override it (below).
+            console.assert(this._authenticationStatus === Buildbot.AuthenticationStatus.Unauthenticated);
+            this._authenticationStatus = savedAuthenticationStatus;
+        }
+    },
+
</ins><span class="cx">     buildPageURLForIteration: function(iteration)
</span><span class="cx">     {
</span><span class="cx">         return this.baseURL + &quot;builders/&quot; + encodeURIComponent(iteration.queue.id) + &quot;/builds/&quot; + iteration.id;
</span></span></pre></div>
<a id="trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotBuilderQueueViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js (163212 => 163213)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js        2014-01-31 23:28:44 UTC (rev 163212)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js        2014-01-31 23:31:00 UTC (rev 163213)
</span><span class="lines">@@ -60,6 +60,11 @@
</span><span class="cx"> 
</span><span class="cx">         function appendBuilderQueueStatus(queue)
</span><span class="cx">         {
</span><ins>+            if (queue.buildbot.needsAuthentication &amp;&amp; !queue.buildbot.isAuthenticated) {
+                this._appendUnauthorizedLineView(queue);
+                return;
+            }
+
</ins><span class="cx">             this._appendPendingRevisionCount(queue);
</span><span class="cx"> 
</span><span class="cx">             var firstRecentUnsuccessfulIteration = queue.firstRecentUnsuccessfulIteration;
</span></span></pre></div>
<a id="trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotQueuejs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js (163212 => 163213)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js        2014-01-31 23:28:44 UTC (rev 163212)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js        2014-01-31 23:31:00 UTC (rev 163213)
</span><span class="lines">@@ -52,7 +52,8 @@
</span><span class="cx"> BuildbotQueue.MaximumQueuesToLoad = 10;
</span><span class="cx"> 
</span><span class="cx"> BuildbotQueue.Event = {
</span><del>-    IterationsAdded: &quot;iterations-added&quot;
</del><ins>+    IterationsAdded: &quot;iterations-added&quot;,
+    UnauthorizedAccess: &quot;unauthorized-access&quot;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> BuildbotQueue.prototype = {
</span><span class="lines">@@ -119,7 +120,11 @@
</span><span class="cx"> 
</span><span class="cx">     update: function(iterationsToLoad)
</span><span class="cx">     {
</span><ins>+        if (this.buildbot.needsAuthentication &amp;&amp; this.buildbot.authenticationStatus === Buildbot.AuthenticationStatus.InvalidCredentials)
+            return;
+
</ins><span class="cx">         JSON.load(this.baseURL, function(data) {
</span><ins>+            this.buildbot.isAuthenticated = true;
</ins><span class="cx">             if (!(data.cachedBuilds instanceof Array))
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><span class="lines">@@ -154,6 +159,21 @@
</span><span class="cx">             this.sortIterations();
</span><span class="cx"> 
</span><span class="cx">             this.dispatchEventToListeners(BuildbotQueue.Event.IterationsAdded, {addedIterations: newIterations});
</span><ins>+        }.bind(this),
+        function(data) {
+            if (this.buildbot.isAuthenticated) {
+                // FIXME (128006): Safari/WebKit should coallesce authentication requests with the same origin and authentication realm.
+                // In absence of the fix, Safari presents additional authentication dialogs regardless of whether an earlier authentication
+                // dialog was dismissed. As a way to ameliorate the user experience where a person authenticated successfully using an
+                // earlier authentication dialog and cancelled the authentication dialog associated with the load for this queue, we call
+                // ourself so that we can schedule another load, which should complete successfully now that we have credentials.
+                this.update();
+                return;
+            }
+            if (data.errorType === JSON.LoadError &amp;&amp; data.errorHTTPCode == 401) {
+                this.buildbot.isAuthenticated = false;
+                this.dispatchEventToListeners(BuildbotQueue.Event.UnauthorizedAccess, { });
+            }
</ins><span class="cx">         }.bind(this), {withCredentials: this.buildbot.needsAuthentication});
</span><span class="cx">     },
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotQueueViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js (163212 => 163213)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js        2014-01-31 23:28:44 UTC (rev 163212)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js        2014-01-31 23:31:00 UTC (rev 163213)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx">         else
</span><span class="cx">             this.platform = queue.platform;
</span><span class="cx">         queue.addEventListener(BuildbotQueue.Event.IterationsAdded, this._queueIterationsAdded, this);
</span><ins>+        queue.addEventListener(BuildbotQueue.Event.UnauthorizedAccess, this.updateSoon, this);
</ins><span class="cx">     }.bind(this));
</span><span class="cx"> 
</span><span class="cx">     this.debugQueues.forEach(function(queue) {
</span><span class="lines">@@ -44,6 +45,7 @@
</span><span class="cx">         else
</span><span class="cx">             this.platform = queue.platform;
</span><span class="cx">         queue.addEventListener(BuildbotQueue.Event.IterationsAdded, this._queueIterationsAdded, this);
</span><ins>+        queue.addEventListener(BuildbotQueue.Event.UnauthorizedAccess, this.updateSoon, this);
</ins><span class="cx">     }.bind(this));
</span><span class="cx"> 
</span><span class="cx">     webkitTrac.addEventListener(Trac.Event.NewCommitsRecorded, this._newCommitsRecorded, this);
</span><span class="lines">@@ -69,6 +71,15 @@
</span><span class="cx">         return queue.iterations[0].previousProductiveIteration;
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    _appendUnauthorizedLineView: function(queue)
+    {
+        console.assert(queue.buildbot.needsAuthentication);
+        console.assert(!queue.buildbot.isAuthenticated);
+        var javascriptURL = &quot;javascript:buildbots[&quot; + buildbots.indexOf(queue.buildbot) + &quot;].updateQueues(Buildbot.UpdateReason.Reauthenticate)&quot;;
+        var status = new StatusLineView(&quot;unauthorized&quot;, StatusLineView.Status.Unauthorized, &quot;&quot;, null, javascriptURL);
+        this.element.appendChild(status.element);
+    },
+
</ins><span class="cx">     _appendPendingRevisionCount: function(queue)
</span><span class="cx">     {
</span><span class="cx">         var latestProductiveIteration = this._latestProductiveIteration(queue);
</span></span></pre></div>
<a id="trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsBuildbotTesterQueueViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js (163212 => 163213)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js        2014-01-31 23:28:44 UTC (rev 163212)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js        2014-01-31 23:31:00 UTC (rev 163213)
</span><span class="lines">@@ -44,6 +44,11 @@
</span><span class="cx"> 
</span><span class="cx">         function appendBuilderQueueStatus(queue)
</span><span class="cx">         {
</span><ins>+            if (queue.buildbot.needsAuthentication &amp;&amp; !queue.buildbot.isAuthenticated) {
+                this._appendUnauthorizedLineView(queue);
+                return;
+            }
+
</ins><span class="cx">             this._appendPendingRevisionCount(queue);
</span><span class="cx"> 
</span><span class="cx">             var appendedStatus = false;
</span></span></pre></div>
<a id="trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardScriptsStatusLineViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/StatusLineView.js (163212 => 163213)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/StatusLineView.js        2014-01-31 23:28:44 UTC (rev 163212)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/StatusLineView.js        2014-01-31 23:31:00 UTC (rev 163213)
</span><span class="lines">@@ -62,7 +62,8 @@
</span><span class="cx">     Neutral: &quot;neutral&quot;,
</span><span class="cx">     Good: &quot;good&quot;,
</span><span class="cx">     Danger: &quot;danger&quot;,
</span><del>-    Bad: &quot;bad&quot;
</del><ins>+    Bad: &quot;bad&quot;,
+    Unauthorized: &quot;unauthorized&quot;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> BaseObject.addConstructorFunctions(StatusLineView);
</span></span></pre></div>
<a id="trunkToolsBuildSlaveSupportbuildwebkitorgconfigpublic_htmldashboardStylesStatusLineViewcss"></a>
<div class="modfile"><h4>Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/StatusLineView.css (163212 => 163213)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/StatusLineView.css        2014-01-31 23:28:44 UTC (rev 163212)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/StatusLineView.css        2014-01-31 23:31:00 UTC (rev 163213)
</span><span class="lines">@@ -54,6 +54,10 @@
</span><span class="cx">     background-color: rgb(76, 151, 61);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.status-line.unauthorized .bubble {
+    background-color: rgb(171, 61, 171);
+}
+
</ins><span class="cx"> .status-line .bubble.pictogram {
</span><span class="cx">     padding: 0;
</span><span class="cx">     max-width: 24px;
</span><span class="lines">@@ -63,6 +67,10 @@
</span><span class="cx">     background-image: url('data:image/svg+xml,&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 100 100&quot;&gt;&lt;g transform=&quot;translate(20 30) rotate(-45 30 17)&quot; shape-rendering=&quot;crispEdges&quot; fill=&quot;white&quot;&gt;&lt;rect y=&quot;5&quot; width=&quot;10&quot; height=&quot;25&quot;/&gt;&lt;rect y=&quot;20&quot; width=&quot;60&quot; height=&quot;10&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;');
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.status-line.unauthorized .bubble.pictogram {
+    background-image: url('data:image/svg+xml,&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 100 100&quot;&gt;&lt;clipPath id=&quot;top-semicircle&quot;&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;100&quot; height=&quot;37&quot;/&gt;&lt;/clipPath&gt;&lt;circle cx=&quot;50&quot; cy=&quot;33&quot; r=&quot;13&quot; clip-path=&quot;url(#top-semicircle)&quot; stroke=&quot;white&quot; stroke-width=&quot;10&quot; fill=&quot;none&quot; /&gt;&lt;rect x=&quot;24&quot; y=&quot;38&quot; width=&quot;52&quot; height=&quot;39&quot; fill=&quot;white&quot;/&gt;&lt;/svg&gt;');
+}
+
</ins><span class="cx"> .status-line.danger .bubble {
</span><span class="cx">     background-color: rgb(230, 175, 44);
</span><span class="cx"> }
</span><span class="lines">@@ -136,6 +144,11 @@
</span><span class="cx">     color: rgb(191, 67, 41);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.status-line.unauthorized .label,
+.status-line.unauthorized .message {
+    color: rgb(171, 61, 171);
+}
+
</ins><span class="cx"> .status-line .bubble.popover-tracking:hover {
</span><span class="cx">     text-shadow: 0px 0px 5px rgba(255, 255, 255, 0.7)
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (163212 => 163213)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-01-31 23:28:44 UTC (rev 163212)
+++ trunk/Tools/ChangeLog        2014-01-31 23:31:00 UTC (rev 163213)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2014-01-31  Daniel Bates  &lt;dabates@apple.com&gt;
+
+        WebKit Bot Watcher's Dashboard: Access restricted queue should only prompt for HTTP credentials once per page load
+        https://bugs.webkit.org/show_bug.cgi?id=127849
+
+        Reviewed by Alexey Proskuryakov.
+
+        Currently whenever the dashboard updates the status of a queue whose Buildbot requires authentication
+        it will cause a browser to prompt for credentials once per update until valid credentials are provided.
+        Instead we should keep track of Buildbots that respond with an HTTP 401 Unauthorized status code to avoid
+        subsequently querying them and hence cause a browser to prompt for credentials. Together with an optional
+        hint provided when instantiating a Buildbot object as to whether it requires authentication, we can make
+        the dashboard prompt for HTTP credentials exactly once per page load for each queue whose associated
+        Buildbot requires authentication.
+
+        Queues whose Buildbot wasn't authenticated will show in the dashboard as &quot;unauthorized&quot;. Clicking on
+        this status message will cause the browser to prompt for credentials.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Buildbot.js:
+        (Buildbot): Initialize instance variable authenticationStatus to Buildbot.AuthenticationStatus.Unauthenticated.
+        (Buildbot.prototype.get needsAuthentication): Added.
+        (Buildbot.prototype.get authenticationStatus): Added.
+        (Buildbot.prototype.get isAuthenticated): Added.
+        (Buildbot.prototype.set isAuthenticated): Added.
+        (Buildbot.prototype.updateQueues): Added.
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js:
+        (BuildbotBuilderQueueView.prototype.update.appendBuilderQueueStatus): Modified to call
+        BuildbotQueueView.prototype._appendUnauthorizedLineView() to update the view and show status of the queue as
+        &quot;unauthorized&quot; if the Buildbot associated with the queue is either unauthenticated or was given invalid credentials.
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js:
+        (BuildbotQueue.prototype.update): Return immediately if the associated Buildbot requires authentication.
+        Additionally, if the JSON load fails with an HTTP 401 Unauthorized access error (say, credentials were
+        invalidated) then update the authentication status of the Buildbot to avoid subsequently prompting a
+        person for credentials the next time the queue update timer fires.
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js:
+        (BuildbotQueueView): Register as a listener for event BuildbotQueue.Event.UnauthorizedAccess on each queue
+        so that the view can be updated to show status &quot;unauthorized&quot;.
+        (BuildbotQueueView.prototype._appendUnauthorizedLineView): Added.
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js:
+        (BuildbotTesterQueueView.prototype.update.appendBuilderQueueStatus):
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/StatusLineView.js: Added new status, StatusLineView.Status.Unauthorized.
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/StatusLineView.css:
+        (.status-line.unauthorized .bubble): Added.
+        (.status-line.unauthorized .bubble.pictogram): Added.
+        (.status-line.unauthorized .message): Added.
+
</ins><span class="cx"> 2014-01-31  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, really make --copy-libraries a no-able option.
</span></span></pre>
</div>
</div>

</body>
</html>