@drodil/backstage-plugin-qeta-node 3.23.0 → 3.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pluginPermissionCommon = require('@backstage/plugin-permission-common');
|
|
4
|
+
var backstagePluginQetaCommon = require('@drodil/backstage-plugin-qeta-common');
|
|
5
|
+
var backstagePluginQetaNode = require('@drodil/backstage-plugin-qeta-node');
|
|
6
|
+
|
|
7
|
+
class DefaultQetaPermissionPolicy {
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
}
|
|
11
|
+
async handle(request, user) {
|
|
12
|
+
if (!user) {
|
|
13
|
+
return { result: pluginPermissionCommon.AuthorizeResult.DENY };
|
|
14
|
+
}
|
|
15
|
+
const moderators = this.config?.getOptionalStringArray("qeta.moderators") ?? [];
|
|
16
|
+
if (moderators.includes(user.identity.userEntityRef) || user.identity.ownershipEntityRefs.some((ref) => moderators.includes(ref))) {
|
|
17
|
+
return { result: pluginPermissionCommon.AuthorizeResult.ALLOW };
|
|
18
|
+
}
|
|
19
|
+
if (request.permission.attributes.action === "create" || request.permission.attributes.action === "read") {
|
|
20
|
+
return { result: pluginPermissionCommon.AuthorizeResult.ALLOW };
|
|
21
|
+
}
|
|
22
|
+
if (request.permission.attributes.action === "update" || request.permission.attributes.action === "delete") {
|
|
23
|
+
if (pluginPermissionCommon.isResourcePermission(request.permission, backstagePluginQetaCommon.POST_RESOURCE_TYPE)) {
|
|
24
|
+
return backstagePluginQetaNode.createPostConditionalDecision(request.permission, {
|
|
25
|
+
allOf: [
|
|
26
|
+
// Can edit and delete own questions
|
|
27
|
+
backstagePluginQetaNode.postAuthorConditionFactory({
|
|
28
|
+
userRef: user.identity.userEntityRef
|
|
29
|
+
})
|
|
30
|
+
]
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (pluginPermissionCommon.isResourcePermission(request.permission, backstagePluginQetaCommon.ANSWER_RESOURCE_TYPE)) {
|
|
34
|
+
return backstagePluginQetaNode.createAnswerConditionalDecision(request.permission, {
|
|
35
|
+
allOf: [
|
|
36
|
+
backstagePluginQetaNode.answerAuthorConditionFactory({
|
|
37
|
+
userRef: user.identity.userEntityRef
|
|
38
|
+
})
|
|
39
|
+
]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (pluginPermissionCommon.isResourcePermission(request.permission, backstagePluginQetaCommon.COMMENT_RESOURCE_TYPE)) {
|
|
43
|
+
return backstagePluginQetaNode.createCommentConditionalDecision(request.permission, {
|
|
44
|
+
allOf: [
|
|
45
|
+
backstagePluginQetaNode.commentAuthorConditionFactory({
|
|
46
|
+
userRef: user.identity.userEntityRef
|
|
47
|
+
})
|
|
48
|
+
]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (pluginPermissionCommon.isResourcePermission(request.permission, backstagePluginQetaCommon.COLLECTION_RESOUCE_TYPE)) {
|
|
52
|
+
return backstagePluginQetaNode.createCollectionConditionalDecision(request.permission, {
|
|
53
|
+
allOf: [
|
|
54
|
+
backstagePluginQetaNode.collectionOwnerConditionFactory({
|
|
55
|
+
userRef: user.identity.userEntityRef
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (pluginPermissionCommon.isResourcePermission(request.permission, backstagePluginQetaCommon.TAG_RESOURCE_TYPE) && pluginPermissionCommon.isUpdatePermission(request.permission)) {
|
|
61
|
+
return { result: pluginPermissionCommon.AuthorizeResult.ALLOW };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { result: pluginPermissionCommon.AuthorizeResult.DENY };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
exports.DefaultQetaPermissionPolicy = DefaultQetaPermissionPolicy;
|
|
69
|
+
//# sourceMappingURL=defaultPermissionPolicy.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultPermissionPolicy.cjs.js","sources":["../src/defaultPermissionPolicy.ts"],"sourcesContent":["/*\n * SPDX-FileCopyrightText: Copyright 2024 OP Financial Group (https://op.fi). All Rights Reserved.\n * SPDX-License-Identifier: LicenseRef-OpAllRightsReserved\n */\nimport { BackstageIdentityResponse } from '@backstage/plugin-auth-node';\nimport {\n AuthorizeResult,\n isResourcePermission,\n isUpdatePermission,\n PolicyDecision,\n} from '@backstage/plugin-permission-common';\nimport {\n PermissionPolicy,\n PolicyQuery,\n} from '@backstage/plugin-permission-node';\nimport {\n ANSWER_RESOURCE_TYPE,\n COLLECTION_RESOUCE_TYPE,\n COMMENT_RESOURCE_TYPE,\n POST_RESOURCE_TYPE,\n TAG_RESOURCE_TYPE,\n} from '@drodil/backstage-plugin-qeta-common';\nimport {\n answerAuthorConditionFactory,\n collectionOwnerConditionFactory,\n commentAuthorConditionFactory,\n createAnswerConditionalDecision,\n createCollectionConditionalDecision,\n createCommentConditionalDecision,\n createPostConditionalDecision,\n postAuthorConditionFactory,\n} from '@drodil/backstage-plugin-qeta-node';\nimport { Config } from '@backstage/config';\n\nexport class DefaultQetaPermissionPolicy implements PermissionPolicy {\n constructor(private readonly config?: Config) {}\n\n async handle(\n request: PolicyQuery,\n user?: BackstageIdentityResponse,\n ): Promise<PolicyDecision> {\n // We cannot do anything without a user\n if (!user) {\n return { result: AuthorizeResult.DENY };\n }\n\n // Moderators can modify anything\n const moderators =\n this.config?.getOptionalStringArray('qeta.moderators') ?? [];\n if (\n moderators.includes(user.identity.userEntityRef) ||\n user.identity.ownershipEntityRefs.some(ref => moderators.includes(ref))\n ) {\n return { result: AuthorizeResult.ALLOW };\n }\n\n if (\n request.permission.attributes.action === 'create' ||\n request.permission.attributes.action === 'read'\n ) {\n return { result: AuthorizeResult.ALLOW };\n }\n\n // Allow updating and deleting only own posts/answers/comments\n if (\n request.permission.attributes.action === 'update' ||\n request.permission.attributes.action === 'delete'\n ) {\n if (isResourcePermission(request.permission, POST_RESOURCE_TYPE)) {\n return createPostConditionalDecision(request.permission, {\n allOf: [\n // Can edit and delete own questions\n postAuthorConditionFactory({\n userRef: user.identity.userEntityRef,\n }),\n ],\n });\n }\n\n if (isResourcePermission(request.permission, ANSWER_RESOURCE_TYPE)) {\n return createAnswerConditionalDecision(request.permission, {\n allOf: [\n answerAuthorConditionFactory({\n userRef: user.identity.userEntityRef,\n }),\n ],\n });\n }\n\n // Allow deleting and updating only own comments\n if (isResourcePermission(request.permission, COMMENT_RESOURCE_TYPE)) {\n return createCommentConditionalDecision(request.permission, {\n allOf: [\n commentAuthorConditionFactory({\n userRef: user.identity.userEntityRef,\n }),\n ],\n });\n }\n\n // Allow deleting and updating only own collections\n if (isResourcePermission(request.permission, COLLECTION_RESOUCE_TYPE)) {\n return createCollectionConditionalDecision(request.permission, {\n allOf: [\n collectionOwnerConditionFactory({\n userRef: user.identity.userEntityRef,\n }),\n ],\n });\n }\n\n // Allow updating any tag by anyone\n if (\n isResourcePermission(request.permission, TAG_RESOURCE_TYPE) &&\n isUpdatePermission(request.permission)\n ) {\n return { result: AuthorizeResult.ALLOW };\n }\n }\n\n return { result: AuthorizeResult.DENY };\n }\n}\n"],"names":["AuthorizeResult","isResourcePermission","POST_RESOURCE_TYPE","createPostConditionalDecision","postAuthorConditionFactory","ANSWER_RESOURCE_TYPE","createAnswerConditionalDecision","answerAuthorConditionFactory","COMMENT_RESOURCE_TYPE","createCommentConditionalDecision","commentAuthorConditionFactory","COLLECTION_RESOUCE_TYPE","createCollectionConditionalDecision","collectionOwnerConditionFactory","TAG_RESOURCE_TYPE","isUpdatePermission"],"mappings":";;;;;;AAkCO,MAAM,2BAAwD,CAAA;AAAA,EACnE,YAA6B,MAAiB,EAAA;AAAjB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA;AAAkB,EAE/C,MAAM,MACJ,CAAA,OAAA,EACA,IACyB,EAAA;AAEzB,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,OAAA,EAAE,MAAQ,EAAAA,sCAAA,CAAgB,IAAK,EAAA;AAAA;AAIxC,IAAA,MAAM,aACJ,IAAK,CAAA,MAAA,EAAQ,sBAAuB,CAAA,iBAAiB,KAAK,EAAC;AAC7D,IAAA,IACE,UAAW,CAAA,QAAA,CAAS,IAAK,CAAA,QAAA,CAAS,aAAa,CAC/C,IAAA,IAAA,CAAK,QAAS,CAAA,mBAAA,CAAoB,KAAK,CAAO,GAAA,KAAA,UAAA,CAAW,QAAS,CAAA,GAAG,CAAC,CACtE,EAAA;AACA,MAAO,OAAA,EAAE,MAAQ,EAAAA,sCAAA,CAAgB,KAAM,EAAA;AAAA;AAGzC,IACE,IAAA,OAAA,CAAQ,WAAW,UAAW,CAAA,MAAA,KAAW,YACzC,OAAQ,CAAA,UAAA,CAAW,UAAW,CAAA,MAAA,KAAW,MACzC,EAAA;AACA,MAAO,OAAA,EAAE,MAAQ,EAAAA,sCAAA,CAAgB,KAAM,EAAA;AAAA;AAIzC,IACE,IAAA,OAAA,CAAQ,WAAW,UAAW,CAAA,MAAA,KAAW,YACzC,OAAQ,CAAA,UAAA,CAAW,UAAW,CAAA,MAAA,KAAW,QACzC,EAAA;AACA,MAAA,IAAIC,2CAAqB,CAAA,OAAA,CAAQ,UAAY,EAAAC,4CAAkB,CAAG,EAAA;AAChE,QAAO,OAAAC,qDAAA,CAA8B,QAAQ,UAAY,EAAA;AAAA,UACvD,KAAO,EAAA;AAAA;AAAA,YAELC,kDAA2B,CAAA;AAAA,cACzB,OAAA,EAAS,KAAK,QAAS,CAAA;AAAA,aACxB;AAAA;AACH,SACD,CAAA;AAAA;AAGH,MAAA,IAAIH,2CAAqB,CAAA,OAAA,CAAQ,UAAY,EAAAI,8CAAoB,CAAG,EAAA;AAClE,QAAO,OAAAC,uDAAA,CAAgC,QAAQ,UAAY,EAAA;AAAA,UACzD,KAAO,EAAA;AAAA,YACLC,oDAA6B,CAAA;AAAA,cAC3B,OAAA,EAAS,KAAK,QAAS,CAAA;AAAA,aACxB;AAAA;AACH,SACD,CAAA;AAAA;AAIH,MAAA,IAAIN,2CAAqB,CAAA,OAAA,CAAQ,UAAY,EAAAO,+CAAqB,CAAG,EAAA;AACnE,QAAO,OAAAC,wDAAA,CAAiC,QAAQ,UAAY,EAAA;AAAA,UAC1D,KAAO,EAAA;AAAA,YACLC,qDAA8B,CAAA;AAAA,cAC5B,OAAA,EAAS,KAAK,QAAS,CAAA;AAAA,aACxB;AAAA;AACH,SACD,CAAA;AAAA;AAIH,MAAA,IAAIT,2CAAqB,CAAA,OAAA,CAAQ,UAAY,EAAAU,iDAAuB,CAAG,EAAA;AACrE,QAAO,OAAAC,2DAAA,CAAoC,QAAQ,UAAY,EAAA;AAAA,UAC7D,KAAO,EAAA;AAAA,YACLC,uDAAgC,CAAA;AAAA,cAC9B,OAAA,EAAS,KAAK,QAAS,CAAA;AAAA,aACxB;AAAA;AACH,SACD,CAAA;AAAA;AAIH,MACE,IAAAZ,2CAAA,CAAqB,QAAQ,UAAY,EAAAa,2CAAiB,KAC1DC,yCAAmB,CAAA,OAAA,CAAQ,UAAU,CACrC,EAAA;AACA,QAAO,OAAA,EAAE,MAAQ,EAAAf,sCAAA,CAAgB,KAAM,EAAA;AAAA;AACzC;AAGF,IAAO,OAAA,EAAE,MAAQ,EAAAA,sCAAA,CAAgB,IAAK,EAAA;AAAA;AAE1C;;;;"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -4,6 +4,7 @@ var extensions = require('./extensions.cjs.js');
|
|
|
4
4
|
var permissionRules = require('./permissionRules.cjs.js');
|
|
5
5
|
var conditionExports = require('./conditionExports.cjs.js');
|
|
6
6
|
var permissionResources = require('./permissionResources.cjs.js');
|
|
7
|
+
var defaultPermissionPolicy = require('./defaultPermissionPolicy.cjs.js');
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
|
|
@@ -54,4 +55,5 @@ exports.collectionPermissionResourceRef = permissionResources.collectionPermissi
|
|
|
54
55
|
exports.commentPermissionResourceRef = permissionResources.commentPermissionResourceRef;
|
|
55
56
|
exports.postPermissionResourceRef = permissionResources.postPermissionResourceRef;
|
|
56
57
|
exports.tagPermissionResourceRef = permissionResources.tagPermissionResourceRef;
|
|
58
|
+
exports.DefaultQetaPermissionPolicy = defaultPermissionPolicy.DefaultQetaPermissionPolicy;
|
|
57
59
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,10 @@ import * as _drodil_backstage_plugin_qeta_common from '@drodil/backstage-plugin-
|
|
|
4
4
|
import { Question, AIResponse, Article, Post, PostFilter, Answer, AnswerFilter, Comment, CommentFilter, TagResponse, TagFilter, Collection, CollectionFilter } from '@drodil/backstage-plugin-qeta-common';
|
|
5
5
|
import * as _backstage_plugin_permission_common_index from '@backstage/plugin-permission-common/index';
|
|
6
6
|
import * as _backstage_plugin_permission_node from '@backstage/plugin-permission-node';
|
|
7
|
+
import { PermissionPolicy, PolicyQuery } from '@backstage/plugin-permission-node';
|
|
8
|
+
import { BackstageIdentityResponse } from '@backstage/plugin-auth-node';
|
|
9
|
+
import { PolicyDecision } from '@backstage/plugin-permission-common';
|
|
10
|
+
import { Config } from '@backstage/config';
|
|
7
11
|
|
|
8
12
|
interface AIHandler {
|
|
9
13
|
/**
|
|
@@ -325,4 +329,10 @@ declare const commentPermissionResourceRef: _backstage_plugin_permission_node.Pe
|
|
|
325
329
|
declare const tagPermissionResourceRef: _backstage_plugin_permission_node.PermissionResourceRef<TagResponse, TagFilter, "tag", "qeta">;
|
|
326
330
|
declare const collectionPermissionResourceRef: _backstage_plugin_permission_node.PermissionResourceRef<Collection, CollectionFilter, "collection", "qeta">;
|
|
327
331
|
|
|
328
|
-
|
|
332
|
+
declare class DefaultQetaPermissionPolicy implements PermissionPolicy {
|
|
333
|
+
private readonly config?;
|
|
334
|
+
constructor(config?: Config | undefined);
|
|
335
|
+
handle(request: PolicyQuery, user?: BackstageIdentityResponse): Promise<PolicyDecision>;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export { type AIHandler, DefaultQetaPermissionPolicy, type QetaAIExtensionPoint, type QetaTagDatabaseExtensionPoint, type TagDatabase, answerAuthorConditionFactory, answerConditions, answerPermissionResourceRef, answerQuestionEntitiesConditionFactory, answerQuestionHasEntityRefs, answerQuestionHasTags, answerQuestionTagsConditionFactory, answerRules, collectionConditions, collectionHasEntities, collectionHasEntitiesConditionFactory, collectionHasTags, collectionHasTagsConditionFactory, collectionOwnerConditionFactory, collectionPermissionResourceRef, collectionRules, commentAuthorConditionFactory, commentConditions, commentPermissionResourceRef, commentRules, createAnswerConditionalDecision, createCollectionConditionalDecision, createCommentConditionalDecision, createPostConditionalDecision, createTagConditionalDecision, isAnswerAuthor, isCollectionOwner, isCommentAuthor, isPostAuthor, isTag, postAuthorConditionFactory, postHasEntities, postHasEntitiesConditionFactory, postHasTags, postHasTagsConditionFactory, postHasType, postHasTypeConditionFactory, postPermissionResourceRef, postRules, qetaAIExtensionPoint, qetaTagDatabaseExtensionPoint, questionConditions, rules, tagConditionFactory, tagConditions, tagPermissionResourceRef, tagRules };
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"backstage.io",
|
|
8
8
|
"node"
|
|
9
9
|
],
|
|
10
|
-
"version": "3.
|
|
10
|
+
"version": "3.24.1",
|
|
11
11
|
"main": "dist/index.cjs.js",
|
|
12
12
|
"types": "dist/index.d.ts",
|
|
13
13
|
"prepublishOnly": "yarn tsc && yarn build",
|
|
@@ -47,22 +47,20 @@
|
|
|
47
47
|
"tsc": "tsc"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@backstage/cli": "^0.
|
|
50
|
+
"@backstage/cli": "^0.31.0"
|
|
51
51
|
},
|
|
52
52
|
"files": [
|
|
53
53
|
"dist"
|
|
54
54
|
],
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@backstage/backend-plugin-api": "^1.2.
|
|
57
|
-
"@backstage/
|
|
58
|
-
"@
|
|
56
|
+
"@backstage/backend-plugin-api": "^1.2.1",
|
|
57
|
+
"@backstage/catalog-client": "^1.9.1",
|
|
58
|
+
"@backstage/catalog-model": "^1.7.3",
|
|
59
|
+
"@backstage/config": "^1.3.2",
|
|
60
|
+
"@backstage/plugin-auth-node": "^0.6.1",
|
|
61
|
+
"@backstage/plugin-permission-common": "^0.8.4",
|
|
62
|
+
"@backstage/plugin-permission-node": "^0.9.0",
|
|
63
|
+
"@drodil/backstage-plugin-qeta-common": "^3.24.1",
|
|
59
64
|
"zod": "^3.22.4"
|
|
60
|
-
},
|
|
61
|
-
"typesVersions": {
|
|
62
|
-
"*": {
|
|
63
|
-
"index": [
|
|
64
|
-
"dist/index.d.ts"
|
|
65
|
-
]
|
|
66
|
-
}
|
|
67
65
|
}
|
|
68
66
|
}
|