atlassian-connect-descriptor-0.2.0.1: Code that helps you create a valid Atlassian Connect Descriptor.

Copyright(c) Robert Massioli, 2014
LicenseAPACHE-2
Maintainerrmassaioli@atlassian.com
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Data.Connect.Descriptor

Contents

Description

This module provides the data types to let you write your own typesafe Atlassian Connect descriptor and it comes with Aeson bindings so that you can easily convert into json: the format that the Atlassian Connect framework expects.

Atlassian Connect is a framework for writing Add-on's that can run inside the Atlassian Cloud products. You can find more information from the Atlassian Connect documentation https://developer.atlassian.com/static/connect/docs/guides/introduction.html.

The plugin descriptor is defined by the Plugin class. The end result of using this Haskell Module should be for you to end up with a valid Plugin. To turn your plugin into JSON that the Atlassian marketplace can accept just use the encode function from the Aeson library. For example, here in an example Atlassian Connect Descriptor:

pluginToJsonString :: Plugin -> ByteString
pluginToJsonString = encode

exampleDescriptor :: Plugin
exampleDescriptor = (pluginDescriptor (PluginKey "my-example-connect") baseURL (Authentication Jwt))
    { pluginName = Just . Name $ "My Example Connect Addon"
    , pluginDescription = Just "This is an example connect descriptor."
    , vendor = Just $ Vendor (Name "Awesome Devs") (toURI "http://awesome-devs.com")
    , lifecycle = Just defaultLifecycle
    , modules = Just exampleModules
    , enableLicensing = Just False
    , links = fromList
        [ ("documentation", toURI "http://awesome-devs.com/docs")
        , ("source", toURI "http://bitbucket.org/awesome-devs/connect-addon")
        ]
    , scopes = Just [Read, Admin]
    }

exampleModules :: Modules
exampleModules = Modules exampleJIRAModules emptyConfluenceModules

exampleJIRAModules :: JIRAModules
exampleJIRAModules = emptyJIRAModules
    { jiraWebPanels =
        [ WebPanel
            { wpKey = "test-web-panel"
            , wpName = Name "Test Web Panel"
            , wpLocation = "some-location-in-jira"
            , wpUrl = "/panel/location/for"
            , wpConditions = [staticJiraCondition UserIsAdminJiraCondition]
            }
        ]
    , jiraGeneralPages =
        [ GeneralPage
            { generalPageKey = "test-general-page"
            , generalPageName = Name "Test General Page"
            , generalPageLocation = Just "some-other-location-in-jira"
            , generalPageWeight = Just 1234
            , generalPageUrl = "/panel/general-page"
            , generalPageIcon = Just IconDetails
                { iconUrl = "/static/path/to/icon.png"
                , iconWidth = Just 20
                , iconHeight = Just 40
                }
            , generalPageConditions = [staticJiraCondition UserHasIssueHistoryJiraCondition]
            }
        ]
    , jiraWebhooks =
        [ Webhook
            { webhookEvent = JiraIssueDeleted
            , webhookUrl = "/webhook/handle-deletion"
            }
        ]
    }

You can use this library to make your own. This library will experience change whenever the Atlassian Connect descriptor changes. There are likely to be many breaking changes but we will keep track of them using the standard Haskell version structure.

Synopsis

Atlassian Connect Add-on Descriptor

data Plugin Source

A Plugin is the end result of an Atlassian Connect descriptor. It is what you should provide to the Atlassian Marketplace in order to register your plugin and it is what your Atlassian Cloud customers will download to install your Add-on via the Atlassian UPM (Universal Plugin Manager). Only a very small number of fields are strictly required to generate a valid Atlassian Connect plugin descriptor. Everything that is optional is marked by a maybe type.

Even though we provide documentation here you shoucd check the Atlassian Connect Descriptor documentation if you want to get accurate information on the contents of a plugin: https://developer.atlassian.com/static/connect/docs/modules/

Constructors

Plugin 

Fields

pluginKey :: PluginKey

