✨(backend) add new ability on document "accesses_view"
We need this ability in the frontend to know whether we should try to display the list of users who have document accesses. If this ability is False (e.g for anonymous users), we should only show the link reach and link role when clicking on the "Share" button.
This commit is contained in:
committed by
Anthony LC
parent
d8673a8cf7
commit
15700ddd8d
@@ -15,6 +15,7 @@ and this project adheres to
|
||||
- 🌐(frontend) add localization to editor #268
|
||||
- ✨Public and restricted doc editable #357
|
||||
- ✨(frontend) Add full name if available #380
|
||||
- ✨(backend) Add view accesses ability #376
|
||||
|
||||
## Fixed
|
||||
|
||||
|
||||
@@ -496,7 +496,8 @@ class Document(BaseModel):
|
||||
# Compute version roles before adding link roles because we don't
|
||||
# want anonymous users to access versions (we wouldn't know from
|
||||
# which date to allow them anyway)
|
||||
can_get_versions = bool(roles)
|
||||
# Anonymous users should also not see document accesses
|
||||
has_role = bool(roles)
|
||||
|
||||
# Add role provided by the document link
|
||||
if self.link_reach == LinkReachChoices.PUBLIC or (
|
||||
@@ -511,19 +512,20 @@ class Document(BaseModel):
|
||||
can_get = bool(roles)
|
||||
|
||||
return {
|
||||
"accesses_manage": is_owner_or_admin,
|
||||
"accesses_view": has_role,
|
||||
"ai_transform": is_owner_or_admin or is_editor,
|
||||
"ai_translate": is_owner_or_admin or is_editor,
|
||||
"attachment_upload": is_owner_or_admin or is_editor,
|
||||
"destroy": RoleChoices.OWNER in roles,
|
||||
"link_configuration": is_owner_or_admin,
|
||||
"manage_accesses": is_owner_or_admin,
|
||||
"invite_owner": RoleChoices.OWNER in roles,
|
||||
"partial_update": is_owner_or_admin or is_editor,
|
||||
"retrieve": can_get,
|
||||
"update": is_owner_or_admin or is_editor,
|
||||
"versions_destroy": is_owner_or_admin,
|
||||
"versions_list": can_get_versions,
|
||||
"versions_retrieve": can_get_versions,
|
||||
"versions_list": has_role,
|
||||
"versions_retrieve": has_role,
|
||||
}
|
||||
|
||||
def email_invitation(self, language, email, role, sender):
|
||||
@@ -679,7 +681,7 @@ class Template(BaseModel):
|
||||
return {
|
||||
"destroy": RoleChoices.OWNER in roles,
|
||||
"generate_document": can_get,
|
||||
"manage_accesses": is_owner_or_admin,
|
||||
"accesses_manage": is_owner_or_admin,
|
||||
"update": is_owner_or_admin or is_editor,
|
||||
"partial_update": is_owner_or_admin or is_editor,
|
||||
"retrieve": can_get,
|
||||
|
||||
@@ -21,13 +21,14 @@ def test_api_documents_retrieve_anonymous_public():
|
||||
assert response.json() == {
|
||||
"id": str(document.id),
|
||||
"abilities": {
|
||||
"accesses_manage": False,
|
||||
"accesses_view": False,
|
||||
"ai_transform": document.link_role == "editor",
|
||||
"ai_translate": document.link_role == "editor",
|
||||
"attachment_upload": document.link_role == "editor",
|
||||
"destroy": False,
|
||||
"invite_owner": False,
|
||||
"link_configuration": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": document.link_role == "editor",
|
||||
"retrieve": True,
|
||||
"update": document.link_role == "editor",
|
||||
@@ -78,13 +79,14 @@ def test_api_documents_retrieve_authenticated_unrelated_public_or_authenticated(
|
||||
assert response.json() == {
|
||||
"id": str(document.id),
|
||||
"abilities": {
|
||||
"accesses_manage": False,
|
||||
"accesses_view": False,
|
||||
"ai_transform": document.link_role == "editor",
|
||||
"ai_translate": document.link_role == "editor",
|
||||
"attachment_upload": document.link_role == "editor",
|
||||
"link_configuration": False,
|
||||
"destroy": False,
|
||||
"invite_owner": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": document.link_role == "editor",
|
||||
"retrieve": True,
|
||||
"update": document.link_role == "editor",
|
||||
|
||||
@@ -22,7 +22,7 @@ def test_api_templates_retrieve_anonymous_public():
|
||||
"abilities": {
|
||||
"destroy": False,
|
||||
"generate_document": True,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
@@ -68,7 +68,7 @@ def test_api_templates_retrieve_authenticated_unrelated_public():
|
||||
"abilities": {
|
||||
"destroy": False,
|
||||
"generate_document": True,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
|
||||
@@ -83,13 +83,14 @@ def test_models_documents_get_abilities_forbidden(is_authenticated, reach, role)
|
||||
user = factories.UserFactory() if is_authenticated else AnonymousUser()
|
||||
abilities = document.get_abilities(user)
|
||||
assert abilities == {
|
||||
"accesses_manage": False,
|
||||
"accesses_view": False,
|
||||
"ai_transform": False,
|
||||
"ai_translate": False,
|
||||
"attachment_upload": False,
|
||||
"link_configuration": False,
|
||||
"destroy": False,
|
||||
"invite_owner": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"retrieve": False,
|
||||
"update": False,
|
||||
@@ -116,13 +117,14 @@ def test_models_documents_get_abilities_reader(is_authenticated, reach):
|
||||
user = factories.UserFactory() if is_authenticated else AnonymousUser()
|
||||
abilities = document.get_abilities(user)
|
||||
assert abilities == {
|
||||
"accesses_manage": False,
|
||||
"accesses_view": False,
|
||||
"ai_transform": False,
|
||||
"ai_translate": False,
|
||||
"attachment_upload": False,
|
||||
"destroy": False,
|
||||
"link_configuration": False,
|
||||
"invite_owner": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
@@ -149,13 +151,14 @@ def test_models_documents_get_abilities_editor(is_authenticated, reach):
|
||||
user = factories.UserFactory() if is_authenticated else AnonymousUser()
|
||||
abilities = document.get_abilities(user)
|
||||
assert abilities == {
|
||||
"accesses_manage": False,
|
||||
"accesses_view": False,
|
||||
"ai_transform": True,
|
||||
"ai_translate": True,
|
||||
"attachment_upload": True,
|
||||
"destroy": False,
|
||||
"link_configuration": False,
|
||||
"invite_owner": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": True,
|
||||
"retrieve": True,
|
||||
"update": True,
|
||||
@@ -171,13 +174,14 @@ def test_models_documents_get_abilities_owner():
|
||||
access = factories.UserDocumentAccessFactory(role="owner", user=user)
|
||||
abilities = access.document.get_abilities(access.user)
|
||||
assert abilities == {
|
||||
"accesses_manage": True,
|
||||
"accesses_view": True,
|
||||
"ai_transform": True,
|
||||
"ai_translate": True,
|
||||
"attachment_upload": True,
|
||||
"destroy": True,
|
||||
"link_configuration": True,
|
||||
"invite_owner": True,
|
||||
"manage_accesses": True,
|
||||
"partial_update": True,
|
||||
"retrieve": True,
|
||||
"update": True,
|
||||
@@ -192,13 +196,14 @@ def test_models_documents_get_abilities_administrator():
|
||||
access = factories.UserDocumentAccessFactory(role="administrator")
|
||||
abilities = access.document.get_abilities(access.user)
|
||||
assert abilities == {
|
||||
"accesses_manage": True,
|
||||
"accesses_view": True,
|
||||
"ai_transform": True,
|
||||
"ai_translate": True,
|
||||
"attachment_upload": True,
|
||||
"destroy": False,
|
||||
"link_configuration": True,
|
||||
"invite_owner": False,
|
||||
"manage_accesses": True,
|
||||
"partial_update": True,
|
||||
"retrieve": True,
|
||||
"update": True,
|
||||
@@ -216,13 +221,14 @@ def test_models_documents_get_abilities_editor_user(django_assert_num_queries):
|
||||
abilities = access.document.get_abilities(access.user)
|
||||
|
||||
assert abilities == {
|
||||
"accesses_manage": False,
|
||||
"accesses_view": True,
|
||||
"ai_transform": True,
|
||||
"ai_translate": True,
|
||||
"attachment_upload": True,
|
||||
"destroy": False,
|
||||
"link_configuration": False,
|
||||
"invite_owner": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": True,
|
||||
"retrieve": True,
|
||||
"update": True,
|
||||
@@ -242,13 +248,14 @@ def test_models_documents_get_abilities_reader_user(django_assert_num_queries):
|
||||
abilities = access.document.get_abilities(access.user)
|
||||
|
||||
assert abilities == {
|
||||
"accesses_manage": False,
|
||||
"accesses_view": True,
|
||||
"ai_transform": False,
|
||||
"ai_translate": False,
|
||||
"attachment_upload": False,
|
||||
"destroy": False,
|
||||
"link_configuration": False,
|
||||
"invite_owner": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
@@ -269,13 +276,14 @@ def test_models_documents_get_abilities_preset_role(django_assert_num_queries):
|
||||
abilities = access.document.get_abilities(access.user)
|
||||
|
||||
assert abilities == {
|
||||
"accesses_manage": False,
|
||||
"accesses_view": True,
|
||||
"ai_transform": False,
|
||||
"ai_translate": False,
|
||||
"attachment_upload": False,
|
||||
"destroy": False,
|
||||
"link_configuration": False,
|
||||
"invite_owner": False,
|
||||
"manage_accesses": False,
|
||||
"partial_update": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
|
||||
@@ -62,7 +62,7 @@ def test_models_templates_get_abilities_anonymous_public():
|
||||
"destroy": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": False,
|
||||
"generate_document": True,
|
||||
}
|
||||
@@ -76,7 +76,7 @@ def test_models_templates_get_abilities_anonymous_not_public():
|
||||
"destroy": False,
|
||||
"retrieve": False,
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": False,
|
||||
"generate_document": False,
|
||||
}
|
||||
@@ -90,7 +90,7 @@ def test_models_templates_get_abilities_authenticated_public():
|
||||
"destroy": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": False,
|
||||
"generate_document": True,
|
||||
}
|
||||
@@ -104,7 +104,7 @@ def test_models_templates_get_abilities_authenticated_not_public():
|
||||
"destroy": False,
|
||||
"retrieve": False,
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": False,
|
||||
"generate_document": False,
|
||||
}
|
||||
@@ -119,7 +119,7 @@ def test_models_templates_get_abilities_owner():
|
||||
"destroy": True,
|
||||
"retrieve": True,
|
||||
"update": True,
|
||||
"manage_accesses": True,
|
||||
"accesses_manage": True,
|
||||
"partial_update": True,
|
||||
"generate_document": True,
|
||||
}
|
||||
@@ -133,7 +133,7 @@ def test_models_templates_get_abilities_administrator():
|
||||
"destroy": False,
|
||||
"retrieve": True,
|
||||
"update": True,
|
||||
"manage_accesses": True,
|
||||
"accesses_manage": True,
|
||||
"partial_update": True,
|
||||
"generate_document": True,
|
||||
}
|
||||
@@ -150,7 +150,7 @@ def test_models_templates_get_abilities_editor_user(django_assert_num_queries):
|
||||
"destroy": False,
|
||||
"retrieve": True,
|
||||
"update": True,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": True,
|
||||
"generate_document": True,
|
||||
}
|
||||
@@ -167,7 +167,7 @@ def test_models_templates_get_abilities_reader_user(django_assert_num_queries):
|
||||
"destroy": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": False,
|
||||
"generate_document": True,
|
||||
}
|
||||
@@ -185,7 +185,7 @@ def test_models_templates_get_abilities_preset_role(django_assert_num_queries):
|
||||
"destroy": False,
|
||||
"retrieve": True,
|
||||
"update": False,
|
||||
"manage_accesses": False,
|
||||
"accesses_manage": False,
|
||||
"partial_update": False,
|
||||
"generate_document": True,
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ export const mockedDocument = async (page: Page, json: object) => {
|
||||
versions_destroy: false,
|
||||
versions_list: true,
|
||||
versions_retrieve: true,
|
||||
manage_accesses: false, // Means not admin
|
||||
accesses_manage: false, // Means not admin
|
||||
update: false,
|
||||
partial_update: false, // Means not editor
|
||||
retrieve: true,
|
||||
|
||||
@@ -215,7 +215,7 @@ test.describe('Doc Editor', () => {
|
||||
versions_destroy: false,
|
||||
versions_list: true,
|
||||
versions_retrieve: true,
|
||||
manage_accesses: false, // Means not admin
|
||||
accesses_manage: false, // Means not admin
|
||||
update: false,
|
||||
partial_update: false, // Means not editor
|
||||
retrieve: true,
|
||||
|
||||
@@ -303,7 +303,7 @@ test.describe('Documents Grid mobile', () => {
|
||||
attachment_upload: true,
|
||||
destroy: true,
|
||||
link_configuration: true,
|
||||
manage_accesses: true,
|
||||
accesses_manage: true,
|
||||
partial_update: true,
|
||||
retrieve: true,
|
||||
update: true,
|
||||
|
||||
@@ -45,7 +45,7 @@ test.describe('Doc Header', () => {
|
||||
versions_destroy: true,
|
||||
versions_list: true,
|
||||
versions_retrieve: true,
|
||||
manage_accesses: true,
|
||||
accesses_manage: true,
|
||||
update: true,
|
||||
partial_update: true,
|
||||
retrieve: true,
|
||||
@@ -182,7 +182,7 @@ test.describe('Doc Header', () => {
|
||||
versions_destroy: true,
|
||||
versions_list: true,
|
||||
versions_retrieve: true,
|
||||
manage_accesses: true, // Means admin
|
||||
accesses_manage: true, // Means admin
|
||||
update: true,
|
||||
partial_update: true,
|
||||
retrieve: true,
|
||||
@@ -252,7 +252,7 @@ test.describe('Doc Header', () => {
|
||||
versions_destroy: true,
|
||||
versions_list: true,
|
||||
versions_retrieve: true,
|
||||
manage_accesses: false, // Means not admin
|
||||
accesses_manage: false, // Means not admin
|
||||
update: true,
|
||||
partial_update: true, // Means editor
|
||||
retrieve: true,
|
||||
@@ -329,7 +329,7 @@ test.describe('Doc Header', () => {
|
||||
versions_destroy: false,
|
||||
versions_list: true,
|
||||
versions_retrieve: true,
|
||||
manage_accesses: false, // Means not admin
|
||||
accesses_manage: false, // Means not admin
|
||||
update: false,
|
||||
partial_update: false, // Means not editor
|
||||
retrieve: true,
|
||||
@@ -489,7 +489,7 @@ test.describe('Documents Header mobile', () => {
|
||||
versions_destroy: true,
|
||||
versions_list: true,
|
||||
versions_retrieve: true,
|
||||
manage_accesses: true,
|
||||
accesses_manage: true,
|
||||
update: true,
|
||||
partial_update: true,
|
||||
retrieve: true,
|
||||
|
||||
@@ -5,7 +5,7 @@ export interface Template {
|
||||
abilities: {
|
||||
destroy: boolean;
|
||||
generate_document: boolean;
|
||||
manage_accesses: boolean;
|
||||
accesses_manage: boolean;
|
||||
retrieve: boolean;
|
||||
update: boolean;
|
||||
partial_update: boolean;
|
||||
|
||||
@@ -115,7 +115,7 @@ export const ModalShare = ({ onClose, doc }: ModalShareProps) => {
|
||||
</Box>
|
||||
</Card>
|
||||
<DocVisibility doc={doc} />
|
||||
{doc.abilities.manage_accesses && (
|
||||
{doc.abilities.accesses_manage && (
|
||||
<AddMembers
|
||||
doc={doc}
|
||||
currentRole={currentDocRole(doc.abilities)}
|
||||
|
||||
@@ -47,7 +47,7 @@ export interface Doc {
|
||||
attachment_upload: true;
|
||||
destroy: boolean;
|
||||
link_configuration: boolean;
|
||||
manage_accesses: boolean;
|
||||
accesses_manage: boolean;
|
||||
partial_update: boolean;
|
||||
retrieve: boolean;
|
||||
update: boolean;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Doc, Role } from './types';
|
||||
export const currentDocRole = (abilities: Doc['abilities']): Role => {
|
||||
return abilities.destroy
|
||||
? Role.OWNER
|
||||
: abilities.manage_accesses
|
||||
: abilities.accesses_manage
|
||||
? Role.ADMIN
|
||||
: abilities.partial_update
|
||||
? Role.EDITOR
|
||||
|
||||
@@ -112,7 +112,7 @@ export const InvitationItem = ({
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
{doc.abilities.manage_accesses && (
|
||||
{doc.abilities.accesses_manage && (
|
||||
<Box $margin={isSmallMobile ? 'auto' : ''}>
|
||||
<Button
|
||||
color="tertiary-text"
|
||||
|
||||
@@ -170,14 +170,14 @@ export const AddMembers = ({ currentRole, doc }: ModalAddMembersProps) => {
|
||||
doc={doc}
|
||||
setSelectedUsers={setSelectedUsers}
|
||||
selectedUsers={selectedUsers}
|
||||
disabled={isPending || !doc.abilities.manage_accesses}
|
||||
disabled={isPending || !doc.abilities.accesses_manage}
|
||||
/>
|
||||
</Box>
|
||||
<Box $css="flex: auto;">
|
||||
<ChooseRole
|
||||
key={resetKey}
|
||||
currentRole={currentRole}
|
||||
disabled={isPending || !doc.abilities.manage_accesses}
|
||||
disabled={isPending || !doc.abilities.accesses_manage}
|
||||
setRole={setSelectedRole}
|
||||
/>
|
||||
</Box>
|
||||
@@ -189,7 +189,7 @@ export const AddMembers = ({ currentRole, doc }: ModalAddMembersProps) => {
|
||||
!selectedUsers.length ||
|
||||
isPending ||
|
||||
!selectedRole ||
|
||||
!doc.abilities.manage_accesses
|
||||
!doc.abilities.accesses_manage
|
||||
}
|
||||
onClick={() => void handleValidate()}
|
||||
style={{ height: '100%', maxHeight: '55px' }}
|
||||
|
||||
@@ -61,7 +61,7 @@ export const MemberItem = ({
|
||||
});
|
||||
|
||||
const isNotAllowed =
|
||||
isOtherOwner || isLastOwner || !doc.abilities.manage_accesses;
|
||||
isOtherOwner || isLastOwner || !doc.abilities.accesses_manage;
|
||||
|
||||
if (!access.user) {
|
||||
return (
|
||||
@@ -112,7 +112,7 @@ export const MemberItem = ({
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
{doc.abilities.manage_accesses && (
|
||||
{doc.abilities.accesses_manage && (
|
||||
<Box $margin={isSmallMobile ? 'auto' : ''}>
|
||||
<Button
|
||||
color="tertiary-text"
|
||||
@@ -136,7 +136,7 @@ export const MemberItem = ({
|
||||
<TextErrors causes={errorUpdate?.cause || errorDelete?.cause} />
|
||||
</Box>
|
||||
)}
|
||||
{(isLastOwner || isOtherOwner) && doc.abilities.manage_accesses && (
|
||||
{(isLastOwner || isOtherOwner) && doc.abilities.accesses_manage && (
|
||||
<Box $margin={{ top: 'tiny' }}>
|
||||
<Alert
|
||||
canClose={false}
|
||||
|
||||
@@ -199,7 +199,7 @@ export class ApiPlugin implements WorkboxPlugin {
|
||||
versions_destroy: true,
|
||||
versions_list: true,
|
||||
versions_retrieve: true,
|
||||
manage_accesses: true,
|
||||
accesses_manage: true,
|
||||
update: true,
|
||||
partial_update: true,
|
||||
retrieve: true,
|
||||
|
||||
Reference in New Issue
Block a user