27c21175d7
Migrate much of BI to Services. Added Wireless Profile Provider plugin feature. Added Certificate Authority Provider plugin feature. Modified Certificate Provider plugin feature. Database migration v17, for Device Profiles. Enrolment Client Updated to support CA Certificates, Wireless Profiles and Hardware Info. New Client Enrolment Protocol to support new features. Plugin Manifest Generator added to main solution. Improved AD search performance.
669 lines
30 KiB
Plaintext
669 lines
30 KiB
Plaintext
@model Disco.Web.Areas.Config.Models.SystemConfig.IndexModel
|
|
@{
|
|
Authorization.Require(Claims.Config.System.Show);
|
|
|
|
var canConfigProxy = Authorization.Has(Claims.Config.System.ConfigureProxy);
|
|
var canConfigAD = Authorization.Has(Claims.Config.System.ConfigureActiveDirectory);
|
|
|
|
ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "System");
|
|
|
|
if (canConfigAD)
|
|
{
|
|
Html.BundleDeferred("~/Style/Fancytree");
|
|
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-Fancytree");
|
|
Html.BundleDeferred("~/ClientScripts/Modules/Disco-PropertyChangeHelpers");
|
|
}
|
|
}
|
|
<div class="form" style="width: 450px">
|
|
<table>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Disco Version:
|
|
</th>
|
|
<td>
|
|
<div>
|
|
<code>@Model.DiscoVersion.ToString(4)</code>
|
|
</div>
|
|
<div class="smallMessage">
|
|
Built @CommonHelpers.FriendlyDate(Model.DiscoVersionBuilt, "Unknown")
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Database Connection:
|
|
</th>
|
|
<td>
|
|
<table class="sub">
|
|
<tr>
|
|
<th>Server:</th>
|
|
<td><span class="code">@Model.DatabaseServer</span></td>
|
|
</tr>
|
|
<tr>
|
|
<th>Database:</th>
|
|
<td><span class="code">@Model.DatabaseName</span></td>
|
|
</tr>
|
|
<tr>
|
|
<th>Authentication:</th>
|
|
<td>@Model.DatabaseAuthentication</td>
|
|
</tr>
|
|
@{if (Model.DatabaseSqlAuthUsername != null)
|
|
{
|
|
<tr>
|
|
<th>SQL User:</th>
|
|
<td><span class="code">@Model.DatabaseSqlAuthUsername</span></td>
|
|
</tr>
|
|
}
|
|
}
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Data Store Location:
|
|
</th>
|
|
<td>
|
|
<span class="code">@Model.DataStoreLocation</span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="form" style="width: 450px; margin-top: 15px;">
|
|
<h2>Updates</h2>
|
|
<table>
|
|
@{
|
|
if (Model.UpdateLatestResponse == null)
|
|
{
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Last Check:
|
|
</th>
|
|
<td>
|
|
<div class="error"><i class="fa fa-exclamation-circle fa-lg"></i> Never</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
else
|
|
{
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Last Run:
|
|
</th>
|
|
<td>
|
|
<span>@CommonHelpers.FriendlyDate(Model.UpdateLatestResponse.UpdateResponseDate.ToLocalTime())</span>
|
|
</td>
|
|
</tr>
|
|
if (Model.UpdateAvailable)
|
|
{
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Update Available:
|
|
</th>
|
|
<td>
|
|
<div>
|
|
<i class="fa fa-info-circle fa-lg information"></i> Version @(Model.UpdateLatestResponse.LatestVersion) is available
|
|
</div>
|
|
<div class="smallMessage">
|
|
[Released @(CommonHelpers.FriendlyDate(Model.UpdateLatestResponse.ReleasedDate))]
|
|
</div>
|
|
<div class="smallMessage">@(new HtmlString(Model.UpdateLatestResponse.Description))</div>
|
|
<a href="@(Model.UpdateLatestResponse.UrlLink)" target="_blank">Download Now</a>
|
|
</td>
|
|
</tr>
|
|
}
|
|
else
|
|
{
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Status:
|
|
</th>
|
|
<td>
|
|
<i class="fa fa-check-square fa-lg success"></i> <span>The latest version is installed</span>
|
|
</td>
|
|
</tr>
|
|
}
|
|
}
|
|
}
|
|
<tr>
|
|
<th style="width: 135px">Check for Update:</th>
|
|
<td>
|
|
@{
|
|
if (Model.UpdateRunningStatus == null)
|
|
{
|
|
<span>@Html.ActionLinkSmallButton("Check Now", MVC.API.System.UpdateCheck())</span>
|
|
<span class="smallMessage">[Will run automatically <strong>@CommonHelpers.FriendlyDate(Model.UpdateNextScheduled, "Unknown")</strong>]</span>
|
|
}
|
|
else
|
|
{
|
|
<span>@Html.ActionLink("View Status", MVC.Config.Logging.TaskStatus(Model.UpdateRunningStatus.SessionId))</span>
|
|
<span class="smallMessage">[Running Now]</span>
|
|
}
|
|
}
|
|
@if (Model.UpdateBetaDeployment)
|
|
{
|
|
<hr />
|
|
<span class="alert"><i class="fa fa-info-circle fa-lg"></i> Beta Deployment</span>
|
|
}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="form" style="width: 450px; margin-top: 15px;">
|
|
<h2>Active Directory</h2>
|
|
<table>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Primary Domain:
|
|
</th>
|
|
<td>
|
|
<code><strong>@Model.ADPrimaryDomain.Name</strong> <span>[@Model.ADPrimaryDomain.NetBiosName]</span></code>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Additional Domains:
|
|
</th>
|
|
<td>
|
|
@if (Model.ADDomains.Count > 1)
|
|
{
|
|
var adAdditionalDomains = Model.ADDomains.Where(d => d != Model.ADPrimaryDomain).OrderBy(d => d.Name).ToList();
|
|
var adDomainFirst = adAdditionalDomains.First();
|
|
<code>@adDomainFirst.Name <span>[@adDomainFirst.NetBiosName]</span></code>
|
|
foreach (var adDomain in adAdditionalDomains.Skip(1))
|
|
{
|
|
<hr />
|
|
<div>
|
|
<code>@adDomain.Name <span>[@adDomain.NetBiosName]</span></code>
|
|
</div>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<span class="smallMessage"><None></span>
|
|
}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Site:
|
|
</th>
|
|
<td>
|
|
<code><strong>@Model.ADSite.Name</strong></code>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Servers:
|
|
</th>
|
|
<td>
|
|
<div>
|
|
@if (Model.ADServers.Count > 0)
|
|
{
|
|
<ul class="none">
|
|
@foreach (var server in Model.ADServers)
|
|
{
|
|
var serverDescription = string.Format("{0} [{1}]", server.Name.EndsWith(server.Domain.Name, StringComparison.OrdinalIgnoreCase) ? server.Name.Substring(0, server.Name.Length - server.Domain.Name.Length - 1) : server.Name, server.Domain.NetBiosName);
|
|
var reachable = server.IsAvailable;
|
|
<li>
|
|
@if (server.IsAvailable)
|
|
{
|
|
<i class="fa fa-check success fa-fw fa-lg" title="Available"></i>
|
|
}
|
|
else
|
|
{
|
|
<i class="fa fa-exclamation warning fa-fw fa-lg" title="Unavailable, will retry at @(server.AvailableWhen.Value.ToLongTimeString())"></i>
|
|
}
|
|
<code>@(serverDescription)</code>
|
|
@if (server.IsSiteServer)
|
|
{
|
|
<i class="fa fa-building-o information fa-fw" title="Site Server"></i>
|
|
}
|
|
else
|
|
{
|
|
<i class="fa fa-globe warning fa-fw" title="Not a Site Server"></i>
|
|
}
|
|
@if (server.IsWritable)
|
|
{
|
|
<i class="fa fa-pencil information fa-fw" title="Writable Domain Controller"></i>
|
|
}
|
|
</li>
|
|
}
|
|
</ul>
|
|
}
|
|
else
|
|
{
|
|
<div class="error">
|
|
<i class="fa fa-exclamation-circle fa-lg"></i> <span>None Found</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Forest:
|
|
</th>
|
|
<td>
|
|
@if (Model.ADForestServers == null)
|
|
{
|
|
<div>
|
|
@Html.CheckBoxFor(m => m.ADSearchAllForestServers, new { disabled = "disabled" }) @Html.LabelFor(m => m.ADSearchAllForestServers)
|
|
</div>
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>Forest servers are currently being retrieved.<br />
|
|
Try refreshing this page in a moment.
|
|
</p>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
if (canConfigAD)
|
|
{
|
|
var canSearchEntireForest = (Model.ADForestServers.Count <= Disco.Services.Interop.ActiveDirectory.ActiveDirectory.MaxForestServerSearch);
|
|
<div>
|
|
@if (!canSearchEntireForest)
|
|
{
|
|
@Html.CheckBoxFor(m => m.ADSearchAllForestServers, new { disabled = "disabled" }) @Html.LabelFor(m => m.ADSearchAllForestServers)
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-exclamation-circle warning"></i>Disco will not search entire forests which consist of more than @(Disco.Services.Interop.ActiveDirectory.ActiveDirectory.MaxForestServerSearch) servers. Only servers within this site will be searched.
|
|
</p>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
@Html.CheckBoxFor(m => m.ADSearchAllForestServers) @Html.LabelFor(m => m.ADSearchAllForestServers) @AjaxHelpers.AjaxLoader()
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>If this setting is enabled, Disco will query all servers within the forest rather than only servers within this site.
|
|
</p>
|
|
</div>
|
|
<script>
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper($('#ADSearchAllForestServers'), null, '@(Url.Action(MVC.API.System.UpdateActiveDirectorySearchAllForestServers()))', 'SearchAllForestServers');
|
|
});
|
|
</script>
|
|
}
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div>
|
|
@Html.CheckBoxFor(m => m.ADSearchAllForestServers, new { disabled = "disabled" }) @Html.LabelFor(m => m.ADSearchAllForestServers)
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>If this setting is enabled, Disco will query all servers within the forest rather than only servers within this site.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
}
|
|
<div>
|
|
<hr />
|
|
<span>All Servers:</span>
|
|
<ul id="Config_System_AD_ForestServers" class="none">
|
|
@{
|
|
var domainIndex = Model.ADDomains.ToDictionary(d => d.Name, StringComparer.OrdinalIgnoreCase);
|
|
foreach (var server in Model.ADForestServers.OrderBy(s => s))
|
|
{
|
|
var isSiteServer = Model.ADServers.Any(s => s.IsSiteServer && s.Name.Equals(server, StringComparison.OrdinalIgnoreCase));
|
|
var serverDescription = server;
|
|
if (server.Contains('.'))
|
|
{
|
|
Disco.Services.Interop.ActiveDirectory.ADDomain serverDomain;
|
|
if (domainIndex.TryGetValue(server.Substring(server.IndexOf('.') + 1), out serverDomain))
|
|
{
|
|
serverDescription = string.Format("{0} [{1}]", server.Substring(0, server.IndexOf('.')), serverDomain.NetBiosName);
|
|
}
|
|
}
|
|
<li>
|
|
<code>@serverDescription</code>@if (isSiteServer)
|
|
{ <i class="fa fa-building-o information fa-fw" title="Site Server"></i> }
|
|
</li>
|
|
}
|
|
}
|
|
</ul>
|
|
<script>
|
|
$(function () {
|
|
var toManyServers = 5;
|
|
var ul = $('#Config_System_AD_ForestServers');
|
|
var ulLi = ul.find('li');
|
|
if (ulLi.length > toManyServers) {
|
|
var liMore = $('<li>').append(
|
|
$('<a>').attr('href', '#')
|
|
.text('Show All Servers (' + (ulLi.length - toManyServers) + ' more)')
|
|
.click(function () {
|
|
$(this).closest('li').remove();
|
|
ul.find('li').show();
|
|
return false;
|
|
}))
|
|
.insertAfter(ulLi[(toManyServers - 1)]);
|
|
ulLi.each(function (i) {
|
|
if (i > (toManyServers - 1))
|
|
$(this).hide();
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
</div>
|
|
}
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Searching:
|
|
</th>
|
|
<td>
|
|
@{
|
|
object ADSearchWildcardSuffixOnlyAttributes = null;
|
|
if (!canConfigAD)
|
|
{
|
|
ADSearchWildcardSuffixOnlyAttributes = new
|
|
{
|
|
disabled = "disabled"
|
|
};
|
|
}
|
|
}
|
|
@Html.CheckBoxFor(m => m.ADSearchWildcardSuffixOnly, ADSearchWildcardSuffixOnlyAttributes) @Html.LabelFor(m => m.ADSearchWildcardSuffixOnly) @AjaxHelpers.AjaxLoader()
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>If this setting is enabled, Disco will utilize Active Directory indexes to greatly improve search performance.
|
|
If disabled, more results may be returned however performance will be reduced especially in large Active Directory domains.
|
|
</p>
|
|
</div>
|
|
@if (canConfigAD)
|
|
{
|
|
<script>
|
|
$(function () {
|
|
document.DiscoFunctions.PropertyChangeHelper($('#ADSearchWildcardSuffixOnly'), null, '@(Url.Action(MVC.API.System.UpdateActiveDirectorySearchWildcardSuffixOnly()))', 'SearchWildcardSuffixOnly');
|
|
});
|
|
</script>
|
|
}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Search Scope:
|
|
</th>
|
|
<td>
|
|
@if (Model.ADSearchContainers != null && Model.ADSearchContainers.Count > 0)
|
|
{
|
|
<div>Searching is restricted to the following Organisational Unit containers</div>
|
|
<ul id="Config_System_AD_SearchScope_DistinguishedNames">
|
|
@foreach (var adContainer in Model.ADSearchContainers)
|
|
{
|
|
<li data-distinguishedname="@adContainer.Item1"><code>@adContainer.Item3</code></li>
|
|
}
|
|
</ul>
|
|
}
|
|
else
|
|
{
|
|
<div>No Organisational Unit restrictions are in effect.</div>
|
|
<div class="info-box">
|
|
<p class="fa-p">
|
|
<i class="fa fa-info-circle"></i>When searching, the entire domain will be queried. This is suitable for most single-domain deployments.
|
|
</p>
|
|
</div>
|
|
}
|
|
@if (canConfigAD)
|
|
{
|
|
<div>
|
|
<hr />
|
|
<a id="Config_System_AD_SearchScope_Update" href="#" class="button small">Update</a>
|
|
</div>
|
|
<div id="Config_System_AD_SearchScope_Dialog" class="dialog" title="Search Scope">
|
|
<div id="Config_System_AD_SearchScope_Dialog_Loading">
|
|
@AjaxHelpers.AjaxLoader() Loading Organisational Units
|
|
</div>
|
|
<div id="Config_System_AD_SearchScope_Tree" class="organisationalUnitTree">
|
|
</div>
|
|
@using (Html.BeginForm(MVC.API.System.UpdateActiveDirectorySearchScope(null, redirect: true)))
|
|
{
|
|
}
|
|
</div>
|
|
<script>
|
|
$(function () {
|
|
var $dialog, $tree, tree, distinguishedNames;
|
|
|
|
function expandNodeTree(node) {
|
|
var parent = node.parent;
|
|
if (parent) {
|
|
expandNodeTree(parent);
|
|
if (!parent.isExpanded())
|
|
parent.setExpanded(true, { noAnimation: true, noEvents: false });
|
|
}
|
|
}
|
|
function selectDistinguishedNames() {
|
|
if (!distinguishedNames) {
|
|
distinguishedNames = $('#Config_System_AD_SearchScope_DistinguishedNames')
|
|
.find('li')
|
|
.map(function () { return $(this).attr('data-distinguishedname'); }).get();
|
|
}
|
|
|
|
if (tree) {
|
|
tree.visit(function (node) {
|
|
if ($.inArray(node.key, distinguishedNames) >= 0) {
|
|
node.setSelected(true);
|
|
expandNodeTree(node);
|
|
} else if (node.isSelected()) {
|
|
node.setSelected(false);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function update() {
|
|
|
|
if (!$dialog) {
|
|
$dialog = $('#Config_System_AD_SearchScope_Dialog').dialog({
|
|
autoOpen: false,
|
|
buttons: null,
|
|
draggable: false,
|
|
modal: true,
|
|
resizable: false,
|
|
width: 500,
|
|
height: 500
|
|
});
|
|
$loading = $('#Config_System_AD_SearchScope_Dialog_Loading');
|
|
$loading.find('i.ajaxLoading').show();
|
|
|
|
$tree = $('#Config_System_AD_SearchScope_Tree');
|
|
$dialog.css('overflow', 'visible');
|
|
$tree.css('height', '100%');
|
|
|
|
$.getJSON('@(Url.Action(MVC.API.System.DomainOrganisationalUnits()))', null, function (data) {
|
|
$loading.hide();
|
|
|
|
tree = $tree.fancytree({
|
|
source: data,
|
|
checkbox: true,
|
|
selectMode: 2,
|
|
keyboard: false,
|
|
fx: null
|
|
}).fancytree('getTree');
|
|
|
|
tree.$container.css('position', 'relative');
|
|
|
|
// Set Buttons
|
|
$dialog.dialog('option', 'buttons', {
|
|
'Search Entire Forest': function () {
|
|
var $this = $(this);
|
|
$this.css('overflow', 'hidden');
|
|
$this.dialog("disable");
|
|
$this.dialog("option", "buttons", null);
|
|
|
|
var $form = $dialog.find('form');
|
|
$form.submit();
|
|
},
|
|
'Save': function () {
|
|
var $this = $(this);
|
|
$this.css('overflow', 'hidden');
|
|
$this.dialog("disable");
|
|
$this.dialog("option", "buttons", null);
|
|
|
|
var nodes = tree.getSelectedNodes();
|
|
var $form = $dialog.find('form');
|
|
$.each(nodes, function (i, node) {
|
|
$('<input>').attr({ 'type': 'hidden', 'name': 'Containers', 'value': node.key }).appendTo($form);
|
|
});
|
|
$form.submit();
|
|
}
|
|
});
|
|
|
|
// Select & Expand
|
|
selectDistinguishedNames();
|
|
|
|
tree.options.fx = { height: "toggle", duration: 200 };
|
|
});
|
|
|
|
}
|
|
|
|
selectDistinguishedNames();
|
|
|
|
$dialog.dialog('open');
|
|
|
|
return false;
|
|
}
|
|
|
|
$('#Config_System_AD_SearchScope_Update').click(update);
|
|
});
|
|
</script>
|
|
}
|
|
</td>
|
|
|
|
|
|
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
@if (canConfigProxy)
|
|
{
|
|
using (Html.BeginForm(MVC.API.System.UpdateProxySettings()))
|
|
{
|
|
<div class="form" style="width: 450px; margin-top: 15px;">
|
|
<h2>Proxy Settings</h2>
|
|
<table>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Address:
|
|
</th>
|
|
<td>
|
|
@Html.EditorFor(m => m.ProxyAddress)<br />
|
|
@Html.ValidationMessageFor(m => m.ProxyAddress)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Port:
|
|
</th>
|
|
<td>
|
|
@Html.EditorFor(m => m.ProxyPort)<br />
|
|
@Html.ValidationMessageFor(m => m.ProxyPort)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Username:
|
|
</th>
|
|
<td>
|
|
@Html.EditorFor(m => m.ProxyUsername)<br />
|
|
@Html.ValidationMessageFor(m => m.ProxyUsername)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Password:
|
|
</th>
|
|
<td>
|
|
@Html.EditorFor(m => m.ProxyPassword)<br />
|
|
@Html.ValidationMessageFor(m => m.ProxyPassword)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
|
|
</th>
|
|
<td>
|
|
<button id="Config_System_Proxy_Save" type="button" class="button small">Save Proxy Settings</button>@AjaxHelpers.AjaxLoader()
|
|
<script>
|
|
$(function () {
|
|
var button = $('#Config_System_Proxy_Save');
|
|
|
|
button.click(function () {
|
|
var url = '@(Url.Action(MVC.API.System.UpdateProxySettings()))';
|
|
var data = {
|
|
ProxyAddress: $('#ProxyAddress').val(),
|
|
ProxyPort: $('#ProxyPort').val(),
|
|
ProxyUsername: $('#ProxyUsername').val(),
|
|
ProxyPassword: $('#ProxyPassword').val()
|
|
}
|
|
var ajaxLoading = button.next('.ajaxLoading').first().show();
|
|
|
|
$.ajax({
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
url: url,
|
|
data: data,
|
|
success: function (response, result) {
|
|
if (result != 'success' || response != 'OK') {
|
|
alert('Unable to change property "' + UpdatePropertyName + '":\n' + response);
|
|
ajaxLoading.hide();
|
|
} else {
|
|
ajaxLoading.hide().next('.ajaxOk').show().delay('fast').fadeOut('slow');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<div class="form" style="width: 450px; margin-top: 15px;">
|
|
<h2>Proxy Settings</h2>
|
|
<table>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Address:
|
|
</th>
|
|
<td>
|
|
@Html.DisplayFor(m => m.ProxyAddress)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Port:
|
|
</th>
|
|
<td>
|
|
@Html.DisplayFor(m => m.ProxyPort)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Username:
|
|
</th>
|
|
<td>
|
|
@Html.DisplayFor(m => m.ProxyUsername)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th style="width: 135px">
|
|
Password:
|
|
</th>
|
|
<td>
|
|
********
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
}
|
|
<div class="actionBar">
|
|
@Html.ActionLinkButton("Update Device Last Network Logons", MVC.API.System.UpdateLastNetworkLogonDates())
|
|
</div>
|