Skip to content

Commit 4efebca

Browse files
committed
resolved #233: Upgraded to Swashbuckle.AspNetCore 2.4.0
1 parent 33306f9 commit 4efebca

File tree

6 files changed

+345
-58
lines changed

6 files changed

+345
-58
lines changed

aspnet-core/src/AbpCompanyName.AbpProjectName.Web.Core/AbpCompanyName.AbpProjectName.Web.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
3535
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.0.4" />
3636
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="2.0.3" />
37-
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.1.0" />
37+
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.4.0" />
3838
<PackageReference Include="Abp.AspNetCore" Version="3.6.1" />
3939
<PackageReference Include="Abp.ZeroCore" Version="3.6.1" />
4040
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.3" />

aspnet-core/src/AbpCompanyName.AbpProjectName.Web.Host/AbpCompanyName.AbpProjectName.Web.Host.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
<DefineConstants>FEATURE_SIGNALR_ASPNETCORE</DefineConstants>
1919
</PropertyGroup>
2020

21+
<ItemGroup>
22+
<Content Remove="wwwroot\swagger\ui\index.html" />
23+
</ItemGroup>
24+
2125
<ItemGroup>
2226
<None Include="app.config" />
2327
<None Update="Dockerfile">
@@ -65,4 +69,10 @@
6569
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
6670
</ItemGroup>
6771

72+
<ItemGroup>
73+
<EmbeddedResource Include="wwwroot\swagger\ui\index.html">
74+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
75+
</EmbeddedResource>
76+
</ItemGroup>
77+
6878
</Project>

