Skip to content

Access Control

Overview

The Permissions System provides access control and permission management for digital assets, folders, and collections. It enables users to set public/private permissions, manage access levels, and enforce role-based access control (RBAC) throughout the DAM module. The system includes permission dialogs, middleware validation, and helper functions for permission checks.

Architecture

System Components

  1. Permission Dialogs: Manage public/private permissions for assets, folders, and collections
  2. Permission Integration: Permission controls integrated into asset/folder components
  3. Permission Middleware: Route-level permission validation
  4. Permission Helpers: RBAC capabilities matrix and permission check functions
  5. Permission Pages: Permission management in asset/folder/collage detail pages

File Structure

Core Permission Components

Vue Component Files (.vue)

  • components/dam/Dialogs/PermissionDialog.vue - Main permission dialog

    • Public/private permission management
    • Permission settings for folders, collections, and assets
    • Permission confirmation
    • Bulk permission changes
  • components/dam/Dialogs/AssetPermissionDialog.vue - Asset permission confirmation dialog

    • Confirm permission changes for assets
    • Warning messages for permission changes
    • Permission change confirmation
  • components/dam/StaticPermissionDialog.vue - Static permission dialog component

    • Upgrade plan message
    • Permission feature limitations
    • Plan-based permission restrictions

Permission Integration in Asset/Folder Components

Vue Component Files (.vue)

  • components/dam/Folders/FolderCard.vue - Folder card component

    • May include permission controls
    • Permission status display
    • Permission change actions
  • components/dam/Collage/FileListingCard.vue - File listing card

    • May include permission controls
    • Permission status indicators
    • Quick permission changes
  • components/dam/Dialogs/FolderDialogs/FolderDialogListItem.vue - Folder dialog list item

    • May include permission settings
    • Permission display in folder dialogs

Permission Pages

Vue Page Files (.vue)

  • pages/_workspace_id/dam/folders/_id/index.vue - Folder details page
    • Contains permission management
    • Permission settings interface
    • Permission change functionality

Route: /:workspace_id/dam/folders/:id

  • pages/_workspace_id/dam/collage_id/index.vue - Collage details page
    • Contains permission management
    • Permission settings for collages
    • Permission change functionality

Route: /:workspace_id/dam/collage_id

  • pages/_workspace_id/dam/files_id.vue - File details page
    • May include permission controls
    • Asset permission management

Route: /:workspace_id/dam/files/:id

Permission Helper Functions & RBAC

JavaScript Files (.js)

  • plugins/helper.js - Helper functions plugin
    • DAM_CAPABILITIES matrix - RBAC capabilities matrix
    • canPerformDamOperation - Check if user can perform DAM operation
    • canManageBrandPortalSettings - Check brand portal settings permission
    • canAddUsers - Check user addition permission
    • Various permission check functions

Permission Middleware

JavaScript Files (.js)

  • middleware/can-access-dam-module.js - DAM module access middleware

    • Checks user roles and permissions
    • Validates DAM module access
    • Redirects if access denied
  • middleware/can-access-dam-settings.js - DAM settings access middleware

    • Checks specific permissions for settings routes
    • Validates settings access
    • Permission-based route protection

Permission Structure

Permission Object

javascript
{
  id: 1,
  resource_type: "asset", // "asset", "folder", "collection"
  resource_id: 456,
  workspace_id: 123,
  is_public: false,
  is_private: true,
  visibility: "private", // "public", "private", "workspace", "team"
  allowed_users: [], // Array of user IDs with access
  allowed_roles: [], // Array of role IDs with access
  created_at: "2024-01-15T10:00:00Z",
  updated_at: "2024-01-20T14:30:00Z"
}

DAM Capabilities Matrix

javascript
const DAM_CAPABILITIES = {
  // Asset operations
  'can-view-assets': ['viewer', 'member', 'admin'],
  'can-upload-assets': ['member', 'admin'],
  'can-edit-assets': ['member', 'admin'],
  'can-delete-assets': ['admin'],
  'can-share-assets': ['member', 'admin'],
  
  // Folder operations
  'can-view-folders': ['viewer', 'member', 'admin'],
  'can-create-folders': ['member', 'admin'],
  'can-edit-folders': ['member', 'admin'],
  'can-delete-folders': ['admin'],
  
  // Collection operations
  'can-view-collections': ['viewer', 'member', 'admin'],
  'can-create-collections': ['member', 'admin'],
  'can-edit-collections': ['member', 'admin'],
  'can-delete-collections': ['admin'],
  
  // Permission operations
  'can-change-permissions': ['admin'],
  'can-manage-permissions': ['admin'],
  
  // Settings operations
  'can-access-dam-settings': ['admin'],
  'can-manage-brand-portal-settings': ['admin'],
  'can-add-users': ['admin'],
  'can-manage-users': ['admin']
}

