use super::action::*;
use crate::ProductionRole;
use std::collections::HashMap;
use strum::IntoEnumIterator;
type PassMap = HashMap<Action, Vec<Action>>;
#[derive(Debug, Clone)]
pub struct UserPass(HashMap<Action, u16>);
impl UserPass {
pub fn empty() -> Self {
Self(HashMap::new())
}
fn perm_sum(&self, action: &Action) -> u16 {
match action {
Action::ProjMetadata(_) => {
*(self
.0
.get(&Action::ProjMetadata(ProjMetadataPerm::default()))
.unwrap_or(&0))
}
#[cfg(feature = "stage_graph")]
Action::ProjWorkflow(_) => {
*(self
.0
.get(&Action::ProjWorkflow(ProjWorkflowPerm::default()))
.unwrap_or(&0))
}
Action::Brief(_) => {
*(self
.0
.get(&Action::Brief(BriefPerm::default()))
.unwrap_or(&0))
}
Action::Staff(_) => {
*(self
.0
.get(&Action::Staff(StaffPerm::default()))
.unwrap_or(&0))
}
Action::Asset(_) => {
*(self
.0
.get(&Action::Asset(AssetPerm::default()))
.unwrap_or(&0))
}
#[cfg(feature = "ticket")]
Action::Defect(_) => {
*(self
.0
.get(&Action::Defect(DefectTrackPerm::default()))
.unwrap_or(&0))
}
#[cfg(feature = "ticket")]
Action::SubDefect(_) => {
*(self
.0
.get(&Action::SubDefect(DefectItemPerm::default()))
.unwrap_or(&0))
}
Action::Review(_) => {
*(self
.0
.get(&Action::Review(ProgressPerm::default()))
.unwrap_or(&0))
}
Action::Status(_) => {
*(self
.0
.get(&Action::Status(StatusActionPerm::default()))
.unwrap_or(&0))
}
#[cfg(feature = "stage_graph")]
Action::Stage(_) => {
*(self
.0
.get(&Action::Stage(StageActionPerm::default()))
.unwrap_or(&0))
}
#[cfg(feature = "query_message")]
Action::Qms(_) => {
*(self
.0
.get(&Action::Qms(QueryMsgPerm::default()))
.unwrap_or(&0))
}
#[cfg(feature = "review_item")]
Action::Notice(_) => {
*(self
.0
.get(&Action::Notice(NoticeSignalPerm::default()))
.unwrap_or(&0))
}
}
}
fn from_map(user: PassMap) -> Self {
Self(
user.into_iter()
.map(|(k, v)| {
(
k,
v.iter()
.map(|v| match v {
Action::ProjMetadata(inner) => *inner as u16,
#[cfg(feature = "stage_graph")]
Action::ProjWorkflow(inner) => *inner as u16,
Action::Brief(inner) => *inner as u16,
Action::Staff(inner) => *inner as u16,
Action::Asset(inner) => *inner as u16,
#[cfg(feature = "ticket")]
Action::Defect(inner) => *inner as u16,
#[cfg(feature = "ticket")]
Action::SubDefect(inner) => *inner as u16,
Action::Review(inner) => *inner as u16,
Action::Status(inner) => *inner as u16,
#[cfg(feature = "stage_graph")]
Action::Stage(inner) => *inner as u16,
#[cfg(feature = "query_message")]
Action::Qms(inner) => *inner as u16,
#[cfg(feature = "review_item")]
Action::Notice(inner) => *inner as u16,
})
.sum(),
)
})
.collect(),
)
}
pub fn is_authorized_for(&self, action: &Action) -> bool {
match action {
Action::ProjMetadata(inner) => {
ProjMetadataPerm::authorized(&self.perm_sum(action), inner)
}
#[cfg(feature = "stage_graph")]
Action::ProjWorkflow(inner) => {
ProjWorkflowPerm::authorized(&self.perm_sum(action), inner)
}
Action::Brief(inner) => BriefPerm::authorized(&self.perm_sum(action), inner),
Action::Staff(inner) => StaffPerm::authorized(&self.perm_sum(action), inner),
Action::Asset(inner) => AssetPerm::authorized(&self.perm_sum(action), inner),
#[cfg(feature = "ticket")]
Action::Defect(inner) => DefectTrackPerm::authorized(&self.perm_sum(action), inner),
#[cfg(feature = "ticket")]
Action::SubDefect(inner) => DefectItemPerm::authorized(&self.perm_sum(action), inner),
Action::Review(inner) => ProgressPerm::authorized(&self.perm_sum(action), inner),
Action::Status(inner) => StatusActionPerm::authorized(&self.perm_sum(action), inner),
#[cfg(feature = "stage_graph")]
Action::Stage(inner) => StageActionPerm::authorized(&self.perm_sum(action), inner),
#[cfg(feature = "query_message")]
Action::Qms(inner) => QueryMsgPerm::authorized(&self.perm_sum(action), inner),
#[cfg(feature = "review_item")]
Action::Notice(inner) => NoticeSignalPerm::authorized(&self.perm_sum(action), inner),
}
}
}
impl ProductionRole {
pub fn user_pass(&self) -> UserPass {
match self {
ProductionRole::ArtDirector => UserPass::from_map(art_director_pass()),
ProductionRole::ArtProducer => UserPass::from_map(art_producer_pass()),
ProductionRole::TechSupport => UserPass::from_map(all_pass()),
ProductionRole::TeamLead => UserPass::from_map(art_producer_pass()),
ProductionRole::Artist => UserPass::from_map(artist_pass()),
ProductionRole::Watcher => UserPass::from_map(view_only_pass()),
ProductionRole::Unassigned => UserPass::empty(),
ProductionRole::Undefined => UserPass::empty(),
}
}
}
#[allow(dead_code)]
fn team_lead_pass() -> PassMap {
HashMap::from([
(
Action::ProjMetadata(ProjMetadataPerm::default()),
vec![
Action::ProjMetadata(ProjMetadataPerm::ViewLink),
Action::ProjMetadata(ProjMetadataPerm::ViewCriterion),
Action::ProjMetadata(ProjMetadataPerm::AssignCriterion),
Action::ProjMetadata(ProjMetadataPerm::ViewProjThumb),
],
),
#[cfg(feature = "stage_graph")]
(
Action::ProjWorkflow(ProjWorkflowPerm::default()),
vec![Action::ProjWorkflow(ProjWorkflowPerm::ViewWorkflow)],
),
(
Action::Brief(BriefPerm::default()),
vec![Action::Brief(BriefPerm::View)],
),
(
Action::Staff(StaffPerm::default()),
vec![
Action::Staff(StaffPerm::View),
Action::Staff(StaffPerm::Create),
Action::Staff(StaffPerm::Edit),
Action::Staff(StaffPerm::Delete),
],
),
(
Action::Asset(AssetPerm::default()),
vec![
Action::Asset(AssetPerm::View),
Action::Asset(AssetPerm::Create),
Action::Asset(AssetPerm::Edit),
Action::Asset(AssetPerm::Delete),
],
),
#[cfg(feature = "ticket")]
(
Action::Defect(DefectTrackPerm::default()),
vec![Action::Defect(DefectTrackPerm::View)],
),
#[cfg(feature = "ticket")]
(
Action::SubDefect(DefectItemPerm::default()),
vec![
Action::SubDefect(DefectItemPerm::StatusOpen),
Action::SubDefect(DefectItemPerm::StatusAddressed),
Action::SubDefect(DefectItemPerm::StatusClosed),
Action::SubDefect(DefectItemPerm::CreateReply),
Action::SubDefect(DefectItemPerm::EditReply),
Action::SubDefect(DefectItemPerm::DeleteReply),
],
),
(
Action::Review(ProgressPerm::default()),
vec![
Action::Review(ProgressPerm::View),
Action::Review(ProgressPerm::Create),
],
),
(
Action::Status(StatusActionPerm::default()),
vec![
Action::Status(StatusActionPerm::FeedbackApproved),
Action::Status(StatusActionPerm::AnnounceTeamLeadFeedback),
Action::Status(StatusActionPerm::AnnounceAdFeedback),
],
),
#[cfg(feature = "stage_graph")]
(
Action::Stage(StageActionPerm::default()),
vec![Action::Stage(StageActionPerm::Toggle)],
),
#[cfg(feature = "query_message")]
(
Action::Qms(QueryMsgPerm::default()),
vec![
Action::Qms(QueryMsgPerm::View),
Action::Qms(QueryMsgPerm::Create),
],
),
#[cfg(feature = "review_item")]
(
Action::Notice(NoticeSignalPerm::default()),
vec![
Action::Notice(NoticeSignalPerm::ViewPanProject),
Action::Notice(NoticeSignalPerm::SignalWip),
Action::Notice(NoticeSignalPerm::SignalApproval),
],
),
])
}
fn artist_pass() -> PassMap {
HashMap::from([
(
Action::ProjMetadata(ProjMetadataPerm::default()),
vec![
Action::ProjMetadata(ProjMetadataPerm::ViewLink),
Action::ProjMetadata(ProjMetadataPerm::ViewCriterion),
Action::ProjMetadata(ProjMetadataPerm::ViewProjThumb),
],
),
#[cfg(feature = "stage_graph")]
(
Action::ProjWorkflow(ProjWorkflowPerm::default()),
vec![Action::ProjWorkflow(ProjWorkflowPerm::ViewWorkflow)],
),
(
Action::Brief(BriefPerm::default()),
vec![Action::Brief(BriefPerm::View)],
),
(
Action::Staff(StaffPerm::default()),
vec![Action::Staff(StaffPerm::View)],
),
(
Action::Asset(AssetPerm::default()),
vec![Action::Asset(AssetPerm::View)],
),
#[cfg(feature = "ticket")]
(
Action::Defect(DefectTrackPerm::default()),
vec![Action::Defect(DefectTrackPerm::View)],
),
#[cfg(feature = "ticket")]
(
Action::SubDefect(DefectItemPerm::default()),
vec![
Action::SubDefect(DefectItemPerm::StatusOpen),
Action::SubDefect(DefectItemPerm::StatusAddressed),
Action::SubDefect(DefectItemPerm::CreateReply),
Action::SubDefect(DefectItemPerm::EditReply),
Action::SubDefect(DefectItemPerm::DeleteReply),
],
),
(
Action::Review(ProgressPerm::default()),
vec![
Action::Review(ProgressPerm::View),
Action::Review(ProgressPerm::Create),
],
),
#[cfg(feature = "query_message")]
(
Action::Qms(QueryMsgPerm::default()),
vec![
Action::Qms(QueryMsgPerm::View),
Action::Qms(QueryMsgPerm::Create),
],
),
#[cfg(feature = "review_item")]
(
Action::Notice(NoticeSignalPerm::default()),
vec![
Action::Notice(NoticeSignalPerm::ViewPanProject),
Action::Notice(NoticeSignalPerm::SignalWip),
Action::Notice(NoticeSignalPerm::SignalApproval),
],
),
])
}
fn view_only_pass() -> PassMap {
HashMap::from([
(
Action::ProjMetadata(ProjMetadataPerm::default()),
vec![
Action::ProjMetadata(ProjMetadataPerm::ViewLink),
Action::ProjMetadata(ProjMetadataPerm::ViewCriterion),
Action::ProjMetadata(ProjMetadataPerm::ViewProjThumb),
],
),
#[cfg(feature = "stage_graph")]
(
Action::ProjWorkflow(ProjWorkflowPerm::default()),
vec![Action::ProjWorkflow(ProjWorkflowPerm::ViewWorkflow)],
),
(
Action::Brief(BriefPerm::default()),
vec![Action::Brief(BriefPerm::View)],
),
(
Action::Staff(StaffPerm::default()),
vec![Action::Staff(StaffPerm::View)],
),
(
Action::Asset(AssetPerm::default()),
vec![Action::Asset(AssetPerm::View)],
),
#[cfg(feature = "ticket")]
(
Action::Defect(DefectTrackPerm::default()),
vec![Action::Defect(DefectTrackPerm::View)],
),
(
Action::Review(ProgressPerm::default()),
vec![Action::Review(ProgressPerm::View)],
),
#[cfg(feature = "query_message")]
(
Action::Qms(QueryMsgPerm::default()),
vec![Action::Qms(QueryMsgPerm::View)],
),
#[cfg(feature = "review_item")]
(
Action::Notice(NoticeSignalPerm::default()),
vec![Action::Notice(NoticeSignalPerm::ViewPanProject)],
),
])
}
fn top_supervisor_pass() -> PassMap {
HashMap::from([
(
Action::ProjMetadata(ProjMetadataPerm::default()),
vec![
Action::ProjMetadata(ProjMetadataPerm::ViewLink),
Action::ProjMetadata(ProjMetadataPerm::CreateLink),
Action::ProjMetadata(ProjMetadataPerm::EditLink),
Action::ProjMetadata(ProjMetadataPerm::DeleteLink),
Action::ProjMetadata(ProjMetadataPerm::ViewCriterion),
Action::ProjMetadata(ProjMetadataPerm::CreateCriterion),
Action::ProjMetadata(ProjMetadataPerm::EditCriterion),
Action::ProjMetadata(ProjMetadataPerm::AssignCriterion),
Action::ProjMetadata(ProjMetadataPerm::ViewProjThumb),
Action::ProjMetadata(ProjMetadataPerm::EditProjThumb),
Action::ProjMetadata(ProjMetadataPerm::DeleteProjThumb),
],
),
#[cfg(feature = "stage_graph")]
(
Action::ProjWorkflow(ProjWorkflowPerm::default()),
vec![
Action::ProjWorkflow(ProjWorkflowPerm::ViewWorkflow),
Action::ProjWorkflow(ProjWorkflowPerm::CreateWorkflow),
Action::ProjWorkflow(ProjWorkflowPerm::EditWorkflow),
Action::ProjWorkflow(ProjWorkflowPerm::DeleteWorkflow),
],
),
(
Action::Brief(BriefPerm::default()),
vec![
Action::Brief(BriefPerm::View),
Action::Brief(BriefPerm::Create),
Action::Brief(BriefPerm::Edit),
Action::Brief(BriefPerm::Delete),
],
),
(
Action::Staff(StaffPerm::default()),
vec![
Action::Staff(StaffPerm::View),
Action::Staff(StaffPerm::Create),
Action::Staff(StaffPerm::Edit),
Action::Staff(StaffPerm::Delete),
],
),
(
Action::Asset(AssetPerm::default()),
vec![
Action::Asset(AssetPerm::View),
Action::Asset(AssetPerm::Create),
Action::Asset(AssetPerm::Edit),
Action::Asset(AssetPerm::Delete),
],
),
#[cfg(feature = "ticket")]
(
Action::Defect(DefectTrackPerm::default()),
vec![
Action::Defect(DefectTrackPerm::View),
Action::Defect(DefectTrackPerm::Create),
Action::Defect(DefectTrackPerm::Edit),
Action::Defect(DefectTrackPerm::Delete),
],
),
#[cfg(feature = "ticket")]
(
Action::SubDefect(DefectItemPerm::default()),
vec![
Action::SubDefect(DefectItemPerm::Create),
Action::SubDefect(DefectItemPerm::Edit),
Action::SubDefect(DefectItemPerm::Delete),
Action::SubDefect(DefectItemPerm::StatusOpen),
Action::SubDefect(DefectItemPerm::StatusClosed),
Action::SubDefect(DefectItemPerm::CreateReply),
Action::SubDefect(DefectItemPerm::EditReply),
Action::SubDefect(DefectItemPerm::DeleteReply),
],
),
(
Action::Review(ProgressPerm::default()),
vec![
Action::Review(ProgressPerm::View),
],
),
(
Action::Status(StatusActionPerm::default()),
vec![
Action::Status(StatusActionPerm::Toggle),
Action::Status(StatusActionPerm::FeedbackApproved),
Action::Status(StatusActionPerm::AnnounceAdFeedback),
Action::Status(StatusActionPerm::AnnounceClientFeedback),
],
),
#[cfg(feature = "stage_graph")]
(
Action::Stage(StageActionPerm::default()),
vec![Action::Stage(StageActionPerm::Toggle)],
),
#[cfg(feature = "query_message")]
(
Action::Qms(QueryMsgPerm::default()),
vec![
Action::Qms(QueryMsgPerm::View),
Action::Qms(QueryMsgPerm::Create),
],
),
#[cfg(feature = "review_item")]
(
Action::Notice(NoticeSignalPerm::default()),
vec![Action::Notice(NoticeSignalPerm::ViewPanProject)],
),
])
}
fn art_director_pass() -> PassMap {
let mut actions = top_supervisor_pass();
if let Some(v) = actions.get_mut(&Action::ProjMetadata(ProjMetadataPerm::default())) {
v.push(Action::ProjMetadata(ProjMetadataPerm::DeleteCriterion));
v.push(Action::ProjMetadata(ProjMetadataPerm::ObliterateCriteria));
};
#[cfg(feature = "stage_graph")]
if let Some(v) = actions.get_mut(&&Action::ProjWorkflow(ProjWorkflowPerm::default())) {
v.push(Action::ProjWorkflow(ProjWorkflowPerm::MakeWorkflowDefault));
};
if let Some(v) = actions.get_mut(&Action::Status(StatusActionPerm::default())) {
v.push(Action::Status(StatusActionPerm::AdApproved));
};
#[cfg(feature = "review_item")]
if let Some(v) = actions.get_mut(&Action::Notice(NoticeSignalPerm::default())) {
v.push(Action::Notice(NoticeSignalPerm::AdReviewTarget));
};
actions
}
fn art_producer_pass() -> PassMap {
let mut actions = top_supervisor_pass();
if let Some(v) = actions.get_mut(&Action::Status(StatusActionPerm::default())) {
v.push(Action::Status(StatusActionPerm::ClientApproved));
};
actions
}
fn all_pass() -> PassMap {
HashMap::from([
(
Action::ProjMetadata(ProjMetadataPerm::default()),
ProjMetadataPerm::iter()
.map(|p| Action::ProjMetadata(p))
.collect(),
),
#[cfg(feature = "stage_graph")]
(
Action::ProjWorkflow(ProjWorkflowPerm::default()),
ProjWorkflowPerm::iter()
.map(|p| Action::ProjWorkflow(p))
.collect(),
),
(
Action::Brief(BriefPerm::default()),
BriefPerm::iter().map(|p| Action::Brief(p)).collect(),
),
(
Action::Staff(StaffPerm::default()),
StaffPerm::iter().map(|p| Action::Staff(p)).collect(),
),
(
Action::Asset(AssetPerm::default()),
AssetPerm::iter().map(|p| Action::Asset(p)).collect(),
),
#[cfg(feature = "ticket")]
(
Action::Defect(DefectTrackPerm::default()),
DefectTrackPerm::iter().map(|p| Action::Defect(p)).collect(),
),
#[cfg(feature = "ticket")]
(
Action::SubDefect(DefectItemPerm::default()),
DefectItemPerm::iter()
.map(|p| Action::SubDefect(p))
.collect(),
),
(
Action::Review(ProgressPerm::default()),
ProgressPerm::iter().map(|p| Action::Review(p)).collect(),
),
(
Action::Status(StatusActionPerm::default()),
StatusActionPerm::iter()
.map(|p| Action::Status(p))
.collect(),
),
#[cfg(feature = "stage_graph")]
(
Action::Stage(StageActionPerm::default()),
StageActionPerm::iter().map(|p| Action::Stage(p)).collect(),
),
#[cfg(feature = "query_message")]
(
Action::Qms(QueryMsgPerm::default()),
QueryMsgPerm::iter().map(|p| Action::Qms(p)).collect(),
),
#[cfg(feature = "review_item")]
(
Action::Notice(NoticeSignalPerm::default()),
NoticeSignalPerm::iter()
.map(|p| Action::Notice(p))
.collect(),
),
])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn enum_repr() {
let authorized = ProjMetadataPerm::authorized(&3, &ProjMetadataPerm::ViewLink);
eprintln!("Authorized: {}", authorized);
}
}