### Space related events

# Spaces > Create space > ... > Create
event {
  category: "Spaces"
  summary: "Space created"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "/rest/create-dialog/1.0/space-blueprint/create-space"  method: POST }
  detail { name: "Space key"  argument { name: "spaceKey" } }
  detail { name: "Space name"  argument { name: "name" } }
  detail { name: "Space description"  argument { name: "description" } }
  detail { name: "Space description"  argument { name: "context.spaceDesc" } }
  detail { name: "Members"  argument { name: "context.members" } }
}

# Space Tools > Configure Sidebar > Edit space details
event {
  category: "Spaces"
  summary: "Space details changed"
  object { argument { name: "spaceKey" } }
  condition {
    url_pattern: "rest/ia/[^/]+/space/setLogo"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Space name"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
}

# Space Tools > Configure Sidebar > Add link
event {
  category: "Spaces"
  summary: "Space sidebar link added"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/ia/[^/]+/link$"  method: POST }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail { name: "Link title"  argument { name: "customTitle" } }
  detail { name: "Link URL"  argument { name: "url" } }
  detail { name: "Link resource type"  argument { name: "resourceType" } }
  detail { name: "Link resource ID"  argument { name: "resourceId" } }
}

# Space Tools > Configure Sidebar > Remove link
event {
  category: "Spaces"
  summary: "Space sidebar link removed"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/ia/[^/]+/link/([^/]+)$"  method: DELETE }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail { name: "Link ID"  argument { name: "1"  source: URL } }
}

# Space Tools > Configure Sidebar > Show/Hide link
event {
  category: "Spaces"
  summary: "Space sidebar link visibility changed"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/ia/[^/]+/link/([^/]+)/((show)|(hide))"  method: POST }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail { name: "Link ID"  argument { name: "1"  source: URL } }
}

# Space Tools > Configure Sidebar > Move link
event {
  category: "Spaces"
  summary: "Space sidebar link moved"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/ia/[^/]+/link/([^/]+)/move"  method: POST }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail { name: "Link ID"  argument { name: "1"  source: URL } }
  detail { name: "Position"  argument { name: "position" } }
  detail { name: "After"  argument { name: "after" } }
}

# Space Tools > Configure Sidebar > Option select
event {
  category: "Spaces"
  summary: "Space sidebar option updated"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/ia/[^/]+/space/option"  method: POST }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail { name: "Option"  argument { name: "option" } }
  detail { name: "Value"  argument { name: "value" } }
}

# Space Admin > General > Space Details > Edit space details
event {
  category: "Spaces"
  summary: "Space details changed"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/doeditspace.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { name: "Space key"  argument { name: "key" } }
  detail { name: "Space name"  phase: BEFORE_AND_AFTER  transformer_name: "SpaceNameByKeyTransformer"  argument { name: "key" } }
  detail { name: "Space description"  phase: BEFORE_AND_AFTER  transformer_name: "SpaceDescriptionByKeyTransformer"  argument { name: "key" } }
  detail { name: "Archived status"  phase: BEFORE_AND_AFTER  transformer_name: "SpaceStatusByKeyTransformer"  argument { name: "key" } }
  detail { name: "Home page title"  phase: BEFORE_AND_AFTER  transformer_name: "SpaceHomePageTitleByKeyTransformer"  argument { name: "key" } }
  error_handling: LOG_IF_CHANGED
}

# Space Admin > General > Delete
event {
  category: "Spaces"
  summary: "Space deleted"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/doremovespace.action"
    parameter { name_pattern: "confirm"  value_pattern: "OK" }
    method: POST
  }
  detail { name: "Space key"  argument { name: "key" } }
  detail {
    name: "Space name"
    phase: BEFORE
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
}

event {
  category: "Spaces"
  summary: "Space copied"
  object { argument { name: "oldKey"} }
  condition {
    url_pattern: "/rest/copy/[^/]+/copy/?$"
    method: POST
  }
  detail { name: "New space key" argument { name: "newKey" } }
  detail { name: "New space name" argument { name: "newName"} }
  detail {
    name: "Copy target"
    argument { name: "copyPages" }
    argument { name: "copyBlogPosts" }
    transformer_name: "CopySpaceTargetTransformer"
  }
  detail { name: "New space description" argument { name: "newDescription"} }
  detail { name: "Include watchers" argument { name: "preserveWatchers"} }
  detail { name: "Existing authors and dates" argument { name: "keepMetaData"} }
  detail { name: "Comments" argument { name: "copyComments"} }
  detail { name: "Attachment" argument { name: "copyAttachments"} }
  detail { name: "Labels" argument { name: "copyLabels"} }
}

# Space Admin > General > Space Details > Categories [edit] > Add
event {
  category: "Spaces"
  summary: "Space categories updated"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/addteamlabeltospace.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { name: "Space key"  argument { name: "key" } }
  detail {
    name: "Space name"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail {
    name: "Categories"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceLabelListTransformer"
    argument { name: "key" }
  }
}

# Space Admin > General > Space Details > Categories [edit] > x
event {
  category: "Spaces"
  summary: "Space categories updated"
  object { argument { name: "1"  source: URL } }
  condition {
    url_pattern: "/rest/ui/.*/space/(.*)/label/.*"
    method: DELETE
    condition_name: "ContainsChangedDetailsCondition"
  }
  detail { name: "Space key"  argument { name: "1"  source: URL } }
  detail {
    name: "Space name"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Categories"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceLabelListTransformer"
    argument { name: "1"  source: URL }
  }
}

# Space Admin > Permissions > Permissions > Edit
event {
  category: "Spaces"
  summary: "Space permissions edited"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/doeditspacepermissions.action"
    parameter { name_pattern: "cancel"  value_pattern: "Cancel"  type: EXCLUDE }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { name: "Space key"  argument { name: "key" } }
  detail { name: "Space name"  transformer_name: "SpaceNameByKeyTransformer"  argument { name: "key" } }
  # Groups
  detail {
    name: "Groups that can view"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "VIEWSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can remove own content"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "REMOVEOWNCONTENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can add pages"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "EDITSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can remove pages"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "REMOVEPAGE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can add blog"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "EDITBLOG"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can remove blog"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "REMOVEBLOG"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can add comments"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "COMMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can remove comments"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "REMOVECOMMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can add attachments"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "CREATEATTACHMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can remove attachments"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "REMOVEATTACHMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can set restrictions"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "SETPAGEPERMISSIONS"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can remove mail"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "REMOVEMAIL"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can export space"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "EXPORTSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Groups that can administer space"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "SETSPACEPERMISSIONS"  source: CONST }
    argument { name: "key" }
  }
  # Users
  detail {
    name: "Users that can view"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "VIEWSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can remove own content"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "REMOVEOWNCONTENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can add pages"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "EDITSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can remove pages"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "REMOVEPAGE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can add blog"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "EDITBLOG"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can remove blog"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "REMOVEBLOG"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can add comments"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "COMMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can remove comments"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "REMOVECOMMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can add attachments"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "CREATEATTACHMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can remove attachments"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "REMOVEATTACHMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can set restrictions"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "SETPAGEPERMISSIONS"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can remove mail"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "REMOVEMAIL"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can export space"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "EXPORTSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Users that can administer space"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "SETSPACEPERMISSIONS"  source: CONST }
    argument { name: "key" }
  }
  # Anonymous
  detail {
    name: "Anonymous can view"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "VIEWSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can remove own content"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "REMOVEOWNCONTENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can add pages"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "EDITSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can remove pages"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "REMOVEPAGE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can add blog"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "EDITBLOG"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can remove blog"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "REMOVEBLOG"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can add comments"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "COMMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can remove comments"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "REMOVECOMMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can add attachments"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "CREATEATTACHMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can remove attachments"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "REMOVEATTACHMENT"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can set restrictions"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "SETPAGEPERMISSIONS"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can remove mail"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "REMOVEMAIL"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can export space"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "EXPORTSPACE"  source: CONST }
    argument { name: "key" }
  }
  detail {
    name: "Anonymous can administer space"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "SETSPACEPERMISSIONS"  source: CONST }
    argument { name: "key" }
  }
}

# TODO: Add logic to show old and new detail values.
# Space tools > Permissions > Analytics permissions
event {
  category: "Spaces"
  summary: "Space analytics permissions edited"
  object { argument { name: "spaceKey" } transformer_name: "SpaceNameByKeyTransformer" }
  condition {
    url_pattern: "/rest/confanalytics/[^/]+/space/restrictions/?$"
    method: PUT
  }
  detail { name: "Space key" argument { name: "spaceKey" } }
  detail {
    name: "Restricted Users"
    name: "Restricted Groups"
    argument { name: "restrictions" }
    transformer_name: "SpaceAnalyticsPermissionsByJsonTransformer"
  }
}



# Space admin > Content Tools > Templates

event {
  category: "Spaces"
  summary: "Space template added"
  object { argument { name: "key" } }
  condition {
    url_pattern: "pages/templates2/docreatepagetemplate.action"
    parameter { name_pattern: "cancel"  value_pattern: "cancel"  type: EXCLUDE }
    parameter { name_pattern: "key"  value_pattern: ".+" }
    method: POST
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail { name: "Template title"  argument { name: "title" } }
  detail { name: "Template content"  argument { name: "wysiwygContent" } }
}


event {
  category: "Spaces"
  summary: "Space template updated"
  object { argument { name: "key" } }
  condition {
    url_pattern: "pages/templates2/doeditpagetemplate(description)?.action"
    parameter { name_pattern: "cancel"  value_pattern: "cancel"  type: EXCLUDE }
    parameter { name_pattern: "key"  value_pattern: ".+" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail {
    name: "Template title"
    name: "Template description"
    name: "Template body type"
    name: "Template content"
    phase: BEFORE_AND_AFTER
    transformer_name: "PageTemplateUpdateParametersByIdTransformer"
    argument { name: "entityId" }
  }
}

event {
  category: "Spaces"
  summary: "Space template promoted"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/create-dialog/[^/]+/promotion/promote-template/(\\d+)"  method: PUT }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Template name"
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Spaces"
  summary: "Space template unpromoted"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/create-dialog/[^/]+/promotion/promote-template/(\\d+)"  method: DELETE }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Template name"
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Spaces"
  summary: "Space template deleted"
  object { argument { name: "key" } }
  condition {
    url_pattern: "pages/templates2/doremovepagetemplate.action"
    parameter { name_pattern: "key"  value_pattern: ".+" }
    method: POST
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail {
    name: "Template title"
    phase: BEFORE
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "entityId" }
  }
}

event {
  category: "Spaces"
  summary: "Space blueprint enabled"
  object { argument { name: "spaceKey" } }
  condition {
    url_pattern: "rest/create-dialog/[^/]+/modules/([^/]+)"
    method: PUT
    parameter { name_pattern: "spaceKey"  value_pattern: ".+" }
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Blueprint name"
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Spaces"
  summary: "Space blueprint disabled"
  object { argument { name: "spaceKey" } }
  condition {
    url_pattern: "rest/create-dialog/[^/]+/modules/([^/]+)"
    method: DELETE
    parameter { name_pattern: "spaceKey"  value_pattern: ".+" }
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Blueprint name"
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Spaces"
  summary: "Space blueprint promoted"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/create-dialog/[^/]+/promotion/promote-blueprint/([^/]+)"  method: PUT }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Blueprint name"
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Spaces"
  summary: "Space blueprint unpromoted"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "rest/create-dialog/[^/]+/promotion/promote-blueprint/([^/]+)"  method: DELETE }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Blueprint name"
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Spaces"
  summary: "Space blueprint template enabled"
  object { argument { name: "spaceKey" } }
  condition {
    url_pattern: "rest/create-dialog/[^/]+/promotion/promote-blueprint/([^/]+)"
    method: DELETE
    parameter { name_pattern: "spaceKey"  value_pattern: ".+" }
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Template name"
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Spaces"
  summary: "Space blueprint template edited"
  object { argument { name: "spaceKey" } }
  condition {
    url_pattern: "plugins/createcontent/do-edit-template.action"
    parameter { name_pattern: "spaceKey"  value_pattern: ".+" }
    method: POST
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail { name: "Template name"  argument { name: "title" } }
  detail { name: "Template body"  argument { name: "wysiwygContent" } }
  # TODO: add BEFORE_AND_AFTER template body comparison
}

event {
  category: "Spaces"
  summary: "Space blueprint template reset to default"
  object { argument { name: "key" } }
  condition {
    url_pattern: "plugins/createcontent/revert-template.action"
    method: GET
    parameter { name_pattern: "key"  value_pattern: ".+" }
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail {
    name: "Template name"
    phase: BEFORE
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "entityId" }
  }
}



# Space admin > Content Tools > Reorder Pages

event {
  category: "Pages"
  summary: "Page order edited"
  object { transformer_name: "SpaceKeyByPageIdTransformer"  argument { name: "pageId" } }
  condition { url_pattern: "pages/movepage.action"  method: GET }
  detail {
    name: "Page title"
    transformer_name: "PageTitleByIdTransformer"
    argument { name: "pageId" }
  }
  detail { name: "Position"  argument { name: "position" } }
  detail {
    name: "Target page"
    transformer_name: "PageTitleByIdTransformer"
    argument { name: "targetId" }
  }
}

# Since Confluence 8.0 this request has POST method.
event {
  category: "Pages"
  summary: "Page order edited"
  object { transformer_name: "SpaceKeyByPageIdTransformer"  argument { name: "pageId" } }
  condition { url_pattern: "pages/movepage.action"  method: POST }
  detail {
    name: "Page title"
    transformer_name: "PageTitleByIdTransformer"
    argument { name: "pageId" }
  }
  detail { name: "Position"  argument { name: "position" } }
  detail {
    name: "Target page"
    transformer_name: "PageTitleByIdTransformer"
    argument { name: "targetId" }
  }
}

# Space admin > Content tools > Retention rules

# TODO: Use SpaceRetentionPolicyService to show old and new values of retention rules
# TODO: (after upgrading Confluence to 7.14+)
event {
  category: "Retention rules"
  summary: "Space retention rule updated"
  object { argument { name: "2" source: URL } }
  condition {
    url_pattern: "/rest(/api)?/retentionpolicy/[^/]+/space/([^/]+)/?$"
    method: PUT
  }
  detail { name: "Space name" argument { name: "spaceName" } }
  detail {
    name: "Attachment versions retention"
    name: "Page versions retention"
    name: "Trash retention"
    name: "Who can add and edit exemptions"
    transformer_name: "RetentionRulesSettingsByJsonTransformer"
    argument { name: "attachmentRetentionRule" }
    argument { name: "pageRetentionRule" }
    argument { name: "trashRetentionRule" }
    argument { name: "spaceOverridesAllowed" }
  }
}

# Space admin > Content Tools > Trash
event {
  category: "Trash"
  summary: "Content restored from trash"
  object { argument { name: "key" } }
  condition {
    url_pattern: "pages/dorestoretrashitem.action"
    parameter { name_pattern: "confirm" }
    method: POST
  }
  detail { name: "Content ID"  argument { name: "contentId" } }
  detail {
    name: "Type"
    name: "Title"
    phase: BEFORE
    transformer_name: "TrashContentParametersByIdTransformer"
    argument { name: "key" }
    argument { name: "contentId" }
  }
}

event {
  category: "Trash"
  summary: "Content purged from trash"
  object { argument { name: "key" } }
  condition {
    url_pattern: "pages/dopurgetrashitem.action"
    parameter { name_pattern: "confirm" }
    method: POST
  }
  detail { name: "Content ID"  argument { name: "contentId" } }
  detail {
    name: "Type"
    name: "Title"
    phase: BEFORE
    transformer_name: "TrashContentParametersByIdTransformer"
    argument { name: "key" }
    argument { name: "contentId" }
  }
}

event {
  category: "Trash"
  summary: "Space trash purged"
  object { argument { name: "key" } }
  condition {
    url_pattern: "pages/doemptytrash.action"
    parameter { name_pattern: "confirm" }
    method: POST
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail {
    name: "Deleted items count"
    name: "Deleted items"
    phase: BEFORE
    transformer_name: "TrashContentBySpaceKeyTransformer"
    argument { name: "key" }
  }
}


# Space admin > Content Tools > Export

event {
  category: "Spaces"
  summary: "Space export started"
  object { argument { name: "key" } }
  condition {
    url_pattern: "spaces/doexportspace.action"
    parameter { name_pattern: "confirm"  value_pattern: "Export" }
    method: POST
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail { name: "Export format"  argument { name: "exportType" } }
  detail {
    name: "Export type"
    name: "Include comments"
    name: "Exported pages"
    name: "Excluded pages"
    transformer_name: "SpaceExportParametersTransformer"
    argument { name: "contentOption" }
    argument { name: "includeComments" }
    argument { name: "contentToBeExported" }
    argument { name: "contentToBeExcluded" }
  }
}

event {
  category: "Spaces"
  summary: "Space export started"
  object { argument { name: "key" } }
  condition {
    url_pattern: "spaces/flyingpdf/doflyingpdf.action"
    parameter { name_pattern: "confirm"  value_pattern: "Export" }
    method: POST
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail { name: "Export format" argument { name: "PDF" source: CONST } }
  detail {
    name: "Export type"
    name: "Include comments"
    name: "Exported pages"
    name: "Excluded pages"
    transformer_name: "SpaceExportParametersTransformer"
    argument { name: "contentOption" }
    argument { name: "includeComments" }
    argument { name: "contentToBeExported" }
    argument { name: "contentToBeExcluded" }
  }
  detail {
    name: "Include Page Numbers"
    argument { name: "addPageNumbers" }
    transformer_name: "FalseIfNullTransformer"
  }
}

# Space admin > Content Tools > Import

event {
  category: "Spaces"
  summary: "Pages imported from directory"
  object { argument { name: "key" } }
  condition {
    url_pattern: "spaces/doimportpages.action"
    parameter { name_pattern: "import"  value_pattern: "Import" }
    method: POST
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "key" }
  }
  detail { name: "Import directory"  argument { name: "directory" } }
  detail {
    name: "Trim file extensions"
    transformer_name: "FalseIfNullTransformer"
    argument { name: "trimExtension" }
  }
  detail {
    name: "Overwrite existing pages"
    transformer_name: "FalseIfNullTransformer"
    argument { name: "overwriteExisting" }
  }
}



### Look & Feel events - Spaces

# Space Admin > Look and Feel > Themes > Choose new theme > Confirm
event {
  category: "Look & Feel"
  summary: "Space theme changed"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/dochoosetheme.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { name: "Space key"  argument { name: "key" } }
  detail {
    name: "Theme key"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceThemeNameTransformer"
    argument { name: "key" }
  }
}

# Space Admin > Look and Feel > Colour Schemes > Global Colour Scheme > Select
event {
  category: "Look & Feel"
  summary: "Global color scheme selected for space"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/dochangecolourscheme.action"
    parameter { name_pattern: "global" }
    method: POST
  }
}

# Space Admin > Permissions > Restricted Pages > Remove Restrictions
event {
  category: "Pages"
  summary: "Page permission removed"
  object { transformer_name: "PageTitleByIdTransformer"  argument { name: "pageId" } }
  condition { url_pattern: "pages/removepagepermission.action"  method: GET }
  detail { name: "Page ID"  argument { name: "pageId" } }
  detail {
    name: "Permission type"
    name: "Group"
    name: "User"
    phase: BEFORE
    transformer_name: "PagePermissionParametersByIdTransformer"
    argument { name: "pageId" }
    argument { name: "permissionId" }
  }
}

# Space Admin > Look and Feel > Colour Schemes > Theme Colour Scheme > Select
event {
  category: "Look & Feel"
  summary: "Space theme color scheme selected"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/dochangecolourscheme.action"
    parameter { name_pattern: "theme" }
    method: POST
  }
}

# Space Admin > Look and Feel > Colour Schemes > Custom Colour Scheme > Select
event {
  category: "Look & Feel"
  summary: "Custom space color scheme selected"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/dochangecolourscheme.action"
    parameter { name_pattern: "custom" }
    method: POST
  }
}

# Space Admin > Look and Feel > Colour Schemes > Custom Colour Scheme > Edit > Save
event {
  category: "Look & Feel"
  summary: "Custom space color scheme edited"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/doeditcolourscheme.action"
    parameter { name_pattern: "confirm" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Top bar"
    name: "Top bar text"
    name: "Header button background"
    name: "Header button text"
    name: "Top bar menu selected background"
    name: "Top bar menu selected text"
    name: "Top bar menu item text"
    name: "Menu item selected background"
    name: "Menu item selected text"
    name: "Search field background"
    name: "Search field text"
    name: "Page menu selected background"
    name: "Page menu item text"
    name: "Heading text"
    name: "Space name text"
    name: "Links"
    name: "Borders and dividers"
    name: "Tab navigation background"
    name: "Tab navigation text"
    name: "Tab navigation background highlight"
    name: "Tab navigation text highlight"
    phase: BEFORE_AND_AFTER
    transformer_name: "OldColorSchemeColorsBySpaceKeyTransformer"
    argument { name: "key" }
  }
}

# Space Admin > Look and Feel > Colour Schemes > Custom Colour Scheme > Edit > Reset
event {
  category: "Look & Feel"
  summary: "Custom space color scheme reset"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/doeditcolourscheme.action"
    parameter { name_pattern: "resetDefaults" }
    method: POST
  }
}

# Space Admin > Look and Feel > Layouts > Edit/Create custom
event {
  category: "Look & Feel"
  summary: "Space layout edited"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/storedecorator.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Decorator name"
    argument { name: "decoratorName" }
    transformer_name: "LayoutDecoratorUiNameBySystemNameTransformer"
  }
  detail {
    name: "Layout body"
    phase: BEFORE_AND_AFTER
    transformer_name: "LayoutDecoratorBodyByNameTransformer"
    argument { name: "decoratorName" }
    argument { name: "key" }
  }
}

# Space Admin > Look and Feel > Layouts > Reset default
event {
  category: "Look & Feel"
  summary: "Space layout reset to default"
  object { argument { name: "key" } }
  condition { url_pattern: "/spaces/resetdecorator.action"  method: GET }
  detail {
    name: "Decorator name"
    argument { name: "decoratorName" }
    transformer_name: "LayoutDecoratorUiNameBySystemNameTransformer"
  }
  detail {
    name: "Layout body"
    phase: BEFORE_AND_AFTER
    transformer_name: "LayoutDecoratorBodyByNameTransformer"
    argument { name: "decoratorName" }
    argument { name: "key" }
  }
}

# Space Admin > Look and Feel > Stylesheet > Edit
event {
  category: "Look & Feel"
  summary: "Space stylesheet edited"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/doeditstylesheet.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Stylesheet"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceStylesheetTransformer"
    argument { name: "key" }
  }
}

# Space Admin > Look and Feel > Sidebar, header and footer > Save
event {
  category: "Look & Feel"
  summary: "Space custom page settings updated"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/docustompagecontent.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Sidebar"
    name: "Header"
    name: "Footer"
    transformer_name: "SpaceCustomPageSettingsByKeyTransformer"
    argument { name: "key" }
    phase: BEFORE_AND_AFTER
  }
}

# Space Admin > Look and Feel > PDF Layout > Edit > Save
event {
  category: "Look & Feel"
  summary: "Space PDF layout updated"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/flyingpdf/doeditpdflayoutconfig.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    method: POST
  }
  detail { name: "PDF space export title page"  argument { name: "titlePage" } }
  detail { name: "PDF space export header"  argument { name: "header" } }
  detail { name: "PDF space export title footer"  argument { name: "footer" } }
}