Component Implementation

Permission Dialog Component

File: components/dam/Dialogs/PermissionDialog.vue

Main dialog for managing public/private permissions.

Features

  • Toggle public/private permission
  • Permission confirmation
  • Bulk permission changes
  • Permission warning messages
  • Resource type handling (asset, folder, collection)

Props

javascript
{
  dialog: {
    type: Boolean,
    default: false
  },
  resource: {
    type: Object,
    required: true
    // Asset, folder, or collection object
  },
  resourceType: {
    type: String,
    required: true
    // 'asset', 'folder', 'collection'
  },
  workspaceId: {
    type: [String, Number],
    required: true
  },
  currentPermission: {
    type: String,
    default: 'private'
    // 'public' or 'private'
  }
}

Data

javascript
data() {
  return {
    selectedPermission: 'private', // 'public' or 'private'
    loading: false,
    warningMessage: null
  }
}

Methods

javascript
// Change permission
async changePermission() {
  // Validate permission change
  if (!this.canChangePermission()) {
    this.$toast.error('You do not have permission to change permissions')
    return
  }
  
  // Show warning if making public
  if (this.selectedPermission === 'public' && this.currentPermission === 'private') {
    const confirmed = await this.showPublicWarning()
    if (!confirmed) {
      return
    }
  }
  
  this.loading = true
  try {
    await this.$axios.post(
      '/digital-assets/permission/change-permission',
      {
        workspace_id: this.workspaceId,
        resource_type: this.resourceType,
        resource_id: this.resource.id,
        permission: this.selectedPermission
      }
    )
    this.$toast.success('Permission updated successfully')
    this.$emit('permission-changed', {
      resource_id: this.resource.id,
      permission: this.selectedPermission
    })
    this.closeDialog()
  } catch (error) {
    this.$toast.error('Failed to change permission')
  } finally {
    this.loading = false
  }
}

// Show public warning
showPublicWarning() {
  return new Promise((resolve) => {
    this.$dialog.confirm({
      title: 'Make Public?',
      text: 'Making this resource public will make it accessible to anyone with the link. Are you sure?',
      persistent: true
    }).then(resolve).catch(() => resolve(false))
  })
}

// Check if can change permission
canChangePermission() {
  return this.$canPerformDamOperation('can-change-permissions')
}

Usage

vue
<template>
  <PermissionDialog
    :dialog="permissionDialogOpen"
    :resource="selectedResource"
    :resource-type="resourceType"
    :workspace-id="workspaceId"
    :current-permission="currentPermission"
    @close="closePermissionDialog"
    @permission-changed="handlePermissionChanged"
  />
</template>

Asset Permission Dialog Component

File: components/dam/Dialogs/AssetPermissionDialog.vue

Confirmation dialog for asset permission changes.

Features

  • Confirm permission changes
  • Warning messages
  • Permission change confirmation
  • Asset-specific warnings

Props

javascript
{
  dialog: {
    type: Boolean,
    default: false
  },
  asset: {
    type: Object,
    required: true
  },
  newPermission: {
    type: String,
    required: true
    // 'public' or 'private'
  }
}

Static Permission Dialog Component

File: components/dam/StaticPermissionDialog.vue

Dialog for displaying upgrade plan messages and permission limitations.

Features

  • Upgrade plan message
  • Permission feature limitations
  • Plan-based restrictions
  • Upgrade CTA

Permission Helper Functions

File: plugins/helper.js

Permission check functions and RBAC capabilities matrix.

DAM Capabilities Matrix

javascript
export const DAM_CAPABILITIES = {
  // Asset operations
  'can-view-assets': ['viewer', 'member', 'admin'],
  'can-upload-assets': ['member', 'admin'],
  'can-edit-assets': ['member', 'admin'],
  'can-delete-assets': ['admin'],
  'can-share-assets': ['member', 'admin'],
  
  // Folder operations
  'can-view-folders': ['viewer', 'member', 'admin'],
  'can-create-folders': ['member', 'admin'],
  'can-edit-folders': ['member', 'admin'],
  'can-delete-folders': ['admin'],
  
  // Collection operations
  'can-view-collections': ['viewer', 'member', 'admin'],
  'can-create-collections': ['member', 'admin'],
  'can-edit-collections': ['member', 'admin'],
  'can-delete-collections': ['admin'],
  
  // Permission operations
  'can-change-permissions': ['admin'],
  'can-manage-permissions': ['admin'],
  
  // Settings operations
  'can-access-dam-settings': ['admin'],
  'can-manage-brand-portal-settings': ['admin'],
  'can-add-users': ['admin'],
  'can-manage-users': ['admin']
}

Can Perform DAM Operation