Plugin keys are required. The important detail about this key is that it should be unique across the Atlassian Marketplace. For example, a good key might be com.yourcompanyorpersonalname.youraddonname because it would be unique in the marketplace.

pluginBaseUrl :: URI

Every plugin must specify a base url where all other relative URI's in the plugin will call to in production. This is the url that the Atlassian Marketplace will query for your descriptor and the url that your customers will come in on. This is especially important for load balanced applications and will also likely be different in your staging and production environments.

authentication :: Authentication

The authentication type that you plugin requires. See Authentication for more details.

pluginName :: Maybe (Name Plugin)

While your add-on does not require a name it is strongly recommended as this is the human readable name that will appear in the UPM amongst other places.

pluginDescription :: Maybe Text

You should give your add-on a description. This description will appear in multiple locations on the Atlassian Marketplace and UPM and will be used to explain what your add-on does.

vendor :: Maybe Vendor

You are the Vendor. Put your details here!

lifecycle :: Maybe Lifecycle

Atlassian Connect addon's have a lifecycle. Register your handlers for the Lifecycle events here so that you can tell, for example, when your addon is installed or enabled.

modules :: Maybe Modules

The modules that your Atlassian Connect add-on provides to the Cloud application. Look at the Modules documentaiton for more information.

apiVersion :: Maybe Text

Required if you wish to provide new versions of your addon to a subset of beta customers.

enableLicensing :: Maybe Bool

If you are giving away a free add-on then you can set this to false, otherwise set it to true.

links :: HashMap Text URI

A collection of custom links that you wish to publish with your add-on. Like documentation or bug-tracking links.

scopes :: Maybe [ProductScope]

The scopes that your add-on requires. See ProductScope for more information.

pluginDescriptor Source

Arguments

:: PluginKey

The key for your add-on.

-> URI

The base url for your add-on.

-> Authentication

The authentication that your add-on requires.

-> Plugin

A bare-bones Atlassian Connect descriptor.

A helper method to generate a bare-bones Atlassian Connect add-on by providing only the absolutely required fields. You can then use Haskell record syntax to update the plugin with more details. For example:

(pluginDescriptor (PluginKey . pack $ "com.company.mycoolplugin") (fromJust . parseURI $ "http://mycoolplugin.company.com") (Authentication Jwt))
   { pluginName = Just . Name . pack $ "My Cool Plugin"
   , pluginDescription = Just . pack $ "Chil and be cool, you have a plugin descriptor."
   }

Basic Types

data Name a Source

Atlassian Connect descriptors contain many names: module names, add-on names, vendor names etc. We want to make sure that these names don't get put in places that they do not belong. Or, if they do get moved around, they get moved around specifically. We are just adding type saefty to names.

Constructors

Name Text 

data Key t a Source

This data type represents a Key for a particular data type.

Constructors

Key t 

Instances

Eq t => Eq (Key t a) 
Show t => Show (Key t a) 
Generic (Key t a) 
type Rep (Key t a) 

data PluginKey Source

This data type represents an Atlassian Connect Add-on key.

Constructors

PluginKey Text 

newtype Timeout Source

Represents a timeout in seconds.

Constructors

Timeout Second 

data IconDetails Source

Represents an arbitrary icon. Potentially for an Atlassian Connect module or for the entire add-on itself.

Constructors

IconDetails 

Fields

iconUrl :: Text

The URI to the icon.

iconWidth :: Maybe Integer

The width of the icon.

iconHeight :: Maybe Integer

The height of the icon.

data Length Source

A basic length type for HTML elements. Useful for WebPanels and other modules that may require length specifications.

Constructors

Pixels Integer

Specify a length in pixels

Percentage Integer

Specify a length as a percentage in the range [0-100].

Authentication

data Authentication Source

If your Atlassian Connect addon wants to perform any server side communication with the host product then you will need to use authentication. Otherwise you should specify that you don't need authentication.

Constructors

Authentication 

Fields

authType :: AuthType

The authentication type that you wish to use.

data AuthType Source

The authentication type that you wish to use in your Add-on.

Constructors

Jwt

