Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GH-85,84,71,49] Confluence Phase-2 (Authorisation/Notifications) #89

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4647686
MI-1721: Added OAuth2.0 for confluence server and cloud (#2)
shivamjosh Jun 8, 2022
e9cb0f4
Reverted unnecessary Makefile changes
shivamjosh Jun 14, 2022
7674a87
fixing bugs
Jun 30, 2022
872fcc0
fixing merge conflicts
Jun 30, 2022
847e853
[MI-1897]:bug fix
Jun 30, 2022
e5f3894
[MI-1897]:fixed github workflow
Jun 30, 2022
4acd7f4
[MI-1897]:fixed review fixes
Kshitij-Katiyar Jul 4, 2022
ed4758a
[MI-1897]:fixed review fixes
Kshitij-Katiyar Jul 5, 2022
5ec8256
added checks for commands
Kshitij-Katiyar Jul 21, 2022
62d3cab
fixed test cases
Kshitij-Katiyar Jul 21, 2022
dbabb8b
Updated assets
Kshitij-Katiyar Jul 22, 2022
053b9d4
Updated userID to delete subscription
Kshitij-Katiyar Sep 28, 2022
27d75d2
[MI-2252]:Added Config manipulation through slash commands (List/Add)…
Kshitij-Katiyar Oct 31, 2022
1e6baaf
[MI-2324]:Fixed review fixes of confluence auth/notification PR (#10)
Kshitij-Katiyar Nov 4, 2022
5a7415b
Fixed merge conflicts
Kshitij-Katiyar Nov 4, 2022
2c17ae5
Updated markdown files for install commands
Kshitij-Katiyar Nov 10, 2022
9281ca2
[MI-2282]:Created /confluence migrate list command to list old subscr…
Kshitij-Katiyar Nov 14, 2022
3d4f6c0
[MI-2362]:Fixed review fixes of confluence PR 89 on mattermost (#13)
Kshitij-Katiyar Nov 18, 2022
e843a42
[MI-2366]:Fixed review fixes of confluence PR 88 on mattermost (#12)
Kshitij-Katiyar Nov 18, 2022
debb47f
deleted github workflow files
Kshitij-Katiyar Nov 18, 2022
54e7f03
[MI-2413]:Fixed merge conflicts and review comments on PR#89 (#14)
Kshitij-Katiyar Dec 2, 2022
b78e955
[MI-2449]:Fixed bugs found by QA (#15)
Kshitij-Katiyar Dec 22, 2022
789389f
Merge branch 'master' of github.com:mattermost/mattermost-plugin-conf…
ayusht2810 Feb 8, 2024
8650c09
Updated the readme to include the new features (#19)
ayusht2810 Feb 12, 2024
88e9fdc
Merge branch 'master' of github.com:mattermost/mattermost-plugin-conf…
raghavaggarwal2308 Feb 19, 2024
3312e4d
Removed unused files
raghavaggarwal2308 Feb 19, 2024
3c2e771
Fixed merge conflicts
Kshitij-Katiyar Apr 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ CURL ?= $(shell command -v curl 2> /dev/null)
MM_DEBUG ?=
MANIFEST_FILE ?= plugin.json
GOPATH ?= $(shell go env GOPATH)
GO_TEST_FLAGS ?= -race
GO_TEST_FLAGS ?= -race -gcflags=-l
GO_BUILD_FLAGS ?=
MM_UTILITIES_DIR ?= ../mattermost-utilities
DLV_DEBUG_PORT := 2346
Expand Down Expand Up @@ -78,7 +78,7 @@ endif
## Ensures NPM dependencies are installed without having to run this all the time.
webapp/node_modules: webapp/package.json
ifneq ($(HAS_WEBAPP),)
cd webapp && $(NPM) install
cd webapp && $(NPM) install --verbose
touch $@
endif

Expand Down Expand Up @@ -124,7 +124,7 @@ dist: apply server webapp bundle
## Builds and installs the plugin to a server.
.PHONY: deploy
deploy: dist
./build/bin/pluginctl deploy $(PLUGIN_ID) dist/$(BUNDLE_NAME)
./build/bin/deploy deploy $(PLUGIN_ID) dist/$(BUNDLE_NAME)

## Builds and installs the plugin to a server, updating the webapp automatically when changed.
.PHONY: watch
Expand Down
12 changes: 12 additions & 0 deletions assets/templates/atlassian-connect.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@
{
"event": "page_updated",
"url": "/cloud/page_updated?secret={{ .SharedSecret }}"
},
{
"event": "space_created",
"url": "/cloud/space_created?secret={{ .SharedSecret }}"
},
{
"event": "space_updated",
"url": "/cloud/space_updated?secret={{ .SharedSecret }}"
},
{
"event": "space_removed",
"url": "/cloud/space_removed?secret={{ .SharedSecret }}"
}
]
}
Expand Down
23 changes: 23 additions & 0 deletions assets/templates/command/install_cloud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{ .ConfluenceURL }} has been successfully added. To finish the configuration, create a new app in your Confluence instance following these steps:

1. Go to the Atlassian [Developer Console](https://developer.atlassian.com/console/myapps/).
![image](https://user-images.githubusercontent.com/90389917/202149604-1f0b8758-96ab-49b0-bd9f-f23ce9d6beda.png)
2. Select **Create > OAuth2.0 integration**.
3. Select **Authorization** in the left menu.
4. Next to OAuth 2.0 (3LO), select **Configure**.
5. In the **Callback URL** field enter:
``
{{ .RedirectURL }}
``.
6. Select **Permissions** in the left menu.
7. Add the **Confluence API**, and then select `Read user`, `Write Confluence content`, `Read Confluence content all`, and `Read Confluence detailed content` scopes, and select **Save**.
8. Copy the `clientID` and `clientSecret` from **Settings**, and paste them into the modal in mattermost which can be opened by using "/confluence config add" slash command.
9. In Mattermost, use the "/confluence connect" slash command to connect your Mattermost account with your Confluence account.
To finish the configuration, add a new app in your Confluence Cloud instance by following these steps:
1. Go to **Settings > Apps > Manage Apps**.
2. Select **Settings** at the bottom of the page, enable development mode, and apply the change. Development mode allows you to install apps from outside of the Atlassian Marketplace.
3. Select **Upload App**.
4. In the **From this URL** field, enter: `{{ .CloudURL }}`.
5. Once installed, you'll see the "Installed and ready to go!" message.

If you see an option to create a Confluence issue, you're all set! If not, refer to our [documentation](https://mattermost.gitbook.io/plugin-confluence) for troubleshooting help.
17 changes: 17 additions & 0 deletions assets/templates/command/install_server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{ .ConfluenceURL }} has been successfully added. To finish the configuration, add an Application Link in your Confluence instance following these steps:

1. Go to [**Settings > Applications > Application Links**]({{ .ConfluenceURL }}/plugins/servlet/applinks/listApplicationLinks)
![image](https://user-images.githubusercontent.com/90389917/202149868-a3044351-37bc-43c0-9671-aba169706917.png)
2. Select **Create link**.
3. On the **Create Link** screen, select **External Application** and **Incoming** as
`Application type` and `Direction` respectively. Select **Continue**.
4. On the **Link Applications** screen, set the following values:
**Name**: `Mattermost`
**Redirect URL**: ```{{ .RedirectURL }}```.
**Application Permissions**: `Admin`
Select **Continue**
5. Copy the `clientID` and `clientSecret` from **Settings**, and paste them into the modal in mattermost which can be opened by using "/confluence config add" slash command.
6. In Mattermost, use the "/confluence connect" slash command to connect your Mattermost account with your
Confluence account.

If you see an option to create a Confluence issue, you're all set! If not, refer to our [documentation](https://mattermost.gitbook.io/plugin-confluence) for troubleshooting help.
73 changes: 73 additions & 0 deletions assets/templates/oauth2/complete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
color: rgb(23, 43, 77);
letter-spacing: -0.01em;
}

.flex-parent {
padding: 50px;
}

.btn {
-webkit-transition: all 0.15s ease;
-webkit-transition-delay: 0s;
-moz-transition: all 0.15s ease;
-o-transition: all 0.15s ease;
transition: all 0.15s ease false;
padding-right: 1em;
padding-left: 1em;
font-size: inherit;
border: none;
height: 2.4em;
border-radius: 4px;
cursor: pointer;
}

.btn-primary {
color: rgb(255, 255, 255);
background: rgb(0, 82, 204);
}

.btn-primary:hover,
.btn-primary:active {
background: rgb(0, 101, 255);
}

.btn-link {
color: #505f79;
background: #f4f5f7;
}

.btn-link:hover,
.btn-link:active {
background: #ebecf0;
}

.accounts-container {
padding: 1.6em 0 0.8em;
opacity: .6;
}
.icon--check {
margin-right: 4px;
}
</style>
<link rel="stylesheet" href="https://unpkg.com/@atlaskit/[email protected]/dist/bundle.css" media="all">
</head>
<body>
<div class="flex-parent">
<h3>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="15" class="icon--check" viewBox="0 0 18 14">
<path fill="#0052CC" d="M100.649576,76.1740942 C100.649576,76.4531124 100.537969,76.7321306 100.337075,76.9330237 L90.7388497,86.5312494 C90.5379566,86.7321425 90.2589384,86.8437498 89.9799202,86.8437498 C89.700902,86.8437498 89.4218838,86.7321425 89.2209908,86.5312494 L83.6629484,80.9732071 C83.4620553,80.772314 83.350448,80.4932958 83.350448,80.2142776 C83.350448,79.9352594 83.4620553,79.6562412 83.6629484,79.4553481 L85.1808074,77.9374892 C85.3817005,77.7365961 85.6607186,77.6249888 85.9397368,77.6249888 C86.218755,77.6249888 86.4977732,77.7365961 86.6986663,77.9374892 L89.9799202,81.2299038 L97.3013575,73.8973058 C97.5022506,73.6964127 97.7812688,73.5848054 98.060287,73.5848054 C98.3393052,73.5848054 98.6183234,73.6964127 98.8192165,73.8973058 L100.337075,75.4151648 C100.537969,75.6160579 100.649576,75.895076 100.649576,76.1740942 Z" transform="translate(-83 -73)"/>
</svg>
Mattermost user is now connected to Confluence
</h3>
<div class="accounts-container">
<div>Mattermost account: {{ .MattermostDisplayName }}</div>
<div>Confluence account: {{ .ConfluenceDisplayName }}</div>
</div>
</div>
</body>
</html>
31 changes: 31 additions & 0 deletions assets/templates/other/message.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
color: rgb(23, 43, 77);
letter-spacing: -0.01em;
}

.flex-parent {
padding: 50px;
}

.message-container {
padding: 1.6em 0 0.8em;
opacity: .6;
}
</style>
<link rel="stylesheet" href="https://unpkg.com/@atlaskit/[email protected]/dist/bundle.css" media="all">
</head>
<body>
<div class="flex-parent">
<h3>
{{ .Header}}
</h3>
<div class="message-container">
<div>{{ .Message }}</div>
</div>
</div>
</body>
</html>
34 changes: 17 additions & 17 deletions build/pluginctl/main.go → build/deploy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"net"
"os"

"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v6/model"
)

const helpText = `
Expand Down Expand Up @@ -58,7 +58,7 @@ func pluginctl() error {
func getClient() (*model.Client4, error) {
socketPath := os.Getenv("MM_LOCALSOCKETPATH")
if socketPath == "" {
socketPath = model.LOCAL_MODE_SOCKET_PATH
socketPath = model.LocalModeSocketPath
}

client, connected := getUnixClient(socketPath)
Expand Down Expand Up @@ -91,9 +91,9 @@ func getClient() (*model.Client4, error) {
if adminUsername != "" && adminPassword != "" {
client := model.NewAPIv4Client(siteURL)
log.Printf("Authenticating as %s against %s.", adminUsername, siteURL)
_, resp := client.Login(adminUsername, adminPassword)
if resp.Error != nil {
return nil, fmt.Errorf("failed to login as %s: %w", adminUsername, resp.Error)
_, _, err := client.Login(adminUsername, adminPassword)
if err != nil {
return nil, fmt.Errorf("failed to login as %s: %w", adminUsername, err)
}
return client, nil
}
Expand All @@ -120,15 +120,15 @@ func deploy(client *model.Client4, pluginID, bundlePath string) error {
defer pluginBundle.Close()

log.Print("Uploading plugin via API.")
_, resp := client.UploadPluginForced(pluginBundle)
if resp.Error != nil {
return fmt.Errorf("failed to upload plugin bundle: %s", resp.Error.Error())
_, _, err = client.UploadPluginForced(pluginBundle)
if err != nil {
return fmt.Errorf("failed to upload plugin bundle: %s", err.Error())
}

log.Print("Enabling plugin.")
_, resp = client.EnablePlugin(pluginID)
if resp.Error != nil {
return fmt.Errorf("failed to enable plugin: %s", resp.Error.Error())
_, err = client.EnablePlugin(pluginID)
if err != nil {
return fmt.Errorf("failed to enable plugin: %s", err.Error())
}

return nil
Expand All @@ -137,9 +137,9 @@ func deploy(client *model.Client4, pluginID, bundlePath string) error {
// disablePlugin attempts to disable the plugin via the Client4 API.
func disablePlugin(client *model.Client4, pluginID string) error {
log.Print("Disabling plugin.")
_, resp := client.DisablePlugin(pluginID)
if resp.Error != nil {
return fmt.Errorf("failed to disable plugin: %w", resp.Error)
_, err := client.DisablePlugin(pluginID)
if err != nil {
return fmt.Errorf("failed to disable plugin: %w", err)
}

return nil
Expand All @@ -148,9 +148,9 @@ func disablePlugin(client *model.Client4, pluginID string) error {
// enablePlugin attempts to enable the plugin via the Client4 API.
func enablePlugin(client *model.Client4, pluginID string) error {
log.Print("Enabling plugin.")
_, resp := client.EnablePlugin(pluginID)
if resp.Error != nil {
return fmt.Errorf("failed to enable plugin: %w", resp.Error)
_, err := client.EnablePlugin(pluginID)
if err != nil {
return fmt.Errorf("failed to enable plugin: %w", err)
}

return nil
Expand Down
53 changes: 11 additions & 42 deletions build/manifest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,27 @@ import (
"io/ioutil"
"os"

"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/pkg/errors"
)

const pluginIDGoFileTemplate = `// This file is automatically generated. Do not modify it manually.

package main

import (
"strings"

"github.com/mattermost/mattermost-server/v5/model"
)

var manifest *model.Manifest

const manifestStr = ` + "`" + `
%s
` + "`" + `

func init() {
manifest = model.ManifestFromJson(strings.NewReader(manifestStr))
var manifest = struct {
ID string
Version string
}{
ID: "%s",
Version: "%s",
}
`

const pluginIDJSFileTemplate = `// This file is automatically generated. Do not modify it manually.

const manifest = JSON.parse(` + "`" + `
%s
` + "`" + `);

export default manifest;
export const id = manifest.id;
export const version = manifest.version;
export const id = '%s';
export const version = '%s';
`

func main() {
Expand Down Expand Up @@ -116,37 +103,19 @@ func dumpPluginVersion(manifest *model.Manifest) {
// applyManifest propagates the plugin_id into the server and webapp folders, as necessary
func applyManifest(manifest *model.Manifest) error {
if manifest.HasServer() {
// generate JSON representation of Manifest.
manifestBytes, err := json.MarshalIndent(manifest, "", " ")
if err != nil {
return err
}
manifestStr := string(manifestBytes)

// write generated code to file by using Go file template.
if err := ioutil.WriteFile(
"server/manifest.go",
[]byte(fmt.Sprintf(pluginIDGoFileTemplate, manifestStr)),
[]byte(fmt.Sprintf(pluginIDGoFileTemplate, manifest.Id, manifest.Version)),
0600,
); err != nil {
return errors.Wrap(err, "failed to write server/manifest.go")
}
}

if manifest.HasWebapp() {
// generate JSON representation of Manifest.
// JSON is very similar and compatible with JS's object literals. so, what we do here
// is actually JS code generation.
manifestBytes, err := json.MarshalIndent(manifest, "", " ")
if err != nil {
return err
}
manifestStr := string(manifestBytes)

// write generated code to file by using JS file template.
if err := ioutil.WriteFile(
"webapp/src/manifest.js",
[]byte(fmt.Sprintf(pluginIDJSFileTemplate, manifestStr)),
[]byte(fmt.Sprintf(pluginIDJSFileTemplate, manifest.Id, manifest.Version)),
0600,
); err != nil {
return errors.Wrap(err, "failed to open webapp/src/manifest.js")
Expand Down
2 changes: 1 addition & 1 deletion build/setup.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ endif
$(shell cd build/manifest && $(GO) build -o ../bin/manifest)

# Ensure that the deployment tools are compiled. Go's caching makes this quick.
$(shell cd build/pluginctl && $(GO) build -o ../bin/pluginctl)
$(shell cd build/deploy && $(GO) build -o ../bin/deploy)

# Extract the plugin id from the manifest.
PLUGIN_ID ?= $(shell build/bin/manifest id)
Expand Down
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ go 1.13

require (
bou.ke/monkey v1.0.2
github.com/gorilla/mux v1.7.4
github.com/mattermost/mattermost-plugin-api v0.0.12
github.com/mattermost/mattermost-server/v5 v5.3.2-0.20200731154015-c5c6a5ce5399
github.com/gorilla/mux v1.8.0
github.com/levigross/exp-html v0.0.0-20120902181939-8df60c69a8f5
github.com/mattermost/mattermost-plugin-api v0.0.26-0.20220223141232-cb8b1984774a
github.com/mattermost/mattermost-server/v6 v6.7.2
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.6.1
github.com/stretchr/testify v1.7.1
github.com/thoas/go-funk v0.6.0
go.uber.org/atomic v1.6.0
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
go.uber.org/atomic v1.9.0
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
)
Loading