mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-06 21:30:21 +03:00
Merge addd10b762
into 5e5db72ea4
This commit is contained in:
commit
761bdca928
12
lib/components/AuthScopes/auth-scopes.html
Normal file
12
lib/components/AuthScopes/auth-scopes.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<ng-template [ngIf]="scopes">
|
||||
<span class="hint--html hint--bottom-left hint--large oauth-scopes-hint">
|
||||
!
|
||||
<div class="oauth-scopes hint__content">
|
||||
<span class="oauth-scopes-header">OAuth2 Scopes</span>
|
||||
<div *ngFor="let scope of scopes.scopes" class="oauth-scope">
|
||||
<p class="oauth-scope-name"> {{scope.name}} </p>
|
||||
<p class="oauth-scope-description"> {{scope.description}} </p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</ng-template>
|
32
lib/components/AuthScopes/auth-scopes.scss
Normal file
32
lib/components/AuthScopes/auth-scopes.scss
Normal file
|
@ -0,0 +1,32 @@
|
|||
$hint-color: #e53935;
|
||||
|
||||
.oauth-scopes-header {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.oauth-scope {
|
||||
padding-top: 1.2em;
|
||||
}
|
||||
|
||||
.oauth-scope-description {
|
||||
font-style: italic;
|
||||
line-height: 0.2em;
|
||||
}
|
||||
|
||||
.oauth-scopes {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.oauth-scopes-hint {
|
||||
width: 1.2em;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
color: $hint-color;
|
||||
line-height: 1.2;
|
||||
text-transform: none;
|
||||
cursor: help;
|
||||
border: 1px solid $hint-color;
|
||||
float: right;
|
||||
}
|
32
lib/components/AuthScopes/auth-scopes.ts
Normal file
32
lib/components/AuthScopes/auth-scopes.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
import { Component, Input, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { BaseComponent, SpecManager } from '../base';
|
||||
import { SchemaHelper } from '../../services/schema-helper.service';
|
||||
import { ComponentParser } from '../../services/component-parser.service';
|
||||
|
||||
@Component({
|
||||
selector: 'auth-scopes',
|
||||
templateUrl: './auth-scopes.html',
|
||||
styleUrls: ['./auth-scopes.css'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class AuthScopes extends BaseComponent implements OnInit {
|
||||
@Input() pointer:string;
|
||||
|
||||
public scopes: any;
|
||||
|
||||
constructor(specMgr:SpecManager) {
|
||||
super(specMgr);
|
||||
}
|
||||
|
||||
init() {
|
||||
let theScopes = this.specMgr.getOperationScopes(this.pointer);
|
||||
if (theScopes.length) {
|
||||
this.scopes = {scopes: theScopes}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.preinit();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
<div class="operation-content">
|
||||
<h2 class="operation-header sharable-header" [class.deprecated]="operation.deprecated">
|
||||
<a class="share-link" href="#{{operation.anchor}}"></a>{{operation.summary}}
|
||||
<auth-scopes pointer="{{pointer}}/security"> </auth-scopes>
|
||||
</h2>
|
||||
<endpoint-link *ngIf="pathInMiddlePanel"
|
||||
[verb]="operation.verb" [path]="operation.path"> </endpoint-link>
|
||||
|
|
|
@ -8,6 +8,7 @@ import { ParamsList } from './ParamsList/params-list';
|
|||
import { RequestSamples } from './RequestSamples/request-samples';
|
||||
import { ResponsesList } from './ResponsesList/responses-list';
|
||||
import { ResponsesSamples } from './ResponsesSamples/responses-samples';
|
||||
import { AuthScopes} from './AuthScopes/auth-scopes';
|
||||
import { SchemaSample } from './SchemaSample/schema-sample';
|
||||
import { SideMenu, SideMenuItems } from './SideMenu/side-menu';
|
||||
import { OperationsList } from './OperationsList/operations-list';
|
||||
|
@ -23,10 +24,10 @@ import { Redoc } from './Redoc/redoc';
|
|||
|
||||
export const REDOC_DIRECTIVES = [
|
||||
ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
||||
ResponsesSamples, SchemaSample, SideMenu, OperationsList, Operation, Warnings, Redoc, SecurityDefinitions,
|
||||
ResponsesSamples, AuthScopes, SchemaSample, SideMenu, OperationsList, Operation, Warnings, Redoc, SecurityDefinitions,
|
||||
LoadingBar, SideMenuItems, RedocSearch, ExternalDocs, EndpointLink
|
||||
];
|
||||
|
||||
export { ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
||||
ResponsesSamples, SchemaSample, SideMenu, OperationsList, Operation, Warnings, Redoc, SecurityDefinitions,
|
||||
ResponsesSamples, AuthScopes, SchemaSample, SideMenu, OperationsList, Operation, Warnings, Redoc, SecurityDefinitions,
|
||||
LoadingBar, SideMenuItems, ExternalDocs, EndpointLink };
|
||||
|
|
|
@ -138,6 +138,42 @@ export class SpecManager {
|
|||
return obj;
|
||||
}
|
||||
|
||||
getOperationScopes(operationPtr:string) {
|
||||
let that = this;
|
||||
function getSecurityDefinition(name:string, scope:string) {
|
||||
let secDefs = that._schema.securityDefinitions;
|
||||
if (secDefs[name] && secDefs[name].type === 'oauth2') {
|
||||
let availScopes = secDefs[name].scopes;
|
||||
if (availScopes && availScopes[scope]) {
|
||||
return availScopes[scope];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
let securityParams = this.byPointer(operationPtr) || [];
|
||||
let scopes = [];
|
||||
|
||||
// only support one security item per operation for now
|
||||
let base = securityParams[0];
|
||||
|
||||
if (base && base[Object.keys(base)[0]]) {
|
||||
let scopeObj = base[Object.keys(base)[0]];
|
||||
let authName = Object.keys(base)[0];
|
||||
Object.keys(scopeObj).forEach(key => {
|
||||
let val = scopeObj[key];
|
||||
let desc = getSecurityDefinition(authName, val);
|
||||
|
||||
// don't add if the security obj doesn't exist in the security definitions
|
||||
if (desc) {
|
||||
scopes.push({name: val, description: desc});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return scopes;
|
||||
}
|
||||
|
||||
getOperationParams(operationPtr:string):SwaggerParameter[] {
|
||||
/* inject JsonPointer into array elements */
|
||||
function injectPointers(array:SwaggerParameter[], root) {
|
||||
|
|
|
@ -22,7 +22,7 @@ import 'prismjs/components/prism-markup.js'; // xml
|
|||
|
||||
import 'dropkickjs/build/css/dropkick.css';
|
||||
import 'prismjs/themes/prism-dark.css';
|
||||
import 'hint.css/hint.base.css';
|
||||
import 'html-hint/dist/html-hint.css';
|
||||
|
||||
if (!IS_PRODUCTION) {
|
||||
require('@angular/platform-browser');
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
"css-loader": "^0.28.1",
|
||||
"deploy-to-gh-pages": "^1.3.3",
|
||||
"dropkickjs": "^2.1.10",
|
||||
"hint.css": "^2.5.0",
|
||||
"html-hint": "^0.2.4",
|
||||
"http-server": "^0.10.0",
|
||||
"https-browserify": "^1.0.0",
|
||||
"istanbul-instrumenter-loader": "^2.0.0",
|
||||
|
|
108
tests/schemas/schema-mgr-operation-security.json
Normal file
108
tests/schemas/schema-mgr-operation-security.json
Normal file
|
@ -0,0 +1,108 @@
|
|||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
"title": "Test schema"
|
||||
},
|
||||
"host": "petstore.swagger.io",
|
||||
"basePath": "/v2/",
|
||||
"parameters": {
|
||||
"extparam": {
|
||||
"name": "extParam",
|
||||
"in": "query",
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"petstore_auth": {
|
||||
"type": "oauth2",
|
||||
"authorizationUrl": "http://petstore.swagger.io/api/oauth/dialog",
|
||||
"flow": "implicit",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets"
|
||||
}
|
||||
},
|
||||
"github_auth": {
|
||||
"type": "oauth2",
|
||||
"authorizationUrl": "https://api.github.com/authorize",
|
||||
"flow": "implicit",
|
||||
"scopes": {
|
||||
"write:account": "modify your account",
|
||||
"read:account": "read your account"
|
||||
}
|
||||
},
|
||||
"api_key": {
|
||||
"type": "apiKey",
|
||||
"name": "api_key",
|
||||
"in": "header"
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"test1": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "pathParam",
|
||||
"in": "path",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"get": {
|
||||
"summary": "test get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "operationParam",
|
||||
"in": "path",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"petstore_auth": [
|
||||
"write:pets",
|
||||
"read:pets"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"test2": {
|
||||
"parameters": [
|
||||
{ "$ref": "#/parameters/extparam" }
|
||||
],
|
||||
"get": {
|
||||
"summary": "test get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "operationParam",
|
||||
"in": "path",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"test3": {
|
||||
"get": {
|
||||
"summary": "test get",
|
||||
"parameters": [
|
||||
{ "$ref": "#/parameters/extparam" }
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"github_auth": [
|
||||
"write:account"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"test4": {
|
||||
"parameters": {
|
||||
"$ref": "#/parameters/extparam"
|
||||
},
|
||||
"get": {
|
||||
"summary": "test get"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -105,6 +105,33 @@ describe('Utils', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('getOperationScopes method', () => {
|
||||
beforeEach(function (done) {
|
||||
specMgr.load('/tests/schemas/schema-mgr-operation-security.json').then(done, done.fail);
|
||||
});
|
||||
|
||||
it('should handle operation oauth2 scopes', () => {
|
||||
let scopes = specMgr.getOperationScopes('/paths/test1/get/security');
|
||||
scopes.length.should.be.equal(2);
|
||||
scopes[0].name.should.be.equal('write:pets');
|
||||
scopes[0].description.should.be.equal('modify pets in your account');
|
||||
scopes[1].name.should.be.equal('read:pets');
|
||||
scopes[1].description.should.be.equal('read your pets');
|
||||
});
|
||||
|
||||
it('should handle operation scopes when multiple definitions are used', () => {
|
||||
let scopes = specMgr.getOperationScopes('/paths/test3/get/security');
|
||||
scopes.length.should.be.equal(1);
|
||||
scopes[0].name.should.be.equal('write:account');
|
||||
scopes[0].description.should.be.equal('modify your account');\
|
||||
});
|
||||
|
||||
it('should handle the case when no security is present', () => {
|
||||
let scopes = specMgr.getOperationScopes('/paths/test2/get/security');
|
||||
scopes.length.should.be.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOperationParams method', () => {
|
||||
beforeEach((done:any) => {
|
||||
specMgr.load('/tests/schemas/schema-mgr-operationParams.json').then(done, done.fail);
|
||||
|
|
Loading…
Reference in New Issue
Block a user