GithubHelp home page GithubHelp logo

atlassian-connect-bundle's Introduction

Atlassian Connect Bundle

Build Status Code Coverage Scrutinizer Code Quality License Latest Stable Version Total Downloads

About

Symfony Bundle for Atlassian Connect platform

Installation

Step 1. Add bundle to composer dependencies

composer require thecatontheflat/atlassian-connect-bundle

Step 2. Enable the bundle

Add the bundle to config/bundles.php

<?php

return [
    // ... other bundles
    AtlassianConnectBundle\AtlassianConnectBundle::class => ['all' => true],
]

Step 3. Bundle configuration

The bundle descriptor is used to install your app on Atlassian. When requesting descriptor - this configuration is converted to JSON.

Sample configuration in packages/atlassian-connect.yaml:

    atlassian_connect:
        dev_tenant: 1
        descriptor:
            key: 'your-addon-key'
            name: 'Your Add-On Name'
            description: 'Your Add-On Description'
            authentication:
            	type: jwt
            vendor:
                name: 'Your Vendor Name'
                url: 'https://marketplace.atlassian.com/vendors/1211528'
            baseUrl: 'https://your-production-domain.com/'
            lifecycle:
                installed: '/handshake'
            scopes: ['READ', 'WRITE', 'ACT_AS_USER'] # If you want get oauth_client_id need to add scope ACT_AS_USER
            modules:
                jiraIssueTabPanels:
                    -
                        key: 'your-addon-key-tab'
                        url: '/protected/list?issue=${issue.key}'
                        weight: 100
                        name:
                            value: 'Tab Name'

If you need to overwrite any config in dev/test environment, overwrite that config in the packages/{env}/atlassian-connect.yaml file.

Step 4. Security configuration

To configure security part - use the following configuration in your security.yml. If you have another firewall that has the "^/" pattern, be sure to set the jwt_secured_area firewall first.

    security:
        enable_authenticator_manager: true
        providers:
            jwt_user_provider:
                id: jwt_user_provider
        firewalls:
            jwt_secured_area:
                custom_authenticators:
                    - AtlassianConnectBundle\Security\JWTAuthenticator
                pattern: "^/protected"
                stateless: true
                provider: jwt_user_provider
                # If you also need an entry_point
                entry_point: AtlassianConnectBundle\Security\JWTAuthenticator

Step 5. Include Routes

Add the following configuration to config/routes.yaml:

    ac:
        resource: "@AtlassianConnectBundle/Resources/config/routing.php"

Step 6. (Optional): Configure License Check

To perform a license check for a certain route - specify the requires_license default in your routing.yml

    some_route:
        path: ...
        defaults:
            requires_license: true

Step 7. Update Database

bin/console doctrine:schema:update --force

Usage Examples

Signed Request

In your protected controller action you can make a signed request to JIRA instance:

<?php declare(strict_types = 1);

namespace App\Controller;

use AtlassianConnectBundle\Service\AtlassianRestClient;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

/**
 * @Route("/protected")
 */
class ProtectedController extends Controller
{
    /**
     * @Route("/", name="main")
     */
    public function index()
    {
        $client = $this->container->get(AtlassianRestClientInterface::class);
        // Or
        // $client = $this->container->get('atlassian_connect_rest_client');
        
        // If you are not in a security context fetch the tenant first
        // $client->setTenant($tenant);
        
        // If you want to impersonate the user
        // $client->actAsUser($this->getUser()->getUserName())
        
        // Send request from anonymous plugin user
        $issue = $client->get('/rest/api/2/issue/KEY-XXX');
        
        // Send request from choosen user
        $user = $client
            ->setUser('5ds4e4352a12451789b13243') // the accountId of the user in Jira/Confluence etc.
            ->get('/rest/api/2/myself')
        ;
        
        return new Response([$issue, $user]);
    }
}

Whitelisting licences

You could whitelist any licence by editing related row in table tenant and setting field is_white_listed to 1. If you will also set white_listed_until - you will be able to set whitelist expiration

Dev environment

In dev environment Tenant with id=1 would be used automatically. You could set configuration variable atlassian_connect.dev_tenant to false in order to disable it, or use another dev tenant id. It would allow you to test your plugin output for any tenant.

Custom tenant entity

If you need to add more properties to tenant entity or reverse-side of your app entity relations - you could override default Tenant entity like

<?php
    namespace AppBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use AtlassianConnectBundle\Entity\TenantTrait;
    use AtlassianConnectBundle\Entity\TenantInterface;
    use Symfony\Component\Security\Core\User\UserInterface;
     
    /**
     * JiraTenant
     *
     * @ORM\Table()
     * @ORM\HasLifecycleCallbacks()
     * @ORM\Entity()
     */
    class JiraTenant implements UserInterface, TenantInterface
    {
        /**
         * @ORM\OneToMany(type="MyEntity", mappedBy="jiraTenant")
         */
        protected $myEntities;
    
        use TenantTrait;    
    
        // getters/setters for your custom properties
    }

And override default one by setting parameter

    atlassian_connect_tenant_entity_class: AppBundle\Entity\JiraTenant

In order to use it you will need to disable doctrine automapping

    auto_mapping: false
        mappings:
            AppBundle: ~

