added stats to admin UI page, restyled scopes and dynamically registered flags
parent
6ec8b77f81
commit
6ed7477bc0
|
@ -37,4 +37,19 @@ public interface StatsService {
|
|||
*/
|
||||
public Map<String, Integer> calculateSummaryStats();
|
||||
|
||||
/**
|
||||
* Calculate usage count for all clients
|
||||
*
|
||||
* @return a map of id of client object to number of approvals
|
||||
*/
|
||||
public Map<Long, Integer> calculateByClientId();
|
||||
|
||||
/**
|
||||
* Calculate the usage count for a single client
|
||||
*
|
||||
* @param id the id of the client to search on
|
||||
* @return
|
||||
*/
|
||||
public Integer countForClientId(Long id);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,15 +22,21 @@ package org.mitre.openid.connect.service.impl;
|
|||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.service.ClientDetailsEntityService;
|
||||
import org.mitre.openid.connect.model.ApprovedSite;
|
||||
import org.mitre.openid.connect.service.ApprovedSiteService;
|
||||
import org.mitre.openid.connect.service.StatsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.Multiset;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -41,6 +47,9 @@ public class DefaultStatsService implements StatsService {
|
|||
@Autowired
|
||||
private ApprovedSiteService approvedSiteService;
|
||||
|
||||
@Autowired
|
||||
private ClientDetailsEntityService clientService;
|
||||
|
||||
@Override
|
||||
public Map<String, Integer> calculateSummaryStats() {
|
||||
// get all approved sites
|
||||
|
@ -62,4 +71,51 @@ public class DefaultStatsService implements StatsService {
|
|||
return e;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.openid.connect.service.StatsService#calculateByClientId()
|
||||
*/
|
||||
@Override
|
||||
public Map<Long, Integer> calculateByClientId() {
|
||||
// get all approved sites
|
||||
Collection<ApprovedSite> allSites = approvedSiteService.getAll();
|
||||
|
||||
Multiset<String> clientIds = HashMultiset.create();
|
||||
for (ApprovedSite approvedSite : allSites) {
|
||||
clientIds.add(approvedSite.getClientId());
|
||||
}
|
||||
|
||||
Map<Long, Integer> counts = getEmptyClientCountMap();
|
||||
for (String clientId : clientIds) {
|
||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||
counts.put(client.getId(), clientIds.count(clientId));
|
||||
}
|
||||
|
||||
return counts;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.openid.connect.service.StatsService#countForClientId(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Integer countForClientId(Long id) {
|
||||
|
||||
Map<Long, Integer> counts = calculateByClientId();
|
||||
return counts.get(id);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new map of all client ids set to zero
|
||||
* @return
|
||||
*/
|
||||
private Map<Long, Integer> getEmptyClientCountMap() {
|
||||
Map<Long, Integer> counts = new HashMap<Long, Integer>();
|
||||
Collection<ClientDetailsEntity> clients = clientService.getAllClients();
|
||||
for (ClientDetailsEntity client : clients) {
|
||||
counts.put(client.getId(), 0);
|
||||
}
|
||||
|
||||
return counts;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
|
@ -44,4 +45,22 @@ public class StatsAPI {
|
|||
|
||||
}
|
||||
|
||||
@RequestMapping(value = "byclientid", produces = "application/json")
|
||||
public String statsByClient(ModelMap m) {
|
||||
Map<Long, Integer> e = statsService.calculateByClientId();
|
||||
|
||||
m.put("entity", e);
|
||||
|
||||
return "jsonEntityView";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "byclientid/{id}", produces = "application/json")
|
||||
public String statsByClientId(@PathVariable("id") Long id, ModelMap m) {
|
||||
Integer e = statsService.countForClientId(id);
|
||||
|
||||
m.put("entity", e);
|
||||
|
||||
return "jsonEntityView";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -303,6 +303,12 @@ var BlackListWidgetView = ListWidgetView.extend({
|
|||
|
||||
});
|
||||
|
||||
// Stats table
|
||||
|
||||
var StatsModel = Backbone.Model.extend({
|
||||
url: "api/stats/byclientid"
|
||||
});
|
||||
|
||||
// Router
|
||||
var AppRouter = Backbone.Router.extend({
|
||||
|
||||
|
@ -340,8 +346,10 @@ var AppRouter = Backbone.Router.extend({
|
|||
this.blackListList = new BlackListCollection();
|
||||
this.approvedSiteList = new ApprovedSiteCollection();
|
||||
this.systemScopeList = new SystemScopeCollection();
|
||||
this.clientStats = new StatsModel();
|
||||
|
||||
this.clientListView = new ClientListView({model:this.clientList});
|
||||
|
||||
this.clientListView = new ClientListView({model:this.clientList, stats: this.clientStats});
|
||||
this.whiteListListView = new WhiteListListView({model:this.whiteListList});
|
||||
this.approvedSiteListView = new ApprovedSiteListView({model:this.approvedSiteList});
|
||||
this.blackListListView = new BlackListListView({model:this.blackListList});
|
||||
|
@ -365,8 +373,12 @@ var AppRouter = Backbone.Router.extend({
|
|||
success: function(collection, response) {
|
||||
app.whiteListList.fetch({
|
||||
success: function(collection, response) {
|
||||
var baseUrl = $.url($('base').attr('href'));
|
||||
Backbone.history.start({pushState: true, root: baseUrl.attr('relative') + 'manage/'});
|
||||
app.clientStats.fetch({
|
||||
success: function(model, response) {
|
||||
var baseUrl = $.url($('base').attr('href'));
|
||||
Backbone.history.start({pushState: true, root: baseUrl.attr('relative') + 'manage/'});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -133,7 +133,8 @@ var ClientView = Backbone.View.extend({
|
|||
},
|
||||
|
||||
render:function (eventName) {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
var json = {client: this.model.toJSON(), count: this.options.count};
|
||||
this.$el.html(this.template(json));
|
||||
|
||||
$('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scope'), systemScopes: app.systemScopeList}));
|
||||
|
||||
|
@ -230,7 +231,11 @@ var ClientListView = Backbone.View.extend({
|
|||
$(this.el).html($('#tmpl-client-table').html());
|
||||
|
||||
_.each(this.model.models, function (client) {
|
||||
$("#client-table",this.el).append(new ClientView({model:client}).render().el);
|
||||
$("#client-table",this.el).append(
|
||||
new ClientView({
|
||||
model:client,
|
||||
count:this.options.stats.get(client.get('id'))
|
||||
}).render().el);
|
||||
}, this);
|
||||
|
||||
this.togglePlaceholder();
|
||||
|
@ -250,9 +255,13 @@ var ClientListView = Backbone.View.extend({
|
|||
|
||||
refreshTable:function() {
|
||||
var _self = this;
|
||||
this.model.fetch({
|
||||
_self.model.fetch({
|
||||
success: function() {
|
||||
_self.render();
|
||||
_self.options.stats.fetch({
|
||||
success: function () {
|
||||
_self.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ var SystemScopeView = Backbone.View.extend({
|
|||
render:function (eventName) {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
|
||||
this.$('.dynamically-registered').tooltip({title: 'This client was dynamically registered'});
|
||||
this.$('.allow-dyn-reg').tooltip({title: 'This scope can be used by dynamically registered clients'});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
|
|
@ -18,19 +18,24 @@
|
|||
|
||||
<script type="text/html" id="tmpl-client">
|
||||
<td>
|
||||
<% if (dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<% if (count) { %>
|
||||
<span class="label label-info"><%= count %></span>
|
||||
<% } else { %>
|
||||
<span class="label label-important">0</span>
|
||||
<% } %>
|
||||
<% if (client.dynamicallyRegistered) { %>
|
||||
<span class="label label-inverse dynamically-registered"><i class="icon-globe icon-white"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=clientId%>
|
||||
<%=client.clientId%>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=clientName%>
|
||||
<% if (clientDescription) { %>
|
||||
<blockquote><small><%=clientDescription%></small></blockquote>
|
||||
<%=client.clientName%>
|
||||
<% if (client.clientDescription) { %>
|
||||
<blockquote><small><%=client.clientDescription%></small></blockquote>
|
||||
<% } %>
|
||||
<div class="scope-list"></div>
|
||||
<!--expandable future information-->
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
<script type="text/html" id="tmpl-grant">
|
||||
<td>
|
||||
<% if (client.dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<span class="label label-inverse dynamically-registered"><i class="icon-globe icon-white"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
|
|
|
@ -47,13 +47,18 @@
|
|||
|
||||
<script type="text/html" id="tmpl-system-scope">
|
||||
<td>
|
||||
<% if (icon) { %>
|
||||
<i class="icon-<%= icon %>"></i>
|
||||
<% if (allowDynReg) { %>
|
||||
<span class="label label-inverse allow-dyn-reg"><i class="icon-globe icon-white"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= value %>
|
||||
<span class="badge badge-info">
|
||||
<% if (icon) { %>
|
||||
<i class="icon-<%= icon %> icon-white"></i>
|
||||
<% } %>
|
||||
<%= value %>
|
||||
</span>
|
||||
<blockquote><small><%= description %></small></blockquote>
|
||||
</td>
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<script type="text/html" id="tmpl-whitelist">
|
||||
<td>
|
||||
<% if (client.dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<span class="label label-inverse dynamically-registered"><i class="icon-globe icon-white"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
|
|
Loading…
Reference in New Issue