-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathpolicy.rs
More file actions
81 lines (73 loc) · 2.66 KB
/
policy.rs
File metadata and controls
81 lines (73 loc) · 2.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use crate::model::additional_resource::{
AdditionalResource, NewAdditionalResource, PatchAdditionalResource,
};
use crate::model::file::File;
use crate::model::work::{Work, WorkType};
use crate::model::Crud;
use crate::policy::{CreatePolicy, DeletePolicy, MovePolicy, PolicyContext, UpdatePolicy};
use thoth_errors::{ThothError, ThothResult};
/// Write policies for `AdditionalResource`.
///
/// These policies are responsible for:
/// - enforcing publisher scoping
/// - preventing attachment to chapter records
/// - preventing manual update of auto-generated Thoth Hosting URLs
pub struct AdditionalResourcePolicy;
fn ensure_work_is_book(db: &crate::db::PgPool, work_id: uuid::Uuid) -> ThothResult<()> {
let work = Work::from_id(db, &work_id)?;
if work.work_type == WorkType::BookChapter {
Err(ThothError::ChapterBookMetadataError)
} else {
Ok(())
}
}
fn ensure_no_hosted_file(
db: &crate::db::PgPool,
additional_resource_id: uuid::Uuid,
) -> ThothResult<()> {
let file = File::from_additional_resource_id(db, &additional_resource_id)?;
if file.is_some() {
Err(ThothError::HostedFileUrlEditError)
} else {
Ok(())
}
}
impl CreatePolicy<NewAdditionalResource> for AdditionalResourcePolicy {
fn can_create<C: PolicyContext>(
ctx: &C,
data: &NewAdditionalResource,
_params: (),
) -> ThothResult<()> {
ctx.require_publisher_for(data)?;
ensure_work_is_book(ctx.db(), data.work_id)
}
}
impl UpdatePolicy<AdditionalResource, PatchAdditionalResource> for AdditionalResourcePolicy {
fn can_update<C: PolicyContext>(
ctx: &C,
current: &AdditionalResource,
patch: &PatchAdditionalResource,
_params: (),
) -> ThothResult<()> {
ctx.require_publisher_for(current)?;
ctx.require_publisher_for(patch)?;
ensure_work_is_book(ctx.db(), current.work_id)?;
ensure_work_is_book(ctx.db(), patch.work_id)?;
if patch.url != current.url && !ctx.allow_hosted_file_url_update() {
ensure_no_hosted_file(ctx.db(), current.additional_resource_id)?;
}
Ok(())
}
}
impl DeletePolicy<AdditionalResource> for AdditionalResourcePolicy {
fn can_delete<C: PolicyContext>(ctx: &C, current: &AdditionalResource) -> ThothResult<()> {
ctx.require_publisher_for(current)?;
ensure_work_is_book(ctx.db(), current.work_id)
}
}
impl MovePolicy<AdditionalResource> for AdditionalResourcePolicy {
fn can_move<C: PolicyContext>(ctx: &C, current: &AdditionalResource) -> ThothResult<()> {
ctx.require_publisher_for(current)?;
ensure_work_is_book(ctx.db(), current.work_id)
}
}