If you need to communicate with the host product then you will want to request JWT authentication.

None

If you do not need to communicate the host product then you should request None for authentication.

Vendor Details

data Vendor Source

Represents the Vendor of the add-on; which will be you. Put your details in this structure.

Constructors

Vendor 

Fields

vendorName :: Name Vendor

Your name as a Vendor. Might be your personal name or your business name.

vendorUrl :: URI

A URL to a website that represents you as a vendor.

Lifecycle

data Lifecycle Source

Every Atlassian Connect add-on can be installed, uninstalled, enabled and disabled. These are known as Lifecycle events. These events will fire on each and every Cloud instance that your add-on is installed on. You can request in your Atlassian Connect add-on descriptor to be alerted of lifecycle events. When the event fires, if you have requested it, you will be given the details of the event in a JSON blob by the host application.

The lifecycle events are documented fully in the Atlassian Connect documentation: https://developer.atlassian.com/static/connect/docs/modules/lifecycle.html

It is important to note that the installed event is particularily important to any Atlassian Connect add-on that needs to use Jwt auth tokens because the installed handler will come with the shared secret for your add-on on that particular instance.

Constructors

Lifecycle 

Fields

installed :: Maybe URI

Potential relative URI to call every time an add-on is installed on an instance.

uninstalled :: Maybe URI

Potential relative URI to call every time an add-on is uninstalled on an instance.

enabled :: Maybe URI

Potential relative URI to call every time an add-on is enabled on an instance.

disabled :: Maybe URI

Potential relative URI to call every time an add-on is disabled on an instance.

emptyLifecycle :: Lifecycle Source

The empty Lifecycle allowing you to specify exactly which events you wish to handle with Haskell record syntax.

defaultLifecycle :: Lifecycle Source

The default Lifecycle where installed goes to /installed and so on and so forth for every lifecycle event. You can choose to disclude certain events by Nothing them out.

Add-on Modules

data Modules Source

Modules are perhaps the most important part of your Atlassian Connect descriptor. They specify which parts of the host application you wish to inject content into. They provide your entry point into the host application.

Atlassian Connect provides a large set of pre-defined entry points into the host application. Some of which are common to every application and some of which are unique to the particular application that you are targeting:

Note: One important point about modules: they must all have a key and that key must be unique inside the same Atlassian Connect addon.

Constructors

Modules 

Fields

jiraModules :: JIRAModules

All of the JIRA Modules that you wish to define.

confluenceModules :: ConfluenceModules

All of the Confluence modules that you wish to define.

data JIRAModules Source

A collection of all of the JIRA Modules that you can define. For more documentation on which Modules are supported the Atlassian Connect framework please see Modules. You can also find more documentation on each of the modules.

emptyJIRAModules :: JIRAModules Source

Empty JIRA Modules; useful when you only want to define a few modules via Haskell record syntax.

data ConfluenceModules Source

A collection of all of the Confluence Modules that you can define. For more documentation on which Modules are supported the Atlassian Connect framework please see Modules. You can also find more documentation on each of the modules.

emptyConfluenceModules :: ConfluenceModules Source

Empty Confluence Modules; useful when you only want to define a few modules via Haskell record syntax.

data WebPanel Source

A WebPanel is an injectable segment of the host application that you can place content inside. Currently the WebPanel has the same structure for both JIRA and Confluence but, potentially, that could change in the future. You can read their Atlassian Connect documentation here:

Here is what an example Hello World web panel might look like:

helloWorldWebPanel = WebPanel
   { wpKey = "hello-world"
   , wpName = Name "Hello world!"
   , wpUrl = "/panel/show-hello-world"
   , wpLocation = "atl.jira.view.issue.right.context"
   , wpConditions = [staticJiraCondition UserIsLoggedInJiraCondition]
   }
   where
      toURI = fromJust . parseRelativeReference

WebPanels are a great way to inject your add-on's content into the host application.

Constructors

WebPanel 

Fields

wpKey :: Text

The add-on unique key for this module.

wpName :: Name WebPanel

The name of this panel, likely to appear in the User Interface.