javascript
export function canPerformDamOperation(operation) {
  const user = this.$store.state.auth.user
  if (!user) {
    return false
  }
  
  const userRole = user.role
  const capabilities = DAM_CAPABILITIES[operation]
  
  if (!capabilities) {
    return false
  }
  
  return capabilities.includes(userRole)
}

Can Manage Brand Portal Settings

javascript
export function canManageBrandPortalSettings() {
  const user = this.$store.state.auth.user
  if (!user) {
    return false
  }
  
  // Check role
  if (user.role !== 'admin') {
    return false
  }
  
  // Check specific permission
  const permissions = this.$store.state.auth.permissions
  return permissions.includes('can-manage-brand-portal-settings')
}

Can Add Users

javascript
export function canAddUsers() {
  const user = this.$store.state.auth.user
  if (!user) {
    return false
  }
  
  // Check role
  if (user.role !== 'admin') {
    return false
  }
  
  // Check specific permission
  const permissions = this.$store.state.auth.permissions
  return permissions.includes('can-add-users')
}

Usage

vue
<script>
import { canPerformDamOperation, canManageBrandPortalSettings } from '~/plugins/helper'

export default {
  computed: {
    canEditAssets() {
      return canPerformDamOperation.call(this, 'can-edit-assets')
    },
    canDeleteAssets() {
      return canPerformDamOperation.call(this, 'can-delete-assets')
    },
    canManageBrandPortal() {
      return canManageBrandPortalSettings.call(this)
    }
  },
  methods: {
    handleEdit() {
      if (!this.canEditAssets) {
        this.$toast.error('You do not have permission to edit assets')
        return
      }
      // Proceed with edit
    }
  }
}
</script>

Permission Middleware

DAM Module Access Middleware

File: middleware/can-access-dam-module.js

Validates user access to DAM module.

javascript
export default async function({ store, route, redirect, error }) {
  const user = store.state.auth.user
  
  if (!user) {
    return redirect('/login')
  }
  
  // Check if user has DAM module access
  const userModules = store.getters['workspace/userModules']
  if (!userModules || !userModules.includes('dam')) {
    return error({
      statusCode: 403,
      message: 'You do not have access to the DAM module'
    })
  }
  
  // Check user role
  const userWorkspace = store.getters['workspace/userWorkspace']
  if (!userWorkspace) {
    return error({
      statusCode: 403,
      message: 'Workspace access denied'
    })
  }
  
  // Check if user role allows DAM access
  const allowedRoles = ['viewer', 'member', 'admin']
  if (!allowedRoles.includes(userWorkspace.role)) {
    return error({
      statusCode: 403,
      message: 'Insufficient permissions for DAM module'
    })
  }
}

DAM Settings Access Middleware

File: middleware/can-access-dam-settings.js

Validates user access to DAM settings routes.

javascript
export default async function({ store, route, redirect, error }) {
  const user = store.state.auth.user
  
  if (!user) {
    return redirect('/login')
  }
  
  // Check if user can access DAM settings
  const canAccess = this.$canPerformDamOperation('can-access-dam-settings')
  
  if (!canAccess) {
    return error({
      statusCode: 403,
      message: 'You do not have permission to access DAM settings'
    })
  }
  
  // Additional permission checks
  const userWorkspace = store.getters['workspace/userWorkspace']
  if (userWorkspace.role !== 'admin') {
    return error({
      statusCode: 403,
      message: 'Admin access required for DAM settings'
    })
  }
}

Usage

javascript
// In page component
export default {
  middleware: ['can-access-dam-module'],
  // ...
}

// For settings pages
export default {
  middleware: ['can-access-dam-module', 'can-access-dam-settings'],
  // ...
}

API Integration

Change Permission

Endpoint: POST /digital-assets/permission/change-permission

Request Body:

json
{
  "workspace_id": 123,
  "resource_type": "asset",
  "resource_id": 456,
  "permission": "public"
}

Response:

json
{
  "success": true,
  "permission": {
    "id": 1,
    "resource_type": "asset",
    "resource_id": 456,
    "workspace_id": 123,
    "is_public": true,
    "is_private": false,
    "visibility": "public",
    "updated_at": "2024-01-20T14:30:00Z"
  }
}

Get Permission

Endpoint: GET /digital-assets/permission/get-permission

Query Parameters:

  • workspace_id (required) - Workspace identifier
  • resource_type (required) - Resource type (asset, folder, collection)
  • resource_id (required) - Resource identifier

Response:

json
{
  "permission": {
    "id": 1,
    "resource_type": "asset",
    "resource_id": 456,
    "workspace_id": 123,
    "is_public": false,
    "is_private": true,
    "visibility": "private",
    "allowed_users": [],
    "allowed_roles": []
  }
}

Workflows

Change Asset Permission

1. User navigates to asset details
   Route: /:workspace_id/dam/files/:id