# Space Admin > PDF Stylesheet > Edit > Save
event {
  category: "Look & Feel"
  summary: "Space PDF stylesheet updated"
  object { argument { name: "key" } }
  condition {
    url_pattern: "/spaces/flyingpdf/doeditpdfstyleconfig.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    method: POST
  }
  detail { name: "PDF export stylesheet"  argument { name: "style" } }
}

# Space Admin > Change space logo > Logo > ON
event {
  category: "Look & Feel"
  summary: "Space logo enabled"
  object { argument { name: "key" } }
  condition { url_pattern: "/spaces/enablespacelogo.action"  method: GET }
}

# Space Admin > Change space logo > Logo > OFF
event {
  category: "Look & Feel"
  summary: "Space logo disabled"
  object { argument { name: "key" } }
  condition { url_pattern: "/spaces/disablespacelogo.action"  method: GET }
}

# Space Admin > Change space logo > Upload logo
event {
  category: "Look & Feel"
  summary: "Space logo edited"
  object { argument { name: "key" } }
  condition { url_pattern: "/spaces/uploadspacelogo.action"  method: POST }
}

# Space Admin > Change space logo > Delete space logo
event {
  category: "Look & Feel"
  summary: "Space logo deleted"
  object { argument { name: "key" } }
  condition { url_pattern: "/spaces/deletespacelogo.action"  method: GET }
}

# Space Admin > Space Tools > Configure Sidebar > Edit space details
event {
  category: "Look & Feel"
  summary: "Space details edited"
  object { argument { name: "spaceKey" } }
  condition { url_pattern: "/space/setLogo"  condition_name: "ContainsChangedDetailsCondition"  method: POST }
  detail {
    name: "Space name"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Logo download path"
    phase: BEFORE_AND_AFTER
    transformer_name: "SpaceLogoTransformer"
    argument { name: "spaceKey" }
  }
}

# Space Tools > Look and Feel > Colour Scheme > Edit > Reset
event {
  category: "Look & Feel"
  summary: "Space global color scheme reset"
  object { argument { name: "1"  source: URL } }
  condition {
    url_pattern: "/rest/api/space/([^/]+)/color-scheme/type/?"
    method: PUT
    parameter { name_pattern: "type"  value_pattern: "global" }
  }
}

# Space Tools > Look and Feel > Colour Scheme > Edit > Save
event {
  category: "Look & Feel"
  summary: "Space global color scheme edited"
  object { argument { name: "1"  source: URL } }
  condition {
    url_pattern: "/rest/api/space/([^/]+)/color-scheme/?"
    condition_name: "ContainsChangedDetailsCondition"
    method: PUT
  }
  detail {
    name: "Space name"
    argument { name: "1" source: URL }
    transformer_name: "SpaceNameByKeyTransformer"
  }
  detail {
    name: "Header (Light theme)"
    name: "Header items (Light theme)"
    name: "Header item hover background (Light theme)"
    name: "Header item hover text (Light theme)"
    name: "Header button (Light theme)"
    name: "Header button text (Light theme)"
    name: "Search field background (Light theme)"
    name: "Search field text (Light theme)"
    name: "Menu item text (Light theme)"
    name: "Menu item hover background (Light theme)"
    name: "Menu item hover text (Light theme)"
    name: "Heading text (Light theme)"
    name: "Links (Light theme)"
    argument { name: "1" source: URL }
    phase: BEFORE_AND_AFTER
    transformer_name: "NewColorSchemeColorsBySpaceKeyTransformer"
  }
  detail {
   name: "Header (Dark theme)"
   name: "Header items (Dark theme)"
   name: "Header item hover background (Dark theme)"
   name: "Header item hover text (Dark theme)"
   name: "Header button (Dark theme)"
   name: "Header button text (Dark theme)"
   name: "Search field background (Dark theme)"
   name: "Search field text (Dark theme)"
   name: "Menu item text (Dark theme)"
   name: "Menu item hover background (Dark theme)"
   name: "Menu item hover text (Dark theme)"
   name: "Heading text (Dark theme)"
   name: "Links (Dark theme)"
    argument { name: "1" source: URL }
    phase: BEFORE_AND_AFTER
    transformer_name: "NewDarkColorSchemeColorsBySpaceKeyTransformer"
  }
}

# Space Admin > Space Tools > Integrations > Application Links
event {
  category: "Spaces"
  summary: "Space application link updated"
  object { argument { name: "1"  source: URL } }
  condition {
    url_pattern: "/rest/applinks/[^/]+/entitylink/com.atlassian.applinks.api.application.confluence.ConfluenceSpaceEntityType/([^/]+)$"
    method: PUT
    parameter { name_pattern: "iconUrl"  value_pattern: ".+" }
    condition_name: "ContainsChangedDetailsCondition"
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "applicationId" }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByKeyTransformer"
    argument { name: "typeId" }
  }
  detail { name: "Link key"  argument { name: "key" } }
  detail {
    name: "Link name"
    transformer_name: "SpaceLinkByKeyTransformer"
    phase: BEFORE_AND_AFTER
    argument { name: "key" }
    argument { name: "1"  source: URL }
  }
  processing: SYNC
}

event {
  category: "Spaces"
  summary: "Space application link added"
  object { argument { name: "1"  source: URL } }
  condition {
    url_pattern: "/rest/applinks/[^/]+/entitylink/com.atlassian.applinks.api.application.confluence.ConfluenceSpaceEntityType/([^/]+)$"
    method: PUT
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "applicationId" }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByKeyTransformer"
    argument { name: "typeId" }
  }
  detail { name: "Link key"  argument { name: "key" } }
  detail { name: "Link name"  argument { name: "name" } }
}

event {
  category: "Spaces"
  summary: "Space application link set as primary"
  object { argument { name: "1" source: URL } }
  condition {
    url_pattern: "/rest/applinks/[^/]+/entitylink/primary/com.atlassian.applinks.api.application.confluence.ConfluenceSpaceEntityType/([^/]+)/?$"
    method: POST
  }
  detail {
    name: "Space key"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "applicationId" }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByKeyTransformer"
    argument { name: "typeId" }
  }
  detail { name: "Link key"  argument { name: "key" } }
  detail {
    name: "Link name"
    transformer_name: "SpaceLinkByKeyTransformer"
    argument { name: "key" }
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Spaces"
  summary: "Space application link deleted"
  object { argument { name: "1"  source: URL } }
  condition {
    url_pattern: "/rest/applinks/[^/]+/entitylink/com.atlassian.applinks.api.application.confluence.ConfluenceSpaceEntityType/([^/]+)$"
    method: DELETE
  }
  detail {
    name: "Space name"
    transformer_name: "SpaceNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "applicationId" }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByKeyTransformer"
    argument { name: "typeId" }
  }
  detail { name: "Link key"  argument { name: "key" } }
  detail {
    name: "Link name"
    transformer_name: "SpaceLinkByKeyTransformer"
    phase: BEFORE
    argument { name: "key" }
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Current primary link"
    transformer_name: "PrimarySpaceApplicationLinkTransformer"
    argument { name: "1"  source: URL }
    argument { name: "username" source: AUTHOR }
  }
}

### Page related events

# Page > Restrictions
event {
  category: "Pages"
  summary: "Page permissions updated"
  object { transformer_name: "PageTitleByIdTransformer"  argument { name: "contentId" } }
  condition {
    url_pattern: "pages/setcontentpermissions.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { name: "Page ID"  argument { name: "contentId" } }
  detail {
    name: "Groups that can view"
    name: "Users that can view"
    name: "Groups that can edit"
    name: "Users that can edit"
    phase: BEFORE_AND_AFTER
    transformer_name: "PagePermissionsByIdTransformer"
    argument { name: "contentId" }
  }
}

event {
  category: "Pages"
  summary: "Page permissions updated"
  object { transformer_name: "PageTitleByIdTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern:  "/rest/access/latest/page/restriction/([^/]+)/grant/(view|edit)/?"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { 
    name: "Page ID"
    argument { name: "1"  source: URL }
  }
  detail {
    # Only "Users that can view" and "Users that can edit" will be used.
    # Other names are used to pass precondition in RequestProcessorImpl.createEvent(EventConfig, RequestData),
    # when PagePermissionsByIdTransformer is used, which returns 4 detail values.
    name: "Groups that can view"
    name: "Users that can view"
    name: "Groups that can edit"
    name: "Users that can edit"
    phase: BEFORE_AND_AFTER
    transformer_name: "PagePermissionsByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

### User related events

# Confluence administration > Users & Security > Users > Add user
event {
  category: "Users"
  summary: "User added"
  object { argument { name: "username" } }
  condition { url_pattern: "/admin/users/docreateuser.action"  method: POST }
  detail { name: "Username"  argument { name: "username" } }
  detail { name: "Full name"  argument { name: "fullName" } }
  detail { name: "Email"  argument { name: "email" } }
  detail { name: "Send email" argument { name: "sendEmail" } transformer_name: "FalseIfNullTransformer" }
  detail { name: "Directory" argument { name: "directoryId" } transformer_name: "DirectoryNameByIdTransformer" }
}

# Confluence administration > Users & Security > Users > View User > Edit Details
event {
  category: "Users"
  summary: "User details edited"
  object { transformer_name: "UserNameByKeyTransformer"  argument { name: "userKey" } }
  condition {
    url_pattern: "/admin/users/doedituser.action"
    parameter { name_pattern: "confirm"  value_pattern: "Submit" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { name: "Username"  phase: BEFORE_AND_AFTER  transformer_name: "UserNameByKeyTransformer"  argument { name: "userKey" } }
  detail { name: "Full name"  phase: BEFORE_AND_AFTER  transformer_name: "UsersFullNameByKeyTransformer"  argument { name: "userKey" } }
  detail { name: "Email"  phase: BEFORE_AND_AFTER  transformer_name: "UserEmailByKeyOrNameTransformer"  argument { name: "userKey" } }
  detail {
    name: "Phone"
    name: "IM"
    name: "Website"
    name: "Position"
    name: "Department"
    name: "Location"
    name: "About"
    phase: BEFORE_AND_AFTER
    transformer_name: "UserAdditionalDetailsByKeyTransformer"
    argument { name: "userKey" }
  }
}

# Confluence administration > Users & Security > Users > View User > Set Password
event {
  category: "Users"
  summary: "User password changed"
  object { argument { name: "username" } }
  condition {
    url_pattern: "/admin/users/dosetuserpassword.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    method: POST
  }
}

# Confluence administration > Users & Security > Users > View User > Disable
event {
  category: "Users"
  summary: "User disabled"
  object { argument { name: "username" } }
  condition {
    url_pattern: "/admin/users/deactivateuser-confirm.action"
    parameter { name_pattern: "confirm"  value_pattern: ".*" }
    method: POST
  }
}

# Confluence administration > Users & Security > Users > View User > Enable
event {
  category: "Users"
  summary: "User enabled"
  object { argument { name: "username" } }
  condition {
    url_pattern: "/admin/users/reactivateuser-confirm.action"
    parameter { name_pattern: "confirm"  value_pattern: ".*" }
    method: POST
  }
}

# Confluence administration > Users & Security > Users > View User > Delete
event {
  category: "Users"
  summary: "User deleted"
  object { argument { name: "username" } }
  condition {
    url_pattern: "/admin/users/removeuser-confirm.action"
    parameter { name_pattern: "confirm"  value_pattern: ".*" }
    method: POST
  }
  detail { name: "Username" argument{ name: "username" } }
  detail { name: "Full name" argument { name: "username" } transformer_name: "UserFullNameByNameTransformer" }
  detail { name: "Email" argument { name: "username" } transformer_name: "UserEmailByKeyOrNameTransformer" }
}

# Confluence administration > Users & Security > Users > View User > Edit Groups
event {
  category: "Users"
  summary: "User groups edited"
  object { argument { name: "username" } }
  condition {
    url_pattern: "/admin/users/editusergroups.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Groups"
    phase: BEFORE_AND_AFTER
    transformer_name: "UserGroupListByNameTransformer"
    argument { name: "username" }
  }
}

# Confluence administration > Users & Security > Users > Invite Users > Invitation Link > Reset
event {
  category: "Users"
  summary: "User invitation URL reset"
  object { argument { name: "User invitation URL"  source: CONST } }
  condition { url_pattern: "/rest/easyuser/[^/]+/refreshToken"  method: POST }
}

# Confluence administration > Users & Security > Users > Invite Users > Invitation Link > Reset
event {
  category: "Users"
  summary: "User invitation URL restored"
  object { argument { name: "User invitation URL"  source: CONST } }
  condition { url_pattern: "/rest/easyuser/[^/]+/undoTokenReset"  method: POST }
}

# Confluence administration > Users & Security > Users > Invite Users > Send
event {
  category: "Users"
  summary: "User invites sent"
  condition { url_pattern: "/rest/easyuser/[^/]+/sendUserInvites"  method: POST }
  detail { name: "Recipients"  argument { name: "recipientList" } }
  detail { name: "Message" argument { name: "emailMessage"} transformer_name: "NoneIfNullTransformer" }
}

# Confluence administration > Users & Security > Users > User Signup Options > Save
event {
  category: "Users"
  summary: "User signup options updated"
  object { argument { name:"User signup options"  source: CONST } }
  condition {
    url_pattern: "/easyuser/[^/]+/signup/setSignupSettings"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Allow people to sign up to create their account"
    name: "Is restricted by domain(s)"
    name: "Domain(s)"
    name: "Notify administrators by email when an account is created"
    phase: BEFORE_AND_AFTER
    transformer_name: "UserSignupOptionsTransformer"
  }
}

# Confluence administration > Users & Security > Users > Unsynced from directory > Save

event {
  category: "Users"
  summary: "User deleted"
  object {
    argument { name: "userKey" }
    transformer_name: "UsersFullNameByKeyTransformer"
    phase: BEFORE
  }
  condition {
    url_pattern: "/admin/users/removeunsynceduser-confirm.action"
    method: POST
    parameter { name_pattern: "confirm" }
  }
}



### Group related events

# Confluence administration > Users & Security > Groups > Add Group
event {
  category: "Groups"
  summary: "Group added"
  object { argument { name: "name" } }
  condition { url_pattern: "/admin/users/creategroup.action"  method: POST }
}

# Confluence administration > Users & Security > Groups > Delete
event {
  category: "Groups"
  summary: "Group deleted"
  object { argument { name: "name" } }
  condition {
    url_pattern: "/admin/users/doremovegroup.action"
    parameter { name_pattern: "confirm"  value_pattern: "Confirm" }
    method: POST
  }
  detail {
    name: "Users in group"
    phase: BEFORE
    transformer_name: "UsersByGroupNameTransformer"
    argument { name: "name" }
  }
}

# Confluence administration > Users & Security > Groups > select group > Add Members
event {
  category: "Groups"
  summary: "Users added to group"
  object { argument { name: "membersOfGroupTerm" } }
  condition {
    url_pattern: "/admin/users/adduserstogroup.action"
    method: POST
  }
  detail {
    name: "Added members"
    transformer_name: "UsersFromListByGroupTransformer"
    argument { name: "membersOfGroupTerm" }
    argument { name: "usersToAdd" }
  }
}

# Confluence administration > Users & Security > Users > Delete Profile picture
event {
  category: "Users"
  summary: "User profile picture deleted"
  object { argument { name: "username" } }
  condition {
    url_pattern: "/users/deleteuserprofilepicture-confirm.action"
    parameter { name_pattern: "confirm" }
    method: POST
  }
}

# Confluence administration > Users & Security > Groups > select group > trash bin by group member
event {
  category: "Groups"
  summary: "User deleted from group"
  object { argument { name: "membersOfGroupTerm" } }
  condition { url_pattern: "/admin/users/removeuserfromgroup.action"  method: GET }
  detail { name: "Deleted member"  argument { name: "username" } }
}


### Global configuration events

# Confluence administration > Users & Security > Security Configuration > Edit
event {
  category: "Global Configuration"
  summary: "Security configuration edited"
  object: { argument: { name: "Security configuration"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditsecurityconfig.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "External user management"
    name: "Append wildcards to user and group searches"
    name: "Hide external links from search engines"
    name: "Anonymous access to remote API"
    name: "Custom stylesheets for spaces"
    name: "Show system information on the 500 page"
    name: "User address visibility"
    name: "Maximum RSS items"
    name: "RSS timeout"
    name: "Page timeout"
    name: "CAPTCHA on login"
    name: "Login attempts threshold"
    name: "Secure administrator sessions"
    name: "Secure administrator sessions (minutes before automatic invalidation)"
    name: "Attachment download security policy"
    name: "XSRF protection adding comments"
    name: "Anti XSS mode for plugins"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalSecuritySettingsTransformer"
  }
}

# Confluence administration > Users & Security > Global Permissions > Edit permissions
event {
  category: "Global Configuration"
  summary: "Global permissions edited"
  object: { argument { name: "Global permissions"  source: CONST } }
  condition {
    url_pattern: "/admin/permissions/doeditglobalpermissions.action"
    parameter { name_pattern: "cancel"  value_pattern: "Cancel"  type: EXCLUDE }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  # Groups
  detail {
    name: "Groups that can browse"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "USECONFLUENCE"  source: CONST }
  }
  detail {
    name: "Groups that can attach files to user profile"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "PROFILEATTACHMENTS"  source: CONST }
  }
  detail {
    name: "Groups that can update user status"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "UPDATEUSERSTATUS"  source: CONST }
  }
  detail {
    name: "Groups that can create personal space"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "PERSONALSPACE"  source: CONST }
  }
  detail {
    name: "Groups that can create spaces"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "CREATESPACE"  source: CONST }
  }
  detail {
    name: "Groups that are Confluence administrators"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "ADMINISTRATECONFLUENCE"  source: CONST }
  }
  detail {
    name: "Groups that are system administrators"
    phase: BEFORE_AND_AFTER
    transformer_name: "GroupsByPermissionAndSpaceTransformer"
    argument { name: "SYSTEMADMINISTRATOR"  source: CONST }
  }
  # Users
  detail {
    name: "Users that can browse"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "USECONFLUENCE"  source: CONST }
  }
  detail {
    name: "Users that can attach files to user profile"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "PROFILEATTACHMENTS"  source: CONST }
  }
  detail {
    name: "Users that can update user status"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "UPDATEUSERSTATUS"  source: CONST }
  }
  detail {
    name: "Users that can create personal space"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "PERSONALSPACE"  source: CONST }
  }
  detail {
    name: "Users that can create spaces"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "CREATESPACE"  source: CONST }
  }
  detail {
    name: "Users that are Confluence administrators"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "ADMINISTRATECONFLUENCE"  source: CONST }
  }
  detail {
    name: "Users that are system administrators"
    phase: BEFORE_AND_AFTER
    transformer_name: "UsersByPermissionAndSpaceTransformer"
    argument { name: "SYSTEMADMINISTRATOR"  source: CONST }
  }
  # Anonymous
  detail {
    name: "Anonymous can browse"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "USECONFLUENCE"  source: CONST }
  }
  detail {
    name: "Anonymous can view user profiles"
    phase: BEFORE_AND_AFTER
    transformer_name: "AnonymousByPermissionAndSpaceTransformer"
    argument { name: "VIEWUSERPROFILES"  source: CONST }
  }
}