wpUrl :: Text

The relative URI that the host product will hit to get HTML content.

wpLocation :: Text

The location that this content should be injected in the host product.

wpConditions :: [Condition]

The Conditions that need to be met for this module to be displayed.

wpWeight :: Maybe Integer
 
wpLayout :: Maybe WebPanelLayout
 

data WebPanelLayout Source

A WebPanelLayout allows you to specify the dimensions of your Web Panel if that is required.

Constructors

WebPanelLayout 

data GeneralPage Source

A GeneralPage makes your add-on take a large section of screen realestate, with the intention of displaying your own page with no other distracting content. This is very useful for pages like Configuration screens or Statistics pages where you really want the user to be fully working with your add-on inside the host product.

General pages, like Web Panels, are common to JIRA and Confluence and share the same json format. However they have separate documentation:

Even though, at this point in time, the documentation looks identical.

Constructors

GeneralPage 

Fields

generalPageKey :: Text

The add-on unique key for this module.

generalPageName :: Name GeneralPage

The name of this General Page. Likely to be used in the page title.

generalPageUrl :: Text

The relative URI that the host product will hit to get the HTML content for the page.

generalPageLocation :: Maybe Text

The location for this General Page to display; see the docs for your options.

generalPageIcon :: Maybe IconDetails

The optional icon to use for this general page.

generalPageWeight :: Maybe Integer

Determines the order that this item appears in any menu or list. Lower numbers mean that it will appear higher in the list.

generalPageConditions :: [Condition]

The Conditions that need to be met for this module to be displayed.

data JIRAProjectAdminTabPanel Source

A JIRAProjectAdminTabPanel is useful for when you want to add a page to the administration screens of a project. This module will create a web item in the sidebar of every project for you and provide a web panel in the JIRA Project Admin section.

Webhooks

data Webhook Source

When users of the host application perform updates your Atlassian Connect add-on will not be alerted unless it listens to the WebhookEvents coming from that application. Webhooks are the way to close the issue recency loop in the Atlassian products. It is important to note that Webhooks are 'best effort' and that there is no guarantee that the webhook will make it to your Atlassian Connect application.

The Atlassian connect webhook documentation explains this in more detail: https://developer.atlassian.com/static/connect/docs/modules/jira/webhook.html

Constructors

Webhook 

Fields

webhookEvent :: WebhookEvent

The event that you want your Atlassian Connect add-on to watch.

webhookUrl :: Text

The relative URI that you wish to handle the webhook response.

data WebhookEvent Source

The webhook event that you wish to watch from your Atlassian Connect add-on.

Module Conditions

data Condition Source

A Condition can be placed on an Atlassian Connect Module to cause it to display or not based on the result it returns. For example, you can choose not to show a WebPanel if the user viewing the page is not logged in. Conditions are very useful in curating when your modules will appear to your users.

The Atlassian Connect documentation describes conditions fully: https://developer.atlassian.com/static/connect/docs/concepts/conditions.html

Constructors

SingleCondition

A single condition based on a source.

Fields

conditionSource :: ConditionSource

The source of this condition.

conditionInverted :: Bool

If you should invert the condition. For example, only show if user is NOT logged in.

conditionParams :: HashMap String String

Extra parameters to pass with the condition to give it context.

CompositeCondition

A condition that is the composition of one or more conditions. The ConditionType decides the way in which the conditions are composed

Fields

subConditions :: [Condition]

The conditions that will be merged together.

conditionType :: ConditionType

The way in which the conditions will be merged together.

data ConditionType Source

Composite Conditions can be joined together to behave as a single condition. The way that you can join them together is decided by the condition type.

Constructors

AndCondition

The boolean intersection of the conditions.

OrCondition

The boolean union of the conditions.

data ConditionSource Source

Conditions can be specified by the Host application or by the Atlassian Connect add-on itself. This means that the source of the condition needs to be specified and that is what you can use this data type to do.

Constructors

StaticJIRACondition JIRACondition

A static JIRA condition.

StaticConfluenceCondition ConfluenceCondition