Troubleshooting

Cant start free trial of my plugin on Jira Cloud

As soon as you will create your plugin - you will be able to access plugin manifest via url https://yourplugindomain.com/atlassian-connect.json

You will be able to setup it in "Manage Addons" section of your Jira Cloud using "Upload addon" interface. But right now AtlassianConnectBundle support only "paid via Atlassian" model, so you will not be able to start your trial.

Instead of using manifest url directly - you should add private listing of your plugin, create token and get manifest url like

https://marketplace.atlassian.com/files/1.0.0-AC/artifact/descriptor/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/atlassian-connect.json?access-token=xxxxxxxx

If you will use that url from marketplace - your trial will be started automatically.

atlassian-connect-bundle's People

Contributors

akorolyov avatar brammm avatar bukashk0zzz avatar matth-- avatar nicrodgers avatar thecatontheflat avatar wslaghekke avatar zhil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

atlassian-connect-bundle's Issues

ACT_AS_USER scope

Atlassian added pretty cool feature, ACT_AS_USER

From what I see, this feature would require this bundle changes.

@thecatontheflat
It looks like good improvement for your toggl plugin (plugin will be able to submit time for users in background), will you be interested in adding ACT_AS_USER to this bundle?

Add new tag

Last tag 0.1.0 - is outdated, current master version seems to be pretty stable - what about adding new tag?

Tests

Would be nice to have tests

Refresh Token

Is there a way to use refresh tokens? Reloading the entire JIRA page is slow and submitted form data is also lost in case the token expires between rendering a form and submitting it.

If there is no option to use refresh tokens, can we at least get a way to bypass immediate termination to implement some kind of fallback that could e.g. displays cached data?

[4.0] Move to PHP CS Fixer

We should move to PHP CS fixer as it has default styles available for Symfony and psr2.
Also, docblocks are not required anymore when types are implemented decently.

Missing documentation about authentication and scope

I'm trying to install this app and I'm getting this error on jira side.

The app descriptor failed to validate against the schema. Please confirm this app is intended for use with JIRA and then contact the app vendor.
  : object has missing required properties (["authentication"])

I know that I can get this error go away by setting:

atlassian_connect:
    prod:
        authentication:
            type: none

Then installation works but I'm not getting tenant oauth_client_id and shared_secret.

If I set type: jwt then I get shared_secret. But still no oauth_client_id.

Now I figured to get oauth_client_id I need to request specific scopes:

    scopes: ['READ', 'WRITE', 'ACT_AS_USER']

So all is working just missing documentation. Please add to docs that

  • to get oauth_client_id need to add scope
  • authentication needs to be set so installation will work and maybe set it to jwt as default

[4.0] Use typed properties

Try to use typed properties as much as we can. As PHP version 7.4 is still supported, union types cannot be used yet.

Security vulnerability

Dear Atlassian Connect vendor,

We've found a vulnerability in one or more of your add-ons, managed by the vendor at this email address. It lets an attacker overwrite the shared secret for an existing installation by crafting a malicious install callback. This will break the add-on on the targeted host product. It will also enable the attacker to sign JWTs with the new secret to authenticate with the add-on service and access protected data for that installation.

Fixing the vulnerability:

After a connect add-on is installed on a host product for the first time, the host will secure every subsequent install callback using a JSON Web Token (JWT) signed with the existing shared secret (not the new shared secret in the request body). The JWT will be included in the Authorization header like so: Authorization: JWT signed.base64-encoded-jwt.goes-here

To fix the vulnerability, make sure that:

Install callback requests for existing installations have the Authorization: header
The JWT in the header is signed with the existing shared secret from the previous registration.
The shared secret is updated to the new shared secret in the payload once the install callback has been verified (because the client will sign JWTs with the new secret from that point on).
You can test your fix using the attached python script (there are two versions: one for python 2.7 and one for python 3.5). The script attempts the shared secret overwrite against a specially-prepared test host, so will not affect your customers.

Thanks again for developing with Atlassian Connect, and please let us know if you have any questions.

Regards,

The Atlassian Connect Team

PS. Your add-on appeared not to be using the atlassian-connect-express framework. If it is using atlassian-connect-express, please simply update to version 1.0.9 of the library.

during installation on the latest symfony 6 the bundle fails.

just try composer require step and it will fail.
I think the reason is because cache:clear runs before the config files are copied.
I added the config files manually and it worked as expected.
something wrong with the compiler pass I believe.
will try to submit a PR for it.

Error installing the bundle on Symfony 4.2 with Flex

Hi @thecatontheflat,
I've installed this bundle on Symfony 4.2 with flex by composer. It throws the following error:
[KO]
Script cache:clear returned with error code 1
!!
!! In AtlassianConnectExtension.php line 26:
!!
!! Notice: Undefined index: prod

image

I guess I should change the configuration, but it looks weird that just installing it throws an error.

Is it prepared to work with Symfony 4.2 with Flex?

Thanks in advance!

Remove dev / prod config split

In config: the dev and prod keys are being used to define the connect config json. We can remove this and use the Symfony mechanism to overwrite config by suggesting users to add config/dev/atlassian-connect.yaml. To overwrite config in dev.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.