1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- module Gql::Subscriptions
- class TicketArticleUpdates < BaseSubscription
- argument :ticket_id, GraphQL::Types::ID, description: 'Ticket identifier'
- description 'Changes to the list of ticket articles'
- field :add_article, Gql::Types::Ticket::ArticleType, description: 'A new article needs to be added to the list'
- field :update_article, Gql::Types::Ticket::ArticleType, description: 'An existing article was changed'
- field :remove_article_id, GraphQL::Types::ID, description: 'An article must be removed from the list'
- class << self
- # Helper methods for triggering with custom payload.
- def trigger_after_create(article)
- trigger_for_ticket(article, { article: article, event: :create })
- end
- def trigger_after_update(article)
- # Add information about changes to the internal flag for later processing.
- trigger_for_ticket(article, { article: article, event: :update, internal_changed?: article.previous_changes['internal'].present? })
- end
- def trigger_after_destroy(article)
- trigger_for_ticket(article, { article_id: Gql::ZammadSchema.id_from_object(article), event: :destroy })
- end
- def trigger_for_ticket(article, payload)
- trigger(payload, arguments: { ticket_id: Gql::ZammadSchema.id_from_object(article.ticket) })
- end
- end
- def authorized?(ticket_id:)
- Gql::ZammadSchema.authorized_object_from_id ticket_id, type: ::Ticket, user: context.current_user
- end
- # This needs to be passed a hash with the correct field name containing the article payload as root object,
- # as we cannot change the (graphql-ruby) function signature of update(ticket_id:).
- def update(ticket_id:)
- event = object[:event]
- article = object[:article]
- # Always send remove events.
- if event == :destroy
- return { remove_article_id: object[:article_id] }
- end
- # Send create only for articles with permission.
- if event == :create
- return article_permission? ? { add_article: article } : no_update
- end
- # For updated articles, there is a special handling if visibility changed.
- if article_permission?
- # If permission to see the article was just added, treat it as an add event.
- return customer_visibility_changed? ? { add_article: article } : { update_article: article }
- elsif customer_visibility_changed?
- # If permission to see the article was just removed, treat it as a remove event.
- return { remove_article_id: Gql::ZammadSchema.id_from_object(article) }
- end
- no_update
- end
- private
- def customer_visibility_changed?
- object[:internal_changed?] && !TicketPolicy.new(context.current_user, object[:article].ticket).agent_read_access?
- end
- # Only send updates for articles with read permission.
- def article_permission?
- Pundit.authorize context.current_user, object[:article], :show?
- rescue Pundit::NotAuthorizedError
- false
- end
- end
- end
|