A static Confluence condition.

RemoteCondition

A remote condition defined by your Atlassian Connect application.

Fields

remoteConditionPath :: String

The relative URI that you should hit in your Atlassian Connect application to get the condition result. This URI, when hit, should return a JSON response in the format:

{ "shouldDisplay": <true|false> }

remoteCondition :: String -> Condition Source

Given a URI that defines a remote condition convert it into a regular Condition.

staticJiraCondition :: JIRACondition -> Condition Source

Turn a standard JIRA Condition into a regular Condition.

data ConfluenceCondition Source

The conditions that have been provided by Confluence. Please see the single condition documentation for more details: https://developer.atlassian.com/static/connect/docs/modules/fragment/single-condition.html

Constructors

ActiveThemeConfluenceCondition 
CanEditSpaceStylesConfluenceCondition 
CanSignupConfluenceCondition 
ContentHasAnyPermissionsSetConfluenceCondition 
CreateContentConfluenceCondition 
EmailAddressPublicConfluenceCondition 
FavouritePageConfluenceCondition 
FavouriteSpaceConfluenceCondition 
FeatureFlagConfluenceCondition 
FollowingTargetUserConfluenceCondition 
HasAttachmentConfluenceCondition 
HasBlogPostConfluenceCondition 
HasPageConfluenceCondition 
HasSpaceConfluenceCondition 
HasTemplateConfluenceCondition 
LatestVersionConfluenceCondition 
NotPersonalSpaceConfluenceCondition 
PrintableVersionConfluenceCondition 
ShowingPageAttachmentsConfluenceCondition 
SpaceFunctionPermissionConfluenceCondition 
SpaceSidebarConfluenceCondition 
TargetUserCanSetStatusConfluenceCondition 
TargetUserHasPersonalBlogConfluenceCondition 
TargetUserHasPersonalSpaceConfluenceCondition 
ThreadedCommentsConfluenceCondition 
TinyUrlSupportedConfluenceCondition 
UserCanCreatePersonalSpaceConfluenceCondition 
UserCanUpdateUserStatusConfluenceCondition 
UserCanUseConfluenceConfluenceCondition 
UserFavouritingTargetUserPersonalSpaceConfluenceCondition 
UserHasPersonalBlogConfluenceCondition 
UserHasPersonalSpaceConfluenceCondition 
UserIsAdminConfluenceCondition 
UserIsConfluenceAdministratorConfluenceCondition 
UserIsLoggedInConfluenceCondition 
UserIsSysadminConfluenceCondition 
UserLoggedInEditableConfluenceCondition 
UserWatchingPageConfluenceCondition 
UserWatchingSpaceConfluenceCondition 
UserWatchingSpaceForContentTypeConfluenceCondition 
ViewingContentConfluenceCondition 
ViewingOwnProfileConfluenceCondition 

staticConfluenceCondition :: ConfluenceCondition -> Condition Source

Turn a standard Confluence Condition into a regular Condition.

invertCondition :: Condition -> Condition Source

Invert the given condition.

Scopes (Permissions)

data ProductScope Source

Scopes are an Atlassian Connect concept that declare how much access your addon requires to any give Cloud instance. These scopes can be thought of as permissions are are well documented: https://developer.atlassian.com/static/connect/docs/scopes/scopes.html

It is important to note that these scopes only give you restricted access to certain REST resources. You can not query any REST url as you would with an Atlassian Server plugin. The restricted set of REST resources per application can be found in the Atlassian Connect documentation.

Constructors

Read

The read scope means that you can pull data from the Cloud application.

Write

The write scope gives you the same access as a regular user of the Atlassian connect application.

Delete

The delete scope is required if you want to perform potentially destructive operations on data.

ProjectAdmin

A JIRA specific scope. Lets your add-on administer a project in JIRA.

SpaceAdmin

A Confluence specific scope. Lets your add-on administer a space in Confluence.

Admin

Gives your Atlassian Connect add-on administrative rights to the Cloud instance. (But NOT system administrator permission. Happily you cannot request that level of access.)