|
@@ -57,13 +57,13 @@ export type AskResult = typeof AskResult.Type
|
|
|
|
|
|
|
|
export const Event = Permission.Event
|
|
export const Event = Permission.Event
|
|
|
|
|
|
|
|
-export class RejectedError extends Schema.TaggedErrorClass<RejectedError>()("PermissionV2.RejectedError", {}) {}
|
|
|
|
|
|
|
+export class DeclinedError extends Schema.TaggedErrorClass<DeclinedError>()("PermissionV2.DeclinedError", {}) {}
|
|
|
|
|
|
|
|
export class CorrectedError extends Schema.TaggedErrorClass<CorrectedError>()("PermissionV2.CorrectedError", {
|
|
export class CorrectedError extends Schema.TaggedErrorClass<CorrectedError>()("PermissionV2.CorrectedError", {
|
|
|
feedback: Schema.String,
|
|
feedback: Schema.String,
|
|
|
}) {}
|
|
}) {}
|
|
|
|
|
|
|
|
-export class DeniedError extends Schema.TaggedErrorClass<DeniedError>()("PermissionV2.DeniedError", {
|
|
|
|
|
|
|
+export class BlockedError extends Schema.TaggedErrorClass<BlockedError>()("PermissionV2.BlockedError", {
|
|
|
rules: Permission.Ruleset,
|
|
rules: Permission.Ruleset,
|
|
|
}) {}
|
|
}) {}
|
|
|
|
|
|
|
@@ -71,7 +71,7 @@ export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Per
|
|
|
requestID: ID,
|
|
requestID: ID,
|
|
|
}) {}
|
|
}) {}
|
|
|
|
|
|
|
|
-export type Error = DeniedError | RejectedError | CorrectedError
|
|
|
|
|
|
|
+export type Error = BlockedError | CorrectedError
|
|
|
|
|
|
|
|
export function evaluate(action: string, resource: string, ...rulesets: Permission.Ruleset[]): Permission.Rule {
|
|
export function evaluate(action: string, resource: string, ...rulesets: Permission.Ruleset[]): Permission.Rule {
|
|
|
return (
|
|
return (
|
|
@@ -103,7 +103,7 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/v2
|
|
|
interface Pending {
|
|
interface Pending {
|
|
|
readonly request: Request
|
|
readonly request: Request
|
|
|
readonly agent?: AgentV2.ID
|
|
readonly agent?: AgentV2.ID
|
|
|
- readonly deferred: Deferred.Deferred<void, RejectedError | CorrectedError>
|
|
|
|
|
|
|
+ readonly deferred: Deferred.Deferred<void, DeclinedError | CorrectedError>
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const layer = Layer.effect(
|
|
const layer = Layer.effect(
|
|
@@ -117,7 +117,7 @@ const layer = Layer.effect(
|
|
|
const pending = new Map<ID, Pending>()
|
|
const pending = new Map<ID, Pending>()
|
|
|
|
|
|
|
|
yield* EffectRuntime.addFinalizer(() =>
|
|
yield* EffectRuntime.addFinalizer(() =>
|
|
|
- EffectRuntime.forEach(pending.values(), (item) => Deferred.fail(item.deferred, new RejectedError()), {
|
|
|
|
|
|
|
+ EffectRuntime.forEach(pending.values(), (item) => Deferred.fail(item.deferred, new DeclinedError()), {
|
|
|
discard: true,
|
|
discard: true,
|
|
|
}).pipe(
|
|
}).pipe(
|
|
|
EffectRuntime.ensuring(
|
|
EffectRuntime.ensuring(
|
|
@@ -176,7 +176,7 @@ const layer = Layer.effect(
|
|
|
const create = (request: Request, agent?: AgentV2.ID) =>
|
|
const create = (request: Request, agent?: AgentV2.ID) =>
|
|
|
EffectRuntime.uninterruptible(
|
|
EffectRuntime.uninterruptible(
|
|
|
EffectRuntime.gen(function* () {
|
|
EffectRuntime.gen(function* () {
|
|
|
- const deferred = yield* Deferred.make<void, RejectedError | CorrectedError>()
|
|
|
|
|
|
|
+ const deferred = yield* Deferred.make<void, DeclinedError | CorrectedError>()
|
|
|
const item = { request, agent, deferred }
|
|
const item = { request, agent, deferred }
|
|
|
if (pending.has(request.id)) return yield* EffectRuntime.die(`Duplicate pending permission ID: ${request.id}`)
|
|
if (pending.has(request.id)) return yield* EffectRuntime.die(`Duplicate pending permission ID: ${request.id}`)
|
|
|
pending.set(request.id, item)
|
|
pending.set(request.id, item)
|
|
@@ -199,13 +199,14 @@ const layer = Layer.effect(
|
|
|
EffectRuntime.gen(function* () {
|
|
EffectRuntime.gen(function* () {
|
|
|
const result = yield* evaluateInput(input)
|
|
const result = yield* evaluateInput(input)
|
|
|
if (result.effect === "deny") {
|
|
if (result.effect === "deny") {
|
|
|
- return yield* new DeniedError({
|
|
|
|
|
|
|
+ return yield* new BlockedError({
|
|
|
rules: relevant(input, result.rules),
|
|
rules: relevant(input, result.rules),
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
if (result.effect === "allow") return
|
|
if (result.effect === "allow") return
|
|
|
const item = yield* create(request(input), input.agent)
|
|
const item = yield* create(request(input), input.agent)
|
|
|
return yield* restore(Deferred.await(item.deferred)).pipe(
|
|
return yield* restore(Deferred.await(item.deferred)).pipe(
|
|
|
|
|
+ EffectRuntime.catchTag("PermissionV2.DeclinedError", (error) => EffectRuntime.die(error)),
|
|
|
EffectRuntime.ensuring(
|
|
EffectRuntime.ensuring(
|
|
|
EffectRuntime.sync(() => {
|
|
EffectRuntime.sync(() => {
|
|
|
pending.delete(item.request.id)
|
|
pending.delete(item.request.id)
|
|
@@ -230,7 +231,7 @@ const layer = Layer.effect(
|
|
|
if (input.reply === "reject") {
|
|
if (input.reply === "reject") {
|
|
|
yield* Deferred.fail(
|
|
yield* Deferred.fail(
|
|
|
existing.deferred,
|
|
existing.deferred,
|
|
|
- input.message ? new CorrectedError({ feedback: input.message }) : new RejectedError(),
|
|
|
|
|
|
|
+ input.message ? new CorrectedError({ feedback: input.message }) : new DeclinedError(),
|
|
|
)
|
|
)
|
|
|
pending.delete(input.requestID)
|
|
pending.delete(input.requestID)
|
|
|
for (const [id, item] of pending) {
|
|
for (const [id, item] of pending) {
|
|
@@ -240,7 +241,7 @@ const layer = Layer.effect(
|
|
|
requestID: item.request.id,
|
|
requestID: item.request.id,
|
|
|
reply: "reject",
|
|
reply: "reject",
|
|
|
})
|
|
})
|
|
|
- yield* Deferred.fail(item.deferred, new RejectedError())
|
|
|
|
|
|
|
+ yield* Deferred.fail(item.deferred, new DeclinedError())
|
|
|
pending.delete(id)
|
|
pending.delete(id)
|
|
|
}
|
|
}
|
|
|
return
|
|
return
|