# Confluence administration > Users & Security > Space Permissions > Edit permissions
event {
  category: "Spaces"
  summary: "Default space permissions edited"
  object { argument { name: "Default space permissions"  source: CONST } }
  condition {
    url_pattern: "/admin/permissions/doeditdefaultspacepermissions.action"
    parameter { name_pattern: "cancel"  value_pattern: "Cancel"  type: EXCLUDE }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { name: "Groups added"  argument { name: "groupsToAdd" } }
    detail {
      name: "Groups that can view"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "VIEWSPACE"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can remove own content"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "REMOVEOWNCONTENT"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can add pages"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "EDITSPACE"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can remove pages"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "REMOVEPAGE"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can edit blog"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "EDITBLOG"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can remove blog"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "REMOVEBLOG"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can add comments"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "COMMENT"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can remove comments"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "REMOVECOMMENT"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can add attachments"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "CREATEATTACHMENT"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can remove attachments"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "REMOVEATTACHMENT"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can set restrictions"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "SETPAGEPERMISSIONS"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can remove mail"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "REMOVEMAIL"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can export space"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "EXPORTSPACE"  source: CONST }
      argument { name: "key" }
    }
    detail {
      name: "Groups that can administer space"
      phase: BEFORE_AND_AFTER
      transformer_name: "GroupsByPermissionAndSpaceTransformer"
      argument { name: "SETSPACEPERMISSIONS"  source: CONST }
      argument { name: "key" }
    }
}

# Confluence administration > Users & Security > User directories

event {
  category: "User directories"
  summary: "Crowd directory added"
  object { argument { name: "name" } }
  condition {
    url_pattern: "plugins/servlet/embedded-crowd/configure/((jira)|(crowd))/$"
    parameter { name_pattern: "save"  value_pattern: "Save.*" }
    parameter { name_pattern: "directoryId"  value_pattern: "0" }
    method: POST
  }
  detail { name: "Directory type"  argument { name: "1"  source: URL } }
  detail { name: "Name"  argument { name: "name" } }
  detail { name: "Server URL"  argument { name: "crowdServerUrl" } }
  detail { name: "Application name"  argument { name: "applicationName" } }
  detail { name: "Connection timeout (milliseconds)"  argument { name: "httpTimeout" } }
  detail { name: "Max connections"  argument { name: "httpMaxConnections" } }
  detail { name: "Proxy host"  argument { name: "httpProxyHost" } }
  detail { name: "Proxy port"  argument { name: "httpProxyPort" } }
  detail { name: "Proxy username"  argument { name: "httpProxyUsername" } }
  detail { name: "Server permissions"  argument { name: "crowdPermissionOption" } }
  detail { name: "Enable nested groups"  argument { name: "nestedGroupsEnabled" } }
  detail { name: "Enable incremental synchronisation"  argument { name: "incrementalSyncEnabled" } }
  detail { name: "Update group memberships when logging in"  argument { name: "groupSyncOnAuthMode" } }
  detail { name: "Synchronisation interval (minutes)"  argument { name: "crowdServerSynchroniseIntervalInMin" } }
}

event {
  category: "User directories"
  summary: "LDAP directory added"
  object { argument { name: "name" } }
  condition {
    url_pattern: "plugins/servlet/embedded-crowd/configure/ldap/$"
    parameter { name_pattern: "save"  value_pattern: "Save.*" }
    parameter { name_pattern: "directoryId"  value_pattern: "0" }
    method: POST
  }
  detail { name: "Name"  argument { name: "name" } }
  detail { name: "Type"  argument { name: "type" } }
  detail { name: "Hostname"  argument { name: "hostname" } }
  detail { name: "Port"  argument { name: "port" } }
  detail { name: "Use SSL"  argument { name: "useSSL" } }
  detail { name: "Username"  argument { name: "ldapUserdn" } }
  detail { name: "Base DN"  argument { name: "ldapBasedn" } }
  detail { name: "Additional user DN"  argument { name: "ldapUserDn" } }
  detail { name: "Additional group DN"  argument { name: "ldapGroupDn" } }
  detail { name: "LDAP permissions"  argument { name: "ldapPermissionOption" } }
  detail { name: "Secure SSL"  argument { name: "ldapSecure" } }
  detail { name: "Enable nested groups"  argument { name: "nestedGroupsEnabled" } }
  detail { name: "Use paged results"  argument { name: "ldapPagedresults" } }
  detail { name: "Paged results size"  argument { name: "ldapPagedresultsSize" } }
  detail { name: "Follow referrals"  argument { name: "ldapReferral" } }
  detail { name: "Naive DN matching"  argument { name: "ldapRelaxedDnStandardisation" } }
  detail { name: "Update group memberships when logging in"  argument { name: "groupSyncOnAuthMode" } }
  detail { name: "Synchronisation interval (minutes)"  argument { name: "ldapCacheSynchroniseIntervalInMin" } }
  detail { name: "Read timeout (seconds)"  argument { name: "ldapReadTimeoutInSec" } }
  detail { name: "Search timeout (seconds)"  argument { name: "ldapSearchTimelimitInSec" } }
  detail { name: "Connection timeout (seconds)"  argument { name: "ldapConnectionTimeoutInSec" } }
  detail { name: "User object class"  argument { name: "ldapUserObjectclass" } }
  detail { name: "User object filter"  argument { name: "ldapUserFilter" } }
  detail { name: "User name attribute"  argument { name: "ldapUserUsername" } }
  detail { name: "User name RDN attribute"  argument { name: "ldapUserUsernameRdn" } }
  detail { name: "User first name attribute"  argument { name: "ldapUserFirstname" } }
  detail { name: "User last name attribute"  argument { name: "ldapUserLastname" } }
  detail { name: "User display name attribute"  argument { name: "ldapUserDisplayname" } }
  detail { name: "User email attribute"  argument { name: "ldapUserEmail" } }
  # detail { name: "User password attribute"  argument { name: "ldapUserPassword" } }
  detail { name: "User password encryption"  argument { name: "ldapUserEncryption" } }
  detail { name: "User unique ID attribute"  argument { name: "ldapExternalId" } }
  detail { name: "Group object class"  argument { name: "ldapGroupObjectclass" } }
  detail { name: "Group object filter"  argument { name: "ldapGroupFilter" } }
  detail { name: "Group name attribute"  argument { name: "ldapGroupName" } }
  detail { name: "Group description attribute"  argument { name: "ldapGroupDescription" } }
  detail { name: "Group members attribute"  argument { name: "ldapGroupUsernames" } }
  detail { name: "User membership attribute"  argument { name: "ldapUserGroup" } }
  detail { name: "Use the user membership attribute when finding the user's group membership"  argument { name: "ldapUsermembershipUse" } }
  detail { name: "Use the user membership attribute when finding the members of a group"  argument { name: "ldapUsermembershipUseForGroups" } }
}