aspnet-core/src/AbpCompanyName.AbpProjectName.Web.Host/Startup/Startup.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Linq;
3+
using System.Reflection;
34
using Microsoft.AspNetCore.Builder;
45
using Microsoft.AspNetCore.Hosting;
56
using Microsoft.AspNetCore.Mvc.Cors.Internal;
@@ -134,9 +135,9 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
134135
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
135136
app.UseSwaggerUI(options =>
136137
{
137-
options.InjectOnCompleteJavaScript("/swagger/ui/abp.js");
138-
options.InjectOnCompleteJavaScript("/swagger/ui/on-complete.js");
139138
options.SwaggerEndpoint("/swagger/v1/swagger.json", "AbpProjectName API V1");
139+
options.IndexStream = () => Assembly.GetExecutingAssembly()
140+
.GetManifestResourceStream("AbpCompanyName.AbpProjectName.Web.Host.wwwroot.swagger.ui.index.html");
140141
}); // URL: /swagger
141142
}
142143

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
var abp = abp || {};
2+
(function () {
3+
4+
/* Swagger */
5+
6+
abp.swagger = abp.swagger || {};
7+
8+
abp.swagger.addAuthToken = function () {
9+
var authToken = abp.auth.getToken();
10+
if (!authToken) {
11+
return false;
12+
}
13+
14+
var cookieAuth = new SwaggerClient.ApiKeyAuthorization(abp.auth.tokenHeaderName, 'Bearer ' + authToken, 'header');
15+
swaggerUi.api.clientAuthorizations.add('bearerAuth', cookieAuth);
16+
return true;
17+
}
18+
19+
abp.swagger.addCsrfToken = function () {
20+
var csrfToken = abp.security.antiForgery.getToken();
21+
if (!csrfToken) {
22+
return false;
23+
}
24+
var csrfCookieAuth = new SwaggerClient.ApiKeyAuthorization(abp.security.antiForgery.tokenHeaderName, csrfToken, 'header');
25+
swaggerUi.api.clientAuthorizations.add(abp.security.antiForgery.tokenHeaderName, csrfCookieAuth);
26+
return true;
27+
}
28+
29+
function loginUserInternal(tenantId, callback) {
30+
var usernameOrEmailAddress = document.getElementById('userName').value;
31+
if (!usernameOrEmailAddress) {
32+
alert('Username or Email Address is required, please try with a valid value !');
33+
return false;
34+
}
35+
36+
var password = document.getElementById('password').value;
37+
if (!password) {
38+
alert('Password is required, please try with a valid value !');
39+
return false;
40+
}
41+
42+
var xhr = new XMLHttpRequest();
43+
44+
xhr.onreadystatechange = function () {
45+
if (xhr.readyState === XMLHttpRequest.DONE) {
46+
if (xhr.status === 200) {
47+
var responseJSON = JSON.parse(xhr.responseText);
48+
var result = responseJSON.result;
49+
var expireDate = new Date(Date.now() + (result.expireInSeconds * 1000));
50+
abp.auth.setToken(result.accessToken, expireDate);
51+
callback();
52+
} else {
53+
alert('Login failed !');
54+
}
55+
}
56+
};
57+
58+
xhr.open('POST', '/api/TokenAuth/Authenticate', true);
59+
xhr.setRequestHeader('Abp.TenantId', tenantId);
60+
xhr.setRequestHeader('Content-type', 'application/json');
61+
xhr.send("{" + "usernameOrEmailAddress:'" + usernameOrEmailAddress + "'," + "password:'" + password + "'}");
62+
};
63+
64+
abp.swagger.login = function (callback) {
65+
//Get TenantId first
66+
var tenancyName = document.getElementById('tenancyName').value;
67+
68+
if (tenancyName) {
69+
var xhrTenancyName = new XMLHttpRequest();
70+
xhrTenancyName.onreadystatechange = function () {
71+
if (xhrTenancyName.readyState === XMLHttpRequest.DONE && xhrTenancyName.status === 200) {
72+
var responseJSON = JSON.parse(xhrTenancyName.responseText);
73+
var result = responseJSON.result;
74+
if (result.state === 1) { // Tenant exists and active.
75+
loginUserInternal(result.tenantId, callback); // Login for tenant
76+
} else {
77+
alert('There is no such tenant or tenant is not active !');
78+
}
79+
}
80+
};
81+
82+
xhrTenancyName.open('POST', '/api/services/app/Account/IsTenantAvailable', true);
83+
xhrTenancyName.setRequestHeader('Content-type', 'application/json');
84+
xhrTenancyName.send("{" + "tenancyName:'" + tenancyName + "'}");
85+
} else {
86+
loginUserInternal(null, callback); // Login for host
87+
}
88+
};
89+
90+
abp.swagger.logout = function () {
91+
abp.auth.clearToken();
92+
}
93+
94+
abp.swagger.closeAuthDialog = function () {
95+
if (document.getElementById('abp-auth-dialog')) {
96+
document.getElementsByClassName("swagger-ui")[1].removeChild(document.getElementById('abp-auth-dialog'));
97+
}
98+
}
99+
100+
abp.swagger.openAuthDialog = function (loginCallback) {
101+
abp.swagger.closeAuthDialog();
102+
103+
var abpAuthDialog = document.createElement('div');
104+
abpAuthDialog.className = 'dialog-ux';
105+
abpAuthDialog.id = 'abp-auth-dialog';
106+
107+
document.getElementsByClassName("swagger-ui")[1].appendChild(abpAuthDialog);
108+
109+
// -- backdrop-ux
110+
var backdropUx = document.createElement('div');
111+
backdropUx.className = 'backdrop-ux';
112+
abpAuthDialog.appendChild(backdropUx);
113+
114+
// -- modal-ux
115+
var modalUx = document.createElement('div');
116+
modalUx.className = 'modal-ux';
117+
abpAuthDialog.appendChild(modalUx);
118+
119+
// -- -- modal-dialog-ux
120+
var modalDialogUx = document.createElement('div');
121+
modalDialogUx.className = 'modal-dialog-ux';
122+
modalUx.appendChild(modalDialogUx);
123+
124+
// -- -- -- modal-ux-inner
125+
var modalUxInner = document.createElement('div');
126+
modalUxInner.className = 'modal-ux-inner';
127+
modalDialogUx.appendChild(modalUxInner);
128+
129+
// -- -- -- -- modal-ux-header
130+
var modalUxHeader = document.createElement('div');
131+
modalUxHeader.className = 'modal-ux-header';
132+
modalUxInner.appendChild(modalUxHeader);
133+
134+
var modalHeader = document.createElement('h3');
135+
modalHeader.innerText = 'Authorize';
136+
modalUxHeader.appendChild(modalHeader);
137+
138+
// -- -- -- -- modal-ux-content
139+
var modalUxContent = document.createElement('div');
140+
modalUxContent.className = 'modal-ux-content';
141+
modalUxInner.appendChild(modalUxContent);
142+
143+
modalUxContent.onkeydown = function (e) {
144+
if (e.keyCode === 13) {
145+
//try to login when user presses enter on authorize modal
146+
abp.swagger.login(loginCallback);
147+
}
148+
};
149+
150+
//Inputs
151+
createInput(modalUxContent, 'tenancyName', 'Tenancy Name (Leave empty for Host)');
152+
createInput(modalUxContent, 'userName', 'Username or email address');
153+
createInput(modalUxContent, 'password', 'Password', 'password');
154+
155+
//Buttons
156+
var authBtnWrapper = document.createElement('div');
157+
authBtnWrapper.className = 'auth-btn-wrapper';
158+
modalUxContent.appendChild(authBtnWrapper);
159+
160+
//Close button
161+
var closeButton = document.createElement('button');
162+
closeButton.className = 'btn modal-btn auth btn-done button';
163+
closeButton.innerText = 'Close';
164+
closeButton.style.marginRight = '5px';
165+
closeButton.onclick = abp.swagger.closeAuthDialog;
166+
authBtnWrapper.appendChild(closeButton);
167+
168+
//Authorize button
169+
var authorizeButton = document.createElement('button');
170+
authorizeButton.className = 'btn modal-btn auth authorize button';
171+
authorizeButton.innerText = 'Login';
172+
authorizeButton.onclick = function() {
173+
abp.swagger.login(loginCallback);
174+
};
175+
authBtnWrapper.appendChild(authorizeButton);
176+
}
177+
178+
function createInput(container, id, title, type) {
179+
var wrapper = document.createElement('div');
180+
wrapper.className = 'wrapper';
181+
container.appendChild(wrapper);
182+
183+
var label = document.createElement('label');
184+
label.innerText = title;
185+
wrapper.appendChild(label);
186+
187+
var section = document.createElement('section');
188+
section.className = 'block-tablet col-10-tablet block-desktop col-10-desktop';
189+
wrapper.appendChild(section);
190+
191+
var input = document.createElement('input');
192+
input.id = id;
193+
input.type = type ? type : 'text';
194+
input.style.width = '100%';
195+
196+
section.appendChild(input);
197+
}
198+
199+
})();
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<!-- HTML for static distribution bundle build -->
2+
<!DOCTYPE html>
3+
<html lang="en">
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>%(DocumentTitle)</title>
7+
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
8+
<link rel="stylesheet" type="text/css" href="./swagger-ui.css">
9+
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
10+
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
11+
<style>
12+
html {
13+
box-sizing: border-box;
14+
overflow: -moz-scrollbars-vertical;
15+
overflow-y: scroll;
16+
}
17+
18+
*,
19+
*:before,
20+
*:after {
21+
box-sizing: inherit;
22+
}
23+
24+
body {
25+
margin: 0;
26+
background: #fafafa;
27+
}
28+
</style>
29+
%(HeadContent)
30+
</head>
31+
32+
<body>
33+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
34+
<defs>
35+
<symbol viewBox="0 0 20 20" id="unlocked">
36+
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
37+
</symbol>
38+
39+
<symbol viewBox="0 0 20 20" id="locked">
40+
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z" />
41+
</symbol>
42+
43+
<symbol viewBox="0 0 20 20" id="close">
44+
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z" />
45+
</symbol>
46+
47+
<symbol viewBox="0 0 20 20" id="large-arrow">
48+
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z" />
49+
</symbol>
50+
51+
<symbol viewBox="0 0 20 20" id="large-arrow-down">
52+
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z" />
53+
</symbol>
54+
55+
56+
<symbol viewBox="0 0 24 24" id="jump-to">
57+
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z" />
58+
</symbol>
59+
60+
<symbol viewBox="0 0 24 24" id="expand">
61+
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
62+
</symbol>
63+
64+
</defs>
65+
</svg>
66+
67+
<div id="swagger-ui"></div>
68+
69+
<script src="./swagger-ui-bundle.js"></script>
70+
<script src="./swagger-ui-standalone-preset.js"></script>
71+
<script src="/swagger/ui/abp.js"></script>
72+
<script src="/swagger/ui/abp.swagger.js"></script>
73+
<script>
74+
window.onload = function () {
75+
var configObject = JSON.parse('%(ConfigObject)');
76+
77+
// Apply mandatory parameters
78+
configObject.dom_id = "#swagger-ui";
79+
configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset];
80+
configObject.layout = "StandaloneLayout";
81+
configObject.requestInterceptor = function (request) {
82+
request.headers.Authorization = "Bearer " + abp.auth.getToken();
83+
return request;
84+
};
85+
if (!configObject.hasOwnProperty("oauth2RedirectUrl")) {
86+
configObject.oauth2RedirectUrl = window.location + "oauth2-redirect.html"; // use the built-in default
87+
}
88+
function getAuthorizeButtonText() {
89+
return abp.auth.getToken() ? 'Logout' : 'Authorize';
90+
}
91+
function getAuthorizeButtonCssClass() {
92+
return abp.auth.getToken() ? 'cancel' : 'authorize';
93+
}
94+
configObject.plugins = [
95+
function (system) {
96+
return {
97+
components: {
98+
authorizeBtn: function () {
99+
return system.React.createElement("button",
100+
{
101+
id: "authorize",
102+
className: "btn " + getAuthorizeButtonCssClass(),
103+
style: {
104+
lineHeight: "normal"
105+
},
106+
onClick: function () {
107+
var authorizeButton = document.getElementById('authorize');
108+
if (abp.auth.getToken()) {
109+
abp.swagger.logout();
110+
authorizeButton.innerText = getAuthorizeButtonText();
111+
authorizeButton.className = 'btn ' + getAuthorizeButtonCssClass();
112+
} else {
113+
abp.swagger.openAuthDialog(function () {
114+
authorizeButton.innerText = getAuthorizeButtonText();
115+
authorizeButton.className = 'btn ' + getAuthorizeButtonCssClass();
116+
abp.swagger.closeAuthDialog();
117+
});
118+
}
119+
}
120+
}, getAuthorizeButtonText());
121+
}
122+
}
123+
}
124+
}
125+
];
126+
// Build a system
127+
SwaggerUIBundle(configObject);
128+
}
129+
</script>
130+
</body>
131+
132+
</html>

0 commit comments

Comments
 (0)