2. Click "Change Permission" or permission toggle
   Component: PermissionDialog opens

3. Select permission
   - Choose "Public" or "Private"
   - See warning if making public

4. Confirm permission change
   - If making public → Show confirmation dialog
   - User confirms

5. Call API
   API: POST /digital-assets/permission/change-permission
   Body: { workspace_id, resource_type: 'asset', resource_id, permission }

6. Permission updated
   - Permission saved to database
   - Resource visibility changed

7. Update UI
   - Refresh permission display
   - Show success message
   - Close dialog

Check Permission Before Action

1. User attempts action (e.g., edit asset)
   Component: AssetCard, FileListingCard

2. Check permission
   Helper: canPerformDamOperation('can-edit-assets')
   - Check user role
   - Check DAM capabilities matrix

3. Permission check result
   - If allowed → Proceed with action
   - If denied → Show error message

4. Execute action (if allowed)
   - Perform operation
   - Update resource

Access DAM Module

1. User navigates to DAM route
   Route: /:workspace_id/dam/...

2. Middleware: can-access-dam-module.js
   - Check if user is authenticated
   - Check if user has DAM module access
   - Check user role

3. Validate access
   - If user has access → Continue
   - If no access → Show 403 error

4. Load DAM module
   - Display DAM interface
   - Load user permissions
   - Initialize DAM features

Component Integration

Using Permission Dialog

vue
<template>
  <div class="asset-card">
    <!-- Asset content -->
    
    <v-btn
      v-if="canChangePermission"
      icon
      @click="openPermissionDialog"
    >
      <v-icon>{{ isPublic ? 'mdi-lock-open' : 'mdi-lock' }}</v-icon>
    </v-btn>
    
    <PermissionDialog
      :dialog="permissionDialogOpen"
      :resource="asset"
      :resource-type="'asset'"
      :workspace-id="workspaceId"
      :current-permission="currentPermission"
      @close="closePermissionDialog"
      @permission-changed="handlePermissionChanged"
    />
  </div>
</template>

<script>
import PermissionDialog from '~/components/dam/Dialogs/PermissionDialog.vue'
import { canPerformDamOperation } from '~/plugins/helper'

export default {
  components: {
    PermissionDialog
  },
  data() {
    return {
      permissionDialogOpen: false,
      asset: {},
      currentPermission: 'private',
      workspaceId: this.$route.params.workspace_id
    }
  },
  computed: {
    canChangePermission() {
      return canPerformDamOperation.call(this, 'can-change-permissions')
    },
    isPublic() {
      return this.currentPermission === 'public'
    }
  },
  methods: {
    openPermissionDialog() {
      this.permissionDialogOpen = true
    },
    closePermissionDialog() {
      this.permissionDialogOpen = false
    },
    handlePermissionChanged(data) {
      this.currentPermission = data.permission
      // Refresh asset data
    }
  }
}
</script>

Using Permission Helpers

vue
<script>
import { 
  canPerformDamOperation,
  canManageBrandPortalSettings,
  canAddUsers
} from '~/plugins/helper'

export default {
  computed: {
    canEditAssets() {
      return canPerformDamOperation.call(this, 'can-edit-assets')
    },
    canDeleteAssets() {
      return canPerformDamOperation.call(this, 'can-delete-assets')
    },
    canShareAssets() {
      return canPerformDamOperation.call(this, 'can-share-assets')
    },
    canManageBrandPortal() {
      return canManageBrandPortalSettings.call(this)
    },
    canAddUsersToWorkspace() {
      return canAddUsers.call(this)
    }
  },
  methods: {
    handleEdit() {
      if (!this.canEditAssets) {
        this.$toast.error('You do not have permission to edit assets')
        return
      }
      // Proceed with edit
    },
    handleDelete() {
      if (!this.canDeleteAssets) {
        this.$toast.error('You do not have permission to delete assets')
        return
      }
      // Proceed with delete
    }
  }
}
</script>

Using Permission Middleware

vue
<script>
export default {
  middleware: ['can-access-dam-module'],
  // Page will only load if user has DAM module access
}
</script>
vue
<script>
export default {
  middleware: ['can-access-dam-module', 'can-access-dam-settings'],
  // Page will only load if user has DAM module and settings access
}
</script>

Permission Levels

Public Permission

  • Resource is accessible to anyone with the link
  • No authentication required
  • Can be shared publicly
  • Visible in public searches (if enabled)

Private Permission

  • Resource is only accessible to workspace members
  • Requires authentication
  • Access controlled by workspace membership
  • Not visible to external users

Workspace Permission

  • Resource is accessible to all workspace members
  • Requires workspace membership
  • Role-based access may apply
  • Internal sharing only

Team Permission

  • Resource is accessible to specific team members
  • Requires team membership
  • Custom access control
  • Restricted to selected users/roles