event {
  category: "User directories"
  summary: "LDAP directory updated"
  object { argument { name: "name" } }
  condition {
    url_pattern: "plugins/servlet/embedded-crowd/configure/ldap/$"
    parameter { name_pattern: "save"  value_pattern: "Save.*" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Name"
    name: "Type"
    name: "Hostname"
    name: "Username"
    name: "Base DN"
    name: "Additional user DN"
    name: "Additional group DN"
    name: "LDAP permissions"
    name: "Secure SSL"
    name: "Disable nested groups"
    name: "Use paged results"
    name: "Paged results size"
    name: "Follow referrals"
    name: "Naive DN matching"
    name: "Update group memberships when logging in"
    name: "Synchronisation interval (seconds)"
    name: "Read timeout (milliseconds)"
    name: "Search timeout (milliseconds)"
    name: "Connection timeout (milliseconds)"
    name: "User object class"
    name: "User object filter"
    name: "User name attribute"
    name: "User name RDN attribute"
    name: "User first name attribute"
    name: "User last name attribute"
    name: "User display name attribute"
    name: "User email attribute"
    name: "User password attribute"
    name: "User password encryption"
    name: "User unique ID attribute"
    name: "Group object class"
    name: "Group object filter"
    name: "Group name attribute"
    name: "Group description attribute"
    name: "Group members attribute"
    name: "User membership attribute"
    name: "Use the user membership attribute when finding the user's group membership"
    name: "Use the user membership attribute when finding the members of a group"
    phase: BEFORE_AND_AFTER
    transformer_name: "LdapDirectoryUpdateParametersByIdTransformer"
    argument { name: "directoryId" }
  }
}

event {
  category: "User directories"
  summary: "Crowd directory updated"
  object { argument { name: "name" } }
  condition {
    url_pattern: "plugins/servlet/embedded-crowd/configure/((jira)|(crowd)|(internal))/$"
    parameter { name_pattern: "save"  value_pattern: "Save.*" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Name"
    name: "Server URL"
    name: "Application name"
    name: "Connection timeout (milliseconds)"
    name: "Max connections"
    name: "Proxy host"
    name: "Proxy port"
    name: "Proxy username"
    name: "Server permissions"
    name: "Enable nested groups"
    name: "Enable incremental synchronisation"
    name: "Update group memberships when logging in"
    name: "Synchronisation interval (minutes)"
    name: "Group implementation class"
    phase: BEFORE_AND_AFTER
    transformer_name: "CrowdDirectoryUpdateParametersByIdTransformer"
    argument { name: "directoryId" }
  }
}

event {
  category: "User directories"
  summary: "Directory synchronised"
  object {  transformer_name: "DirectoryNameByIdTransformer"  argument { name: "directoryId" } }
  condition { url_pattern: "plugins/servlet/embedded-crowd/directories/sync"  method: GET }
  detail {
    name: "Directory name"
    transformer_name: "DirectoryNameByIdTransformer"
    argument { name: "directoryId" }
  }
}

event {
  category: "User directories"
  summary: "Directory enabled"
  object {  transformer_name: "DirectoryNameByIdTransformer"  argument { name: "directoryId" } }
  condition { url_pattern: "plugins/servlet/embedded-crowd/directories/enable"  method: GET }
  detail {
    name: "Directory name"
    transformer_name: "DirectoryNameByIdTransformer"
    argument { name: "directoryId" }
  }
}

event {
  category: "User directories"
  summary: "Directory disabled"
  object {  transformer_name: "DirectoryNameByIdTransformer"  argument { name: "directoryId" } }
  condition { url_pattern: "plugins/servlet/embedded-crowd/directories/disable"  method: GET }
  detail {
    name: "Directory name"
    transformer_name: "DirectoryNameByIdTransformer"
    argument { name: "directoryId" }
  }
}

event {
  category: "User directories"
  summary: "Directory tested"
  object {  transformer_name: "DirectoryNameByIdTransformer"  argument { name: "directoryId" } }
  condition { url_pattern: "plugins/servlet/embedded-crowd/directories/troubleshoot/"  method: POST }
  detail {
    name: "Directory name"
    transformer_name: "DirectoryNameByIdTransformer"
    argument { name: "directoryId" }
  }
  detail { name: "Username"  argument { name: "username" } }
}

event {
  category: "User directories"
  summary: "Directory moved up"
  object {  transformer_name: "DirectoryNameByIdTransformer"  argument { name: "directoryId" } }
  condition { url_pattern: "plugins/servlet/embedded-crowd/directories/moveUp"  method: GET }
  detail {
    name: "Directory name"
    transformer_name: "DirectoryNameByIdTransformer"
    argument { name: "directoryId" }
  }
}

event {
  category: "User directories"
  summary: "Directory moved down"
  object {  transformer_name: "DirectoryNameByIdTransformer"  argument { name: "directoryId" } }
  condition { url_pattern: "plugins/servlet/embedded-crowd/directories/moveDown"  method: GET }
  detail {
    name: "Directory name"
    transformer_name: "DirectoryNameByIdTransformer"
    argument { name: "directoryId" }
  }
}

event {
  category: "User directories"
  summary: "Directory removed"
  object {  phase: BEFORE  transformer_name: "DirectoryNameByIdTransformer"  argument { name: "directoryId" } }
  condition { url_pattern: "plugins/servlet/embedded-crowd/directories/remove"  method: GET }
  detail {
    name: "Directory name"
    phase: BEFORE
    transformer_name: "DirectoryNameByIdTransformer"
    argument { name: "directoryId" }
  }
}

event {
  category: "User directories"
  summary: "LDAP connection pool configuration updated"
  object { argument { name: "LDAP connection pool configuration"  source: CONST } }
  condition {
    url_pattern: "plugins/servlet/embedded-crowd/configure/connection-pool/"
    parameter { name_pattern: "save"  value_pattern: "Save.*" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Initial pool size"
    name: "Preferred pool size"
    name: "Maximum pool size"
    name: "Pool timeout (seconds)"
    name: "Pool protocol"
    name: "Pool authentication"
    phase: BEFORE_AND_AFTER
    transformer_name: "LdapConnectionPoolConfigurationTransformer"
  }
}


# Confluence administration > Users & Security > Whitelist

event {
  category: "Whitelist"
  summary: "Whitelist enabled"
  object { argument { name: "Whitelist"  source: CONST } }
  condition { url_pattern: "rest/whitelist/[^/]+/enable"  method: POST }
}

event {
  category: "Whitelist"
  summary: "Whitelist disabled"
  object { argument { name: "Whitelist"  source: CONST } }
  condition { url_pattern: "rest/whitelist/[^/]+/disable"  method: POST }
}

event {
  category: "Whitelist"
  summary: "Whitelist settings changed"
  object { argument { name:"Whitelist" source: CONST } }
  condition { url_pattern: "/rest/whitelist/[^/]+/settings/?$" method: PUT }
  detail {
    name: "Default settings"
    argument { name: "applicationLinkRestrictiveness" }
    transformer_name: "WhitelistDefaultSettingByKeyTransformer"
  }
}

event {
  category: "Whitelist"
  summary: "Whitelist expression added"
  object { argument { name: "expression" } }
  condition { url_pattern: "rest/whitelist/[^/]+/?$"  method: POST }
  detail { name: "Expression"  argument { name: "expression" } }
  detail {
    name: "Type"
    transformer_name: "WhitelistTypeNameByKeyTransformer"
    argument { name: "type" }
  }
  detail { name: "Allow incoming"  argument { name: "allowInbound" } }
  detail { name: "Allow anonymous users"  argument { name: "allowAnonymousUser" } }
}

event {
  category: "Whitelist"
  summary: "Whitelist expression updated"
  object { transformer_name: "WhitelistExpressionByIdTransformer"  argument { name: "id" } }
  condition {
    url_pattern: "rest/whitelist/[^/]+/(\\d+)/?$"
    method: PUT
    condition_name: "ContainsChangedDetailsCondition"
  }
  detail {
    name: "Expression"
    name: "Type"
    name: "Allow incoming"
    name: "Allow anonymous users"
    phase: BEFORE_AND_AFTER
    transformer_name: "WhitelistUpdateParametersByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Whitelist"
  summary: "Whitelist expression deleted"
  object {
    phase: BEFORE
    transformer_name: "WhitelistExpressionByIdTransformer"
    argument { name: "1"  source: URL }
  }
  condition { url_pattern: "rest/whitelist/[^/]+/(\\d+)/?$"  method: DELETE }
  detail {
    name: "Expression"
    name: "Type"
    name: "Allow incoming"
    name: "Allow anonymous users"
    phase: BEFORE
    transformer_name: "WhitelistUpdateParametersByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

# TODO: add logic to show old and new settings.
# Confluence administration > Confluence analytics > Configuration
event {
  category: "Analytics settings"
  summary: "Data retention period changed"
  object { argument { name: "Analytics settings" source: CONST } }
  condition { url_pattern: "/rest/confanalytics/[^/]+/settings/dataRetention/?$" method: PUT }
  detail {
    name: "Months"
    argument { name: "months"}
  }
}

event {
  category: "Analytics settings"
  summary: "Event retention number changed"
  object { argument { name: "Analytics settings" source: CONST } }
  condition { url_pattern: "/rest/confanalytics/[^/]+/settings/eventLimit/?$" method: PUT }
  detail {
    name: "Maximum events"
    argument { name: "maxRowCount"}
  }
}

event {
  category: "Analytics settings"
  summary: "Increased privacy mode settings changed"
  object { argument { name: "Analytics settings" source: CONST } }
  condition { url_pattern: "/rest/confanalytics/[^/]+/settings/privacy/?$" method: PUT }
  detail {
    name: "Enabled"
    argument { name: "enabled" }
  }
}

event {
  category: "Analytics settings"
  summary: "Rate limiting settings changed"
  object { argument { name: "Analytics settings" source: CONST } }
  condition { url_pattern: "/rest/confanalytics/[^/]+/settings/rateLimit/?$" method: PUT }
  detail { name: "Enabled" argument { name: "enabled" } }
  detail { name: "Maximum concurrent sessions" argument { name: "concurrentSessions" } }
  detail { name: "Maximum concurrent reports per session" argument { name: "concurrentOperationsPerSession" } }
  detail { name: "Report timeout (seconds)" argument { name: "staleOperationSeconds" } }
}

# Confluence administration > Authentication methods

event {
  category: "Authentication methods"
  summary: "Authentication on API calls settings changed"
  object {
    argument { name: "Authentication on API calls" source: CONST }
  }
  condition { url_pattern: "/rest/basicauth/[^/]+/config/?$" method: PUT }
  detail {
    name: "Enabled"
    argument { name: "block-requests" }
    transformer_name: "OppositeBooleanValueTransformer"
  }
}

# Confluence administration > Faster permissions

event {
  category: "Faster permissions"
  summary: "Faster permissions enabled"
  object {
    argument { name: "Faster permissions" source: CONST }
  }
  condition { url_pattern: "/rest/fasterpermissions/[^/]+/enableservice/?$" method: POST }
}

event {
  category: "Faster permissions"
  summary: "Faster permissions disabled"
  object {
    argument { name: "Faster permissions" source: CONST }
  }
  condition { url_pattern: "/rest/fasterpermissions/[^/]+/disableservice/?$" method: POST }
}


# Confluence administration > General Configuration > Edit
event {
  category: "Global Configuration"
  summary: "General configuration edited"
  object: { argument { name: "General configuration"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditgeneralconfig.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Site title"
    name: "Server base URL"
    name: "Contact administrators message"
    name: "Display contact administrators form"
    name: "Indexing language"
    name: "Encoding"
    name: "Time format"
    name: "Date time format"
    name: "Date format"
    name: "Long number format"
    name: "Decimal number format"
    name: "Attachment maximum size"
    name: "Maximum attachments per upload"
    name: "Compress HTTP responses"
    name: "External connections enabled"
    name: "Connection timeout (milliseconds)"
    name: "Socket timeout (milliseconds)"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalGeneralSettingsTransformer"
  }
}

# Confluence administration > Further Configuration > Edit
event {
  category: "Global Configuration"
  summary: "Further configuration edited"
  object: { argument { name: "Further configuration"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditspacesconfig.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Site homepage"
    name: "Threaded comments"
    name: "Allow trackbacks"
    name: "Allow remote API"
    name: "Enable open search"
    name: "Draft save interval (seconds)"
    name: "Enable quick navigation"
    name: "Max simultaneous quicknav requests" 
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalFurtherSettingsTransformer"
  }
}

# Confluence administration > Backup Administration
event {
  category: "Global Configuration"
  summary: "Backup settings edited"
  object: { argument { name: "Backup settings"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditdailybackupsettings.action"
    parameter { name_pattern: "confirm"  value_pattern: "Submit" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Backup file prefix"
    name: "Backup file date pattern"
    name: "Backup path"
    name: "Enable backup attachments"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalBackupSettingsTransformer"
  }
}

# Confluence administration > Languages > Edit
event {
  category: "Global Configuration"
  summary: "Languages edited"
  object: { argument { name: "Languages"  source: CONST } }
  condition {
    url_pattern: "/admin/doconfigurelanguage.action"
    parameter { name_pattern: "confirm"  value_pattern: "Submit" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Global default language"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalLanguageSettingsTransformer"
  }
}

# Confluence administration > Shortcut Links
event {
  category: "Global Configuration"
  summary: "Shortcut link added"
  object: { argument { name: "key"  } }
  condition {
    url_pattern: "/admin/createshortcut.action"
    parameter { name_pattern: "confirm"  value_pattern: "Submit" }
    method: POST
  }
  detail { name: "Expanded value"  argument { name: "shortcutLinkConfig.expandedValue" } }
  detail { name: "Default alias"  argument { name: "shortcutLinkConfig.defaultAlias" } }
}

event {
  category: "Global Configuration"
  summary: "Shortcut link deleted"
  object: { argument { name: "key"  } }
  condition { url_pattern: "/admin/removeshortcut.action"  method: GET }
  detail {
    name: "Expanded value"
    name: "Default alias"
    phase: BEFORE
    transformer_name: "ShortcutLinkDetailsByKeyTransformer"
    argument { name: "key" }
  }
}

# Confluence administration > External Gadgets
event {
  category: "Global Configuration"
  summary: "Gadget added"
  object: { argument { name: "Gadgets"  source: CONST } }
  condition { url_pattern: "/admin/addgadget.action"  method: POST }
  detail { name: "Gadget URL"  argument { name: "gadgetUrlToAdd" } }
}

event {
  category: "Global Configuration"
  summary: "Gadget deleted"
  object: { argument { name: "Gadgets"  source: CONST } }
  condition { url_pattern: "/admin/removegadget.action"  method: POST }
  detail { name: "Gadget URL"  argument { name: "gadgetUrlToRemove" } }
}

event {
  category: "Global Configuration"
  summary: "Gadget feed added"
  object: { argument { name: "Gadgets"  source: CONST } }
  condition { url_pattern: "/admin/addgadgetfeed.action"  method: POST }
  detail { name: "Gadget feed URL"  argument { name: "gadgetFeedToAdd" } }
}

event {
  category: "Global Configuration"
  summary: "Gadget feed deleted"
  object: { argument { name: "Gadgets"  source: CONST } }
  condition { url_pattern: "/admin/removegadgetfeed.action"  method: POST }
  detail {
    name: "Gadget feed URL"
    phase: BEFORE
    transformer_name: "GadgetFeedUrlByIdTransformer"
    argument { name: "gadgetFeedToRemove" }
  }
}



# Confluence administration > Global Templates and Blueprints

event {
  category: "Global Configuration"
  summary: "Global page template added"
  object { argument { name: "title" } }
  condition {
    url_pattern: "pages/templates2/docreatepagetemplate.action"
    parameter { name_pattern: "cancel"  value_pattern: "cancel"  type: EXCLUDE }
    parameter { name_pattern: "key"  value_pattern: ".+"  type: EXCLUDE }
    method: POST
  }
  detail { name: "Template title"  argument { name: "title" } }
  detail { name: "Template content"  argument { name: "wysiwygContent" } }
}


event {
  category: "Global Configuration"
  summary: "Global page template updated"
  object {
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "entityId" }
  }
  condition {
    url_pattern: "pages/templates2/doeditpagetemplate(description)?.action"
    parameter { name_pattern: "cancel"  value_pattern: "cancel"  type: EXCLUDE }
    parameter { name_pattern: "key"  value_pattern: ".+"  type: EXCLUDE }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Template name"
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "entityId" }
  }
  detail {
    name: "Template title"
    name: "Template description"
    name: "Template body type"
    name: "Template content"
    phase: BEFORE_AND_AFTER
    transformer_name: "PageTemplateUpdateParametersByIdTransformer"
    argument { name: "entityId" }
  }
}

event {
  category: "Global Configuration"
  summary: "Global page template deleted"
  object {
    phase: BEFORE
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "entityId" }
  }
  condition {
    url_pattern: "pages/templates2/doremovepagetemplate.action"
    parameter { name_pattern: "spaceKey"  value_pattern: ".+"  type: EXCLUDE }
    method: POST
  }
  detail {
    name: "Template name"
    phase: BEFORE
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "entityId" }
  }
}

event {
  category: "Global Configuration"
  summary: "Global space blueprint enabled"
  condition {
    url_pattern: "rest/create-dialog/[^/]+/modules/space-blueprint/([^/]+)"
    method: PUT
  }
  detail { name: "Blueprint ID"  argument { name: "1"  source: URL } }
  # TODO: get blueprint name by ID
}

event {
  category: "Global Configuration"
  summary: "Global space blueprint disabled"
  condition {
    url_pattern: "rest/create-dialog/[^/]+/modules/space-blueprint/([^/]+)"
    method: DELETE
  }
  detail { name: "Blueprint ID"  argument { name: "1"  source: URL } }
  # TODO: get blueprint name by ID
}

event {
  category: "Global Configuration"
  summary: "Global page blueprint enabled"
  object {
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
  condition {
    url_pattern: "rest/create-dialog/[^/]+/modules/([^/]+)"
    method: PUT
    parameter { name_pattern: "spaceKey"  value_pattern: ".+"  type: EXCLUDE }
  }
  detail {
    name: "Blueprint name"
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Global Configuration"
  summary: "Global page blueprint disabled"
  object {
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
  condition {
    url_pattern: "rest/create-dialog/[^/]+/modules/([^/]+)"
    method: DELETE
    parameter { name_pattern: "spaceKey"  value_pattern: ".+"  type: EXCLUDE }
  }
  detail {
    name: "Blueprint name"
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Global Configuration"
  summary: "Global page blueprint template enabled"
  object {
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
  condition {
    url_pattern: "rest/create-dialog/[^/]+/promotion/promote-blueprint/([^/]+)"
    method: DELETE
    parameter { name_pattern: "spaceKey"  value_pattern: ".+"  type: EXCLUDE }
  }
  detail {
    name: "Template name"
    transformer_name: "BlueprintNameByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Global Configuration"
  summary: "Global page blueprint template edited"
  object { argument { name: "title" } }
  condition {
    url_pattern: "plugins/createcontent/do-edit-template.action"
    parameter { name_pattern: "spaceKey"  value_pattern: ".+"  type: EXCLUDE }
    method: POST
  }
  detail { name: "Template name"  argument { name: "title" } }
  detail { name: "Template body"  argument { name: "wysiwygContent" } }
  # TODO: add BEFORE_AND_AFTER template body comparison
}

event {
  category: "Global Configuration"
  summary: "Global page blueprint template reset to default"
  object {
    phase: BEFORE
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "entityId" }
  }
  condition {
    url_pattern: "plugins/createcontent/revert-template.action"
    method: GET
    parameter { name_pattern: "key"  value_pattern: ".+"  type: EXCLUDE }
  }
  detail {
    name: "Category"
    transformer_name: "PageTemplateCategoryByIdTransformer"
    argument { name: "entityId" }
    phase: BEFORE
  }
  detail {
    name: "Template name"
    phase: BEFORE
    transformer_name: "PageTemplateNameByIdTransformer"
    argument { name: "entityId" }
  }
}

# Confluence administration > Recommended Updates Email
event {
  category: "Global Configuration"
  summary: "Recommended updates email settings updated"
  object: { argument { name: "Recommended updates email settings"  source: CONST } }
  condition { url_pattern: "rest/daily-summary-email/[^/]+/admin/"  method: PUT }
  detail { name: "Default schedule"  argument { name: "defaultSchedule" } }
  detail { name: "Send by default"  argument { name: "defaultEnabled" } }
}

# Confluence administration > Spam Prevention > Captcha on/off
event {
  category: "Global Configuration"
  summary: "Attachment storage updated"
  object: { argument { name: "Attachment storage"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditattachmentstorage.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Attachment storage"
    phase: BEFORE_AND_AFTER
    transformer_name: "AttachmentStorageTransformer"
  }
}

# Confluence administration > Spam Prevention > Captcha on/off
event {
  category: "Global Configuration"
  summary: "Captcha enabled"
  object: { argument { name: "Captcha configuration"  source: CONST } }
  condition {
    url_pattern: "/admin/doconfigurecaptcha.action"
    method: GET
    parameter { name_pattern: "captchaEnabled"  value_pattern: "true" }
  }
}
event {
  category: "Global Configuration"
  summary: "Captcha disabled"
  object: { argument { name: "Captcha configuration"  source: CONST } }
  condition {
    url_pattern: "/admin/doconfigurecaptcha.action"
    method: GET
    parameter { name_pattern: "captchaEnabled"  value_pattern: "false" }
  }
}

event {
  category: "Global Configuration"
  summary: "Captcha exclusions updated"
  object: { argument { name: "Captcha configuration"  source: CONST } }
  condition {
    url_pattern: "/admin/doconfigurecaptcha.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Exclude from captchas"
    name: "Groups"
    phase: BEFORE_AND_AFTER
    transformer_name: "CaptchaExcludeSettingsTransformer"
  }
}


### Administration events


# Confluence administration > Collaborative editing
event {
  category: "Administration"
  summary: "Synchrony restarted"
  object: { argument { name: "Synchrony"  source: CONST } }
  condition { url_pattern: "rest/synchrony-interop/restart$"  method: POST }
}

event {
  category: "Administration"
  summary: "Collaborative editing mode enabled"
  object: { argument { name: "Collaborative editing configuration"  source: CONST } }
  condition { url_pattern: "/rest/synchrony-interop/enable/?$" method: POST }
}

event {
  category: "Administration"
  summary: "Collaborative editing mode disabled"
  object: { argument { name: "Collaborative editing configuration"  source: CONST } }
  condition { url_pattern: "/rest/synchrony-interop/disable/?$" method: POST }
}

# Confluence administration > Collaborative editing feedback reports
# TODO: Add logic to show old and new value.
event {
  category: "Administration"
  summary: "Collaborative editing feedback reports settings updated"
  object: { argument { name: "Collaborative editing feedback reports" source: CONST } }
  condition { url_pattern: "/rest/collaborative-editing/feedback/[^/]+/settings/?$" method: POST }
  detail {
    name: "Allow users to report editor problems"
    argument { name: "editorReportsEnabled" }
  }
}

event {
  category: "Administration"
  summary: "Feedback report created"
  object: { argument { name: "Feedback report" source: CONST } }
  condition { url_pattern: "/rest/collaborative-editing/feedback/[^/]+/collect/(\\d+)/?$" method: PUT }
  detail { name: "Page ID" argument { name : "1" source : URL } }
  detail {
    name: "Page title"
    argument { name: "1" source: URL }
    transformer_name: "PageTitleByIdTransformer"
  }
}

event {
  category: "Administration"
  summary: "Feedback report deleted"
  object: { argument { name: "Feedback report" source: CONST } }
  condition { url_pattern: "/rest/collaborative-editing/feedback/[^/]+/file/?$" method: DELETE }
  detail {
    name: "Page ID"
    name: "Page title"
    name: "Creation time"
    transformer_name: "PageDetailsByFeedbackReportFileNameTransformer"
    argument { name: "fileName" }
  }
  detail {
    name: "File name"
    argument { name: "fileName" }
  }
}


# Confluence administration > Backup & Restore > Back Up
event {
  category: "Administration"
  summary: "Confluence data backup created"
  object: { argument { name: "Confluence backup"  source: CONST } }
  condition { url_pattern: "/admin/dobackup.action"  method: GET }
  detail { name: "Archive to backups folder"  transformer_name: "FalseIfNullTransformer"  argument { name: "archiveBackup" } }
  detail { name: "Back up attachments"  transformer_name: "FalseIfNullTransformer"  argument { name: "backupAttachments" } }
}

# Confluence 7.2
# Confluence administration > Backup & Restore > Back Up
event {
  category: "Administration"
  summary: "Confluence data backup created"
  object: { argument { name: "Confluence backup"  source: CONST } }
  condition { url_pattern: "/admin/dobackup.action"  method: POST }
  detail { name: "Archive to backups folder"  transformer_name: "FalseIfNullTransformer"  argument { name: "archiveBackup" } }
  detail { name: "Back up attachments"  transformer_name: "FalseIfNullTransformer"  argument { name: "backupAttachments" } }
}

# Confluence 8.0
# TODO: Add backup finished event after upgrading Confluence min supported version to 7.17.0
# TODO: Use com.atlassian.confluence.impl.backuprestore.ConfluenceBackupRestoreManager

# Confluence administration > Backup & Restore > Back Up
event {
  category: "Administration"
  summary: "Confluence site data backup creation process started"
  object: { argument {name: "Confluence backup" source : CONST } }
  condition { url_pattern: "/rest/api/backup-restore/backup/site/?$" method: POST }
  detail { name: "File name prefix" argument { name: "fileNamePrefix" } }
  detail { name: "Keep permanently" argument { name: "keepPermanently" } }
  detail { name: "Skip attachments" argument { name: "skipAttachments" } }
}

# Confluence administration > Backup & Restore > Back Up
event {
  category: "Administration"
  summary: "Confluence spaces data backup creation process started"
  object: { argument {name: "Confluence backup" source : CONST } }
  condition { url_pattern: "/rest/api/backup-restore/backup/space/?$" method: POST }
  detail { name: "File name prefix" argument { name: "fileNamePrefix" } }
  detail { name: "Keep permanently" argument { name: "keepPermanently" } }
  detail { name: "Spaces" argument { name: "spaceKeys" } transformer_name: "SpaceNamesByKeysTransformer" }
  detail { name: "Space keys" argument { name: "spaceKeys"} }
}

# TODO: Add logic to track stopped/finished events.
# Confluence administration > Backup & Restore > Restore
event {
  category: "Administration"
  summary: "Confluence spaces restore from backup process started"
  object: { argument { name: "Confluence backup" source: CONST } }
  condition { url_pattern: "/rest/api/backup-restore/restore/space(/upload)?/?$" method: POST }
  detail { name: "File name" argument { name: "fileName" } }
}

# TODO: Add logic to track stopped/finished events.
# Confluence administration > Backup & Restore > Restore
event {
  category: "Administration"
  summary: "Confluence site restore from backup process started"
  object: { argument { name: "Confluence backup" source: CONST } }
  condition { url_pattern: "/rest/api/backup-restore/restore/site/(upload)?/?$" method: POST }
  detail { name: "File name" argument { name: "fileName" } }
}

# TODO: Use com.atlassian.confluence.impl.backuprestore.ConfluenceBackupRestoreManager to provide more details about the Job.
event {
  category: "Administration"
  summary: "Confluence data backup creation process canceled"
  object: { argument { name: "Confluence backup" source: CONST } }
  condition {
    url_pattern: "/rest/api/backup-restore/jobs/(\\d+)/cancel/?$"
    method: PUT
  }
  detail { name: "Job id" argument { name: "1" source: URL } }
}

# Confluence administration > Content Delivery Network
# TODO: Add logic to show old and new values.
event {
  category: "Administration"
  summary: "Content delivery network settings updated"
  object: { argument { name: "Content Delivery Network" source: CONST } }
  condition {
    url_pattern: "/rest/static-asset-caching/configuration/?$"
    method: PUT
  }
  detail { name: "Enabled" argument { name: "enabled"} }
  detail { name: "URL" argument { name: "url"} }
}

# Confluence administration > Backup & Restore > Restore Confluence Data > Upload and Restore
# TODO: This entry gets removed once the asynchronous restore is done, so this does nothing.
#       Think of some way to make this survive backup restore.
event {
  category: "Administration"
  summary: "Backup restored from uploaded file"
  object: { argument { name: "Confluence backup"  source: CONST } }
  condition { url_pattern: "/admin/restore.action"  method: POST }
}

# Confluence administration > Content reindex
event {
  category: "Administration"
  summary: "Spaces re-indexed"
  object: { argument { name: "Spaces" source: CONST } }
  condition {
    url_pattern: "/rest/prototype/[^/]+/index/reindex/?$"
    method: POST
    parameter { name_pattern: "spaceKey" }
  }
  detail {
    name: "Space keys"
    argument { name: "spaceKey" }
  }
  detail {
    name: "Space names"
    argument { name: "spaceKey" }
    transformer_name: "SpaceNamesByKeysTransformer"
  }
}

# Confluence administration > Data pipeline
# TODO: Add logic to show old and new detail values.
event {
  category: "Administration"
  summary: "Data pipeline schedule settings changed"
  object: { argument { name: "Data pipeline" source: CONST } }
  condition {
    url_pattern: "/rest/datapipeline/[^/]+/config/schedule/?$"
    method: PUT
  }
  detail { name: "Repeat every (weeks)" argument { name : "repeatIntervalInWeeks" } }
  detail { name: "Repeat on (days)" argument { name: "days" } }
  detail { name: "Repeat at (time)" argument { name: "time" } }
  # Showing date without time, because time is always 00:00:00.
  detail { name: "Include data from" argument { name: "fromDate" } transformer_name: "DateWithoutTimeTransformer" }
  detail { name: "Schema version" argument { name: "schemaVersion" } }
}

event {
  category: "Administration"
  summary: "Data pipeline schedule disabled"
  object: { argument { name: "Data pipeline" source: CONST } }
  condition {
    url_pattern: "/rest/datapipeline/[^/]+/config/schedule/?$"
    method: DELETE
  }
}

event {
  category: "Administration"
  summary: "Site re-indexed"
  object: { argument { name: "Site" source: CONST } }
  condition { url_pattern: "/rest/prototype/[^/]+/index/reindex/?$" method: POST }
}

# Confluence administration > Backup & Restore > Restore Confluence Data > Restore
# TODO: This entry gets removed once the asynchronous restore is done, so this does nothing.
#       Think of some way to make this survive backup restore.
event {
  category: "Administration"
  summary: "Backup restored from local file"
  object: { argument { name: "Confluence backup"  source: CONST } }
  condition { url_pattern: "/admin/restore-local-file.action"  method: POST }
  detail { name: "File name"  argument { name: "localFileName" } }
  detail { name: "Build index"  argument { name: "buildIndex" } }
}

# Confluence administration > Content Indexing > Search Index > Rebuild
event {
  category: "Administration"
  summary: "Search index rebuilt"
  object: { argument { name: "Search index"  source: CONST } }
  condition { url_pattern: "/admin/reindex.action"  method: POST }
}

# Confluence administration > Mail Queue > Flush Mail Queue
event {
  category: "Administration"
  summary: "Mail queue flushed"
  object: { argument { name: "Mail queue"  source: CONST } }
  condition { url_pattern: "/admin/mail/flushqueue.action"  method: GET }
}

# Confluence administration > Mail Queue > Error Queue > Flush Mail Queue
event {
  category: "Administration"
  summary: "Error queue resent"
  object: { argument { name: "Mail queue"  source: CONST } }
  condition { url_pattern: "/admin/mail/resenderrorqueue.action"  method: GET }
}

# Confluence administration > Mail Queue > Error Queue > Delete Mail Queue
event {
  category: "Administration"
  summary: "Error queue deleted"
  object: { argument { name: "Mail queue"  source: CONST } }
  condition { url_pattern: "/admin/mail/deleteerrorqueue.action"  method: GET }
}

# Confluence administration > Scheduled jobs > Run
event {
  category: "Administration"
  summary: "Scheduled job run"
  object: { argument { name: "id" } transformer_name: "ScheduledJobNameByIdTransformer" }
  condition { url_pattern: "/admin/scheduledjobs/runJob.action"  method: GET }
  detail { name: "Job ID" argument { name: "id" } }
}

# For Confluence 9+
# Confluence administration > Scheduled jobs > Edit
event {
  category: "Administration"
  summary: "Job schedule edited"
  object: { argument { name: "id" } transformer_name: "ScheduledJobNameByIdTransformer" }
  condition {
    url_pattern: "/admin/scheduledjobs/change(((Cron)|(Simple))Job)?Schedule.action"
    method: POST
    method: GET
  }
  detail {
    name: "Cron expression"
    phase: BEFORE_AND_AFTER
    transformer_name: "JobScheduleByIdTransformer"
    argument { name: "group" }
    argument { name: "id" }
  }
  detail {
    name: "Job interval (seconds)"
    argument { name: "repeatInterval" }
  }
  # TODO: get previous interval
  # https://bitbucket.org/enhancera/auditor/issues/470/confluence-add-previous-job-schedule
}

# Confluence administration > Scheduled jobs > Disable
event {
  category: "Administration"
  summary: "Scheduled job disabled"
  object: { argument { name: "id" } transformer_name: "ScheduledJobNameByIdTransformer" }
  condition { url_pattern: "/admin/scheduledjobs/disableJob.action"  method: GET }
}

# Confluence administration > Scheduled jobs > Enable
event {
  category: "Administration"
  summary: "Scheduled job enabled"
  object: { argument { name: "id" } transformer_name: "ScheduledJobNameByIdTransformer" }
  condition { url_pattern: "/admin/scheduledjobs/enableJob.action"  method: GET }
}

# Confluence administration > Troubleshooting and support

event {
  category: "Troubleshooting and support"
  summary: "Instance health check value enabled"
  object: { argument { name: "healthCheckKey"} transformer_name: "HealthCheckNameByKeyTransformer" }
  condition {
    url_pattern: "/rest/troubleshooting/[^/]+/setEnabled/?$"
    parameter { name_pattern: "enabled"  value_pattern: "true" }
    method: POST
  }
}

event {
  category: "Troubleshooting and support"
  summary: "Instance health check value disabled"
  object: { argument { name: "healthCheckKey"} transformer_name: "HealthCheckNameByKeyTransformer" }
  condition {
    url_pattern: "/rest/troubleshooting/[^/]+/setEnabled/?$"
    parameter { name_pattern: "enabled"  value_pattern: "false" }
    method: POST
  }
}

event {
  category: "Troubleshooting and support"
  summary: "Log analyzer scan started"
  object: { argument { name: "Log analyzer" source: CONST } }
  condition { url_pattern: "/plugins/servlet/troubleshooting/view/hercules/execute/?$" method: POST }
  detail { name: "Log file path" argument { name: "logFilePath" } }
}

event {
  category: "Troubleshooting and support"
  summary: "Log analyzer scan stopped"
  object: { argument { name: "Log analyzer" source: CONST } }
  condition { url_pattern: "/plugins/servlet/troubleshooting/view/hercules/?$"  method: POST }
}

event {
  category: "Troubleshooting and support"
  summary: "Log analyzer scan finished"
  object: { argument { name: "Log analyzer" source: CONST } }
  condition { url_pattern: "/plugins/servlet/troubleshooting/view/hercules/execute/?$" method: GET }
}

#TODO: Add logic to show old and new values.
event {
  category: "Troubleshooting and support"
  summary: "Log analyzer periodic scan settings changed"
  object: { argument { name: "Log analyzer" source: CONST } }
  condition { url_pattern: "/rest/troubleshooting/[^/]+/hercules/periodicScanner/settings/?$" method: POST }
  detail { name: "Enabled" argument { name: "enabled" }  transformer_name: "TrueIfPresentTransformer" }
  detail { name: "Start time (Hours)" argument { name: "start-time-hour"} }
  detail { name: "Start time (Minutes)" argument { name: "start-time-minute"} }
  detail { name: "Frequency" argument { name: "frequency" } }
  detail { name: "Recipients" argument { name: "recipients" } }
}

event {
  category: "Troubleshooting and support"
  summary: "Thread diagnostics enabled"
  object: { argument { name: "Thread diagnostics" source: CONST } }
  condition {
    url_pattern: "/rest/troubleshooting/[^/]+/threadDiagnostics/config/?$"
    method: POST
    parameter { name_pattern: "enabled"  value_pattern: "true" }
  }
}

event {
  category: "Troubleshooting and support"
  summary: "Thread diagnostics disabled"
  object: { argument { name: "Thread diagnostics" source: CONST } }
  condition {
    url_pattern: "/rest/troubleshooting/[^/]+/threadDiagnostics/config/?$"
    method: POST
    parameter { name_pattern: "enabled"  value_pattern: "false" }
  }
}

event {
  category: "Troubleshooting and support"
  summary: "Java Flight Recorder enabled"
  object: { argument { name: "Java Flight Recorder" source: CONST } }
  condition {
    url_pattern: "/rest/troubleshooting/[^/]+/jfr/settings/?$"
    method: POST
    parameter { name_pattern: "enabled"  value_pattern: "true" }
  }
}

event {
  category: "Troubleshooting and support"
  summary: "Java Flight Recorder disabled"
  object: { argument { name: "Java Flight Recorder" source: CONST } }
  condition {
    url_pattern: "/rest/troubleshooting/[^/]+/jfr/settings/?$"
    method: POST
    parameter { name_pattern: "enabled"  value_pattern: "false" }
  }
}

event {
  category: "Troubleshooting and support"
  summary: "Create support zip process started"
  object: { argument { name: "Support zip" source: CONST } }
  condition { url_pattern: "/rest/troubleshooting/[^/]+/support-zip/local/?$"  method: POST }
  detail {
    name: "File modification date"
    argument { name: "fileConstraintLastModified" }
    transformer_name: "FileModificationDateByNumberTransformer"
  }
  detail {
    name: "Maximum file size"
    argument { name: "fileConstraintSize" }
    transformer_name: "MaximumFileSizeTransformer"
  }
  detail {
    name: "Configuration files"
    argument { name: "items" }
    transformer_name: "ConfigurationFileNameByIdTransformer"
  }
}

event {
  category: "Troubleshooting and support"
  summary: "Create support zip process canceled"
  object: { argument { name: "Support zip" source: CONST } }
  condition { url_pattern: "/rest/troubleshooting/[^/]+/support-zip/task/[^/]+/?$" method: DELETE }
}

# Confluence administration > Team calendars
#TODO: Add logic to show old and new detail values.
event {
  category: "Team Calendars"
  summary: "Team calendars global settings changed"
  object: { argument { name: "Global Settings" source: CONST } }
  condition { url_pattern: "/calendar/setGlobalSettings.action" method: POST }
  detail { name: "Cache expire time" argument { name: "cacheExpireTime" } }
  detail { name: "First day of week" argument { name: "startOfWeek" } transformer_name: "WeekDayByNumberTransformer" }
  detail { name: "Display time format" argument { name: "displayTimeFormat" } transformer_name: "TeamCalendarsDisplayTimeFormatTransformer" }
  detail { name: "Display week numbers" argument { name: "displayWeekNumber" } transformer_name: "FalseIfNullTransformer" }
  detail { name: "Disable private URLs" argument { name: "disablePrivateUrls" } transformer_name: "FalseIfNullTransformer" }
  detail { name: "Don't notify space or page watchers" argument { name: "excludeSubscriptionsFromContent" } transformer_name: "FalseIfNullTransformer" }
}

event {
  category: "Team Calendars"
  summary: "Team calendars subscriptions deleted"
  object: { argument { name: "Global Settings" source: CONST } }
  condition { url_pattern: "/calendar/resetsubscriptions.action" method: POST }
}

event {
  category: "Team Calendars"
  summary: "Team calendars search index rebuilt"
  object: { argument { name: "Global Settings" source: CONST } }
  condition { url_pattern: "/rest/calendar-services/[^/]+/calendarcontenttype/reindex/?$" method: POST }
}

event {
  category: "Team Calendars"
  summary: "Team calendars space index rebuilt"
  object: { argument { name: "Global Settings" source: CONST } }
  condition { url_pattern: "/rest/calendar-services/[^/]+/migration/spacecalendars/?$" method: POST }
}

# Confluence administration > Cache Management > select cache > Flush
# NOTE: Must precede the previous more generic event in order to be selected correctly.
event {
  category: "Administration"
  summary: "Cache flushed"
  object { argument { name: "cacheName" } }
  condition {
    url_pattern: "/rest/cacheManagement/.*/cacheEntries"
    method: DELETE
    parameter { name_pattern: "cacheName" }
  }
}

# Confluence administration > Cache Management > Flush all
# NOTE: Must follow the previous more specific event in order not to be selected erroneously.
event {
  category: "Administration"
  summary: "All caches flushed"
  object: { argument { name: "Cache"  source: CONST } }
  condition { url_pattern: "/rest/cacheManagement/.*/cacheEntries"  method: DELETE }
}

# Confluence administration > License details > Save
event {
  category: "Administration"
  summary: "License updated"
  object: { argument { name: "Confluence license"  source: CONST } }
  condition {
    url_pattern: "/admin/doupdatelicense.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Organisation"
    name: "Date purchased"
    name: "License type"
    name: "Licensed users"
    name: "License expiration date"
    name: "Support Entitlement Number"
    name: "Server ID"
    phase: BEFORE_AND_AFTER
    transformer_name: "ConfluenceLicenseDetailsTransformer"
  }
}

# Confluence administration > Logging and Profiling > Enable profiling
event {
  category: "Administration"
  summary: "Profiling enabled"
  object: { argument { name: "Profiling configuration"  source: CONST } }
  condition {
    url_pattern: "/admin/changeprofiling.action"
    parameter { name_pattern: "profilingOn"  value_pattern: "true" }
    method: POST
  }
}

# Confluence administration > Logging and Profiling > Disable profiling
event {
  category: "Administration"
  summary: "Profiling disabled"
  object: { argument { name: "Profiling configuration"  source: CONST } }
  condition {
    url_pattern: "/admin/changeprofiling.action"
    parameter { name_pattern: "profilingOn"  value_pattern: "false" }
    method: POST
  }
}

# Confluence administration > Logging and Profiling > Enable SQL logging
event {
  category: "Administration"
  summary: "SQL logging enabled"
  object: { argument { name: "SQL logging configuration"  source: CONST } }
  condition { url_pattern: "/admin/turnonhibernatelogging.action"  method: POST }
}

# Confluence administration > Logging and Profiling > Disable SQL logging
event {
  category: "Administration"
  summary: "SQL logging disabled"
  object: { argument { name: "SQL logging configuration"  source: CONST } }
  condition { url_pattern: "/admin/turnoffhibernatelogging.action"  method: POST }
}

# Confluence administration > Logging and Profiling > Log4j Logging
# TODO: Add logic to show old and new detail values.
event {
  category: "Administration"
  summary: "Log4j logging settings updated"
  object { argument { name:"Log4j logging settings"  source: CONST } }
  condition { url_pattern: "/admin/changeloggingprofile.action"  method: POST }
  detail { name: "Log level"  argument { name: "profileName" } }
}

# Confluence administration > Logging and Profiling > Log4j Logging > Add New Entry
event {
  category: "Administration"
  summary: "Log4j logging entry added"
  object { argument { name:"Log4j logging settings"  source: CONST } }
  condition { url_pattern: "/admin/addlog4jentry.action"  method: POST }
  detail { name: "Class/Package Name"  argument { name: "extraClassName" } }
  detail { name: "Logging level"  argument { name: "extraLevelName" } }
}

# Confluence administration > Maintenance
# TODO: Add logic to show old and new detail values.
event {
  category: "Administration"
  summary: "Maintenance settings changed"
  object { argument { name: "Maintenance" source: CONST } }
  condition { url_pattern: "/admin/maintenance/doedit.action" method: POST }
  detail {
    name: "Read-only mode enabled"
    argument { name: "readOnlyModeEnabled" }
    transformer_name: "FalseIfNullTransformer"
  }
  detail {
    name: "Banner message enabled"
    argument { name: "bannerMessageOn" }
    argument { name: "readOnlyModeEnabled" }
    transformer_name: "MaintenanceBannerMessageTransformer"
  }
  detail { name: "Banner message" argument { name: "bannerMessage" } }
}

# Confluence administration > Mobile settings
event {
  category: "Administration"
  summary: "Mobile push notifications enabled"
  object { argument { name: "Push notifications" source: CONST } }
  condition { url_pattern: "/rest/nativemobile/[^/]+/push-notification/status/enabled/?$" method: POST }
}

event {
  category: "Administration"
  summary: "Mobile push notifications disabled"
  object { argument { name: "Push notifications" source: CONST } }
  condition { url_pattern: "/rest/nativemobile/[^/]+/push-notification/status/disabled/?$" method: POST }
}

# Confluence administration > Monitoring
event {
  category: "Administration"
  summary: "JMX Monitoring enabled"
  object { argument { name: "JMX Monitoring" source: CONST } }
  condition {
    url_pattern: "/admin/toggleJmxEnabled.action"
    method: POST
    parameter { name_pattern: "isChecked" }
  }
}

event {
  category: "Administration"
  summary: "JMX Monitoring disabled"
  object { argument { name: "JMX Monitoring" source: CONST } }
  condition { url_pattern: "/admin/toggleJmxEnabled.action" method: POST}
}

event {
  category: "Administration"
  summary: "App Monitoring enabled"
  object { argument { name: "JMX Monitoring" source: CONST } }
  condition {
    url_pattern: "/admin/toggleAppMonitoringEnabled.action"
    method: POST
    parameter { name_pattern: "isChecked" }
  }
}

event {
  category: "Administration"
  summary: "App Monitoring disabled"
  object { argument { name: "JMX Monitoring" source: CONST } }
  condition {
    url_pattern: "/admin/toggleAppMonitoringEnabled.action"
    method: POST
  }
}

event {
  category: "Administration"
  summary: "In-product diagnostics enabled"
  object { argument { name: "JMX Monitoring" source: CONST } }
  condition {
    url_pattern: "/admin/toggleIpdMonitoringEnabled.action"
    method: POST
    parameter { name_pattern: "isChecked" }
  }
}

event {
  category: "Administration"
  summary: "In-product diagnostics disabled"
  object { argument { name: "JMX Monitoring" source: CONST } }
  condition {
    url_pattern: "/admin/toggleIpdMonitoringEnabled.action"
    method: POST
  }
}

# Confluence administration > Rate limiting
event {
  category: "Rate limiting"
  summary: "Settings updated"
  object: { argument { name: "Rate limiting" source: CONST } }
  condition { url_pattern: "rest/rate-limiting/[^/]+/admin/rate-limit/settings/?$" method: PUT }
  detail { name: "Mode" argument { name: "mode" } }
  detail {
    name: "Type"
    argument { name: "defaultCapacity" }
    transformer_name: "RateLimitingTypeByCapacityTransformer"
  }
  detail {
    name: "Requests allowed per node"
    argument { name: "defaultFillRate" }
    argument { name: "defaultIntervalFrequency" }
    argument { name: "defaultIntervalTimeUnit" }
    transformer_name: "RateLimitingRequestsPerNodeByParamsTransformer"
  }
  detail { name: "Max requests" argument { name: "defaultCapacity" } transformer_name: "RateLimitingDefaultCapacityTransformer" }
}

event {
  category: "Rate limiting"
  summary: "Rate limiting exemption updated"
  object: { argument { name: "Exemption" source: CONST } }
  condition {
    url_pattern: "/rest/rate-limiting/[^/]+/admin/rate-limit/settings/users/token-bucket/?$"
    method: PUT
  }
  detail { name: "Users" argument { name: "userIds" } }
  detail {
    name: "Type"
    argument { name: "Assign custom limit" source: CONST }
  }
  detail {
    name: "Requests allowed per node"
    name: "Max requests"
    argument { name: "tokenBucketSettings" }
    transformer_name: "RateLimitingRequestsPerNodeByJsonTransformer"
  }
}

event {
  category: "Rate limiting"
  summary: "Rate limiting whitelist exemption added"
  object: { argument { name: "Exemption" source: CONST } }
  condition {
    url_pattern: "/rest/rate-limiting/[^/]+/admin/rate-limit/settings/users/whitelist/?$"
    method: PUT
  }
  detail { name: "Users" argument { name: "userIds" } }
  detail {
    name: "Type"
    argument { name: "Allow unlimited requests" source: CONST }
  }
}

event {
  category: "Rate limiting"
  summary: "Rate limiting blacklist exemption added"
  object: { argument { name: "Exemption" source: CONST } }
  condition {
    url_pattern: "/rest/rate-limiting/[^/]+/admin/rate-limit/settings/users/blacklist/?$"
    method: PUT
  }
  detail { name: "Users" argument { name: "userIds" } }
  detail {
    name: "Type"
    argument { name: "Block all requests" source: CONST }
  }
}

event {
  category: "Rate limiting"
  summary: "Rate limiting exemption removed"
  object: { argument { name: "Exemption" source: CONST } }
  condition {
    url_pattern: "/rest/rate-limiting/[^/]+/admin/rate-limit/settings/users/([^/]+)/?$"
    method: DELETE
  }
  detail { name: "User" argument { name: "1" source: URL } }
}

# Confluence administration > Logging and Profiling > Log4j Logging > Existing Levels > Remove
event {
  category: "Administration"
  summary: "Log4j logging entry deleted"
  object { argument { name:"Log4j logging settings"  source: CONST } }
  condition { url_pattern: "/admin/deleteLogEntry.action"  method: GET }
  detail { name: "Class/Package Name"  argument { name: "toDeleteName" } }
  detail {
    name: "Logging level"
    phase: BEFORE
    transformer_name: "Log4jLevelByNameTransformer"
    argument { name: "toDeleteName" }
  }
}

# Confluence administration > Logging and Profiling > Log4j Logging > Existing Levels > Save
event {
  category: "Administration"
  summary: "Log4j logging entries updated"
  object { argument { name:"Log4j logging settings"  source: CONST } }
  condition {
    url_pattern: "/admin/savelog4j.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name_transformer_name: "Log4jLevelNamesTransformer"
    phase: BEFORE_AND_AFTER
    transformer_name: "Log4jLevelByNameTransformer"
    argument { name: "classNames" }
  }
}

# Confluence administration > Analytics > Enabled > Save
event {
  category: "Administration"
  summary: "Atlassian analytics settings changed"
  object: { argument { name: "Analytics configuration"  source: CONST } }
  condition {
    url_pattern: "/rest/analytics/.*/config/enable"
    method: PUT
    condition_name: "ContainsChangedDetailsCondition"
  }
  detail {
    name: "Enabled"
    transformer_name: "AnalyticsTransformer"
    phase: BEFORE_AND_AFTER
  }
}

event {
  category: "Analytics"
  summary: "Analytics user feedback enabled"
  object: { argument { name: "Analytics configuration"  source: CONST } }
  condition {
    url_pattern: "/nps/[^/]+/status/enable"
    parameter { name_pattern: "npsEnabled"  value_pattern: "true" }
    method: PUT
  }
}

event {
  category: "Analytics"
  summary: "Analytics user feedback disabled"
  object: { argument { name: "Analytics configuration"  source: CONST } }
  condition {
    url_pattern: "/nps/[^/]+/status/enable"
    parameter { name_pattern: "npsEnabled"  value_pattern: "false" }
    method: PUT
  }
}

# Confluence administration > Support tools > Create support zip

event {
  category: "Administration"
  summary: "Support zip file created"
  object: { argument { name: "Support zip file"  source: CONST } }
  condition { url_pattern: "plugins/servlet/stp/view/support-zip/execute"  method: POST }
  detail { name: "Application properties"  argument { name: "application-properties" } }
  detail { name: "Thread dumps"  argument { name: "thread-dump" } }
  detail { name: "Confluence configuration files"  argument { name: "application-config" } }
  detail { name: "Confluence customisations"  argument { name: "confluence-customisations" } }
  detail { name: "Healthcheck results"  argument { name: "healthchecks" } }
  detail { name: "Tomcat configuration files"  argument { name: "tomcat-config" } }
  detail { name: "Authentication configuration files"  argument { name: "auth-cfg" } }
  detail { name: "Cache configuration files"  argument { name: "cache-cfg" } }
  detail { name: "Confluence application logs"  argument { name: "application-logs" } }
  detail { name: "Tomcat logs"  argument { name: "tomcat-logs" } }
  detail { name: "Limit file sizes"  argument { name: "limit-file-sizes" } }
}

event {
  category: "Administration"
  summary: "Health check notification settings updated"
  object: { argument { name: "Health check notification settings"  source: CONST } }
  condition { url_pattern: "rest/(supportHealthCheck|troubleshooting)/[^/]+/user-setting/admin/notification-severity"  method: PUT }
  detail {
    name: "Notification settings"
    transformer_name: "HealthCheckNotificationsParameterByKeyTransformer"
    argument { source: BODY }
  }
}

event {
  category: "Administration"
  summary: "Log analysis file updated"
  object: { argument { name: "logFilePath" } }
  condition { url_pattern: "plugins/servlet/stp/view/hercules/execute"  method: POST }
}

event {
  category: "Administration"
  summary: "Log analysis settings updated"
  object: { argument { name: "Log analysis settings"  source: CONST } }
  condition { url_pattern: "rest/stp/latest/hercules/periodicScanner/settings"  method: POST }
  detail { name: "Enable"  transformer_name: "FalseIfNullTransformer"  argument { name: "enabled" } }
  detail { name: "Start time hour"  argument { name: "start-time-hour" } }
  detail { name: "Start time minute"  argument { name: "start-time-minute" } }
  detail { name: "Frequency"  argument { name: "frequency" } }
  detail { name: "Recipients"  argument { name: "recipients" } }
}



# Confluence administration > Application links

event {
  category: "Integrations"
  summary: "Application link created"
  object: { argument { name: "name" } }
  condition { url_pattern: "rest/applinks/[^/]+/applicationlink/?$"  method: PUT }
  detail { name: "Application link name"  argument { name: "name" } }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByKeyTransformer"
    argument { name: "typeId" }
  }
  detail { name: "Application URL"  argument { name: "rpcUrl" } }
  detail { name: "Display URL"  argument { name: "displayUrl" } }
}

event {
  category: "Integrations"
  summary: "External application link created"
  object: { argument { name: "name" } }
  condition { url_pattern: "/rest/oauth2/[^/]+/client/?$" method: POST }
  detail { name: "Name" argument { name: "name" } }
  detail { name: "Redirect URL" argument { name: "redirects" } }
  detail { name: "Scope" argument { name: "scope" } }
}

# TODO: add logic to show old and new values of details.
event {
  category: "Integrations"
  summary: "External Application link updated"
  object: { argument { name: "name" } }
  condition { url_pattern: "/rest/oauth2/[^/]+/client/[^/]+/?$" method: PUT }
  detail { name: "Name" argument { name: "name" } }
  detail { name: "Redirect URL" argument { name: "redirects" } }
  detail { name: "Scope" argument { name: "scope" } }
}

event {
  category: "Integrations"
  summary: "External Application link deleted"
  object: { argument { name: "External application link" source: CONST } }
  condition { url_pattern: "/rest/oauth2/[^/]+/client/([^/]+)/?$" method: DELETE }
  detail { name: "ID" argument { name: "1" source: URL } }
  detail { name: "Scope" argument { name: "scope" } }
}

event {
  category: "Integrations"
  summary: "Application link details updated"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "4"  source: URL } }
  condition {
    url_pattern: "rest/applinks/[^/]+/app((licationlink)|(links))/([^/]+)$"
    method: PUT
    condition_name: "ContainsChangedDetailsCondition"
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "4"  source: URL }
  }
  detail {
    name: "Application link name"
    name: "Application URL"
    name: "Display URL"
    name: "Primary"
    phase: BEFORE_AND_AFTER
    transformer_name: "ApplicationLinkUpdateParametersByKeyTransformer"
    argument { name: "4"  source: URL }
  }
}

event {
  category: "Integrations"
  summary: "Application link authentication parameters updated"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "rest/applinks/[^/]+/status/([^/]+)/oauth$"
    method: PUT
  }
  detail {
    name: "Application link name"
    name: "Application URL"
    name: "Display URL"
    name: "Application link type"
    transformer_name: "ApplicationLinkDetailsByKeyTransformer"
    phase: BEFORE_AND_AFTER
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Incoming authentication"
    transformer_name: "ApplicationLinkAuthenticationTypeByParametersTransformer"
    argument { name: "incoming.enabled" }
    argument { name: "incoming.twoLoImpersonationEnabled" }
  }
  detail {
    name: "Outgoing authentication"
    transformer_name: "ApplicationLinkAuthenticationTypeByParametersTransformer"
    argument { name: "outgoing.enabled" }
    argument { name: "outgoing.twoLoImpersonationEnabled" }
  }
}

event {
  category: "Integrations"
  summary: "Application link deleted"
  object: {
    phase: BEFORE
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  condition { url_pattern: "rest/applinks/[^/]+/applinks/([^/]+)$"  method: DELETE }
  detail {
    name: "Application link name"
    phase: BEFORE
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    phase: BEFORE
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Primary application links"
    transformer_name: "PrimaryApplicationLinkTransformer"
  }
}

event {
  category: "Integrations"
  summary: "Application link authentication parameters added"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition { url_pattern: "rest/applinks/[^/]+/applicationlink/([^/]+)/authentication/provider/?$"  method: PUT }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1" source: URL }
  }
  detail { name: "Provider type"  argument { name: "provider" } }
  detail {
    name: "Access token URL"
    name: "Request token URL"
    name: "Authorize URL"
    name: "Consumer key"
    transformer_name: "ApplicationLinkAuthenticationParametersByConfigParameterTransformer"
    argument { name: "config" }
  }
}

event {
  category: "Integrations"
  summary: "Application link outgoing authentication parameters added"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "rest/applinks-oauth/[^/]+/applicationlink/([^/]+)/authentication/consumer/?$"
    method: PUT
    parameter { name_pattern: "outgoing"  value_pattern: "true" }
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail { name: "Consumer key"  argument { name: "key" } }
  detail { name: "Service provider name"  argument { name: "name" } }
  detail { name: "Description"  argument { name: "description" } }
}

event {
  category: "Integrations"
  summary: "Application link incoming authentication parameters added"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "rest/applinks-oauth/[^/]+/applicationlink/([^/]+)/authentication/consumer/?$"
    method: PUT
    parameter { name_pattern: "outgoing"  value_pattern: "false" }
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail { name: "Consumer key"  argument { name: "key" } }
  detail { name: "Consumer name"  argument { name: "name" } }
  detail { name: "Description"  argument { name: "description" } }
  # detail { name: "Shared secret"  argument { name: "sharedSecret" } }
  # detail { name: "Public key"  argument { name: "publicKey" } }
}

event {
  category: "Integrations"
  summary: "Application link outgoing OAuth authentication enabled"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
     url_pattern: "plugins/servlet/applinks/auth/conf/oauth/outbound/3rdparty/([^/]+)$"
     parameter { name_pattern: "oauth-outgoing-enabled"  value_pattern: "true" }
     method: POST
   }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail { name: "Service provider name"  argument { name: "name" } }
  detail { name: "Consumer key"  argument { name: "key" } }
  # detail { name: "Shared secret"  argument { name: "sharedSecret" } }
  detail { name: "Description"  argument { name: "description" } }
  detail { name: "Request token URL"  argument { name: "requestTokenUrl" } }
  detail { name: "Access token URL"  argument { name: "accessTokenUrl" } }
  detail { name: "Authorize URL"  argument { name: "authorizeUrl" } }
}

event {
  category: "Integrations"
  summary: "Application link outgoing OAuth authentication disabled"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
     url_pattern: "plugins/servlet/applinks/auth/conf/oauth/outbound/3rdparty/([^/]+)$"
     parameter { name_pattern: "oauth-outgoing-enabled"  value_pattern: "false" }
     method: POST
   }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Integrations"
  summary: "Application link basic outgoing authentication enabled"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "plugins/servlet/applinks/auth/conf/basic/([^/]+)$"
    parameter { name_pattern: "method"  value_pattern: "PUT" }
    method: POST
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail { name: "Username"  argument { name: "username" } }
}

event {
  category: "Integrations"
  summary: "Application link basic outgoing authentication disabled"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "plugins/servlet/applinks/auth/conf/basic/([^/]+)$"
    parameter { name_pattern: "method"  value_pattern: "DELETE" }
    method: POST
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Integrations"
  summary: "Application link incoming OAuth authentication parameters updated"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "plugins/servlet/applinks/auth/conf/oauth/add-consumer-manually/([^/]+)$"
    parameter { name_pattern: "oauth-incoming-enabled"  value_pattern: "true" }
    method: POST
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail { name: "Consumer key"  argument { name: "key" } }
  detail { name: "Consumer name"  argument { name: "consumerName" } }
  detail { name: "Description"  argument { name: "description" } }
  # detail { name: "Public key"  argument { name: "publicKey" } }
  detail { name: "Consumer callback URL"  argument { name: "callback" } }
  detail {
    name: "Allow 2-Legged OAuth"
    transformer_name: "FalseIfNullTransformer"
    argument { name: "two-lo-enabled" }
  }
  detail { name: "Execute as"  argument { name: "two-lo-execute-as" } }
  detail { name: "Allow user impersonation through 2-Legged OAuth"  argument { name: "two-lo-impersonation-enabled" } }
  detail { name: "OAuth incoming enabled"  argument { name: "oauth-incoming-enabled	" } }
  detail {
    name: "Allow user impersonation through 2-Legged OAuth"
    transformer_name: "FalseIfNullTransformer"
    argument { name: "two-lo-impersonation-enabled" }
  }
}

event {
  category: "Integrations"
  summary: "Application link incoming OAuth authentication disabled"
  object: { transformer_name: "ApplicationLinkNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "plugins/servlet/applinks/auth/conf/oauth/add-consumer-manually/([^/]+)$"
    parameter { name_pattern: "oauth-incoming-enabled"  value_pattern: "false" }
    method: POST
  }
  detail {
    name: "Application link name"
    transformer_name: "ApplicationLinkNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Application link type"
    transformer_name: "ApplicationLinkTypeByLinkKeyTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Integrations"
  summary: "Application navigation link added"
  object: { argument { name: "displayName" } }
  condition { url_pattern: "rest/custom-apps/[^/]+/customapps$"  method: POST }
  detail { name: "Link name"  argument { name: "displayName" } }
  detail { name: "Link URL"  argument { name: "url" } }
  detail { name: "Hidden"  argument { name: "hide" } }
  detail { name: "Restricted to groups"  argument { name: "allowedGroups" } }
}

event {
  category: "Integrations"
  summary: "Application navigation link updated"
  object: { transformer_name: "ApplicationNavigationLinkNameByIdTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "rest/custom-apps/[^/]+/customapps/(\\d+)$"
    method: PUT
    condition_name: "ContainsChangedDetailsCondition"
  }
  detail {
    name: "Link name"
    name: "Link URL"
    name: "Hidden"
    name: "Restricted to groups"
    phase: BEFORE_AND_AFTER
    transformer_name: "ApplicationNavigationLinkUpdateParametersByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

event {
  category: "Integrations"
  summary: "Application navigation link moved"
  object: { transformer_name: "ApplicationNavigationLinkNameByIdTransformer"  argument { name: "1"  source: URL } }
  condition { url_pattern: "rest/custom-apps/[^/]+/customapps/(\\d+)/move/?$"  method: POST }
  detail {
    name: "Position"
    argument { name: "1" source: URL }
    transformer_name: "ApplicationNavigationLinkPositionByIdTransformer"
    phase: BEFORE_AND_AFTER
  }
  detail { name: "After"  transformer_name: "ApplicationNavigationLinkNameByIdTransformer"  argument { name: "after" } }
}

event {
  category: "Integrations"
  summary: "Application navigation link deleted"
  object: { phase: BEFORE  transformer_name: "ApplicationNavigationLinkNameByIdTransformer"  argument { name: "1"  source: URL } }
  condition { url_pattern: "rest/custom-apps/[^/]+/customapps/(\\d+)$"  method: DELETE }
  detail {
    name: "Link name"
    name: "Link URL"
    name: "Hidden"
    name: "Restricted to groups"
    phase: BEFORE
    transformer_name: "ApplicationNavigationLinkUpdateParametersByIdTransformer"
    argument { name: "1"  source: URL }
  }
}

#TODO: Add logic to show old and new values for audit log settings.
#TODO: Make all audit log settings updated events into one event,
#TODO: because currently we log multiple events when user submits audit
#TODO: log settings form (because there are multiple requests sent at once).
#Confluence administration > Audit log

event {
  category: "Administration"
  summary: "System audit log database retention period updated"
  object: { argument { name: "Audit log" source: CONST } }
  condition {
    url_pattern: "/rest/auditing/[^/]+/configuration/retention/?$"
    method: PUT
  }
  detail {
    name: "Period"
    argument { name: "period" }
  }
}

event {
  category: "Administration"
  summary: "System audit log file retention period updated"
  object: { argument { name: "Audit log" source: CONST } }
  condition {
    url_pattern: "/rest/auditing/[^/]+/configuration/retention/file/?$"
    method: PUT
  }
  detail {
    name: "Number of files stored"
    argument { name: "maxFileCount" }
  }
}

event {
  category: "Administration"
  summary: "System audit log excluded events list updated"
  object: { argument { name: "Audit log" source: CONST } }
  condition {
    url_pattern: "/rest/auditing/[^/]+/configuration/denylist/?$"
    method: PUT
  }
 detail {
     name: "New excluded events list"
     argument { name: "actions" }
     transformer_name: "NoneIfNullOrEmptyTransformer"
   }
}

event {
  category: "Administration"
  summary: "System audit log coverage settings updated"
  object: { argument { name: "Audit log" source: CONST } }
  condition {
    url_pattern: "/rest/auditing/[^/]+/configuration/coverage/?$"
    method: PUT
  }
  detail { name: "Global configuration and administration" argument { name: "levelByArea.global-config-and-administration" } }
  detail { name: "User management" argument { name: "levelByArea.user-management" } }
  detail { name: "Permissions" argument { name: "levelByArea.permissions" } }
  detail { name: "Local configuration and administration" argument { name: "levelByArea.local-config-and-administration" } }
  detail { name: "Security" argument { name: "levelByArea.security" } }
  detail { name: "End user activity" argument { name: "levelByArea.activity" } }
  detail { name: "Apps" argument { name: "levelByArea.ecosystem" } }
}

# Confluence administration > Analytics > Disabled > Save
event {
  category: "Administration"
  summary: "Atlassian analytics disabled"
  object: { argument { name: "Analytics configuration"  source: CONST } }
  condition {
    url_pattern: "/rest/analytics/.*/config/enable"
    method: PUT
    parameter { name_pattern: "analyticsEnabled"  value_pattern: "false" }
  }
}


### Mail configuration events

# Confluence administration > Mail Servers > Add a new SMTP mail server
event {
  category: "Mail"
  summary: "Mail server added"
  object { argument { name: "name" } }
  condition {
    url_pattern: "/admin/mail/docreatemailserver.action"
    parameter { name_pattern: "confirm"  value_pattern: "Submit" }
    method: POST
  }
  detail { name: "Server name"  argument { name: "name" } }
  detail { name: "To address"  argument { name: "emailAddress" } }
  detail { name: "From name"  argument { name: "fromName" } }
  detail { name: "Subject prefix"  argument { name: "prefix" } }
  detail { name: "Server hostname"  argument { name: "hostname" } }
  detail { name: "Server port"  argument { name: "port" } }
  detail { name: "Use TLS"  argument { name: "tlsRequired" } }
  detail { name: "JNDI location"  argument { name: "jndiName" } }
  detail { name: "User name"  argument { name: "userName" } }
  detail { name: "Protocol"  argument { name: "protocol" } }
}

# Confluence administration > Mail Servers > Del
event {
  category: "Mail"
  summary: "Mail server deleted"
  object { argument { name: "id" }  phase: BEFORE  transformer_name: "MailServerNameByIdTransformer" }
  condition { url_pattern: "/admin/mail/removemailserver.action"  method: GET }
  detail {
    name: "Server name"
    name: "From address"
    name: "From name"
    name: "To address"
    name: "Subject prefix"
    name: "Server hostname"
    name: "Server port"
    name: "Use TLS"
    name: "JNDI location"
    name: "User name"
    # Password is encrypted, but we need it, to show event even if user changed just password.
    name: "Password"
    name: "Protocol"
    phase: BEFORE
    transformer_name: "MailServerDetailsByIdTransformer"
    argument { name: "id" }
 }
}

# Confluence administration > Mail Servers > Edit
event {
  category: "Mail"
  summary: "Mail server edited"
  object { argument { name: "name" } }
  condition {
    url_pattern: "/admin/mail/doeditmailserver.action"
    parameter { name_pattern: "confirm"  value_pattern: "Submit" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Server name"
    name: "From address"
    name: "From name"
    name: "To address"
    name: "Subject prefix"
    name: "Server hostname"
    name: "Server port"
    name: "Use TLS"
    name: "JNDI location"
    name: "User name"
    # Password is encrypted, but we need it, to show event even if user changed just password.
    name: "Password"
    name: "Protocol"
    phase: BEFORE_AND_AFTER
    transformer_name: "MailServerDetailsByIdTransformer"
    argument { name: "id" }
  }
}


# Confluence administration > User Macros

event {
  category: "Global Configuration"
  summary: "User macro added"
  object { argument { name: "userMacro.name" } }
  condition {
    url_pattern: "admin/addusermacro.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    method: POST
  }
  detail { name: "Macro name"  argument { name: "userMacro.name" } }
  detail { name: "Visible to all users in the Macro Browser"  argument { name: "showInMacroBrowser" } }
  detail { name: "Macro title"  argument { name: "userMacro.title" } }
  detail { name: "Description"  argument { name: "userMacro.description" } }
  detail { name: "Categories"  argument { name: "userMacro.categories" } }
  detail { name: "Icon URL"  argument { name: "userMacro.iconLocation" } }
  detail { name: "Documentation URL"  argument { name: "userMacro.documentationUrl" } }
  detail { name: "Macro body processing"  argument { name: "userMacro.bodyType" } }
  detail { name: "Macro template"  argument { name: "userMacro.template" } }
}

event {
  category: "Global Configuration"
  summary: "User macro updated"
  object { argument { name: "originalName" } }
  condition {
    url_pattern: "admin/updateusermacro.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Macro name"
    name: "Visible to all users"
    name: "Macro title"
    name: "Description"
    name: "Categories"
    name: "Icon URL"
    name: "Documentation URL"
    name: "Macro body processing"
    name: "Macro template"
    argument { name: "userMacro.name" }
    argument { name: "originalName" }
    transformer_name: "UserMacroDetailsByNameTransformer"
    phase: BEFORE_AND_AFTER
  }
}

event {
  category: "Global Configuration"
  summary: "User macro deleted"
  object { argument { name: "macro" } }
  condition { url_pattern: "admin/removeusermacro.action"  method: GET }
  detail {
    name: "Macro name"
    name: "Visible to all users"
    name: "Macro title"
    name: "Description"
    name: "Categories"
    name: "Icon URL"
    name: "Documentation URL"
    name: "Macro body processing"
    name: "Macro template"
    argument { name: "macro" }
    argument { name: "macro" }
    transformer_name: "UserMacroDetailsByNameTransformer"
    phase: BEFORE
  }
}

# Confluence administration -> Webhooks

event {
  category: "Webhooks"
  summary: "Webhook added"
  object { argument { name: "name" } }
  condition { url_pattern: "rest/api/webhooks/?$" method: POST }
  detail { name: "URL" argument { name: "url" } }
  detail { name: "Events" argument { name: "events" } }
  detail { name: "Active" argument { name: "active" } }
}

event {
  category: "Webhooks"
  summary: "Webhook updated"
  object { argument { name: "name" } }
  condition {
    url_pattern: "rest/api/webhooks/(\\d+)/?$"
    method: PUT
    condition_name: "ContainsChangedDetailsCondition"
  }
  detail {
    name: "Name"
    name: "URL"
    name: "Events"
    name: "Active"
    argument { name: "1" source: URL }
    transformer_name: "WebhookDetailsByIdTransformer"
    phase: BEFORE_AND_AFTER
  }
}

event {
  category: "Webhooks"
  summary: "Webhook deleted"
  object {
    argument { name: "1" source: URL }
    transformer_name: "WebhookNameByIdTransformer"
    phase: BEFORE
  }
  condition {
    url_pattern: "rest/api/webhooks/(\\d+)/?$"
    method: DELETE
  }
  detail {
    name: "Name"
    name: "URL"
    name: "Events"
    name: "Active"
    argument { name: "1" source: URL }
    transformer_name: "WebhookDetailsByIdTransformer"
    phase: BEFORE
  }
}

# Settings > Personal access token

event {
  category: "Personal access token"
  summary: "Personal access token created"
  object {
    argument { name: "name" }
  }
  condition {
    url_pattern: "/rest/pat/[^/]+/tokens/?$"
    method: POST
  }
  detail {
    name: "Expiration duration"
    argument { name: "expirationDuration" }
  }
}

event {
  category: "Personal access token"
  summary: "Personal access token revoked"
  object {
    argument { name: "Personal access token" source: CONST }
  }
  condition {
    url_pattern: "/rest/pat/[^/]+/tokens/(\\d+)/?$"
    method: DELETE
  }
  #TODO: add name detail.
  detail {
    name: "ID"
    argument { name: "1" source: CONST }
  }
}

event {
  category: "Personal access token"
  summary: "Personal access tokens revoked"
  object {
    argument { name: "Personal access token" source: CONST }
  }
  condition {
    url_pattern: "/rest/pat/[^/]+/admin/tokens/?$"
    method: DELETE
  }
  #TODO: add name detail.
  detail {
    name: "IDs"
    argument { source: BODY }
    transformer_name: "RemoveQuotesTransformer"
  }
}

# Confluence administration > In-app Notifications

event {
  category: "Global Configuration"
  summary: "In-app notification settings updated"
  object { argument { name: "In-app notification settings"  source: CONST } }
  condition { url_pattern: "plugins/servlet/myworkserviceselector"  method: POST }
  detail {
    name: "Notifications handling"
    name: "Active polling interval (seconds)"
    name: "Inactive polling interval (seconds)"
    name: "Remote application name"
    name: "Remote application URL"
    transformer_name: "InAppNotificationSettingsParametersTransformer"
    argument { name: "target" }
    argument { name: "pollingInterval" }
    argument { name: "maxPollingInterval" }
    argument { name: "host" }
  }
}

# Confluence administration > HipChat Integration

event {
  category: "Integrations"
  summary: "HipChat connected"
  object { argument { name: "HipChat"  source: CONST } }
  condition { url_pattern: "rest/hipchat/integration/[^/]+/installation/complete$"  method: POST }
}

event {
  category: "Integrations"
  summary: "HipChat room notification added"
  object { argument { name: "HipChat"  source: CONST } }
  condition {
    url_pattern: "rest/hipchat/spacetoroom/[^/]+/config/([^/]+)/([^/]+)/((BlogCreate)|(PageCreate)|(PageUpdate))"
    method: PUT
  }
  detail { name: "Space key"  argument { name: "1"  source: URL } }
  detail { name: "HipChat room ID"  argument { name: "2"  source: URL } }
  detail {
    name: "Notification trigger"
    transformer_name: "HipChatNotificationTriggerByKeyTransformer"
    argument: { name: "3"  source: URL }
  }
}

event {
  category: "Integrations"
  summary: "HipChat room notification deleted"
  object { argument { name: "HipChat"  source: CONST } }
  condition {
    url_pattern: "rest/hipchat/spacetoroom/[^/]+/config/([^/]+)/([^/]+)/((BlogCreate)|(PageCreate)|(PageUpdate))"
    method: DELETE
  }
  detail { name: "Space key"  argument { name: "1"  source: URL } }
  detail { name: "HipChat room ID"  argument { name: "2"  source: URL } }
  detail {
    name: "Notification trigger"
    transformer_name: "HipChatNotificationTriggerByKeyTransformer"
    argument: { name: "3"  source: URL }
  }
}

event {
  category: "Integrations"
  summary: "HipChat room user notification enabled"
  object { argument { name: "HipChat"  source: CONST } }
  condition {
    url_pattern: "rest/hipchat/spacetoroom/[^/]+/configsettings/notifyclient/([^/]+)/([^/]+)"
    method: PUT
  }
  detail { name: "Space key"  argument { name: "1"  source: URL } }
  detail { name: "HipChat room ID"  argument { name: "2"  source: URL } }
}

event {
  category: "Integrations"
  summary: "HipChat room user notification disabled"
  object { argument { name: "HipChat"  source: CONST } }
  condition {
    url_pattern: "rest/hipchat/spacetoroom/[^/]+/configsettings/notifyclient/([^/]+)/([^/]+)"
    method: DELETE
  }
  detail { name: "Space key"  argument { name: "1"  source: URL } }
  detail { name: "HipChat room ID"  argument { name: "2"  source: URL } }
}

event {
  category: "Integrations"
  summary: "HipChat room notifications disabled"
  object { argument { name: "HipChat"  source: CONST } }
  condition {
    url_pattern: "rest/hipchat/spacetoroom/[^/]+/config/([^/]+)/([^/]+)"
    method: DELETE
  }
  detail { name: "Space key"  argument { name: "1"  source: URL } }
  detail { name: "HipChat room ID"  argument { name: "2"  source: URL } }
}

event {
  category: "Integrations"
  summary: "HipChat integration removed"
  object { argument { name: "HipChat"  source: CONST } }
  condition {
    url_pattern: "plugins/servlet/hipchat/configure"
    method: GET
    parameter { name_pattern: "uninstall"  value_pattern: "true" }
  }
}

event {
  category: "Integrations"
  summary: "Users invited to HipChat"
  object { argument { name: "HipChat"  source: CONST } }
  condition { url_pattern: "rest/hipchat/integration/latest/users/invite$"  method: POST }
  detail { name: "User names"  argument { name: "user-names" } }
}



# Confluence administration > PDF Export Language Support
event {
  category: "Global Configuration"
  summary: "PDF export font installed"
  object { argument { name: "PDF export font"  source: CONST } }
  condition { url_pattern: "admin/flyingpdf/doconfigurepdflanguagesupport.action"  method: POST }
}

event {
  category: "Global Configuration"
  summary: "PDF export font reset to default"
  object { argument { name: "PDF export font"  source: CONST } }
  condition { url_pattern: "admin/flyingpdf/restoredefaultpdflanguage.action"  method: GET }
}

# Confluence administration > Retention rules
event {
  category: "Retention rules"
  summary: "Retention rules settings updated"
  object { argument { name: "Retention rules" source: CONST } }
  condition { url_pattern: "/rest(/api)?/retentionpolicy/[^/]+/?$" method: PUT }
  detail {
    name: "Attachment versions retention"
    name: "Page versions retention"
    name: "Trash retention"
    name: "Who can add and edit exemptions"
    transformer_name: "RetentionRulesSettingsByJsonTransformer"
    argument { name: "attachmentRetentionRule" }
    argument { name: "pageRetentionRule" }
    argument { name: "trashRetentionRule" }
    argument { name: "spaceOverridesAllowed" }
  }
}

event {
  category: "Retention rules"
  summary: "Space retention rule deleted"
  object { argument { name: "2" source: URL } }
  detail {
    name: "Space name"
    argument { name: "2" source: URL }
    transformer_name: "SpaceNameByKeyTransformer"
  }
  condition { url_pattern: "/rest(/api)?/retentionpolicy/[^/]+/space/([^/]+)/?$" method: DELETE }
}

# Confluence administration > Configure Code Macro
event {
  category: "Global Configuration"
  summary: "Code macro configuration updated"
  object { argument { name: "Code macro configuration"  source: CONST } }
  condition {
    url_pattern: "admin/plugins/newcode/save.action"
    method: POST
  }
  detail {
    name: "Default theme"
    argument { name: "defaultThemeName" }
  }
  detail {
    name: "Default language"
    argument { name: "defaultLanguageName" }
  }
}

event {
  category: "Global Configuration"
  summary: "Code macro language added"
  # TODO: get language name from request body
  # https://bitbucket.org/enhancera/auditor/issues/451/implement-web-request-body-parameters
  condition { url_pattern: "admin/plugins/newcode/addlanguage.action"  method: POST }
}

# Confluence administration > Office connector
event {
  category: "Integrations"
  summary: "Office connector configuration updated"
  object { argument { name: "Office connector configuration"  source: CONST } }
  condition { url_pattern: "admin/worddav/adminwordsubmit.action"  method: POST }
  detail { name: "Edit in word button location"  transformer_name: "OfficeConnectorWordButtonLocationByParameterTransformer"  argument { name: "locationCode" } }
  detail { name: "Show warnings"  transformer_name: "FalseIfNullTransformer"  argument { name: "showWarning" } }
  detail { name: "Use footnote macro"  transformer_name: "FalseIfNullTransformer"  argument { name: "doFootnotes" } }
  detail { name: "Max imported image height (pixels)"  argument { name: "maxImportImageHeight" } }
  detail { name: "Max imported image width (pixels)"  argument { name: "maxImportImageWidth" } }
  detail { name: "Temporary storage for viewfile macro"  transformer_name: "OfficeConnectorCacheStorageByParameterTransformer"  argument { name: "cacheType" } }
  detail { name: "Maximum file space for cache (MB)"  argument { name: "maxCacheSize" } }
  detail { name: "Number of conversion queues"  argument { name: "maxQueues" } }
  detail { name: "Allow authentication tokens in the URL path"  transformer_name: "FalseIfNullTransformer"  argument { name: "pathAuth" } }
  detail { name: "File editing method" argument { name: "editInOffice"} transformer_name: "FalseIfNullTransformer" }
  detail { name: "File authentication" argument { name: "pathAuth"} transformer_name: "FalseIfNullTransformer" }
}

# Confluence administration > WebDAV Configuration
event {
  category: "Integrations"
  summary: "WebDAV configuration updated"
  object { argument { name: "WebDAV configuration"  source: CONST } }
  condition {
    url_pattern: "admin/plugins/webdav/doconfig.action"
    parameter { name_pattern: "save"  value_pattern: "Save" }
    method: POST
  }
  detail { name: "Denied clients"  argument { name: "denyRegexes" } }
  detail { name: "Disable strict path check"  transformer_name: "FalseIfNullTransformer"  argument { name: "disableStrictPathCheck" } }
}


### Look & Feel events - Global

# Confluence administration > Theme > Choose new theme > Confirm
event {
  category: "Look & Feel"
  summary: "Global site theme changed"
  object: { argument { name: "Global theme"  source: CONST } }
  condition {
    url_pattern: "/admin/dochoosetheme.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Theme key"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalThemeNameTransformer"
  }
}

# Confluence administration > Colour Schemes > Theme Colour Scheme > Select
event {
  category: "Look & Feel"
  summary: "Global theme color scheme selected"
  object: { argument { name: "Theme colour scheme"  source: CONST } }
  condition {
    url_pattern: "/admin/dochangecolourscheme.action"
    parameter { name_pattern: "theme" }
    method: POST
  }
}

# Confluence administration > Colour Schemes > Custom Colour Scheme > Select
event {
  category: "Look & Feel"
  summary: "Custom global color scheme selected"
  object { argument { name: "Custom global color scheme"  source: CONST } }
  condition {
    url_pattern: "/admin/dochangecolourscheme.action"
    parameter { name_pattern: "custom" }
    method: POST
  }
}

# Confluence administration > Colour Schemes > Custom Colour Scheme > Edit > Reset
event {
  category: "Look & Feel"
  summary: "Custom global color scheme reset"
  object { argument { name: "Custom global color scheme"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditcolourscheme.action"
    parameter { name_pattern: "resetDefaults" }
    method: POST
  }
}

# Confluence administration > Colour Schemes > Custom Colour Scheme > Edit > Save
event {
  category: "Look & Feel"
  summary: "Custom global color scheme edited"
  object { argument { name: "Custom global color scheme"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditcolourscheme.action"
    parameter { name_pattern: "confirm" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Top bar"
    name: "Top bar text"
    name: "Header button background"
    name: "Header button text"
    name: "Top bar menu selected background"
    name: "Top bar menu selected text"
    name: "Top bar menu item text"
    name: "Menu item selected background"
    name: "Menu item selected text"
    name: "Search field background"
    name: "Search field text"
    name: "Page menu selected background"
    name: "Page menu item text"
    name: "Heading text"
    name: "Space name text"
    name: "Links"
    name: "Borders and dividers"
    name: "Tab navigation background"
    name: "Tab navigation text"
    name: "Tab navigation background highlight"
    name: "Tab navigation text highlight"
    phase: BEFORE_AND_AFTER
    transformer_name: "OldColorSchemeColorsBySpaceKeyTransformer"
  }
}

# Since Confluence 9.2.0
# Confluence administration > Colour Schemes > Custom Colour Scheme > Edit > Reset
event {
  category: "Look & Feel"
  summary: "Custom global color scheme reset"
  object { argument { name: "Custom global color scheme"  source: CONST } }
  condition { url_pattern: "/rest/api/color-scheme/reset" method: PUT }
}


# Since Confluence 9.1.0
# Confluence administration > Colour Schemes > Custom Colour Scheme > Edit > Save
event {
  category: "Look & Feel"
  summary: "Custom global color scheme edited"
  object { argument { name: "Custom global color scheme"  source: CONST } }
  condition {
    url_pattern: "/rest/api/color-scheme"
    condition_name: "ContainsChangedDetailsCondition"
    method: PUT
  }
  detail {
    name: "Top bar (Light theme)"
    name: "Top bar text (Light theme)"
    name: "Header button background (Light theme)"
    name: "Header button text (Light theme)"
    name: "Top bar menu selected background (Light theme)"
    name: "Top bar menu selected text (Light theme)"
    name: "Top bar menu item text (Light theme)"
    name: "Menu item selected background (Light theme)"
    name: "Menu item selected text (Light theme)"
    name: "Search field background (Light theme)"
    name: "Search field text (Light theme)"
    name: "Page menu selected background (Light theme)"
    name: "Page menu item text (Light theme)"
    name: "Heading text (Light theme)"
    name: "Space name text (Light theme)"
    name: "Links (Light theme)"
    name: "Borders and dividers (Light theme)"
    name: "Tab navigation background (Light theme)"
    name: "Tab navigation text (Light theme)"
    name: "Tab navigation background highlight (Light theme)"
    name: "Tab navigation text highlight (Light theme)"
    phase: BEFORE_AND_AFTER
    transformer_name: "OldColorSchemeColorsBySpaceKeyTransformer"
  }
  detail {
    name: "Top bar (Dark theme)"
    name: "Top bar text (Dark theme)"
    name: "Header button background (Dark theme)"
    name: "Header button text (Dark theme)"
    name: "Top bar menu selected background (Dark theme)"
    name: "Top bar menu selected text (Dark theme)"
    name: "Top bar menu item text (Dark theme)"
    name: "Menu item selected background (Dark theme)"
    name: "Menu item selected text (Dark theme)"
    name: "Search field background (Dark theme)"
    name: "Search field text (Dark theme)"
    name: "Page menu selected background (Dark theme)"
    name: "Page menu item text (Dark theme)"
    name: "Heading text (Dark theme)"
    name: "Links (Dark theme)"
    name: "Borders and dividers (Dark theme)"
    phase: BEFORE_AND_AFTER
    transformer_name: "OldDarkColorSchemeColorsBySpaceKeyTransformer"
  }
}

# Confluence administration > Layouts > Edit/Create custom
event {
  category: "Look & Feel"
  summary: "Global layout edited"
  object { transformer_name: "LayoutDecoratorUiNameBySystemNameTransformer" argument { name: "decoratorName" } }
  condition {
    url_pattern: "/admin/storedecorator.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Layout body"
    phase: BEFORE_AND_AFTER
    transformer_name: "LayoutDecoratorBodyByNameTransformer"
    argument { name: "decoratorName" }
  }
}

# Confluence administration > Layouts > Reset default
event {
  category: "Look & Feel"
  summary: "Global layout reset to default"
  object { transformer_name: "LayoutDecoratorUiNameBySystemNameTransformer" argument { name: "decoratorName" } }
  condition { url_pattern: "/admin/resetdecorator.action"  method: GET }
  detail {
    name: "Layout body"
    phase: BEFORE_AND_AFTER
    transformer_name: "LayoutDecoratorBodyByNameTransformer"
    argument { name: "decoratorName" }
  }
}

# Confluence administration > Stylesheet > Edit
event {
  category: "Look & Feel"
  summary: "Global stylesheet edited"
  object { argument { name: "Global stylesheet"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditstylesheet.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Stylesheet"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalStylesheetTransformer"
  }
}

# Confluence administration > Site Logo & Favicon > Save
event {
  category: "Look & Feel"
  summary: "Site logo and title edited"
  object { argument { name: "Site logo"  source: CONST } }
  condition {
    url_pattern: "/admin/sitelogo/upload.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Site title"
    name: "Display option"
    phase: BEFORE_AND_AFTER
    transformer_name: "SiteTitleTransformer"
  }
}

# Confluence administration > Site Logo & Favicon > Reset to default
event {
  category: "Look & Feel"
  summary: "Site logo reset to default"
  object { argument { name: "Site logo"  source: CONST } }
  condition { url_pattern: "/admin/sitelogo/reset.action"  method: GET }
}

# Confluence administration > Site Logo and Favicon > Save
event {
  category: "Look & Feel"
  summary: "Favicon edited"
  object { argument { name: "Site favicon"  source: CONST } }
  condition { url_pattern: "/admin/sitelogo/uploadFavicon.action"  method: POST }
}

# Confluence administration > Site Logo and Favicon > Reset to default
event {
  category: "Look & Feel"
  summary: "Favicon reset to default"
  object { argument { name: "Site favicon"  source: CONST } }
  condition { url_pattern: "/admin/sitelogo/resetFavicon.action"  method: GET }
}

# Confluence administration > Default Space Logo > ON
event {
  category: "Look & Feel"
  summary: "Default space logo enabled"
  object { argument { name: "Default space logo"  source: CONST } }
  condition { url_pattern: "/admin/enabledefaultspacelogo.action"  method: GET }
}

# Confluence administration > Default Space Logo > OFF
event {
  category: "Look & Feel"
  summary: "Default space logo disabled"
  object { argument { name: "Default space logo"  source: CONST } }
  condition { url_pattern: "/admin/disabledefaultspacelogo.action"  method: GET }
}

# Confluence administration > Default Space Logo > Upload
event {
  category: "Look & Feel"
  summary: "Default space logo edited"
  object { argument { name: "Default space logo"  source: CONST } }
  condition {
    url_pattern: "/admin/uploaddefaultspacelogo.action"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Logo download path"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalLogoTransformer"
  }
}

# Confluence administration > Default Space Logo > Rest to default
event {
  category: "Look & Feel"
  summary: "Default space logo reset"
  object { argument { name: "Default space logo"  source: CONST } }
  condition { url_pattern: "/admin/deletedefaultspacelogo.action"  method: GET }
  detail {
    name: "Logo download path"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalLogoTransformer"
  }
}

#TODO : add logic to show old and new detail values.
# Confluence administration > PDF Layout > Edit > Save
event {
  category: "Look & Feel"
  summary: "Global PDF layout updated"
  object { argument { name: "Global PDF layout"  source: CONST } }
  condition {
    url_pattern: "/admin/flyingpdf/doeditpdflayoutconfig.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    method: POST
  }
  detail { name: "PDF space export title page"  argument { name: "titlePage" } }
  detail { name: "PDF space export header"  argument { name: "header" } }
  detail { name: "PDF space export title footer"  argument { name: "footer" } }
}

#TODO : add logic to show old and new detail values.
# Confluence administration > PDF Stylesheet > Edit > Save
event {
  category: "Look & Feel"
  summary: "Global PDF stylesheet updated"
  object { argument { name: "Global PDF stylesheet"  source: CONST } }
  condition {
    url_pattern: "/admin/flyingpdf/doeditpdfstyleconfig.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    method: POST
  }
  detail { name: "PDF export stylesheet"  argument { name: "style" } }
}

#TODO : add logic to show old and new detail values.
# Confluence administration > Sidebar, header and footer > Save
event {
  category: "Look & Feel"
  summary: "Default custom page settings updated"
  object { argument { name: "Default custom page settings"  source: CONST } }
  condition {
    url_pattern: "/admin/docustompagecontent.action"
    parameter { name_pattern: "confirm"  value_pattern: "Save" }
    method: POST
  }
  detail { name: "Sidebar"  argument { name: "sidebarText" } }
  detail { name: "Header"  argument { name: "headerText" } }
  detail { name: "Footer"  argument { name: "footerText" } }
  ## NOTE: BEFORE_AND_AFTER state comparison can be added for Confluence 5.9+
  ## see com.atlassian.confluence.core.CustomPageSettingsManager (available since 5.9.0)
}

# Confluence administration > Custom HTML > Edit
event {
  category: "Look & Feel"
  summary: "Custom HTML edited"
  object { argument { name: "Custom HTML"  source: CONST } }
  condition {
    url_pattern: "/admin/doeditcustomhtml.action"
    parameter { name_pattern: "update"  value_pattern: "Save" }
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "At end of the HEAD"
    name: "At beginning of the BODY"
    name: "At end of the BODY"
    phase: BEFORE_AND_AFTER
    transformer_name: "GlobalCustomHtmlSettingsTransformer"
  }
}


### Add-on related events

# Confluence administration > Manage add-ons > select add-on > select module > Enable
event {
  category: "Add-ons"
  summary: "Add-on module enabled"
  object { transformer_name: "PluginNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "/rest/plugins/.+/(.+)-key/modules/(.+)-key$"
    parameter { name_pattern: "enabled"  value_pattern: "true" }
    method: PUT
  }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail { name: "Module key"  argument { name: "2"  source: URL } }
  detail { name: "Module name"  argument { name: "name" } }
}

# We need BEFORE event phase in case Auditor won't be able to log the event after module is disabled.
# But the downside of using BEFORE phase for all addons is that we are completely missing error validation.
# The fewer events we have with this phase, the better.
event {
  phase: BEFORE
  category: "Add-ons"
  summary: "Add-on module disabled"
  object {
    phase: BEFORE
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  condition {
    url_pattern: "plugins/[^/]+/(com.enhancera.auditor.confauditor)-key/modules/([^/]+)-key"
    method: PUT
    parameter { name_pattern: "enabled"  value_pattern: "false" }
  }
  detail { name: "Add-on key"  phase: BEFORE  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    phase: BEFORE
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail { name: "Module key"  phase: BEFORE  argument { name: "2"  source: URL } }
  detail { name: "Module name"  phase: BEFORE  argument { name: "name" } }
}
# Confluence administration > Manage add-ons > select add-on > select module > Disable
event {
  category: "Add-ons"
  summary: "Add-on module disabled"
  object {
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  condition {
    url_pattern: "/rest/plugins/.+/(.+)-key/modules/(.+)-key$"
    parameter { name_pattern: "enabled"  value_pattern: "false" }
    method: PUT
  }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail { name: "Module key"  argument { name: "2"  source: URL } }
  detail { name: "Module name"  argument { name: "name" } }
}

# Confluence administration > Manage add-ons > select add-on > Enable
event {
  category: "Add-ons"
  summary: "Add-on enabled"
  object { argument { name: "name" } }
  condition {
    url_pattern: "/rest/plugins/.+/(.+)-key$"
    parameter { name_pattern: "enabled"  value_pattern: "true" }
    method: PUT
  }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail { name: "Add-on name"  argument { name: "name" } }
}

# We need BEFORE event phase because Auditor won't be able to log the event after it is disabled.
# But the downside of using BEFORE phase for all addons is that we are completely missing error validation.
# The fewer events we have with this phase, the better.
event {
  phase: BEFORE
  category: "Add-ons"
  summary: "Add-on disabled"
  object { phase: BEFORE  argument { name: "name" } }
  condition {
    url_pattern: "/plugins/[^/]+/(com.enhancera.auditor.confauditor)-key$"
    method: PUT
    parameter { name_pattern: "enabled"  value_pattern: "false" }
  }
  detail { name: "Add-on key"  phase: BEFORE  argument { name: "1"  source: URL } }
  detail { name: "Add-on name"  phase: BEFORE  argument { name: "name" } }
}
# Confluence administration > Manage add-ons > select add-on > Disable
event {
  category: "Add-ons"
  summary: "Add-on disabled"
  object { argument { name: "name" } }
  condition {
    url_pattern: "/rest/plugins/.+/(.+)-key$"
    parameter { name_pattern: "enabled"  value_pattern: "false" }
    method: PUT
  }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail { name: "Add-on name"  argument { name: "name" } }
}


# Specific handling for Auditor
event {
  category: "Add-ons"
  summary: "Add-on license updated"
  object { transformer_name: "PluginNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "plugins/[^/]+/(com.enhancera.auditor.confauditor)-key/license/?$"
    method: PUT
    condition_name: "ContainsChangedDetailsCondition"
  }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "License type"
    name: "License expiration date"
    name: "Support Entitlement Number"
    phase: BEFORE_AND_AFTER
    transformer_name: "AuditorLicenseDetailsTransformer"
  }
}
event {
  category: "Add-ons"
  summary: "Add-on license updated"
  object { transformer_name: "PluginNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "plugins/servlet/upm/license/(com.enhancera.auditor.confauditor)$"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "License type"
    name: "License expiration date"
    name: "Support Entitlement Number"
    phase: BEFORE_AND_AFTER
    transformer_name: "AuditorLicenseDetailsTransformer"
  }
}
# Confluence administration > Manage add-ons > select add-on > paste license key > Update
event {
  category: "Add-ons"
  summary: "Add-on license updated"
  object { transformer_name: "PluginNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition { url_pattern: "/rest/plugins/.+/(.+)-key/license"  method: PUT }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
}

# Confluence administration > Manage add-ons > select add-on > go to my.atlassian.com > apply
event {
  category: "Add-ons"
  summary: "Add-on license updated"
  object { transformer_name: "PluginNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition { url_pattern: "/upm/license/([^/]+)"  method: POST }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
}

# We need BEFORE event phase because Auditor won't be able to log the event after license is deleted.
# But the downside of using BEFORE phase for all addons is that we are completely missing error validation.
# The fewer events we have with this phase, the better.
event {
  phase: BEFORE
  category: "Add-ons"
  summary: "Add-on license removed"
  object {
    phase: BEFORE
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  condition {
    url_pattern: "plugins/[^/]+/(com.enhancera.auditor.confauditor)-key/license/?$"
    method: DELETE
  }
  detail { name: "Add-on key"  phase: BEFORE  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    phase: BEFORE
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "License type"
    name: "License expiration date"
    name: "Support Entitlement Number"
    phase: BEFORE
    transformer_name: "AuditorLicenseDetailsTransformer"
  }
}
# Confluence administration > Manage add-ons > select add-on > erase license key > Update
event {
  category: "Add-ons"
  summary: "Add-on license removed"
  object {
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  condition { url_pattern: "/rest/plugins/.+/(.+)-key/license"  method: DELETE }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
}

# We need BEFORE event phase in case Auditor won't be able to log the event after it is uninstalled.
# But the downside of using BEFORE phase for all addons is that we are completely missing error validation.
# The fewer events we have with this phase, the better.
event {
  phase: BEFORE
  category: "Add-ons"
  summary: "Add-on uninstalled"
  object { phase: BEFORE  transformer_name: "PluginNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition {
    url_pattern: "plugins/[^/]+/(com.enhancera.auditor.confauditor)-key$"
    method: DELETE
  }
  detail { name: "Add-on key"  phase: BEFORE  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    phase: BEFORE
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Add-on version"
    phase: BEFORE
    transformer_name: "PluginVersionByKeyTransformer"
    argument { name: "1"  source: URL }
  }
}

# Confluence administration > Manage add-ons > select add-on > Uninstall
event {
  category: "Add-ons"
  summary: "Add-on uninstalled"
  object { phase: BEFORE  transformer_name: "PluginNameByKeyTransformer"  argument { name: "1"  source: URL } }
  condition { url_pattern: "/rest/plugins/.+/(.+)-key$"  method: DELETE }
  detail { name: "Add-on key"  argument { name: "1"  source: URL } }
  detail {
    name: "Add-on name"
    phase: BEFORE
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "1"  source: URL }
  }
  detail {
    name: "Add-on version"
    phase: BEFORE
    transformer_name: "PluginVersionByKeyTransformer"
    argument { name: "1"  source: URL }
  }
}

# Confluence administration > Find new add-ons > select add-on > Install
event {
  category: "Add-ons"
  summary: "Add-on installed"
  object { argument { name: "pluginName" } }
  condition {
    url_pattern: "/rest/plugins/.+/$"
    parameter { name_pattern: "pluginName" }
    parameter { name_pattern: "pluginUri" }
    method: POST
  }
  detail { name: "Add-on name"  argument { name: "pluginName" } }
  detail { name: "Add-on version"  argument { name: "pluginVersion" } }
  detail { # Version is not updated at the end of this request, hence BEFORE_AND_AFTER phase will not work
    name: "Old version"
    phase: BEFORE
    transformer_name: "PluginVersionByNameTransformer"
    argument { name: "pluginName" }
  }
  detail { name: "Add-on URI"  argument { name: "pluginUri" } }
}

# Confluence administration > Find new add-ons > select add-on > Upload
event {
  category: "Add-ons"
  summary: "Add-on uploaded"
  object {
    transformer_name: "FilenameByRequestBodyTransformer"
    argument { source: BODY }
  }
  condition {
    url_pattern: "/rest/plugins/.+/$"
    method: POST
  }
  detail {
    name: "File name"
    transformer_name: "FilenameByRequestBodyTransformer"
    argument { source: BODY }
  }
}

# Confluence administration > Manage apps > select add-on > Free trial
event {
  category: "Add-ons"
  summary: "Add-on license requested"
  object {
    transformer_name: "PluginNameByKeyTransformer"
    argument { name: "data.pk" }
  }
  condition  {
    url_pattern: "/plugins/[^/]+/analytics/?$"
    method: POST
    parameter { name_pattern: "data.type"  value_pattern: "try" }
    parameter { name_pattern: "data.pk"  value_pattern: ".*" }
  }
}


# Audit log parameters
event {
  category: "Auditor"
  summary: "Auditor setting edited"
  object: { argument { name: "Auditor"  source: CONST } }
  condition {
    url_pattern: "/auditlog/[^/]+/settings"
    condition_name: "ContainsChangedDetailsCondition"
    method: POST
  }
  detail {
    name: "Retention period"
    name: "Number of events per page"
    name: "System admin access only"
    name: "Notified users"
    name: "Write events to file"
    name: "File path"
    name: "Write events to syslog"
    name: "Syslog host"
    name: "Syslog facility"
    name: "Syslog level"
    phase: BEFORE_AND_AFTER
    transformer_name: "AuditorSettingsTransformer"
  }
}


### Error patterns

# HipChat integration removing and Site logo updating requests response contains 'class="error"' in case of success.
# Negative lookbehind/lookahead assertions added to ignore these cases.
error_pattern: "(?<!((placeholder=\"http://www.hipchat.com\"></input>)|(id=\"logo-reset\">.{10,200}?</a></div>))<div )class=\"error\"(?! id=\"btf-error\">)"
# Atlassian support zip file creation response contains 'class="aui-message error"' in case of success.
# Negative lookbehind assertion added to ignore this case
error_pattern: "(?<!<div id=\"stp-zip-errors\" )class=\"aui-message\\s+error.*\""
error_pattern: "class=\"aui-message\\s+aui-message-error.*"
