-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* improve error handling in editor * update git Dockerfile * fix compose files * add api support for linked keys * add management support for linked keys * [editor] redirect link keys * organize files * add authoring support for linked keys * [editor] display linked keys * Added api and management unit tests * rename 'link' key type to 'alias' * added key aliases test * combine dependents endpoints * [editor] handle alias value type * added more tests * [editor] deleting a key should delete aliases * [editor] move keyPath validation to NewKeyInput component * [editor] Alert component can display custom components * [editor] added addAlias action to selectedKey duck * [editor] added validation and component data to Alert component * [editor] NewKeyInput styles * [editor] added option to add alias for key * [e2e-ui] fix aliases tests * [e2e-ui] added add alias test * [editor] style review * [authoring] fix delete single key * [editor] added delete alias * [e2e-ui] added delete alias test * [e2e-integration] rename test key * [smoke-tests] rename test keys * [e2e-integration] added alias test * code review * bump versions
- Loading branch information
Showing
173 changed files
with
1,790 additions
and
1,471 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
core/Engine/Tweek.Engine.Tests/Core/KeyAliasParserTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using LanguageExt; | ||
using Tweek.Engine.Core.Context; | ||
using Xunit; | ||
using static LanguageExt.Prelude; | ||
|
||
namespace Tweek.Engine.Tests.Core | ||
{ | ||
public class KeyAliasParserTests | ||
{ | ||
[Fact] | ||
public void ParseLink_GetLinkValue() | ||
{ | ||
// Arrange | ||
const string ORIGINAL_KEY = "some_key"; | ||
var parser = Engine.Core.Rules.Utils.KeyAliasParser; | ||
|
||
string requestedContext = null; | ||
var getContextValue = new GetContextValue(key => | ||
{ | ||
requestedContext = key; | ||
return None; | ||
}); | ||
|
||
// Act | ||
var result = parser.Parse(ORIGINAL_KEY).GetValue(getContextValue); | ||
|
||
// Assert | ||
Assert.Equal(result, None); | ||
Assert.Equal(requestedContext, $"keys.{ORIGINAL_KEY}"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,37 @@ | ||
const chai = require('chai'); | ||
chai.should(); | ||
const {init:initClients} = require("../../utils/clients"); | ||
const delay = (duration)=> new Promise(resolve=>setTimeout(resolve,duration)); | ||
const { init: initClients } = require('../../utils/clients'); | ||
|
||
describe('authoring api', () => { | ||
describe('authoring api - add app', () => { | ||
let clients; | ||
before(async () => { | ||
clients = await initClients(); | ||
}); | ||
|
||
describe('/posts /apps/new', () => { | ||
it('allow creating new app with keys-read permission', async () => { | ||
const response = await clients.authoring.post('/api/apps?author.name=test&[email protected]') | ||
.send({ name: 'my-app', permissions: ['keys-read'] }) | ||
.expect(200); | ||
|
||
let {appId, appSecret} = response.body; | ||
|
||
let appClient = await clients.authoring.with(client => | ||
client.set( {"x-client-id": appId, "x-client-secret": appSecret } ) | ||
.unset("Authorization") | ||
); | ||
|
||
await appClient.get('/api/keys/@integration_tests/some_key') | ||
.expect(200) | ||
|
||
await appClient.get('/api/keys') | ||
.expect(403) | ||
}); | ||
|
||
it('allow creating new app with invalid permission', async () => { | ||
await clients.authoring.post('/api/apps?author.name=test&[email protected]') | ||
.send({ name: 'my-app', permissions: ['admin'] }) | ||
.expect(400); | ||
|
||
await clients.authoring.post('/api/apps?author.name=test&[email protected]') | ||
.send({ name: 'my-app', permissions: ['my-permission'] }) | ||
.expect(400); | ||
|
||
}); | ||
it('allow creating new app with keys-read permission', async () => { | ||
const response = await clients.authoring | ||
.post('/api/apps?author.name=test&[email protected]') | ||
.send({ name: 'my-app', permissions: ['keys-read'] }) | ||
.expect(200); | ||
|
||
let { appId, appSecret } = response.body; | ||
|
||
let appClient = await clients.authoring.with(client => | ||
client.set({ 'x-client-id': appId, 'x-client-secret': appSecret }).unset('Authorization'), | ||
); | ||
|
||
await appClient.get('/api/keys/integration_tests/some_key').expect(200); | ||
|
||
await appClient.get('/api/keys').expect(403); | ||
}); | ||
|
||
it('allow creating new app with invalid permission', async () => { | ||
await clients.authoring | ||
.post('/api/apps?author.name=test&[email protected]') | ||
.send({ name: 'my-app', permissions: ['admin'] }) | ||
.expect(400); | ||
|
||
await clients.authoring | ||
.post('/api/apps?author.name=test&[email protected]') | ||
.send({ name: 'my-app', permissions: ['my-permission'] }) | ||
.expect(400); | ||
}); | ||
}); |
206 changes: 103 additions & 103 deletions
206
e2e/integration/spec/authoring-api/app-permissions.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,131 +1,131 @@ | ||
const { init: initClients } = require("../../utils/clients"); | ||
const permissions = ['keys-list', 'keys-read', 'keys-write', 'schemas-read', 'schemas-write', 'history', 'search', 'search-index', 'tags-read', 'tags-write']; | ||
const { init: initClients } = require('../../utils/clients'); | ||
const permissions = [ | ||
'keys-list', | ||
'keys-read', | ||
'keys-write', | ||
'schemas-read', | ||
'schemas-write', | ||
'history', | ||
'search', | ||
'search-index', | ||
'tags-read', | ||
'tags-write', | ||
]; | ||
const { expect } = require('chai'); | ||
|
||
describe("app permissions test", () => { | ||
let clients; | ||
before(async () => { | ||
clients = await initClients(); | ||
}); | ||
const cases = [{ | ||
name: "read_specific_key", | ||
requirePermission: "keys-read", | ||
action: async (client) => { | ||
await client.get('/api/keys/@integration_tests/some_key') | ||
.expect(200) | ||
} | ||
describe('authoring api - app permissions', () => { | ||
let clients; | ||
before(async () => { | ||
clients = await initClients(); | ||
}); | ||
const cases = [ | ||
{ | ||
name: 'read_specific_key', | ||
requirePermission: 'keys-read', | ||
action: async client => { | ||
await client.get('/api/keys/integration_tests/some_key').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "read_specific_key", | ||
requirePermission: "keys-read", | ||
action: async (client) => { | ||
await client.get('/api/key?keyPath=%40integration_tests%2Fsome_key') | ||
.expect(200) | ||
} | ||
name: 'read_specific_key', | ||
requirePermission: 'keys-read', | ||
action: async client => { | ||
await client.get('/api/key?keyPath=integration_tests%2Fsome_key').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "read_manifests", | ||
requirePermission: "keys-read", | ||
action: async (client) => { | ||
await client.get('/api/manifests/@integration_tests/some_key') | ||
.expect(200) | ||
} | ||
name: 'read_manifests', | ||
requirePermission: 'keys-read', | ||
action: async client => { | ||
await client.get('/api/manifests/integration_tests/some_key').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "list_keys", | ||
requirePermission: "keys-list", | ||
action: async (client) => { | ||
await client.get('/api/keys') | ||
.expect(200) | ||
} | ||
name: 'list_keys', | ||
requirePermission: 'keys-list', | ||
action: async client => { | ||
await client.get('/api/keys').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "list_manifests", | ||
requirePermission: "keys-list", | ||
action: async (client) => { | ||
await client.get('/api/manifests') | ||
.expect(200) | ||
} | ||
name: 'list_manifests', | ||
requirePermission: 'keys-list', | ||
action: async client => { | ||
await client.get('/api/manifests').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "get_dependents", | ||
requirePermission: "keys-read", | ||
action: async (client) => { | ||
await client.get('/api/dependents/@integration_tests/some_key') | ||
.expect(200) | ||
} | ||
name: 'get_dependents', | ||
requirePermission: 'keys-read', | ||
action: async client => { | ||
await client.get('/api/dependents/integration_tests/some_key').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "get_dependents", | ||
requirePermission: "keys-read", | ||
action: async (client) => { | ||
await client.get('/api/dependents/@integration_tests/some_key') | ||
.expect(200) | ||
} | ||
name: 'get_dependents', | ||
requirePermission: 'keys-read', | ||
action: async client => { | ||
await client.get('/api/dependents/integration_tests/some_key').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "get_schemas", | ||
requirePermission: "schemas_read", | ||
action: async (client) => { | ||
await client.get('/api/schemas') | ||
.expect(200) | ||
} | ||
name: 'get_schemas', | ||
requirePermission: 'schemas_read', | ||
action: async client => { | ||
await client.get('/api/schemas').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "search", | ||
requirePermission: "search", | ||
action: async (client) => { | ||
await client.get('/api/search') | ||
.expect(200) | ||
} | ||
name: 'search', | ||
requirePermission: 'search', | ||
action: async client => { | ||
await client.get('/api/search').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "suggestions", | ||
requirePermission: "search", | ||
action: async (client) => { | ||
await client.get('/api/suggestions') | ||
.expect(200) | ||
} | ||
name: 'suggestions', | ||
requirePermission: 'search', | ||
action: async client => { | ||
await client.get('/api/suggestions').expect(200); | ||
}, | ||
}, | ||
{ | ||
name: "search-index", | ||
requirePermission: "search-index", | ||
action: async (client) => { | ||
await client.get('/api/search-index') | ||
.expect(200) | ||
} | ||
} | ||
]; | ||
|
||
for (let permission of permissions) { | ||
it(`testing permission ${permission}`, async () => { | ||
|
||
const relevantCases = cases.filter(c => c.requirePermission === permission); | ||
const forbiddenCases = cases.filter(c => c.requirePermission !== permission); | ||
name: 'search-index', | ||
requirePermission: 'search-index', | ||
action: async client => { | ||
await client.get('/api/search-index').expect(200); | ||
}, | ||
}, | ||
]; | ||
|
||
let response = await clients.authoring.post('/api/apps?author.name=test&[email protected]') | ||
.send({ name: 'my-app', permissions: [permission] }) | ||
.expect(200); | ||
for (let permission of permissions) { | ||
it(`testing permission ${permission}`, async () => { | ||
const relevantCases = cases.filter(c => c.requirePermission === permission); | ||
const forbiddenCases = cases.filter(c => c.requirePermission !== permission); | ||
|
||
let { appId, appSecret } = response.body; | ||
let response = await clients.authoring | ||
.post('/api/apps?author.name=test&[email protected]') | ||
.send({ name: 'my-app', permissions: [permission] }) | ||
.expect(200); | ||
|
||
let appClient = await clients.authoring.with(client => | ||
client.set({ "x-client-id": appId, "x-client-secret": appSecret }) | ||
.unset("Authorization") | ||
); | ||
let { appId, appSecret } = response.body; | ||
|
||
await Promise.all(relevantCases.map(x=> x.action(appClient))) | ||
|
||
await Promise.all(forbiddenCases.map(async x=> { | ||
await x.action(appClient).then(()=>true, ex=> { | ||
return expect(ex.message).to.contain("403"); | ||
}) | ||
})); | ||
|
||
|
||
}).timeout(6000); | ||
} | ||
let appClient = await clients.authoring.with(client => | ||
client.set({ 'x-client-id': appId, 'x-client-secret': appSecret }).unset('Authorization'), | ||
); | ||
|
||
await Promise.all(relevantCases.map(x => x.action(appClient))); | ||
|
||
}); | ||
await Promise.all( | ||
forbiddenCases.map(async x => { | ||
await x.action(appClient).then( | ||
() => true, | ||
ex => { | ||
return expect(ex.message).to.contain('403'); | ||
}, | ||
); | ||
}), | ||
); | ||
}).timeout(6000); | ||
} | ||
}); |
Oops, something went wrong.