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

Confluence token authentication #824

Merged
merged 1 commit into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 34 additions & 5 deletions perceval/backends/core/confluence.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# Harshal Mittal <[email protected]>
#

import base64
import logging
import json

Expand Down Expand Up @@ -63,20 +64,26 @@ class Confluence(Backend):
:param ssl_verify: enable/disable SSL verification
:param spaces: name of spaces to fetch, (default the entire instance)
:param max_contents: maximum number of contents to fetch per request
:param user: Confluence user name. It is required for Confluence Cloud,
optional for Confluence Data Center and server editions 7.9 and later
:param api_token: Confluence user's personal access token or api token
"""
version = '0.14.1'
version = '0.15.0'

CATEGORIES = [CATEGORY_HISTORICAL_CONTENT]

def __init__(self, url, tag=None, archive=None, ssl_verify=True,
spaces=None, max_contents=MAX_CONTENTS):
spaces=None, max_contents=MAX_CONTENTS,
user=None, api_token=None):
zhifeiyue marked this conversation as resolved.
Show resolved Hide resolved
origin = url

super().__init__(origin, tag=tag, archive=archive, ssl_verify=ssl_verify)
self.url = url
self.client = None
self.spaces = spaces
self.max_contents = max_contents
self.user = user
self.api_token = api_token

def search_fields(self, item):
"""Add search fields to an item.
Expand Down Expand Up @@ -273,7 +280,8 @@ def _init_client(self, from_archive=False):

return ConfluenceClient(self.url, archive=self.archive, from_archive=from_archive,
ssl_verify=self.ssl_verify, spaces=self.spaces,
max_contents=self.max_contents)
max_contents=self.max_contents,
user=self.user, api_token=self.api_token)

def __fetch_contents_summary(self, from_date, max_contents):
logger.debug("Fetching contents summary from %s", str(from_date))
Expand Down Expand Up @@ -340,6 +348,8 @@ def setup_cmd_parser(cls):

parser = BackendCommandArgumentParser(cls.BACKEND,
from_date=True,
basic_auth=True,
token_auth=True,
archive=True,
ssl_verify=True)

Expand Down Expand Up @@ -368,6 +378,8 @@ class ConfluenceClient(HttpClient):
:param ssl_verify: enable/disable SSL verification
:param spaces: name of spaces to fetch, (default the entire instance)
:param max_contents: maximum number of contents to fetch per request
:param user: Confluence user name
:param api_token: Confluence user's personal access token or api token
"""
URL = "%(base)s/rest/api/%(resource)s"

Expand Down Expand Up @@ -395,8 +407,25 @@ class ConfluenceClient(HttpClient):
VHISTORICAL = 'historical'

def __init__(self, base_url, archive=None, from_archive=False, ssl_verify=True,
spaces=None, max_contents=MAX_CONTENTS):
super().__init__(base_url.rstrip('/'), archive=archive, from_archive=from_archive, ssl_verify=ssl_verify)
spaces=None, max_contents=MAX_CONTENTS,
user=None, api_token=None):
zhifeiyue marked this conversation as resolved.
Show resolved Hide resolved
auth_header = {}
if api_token:
if user is None:
# Confluence Data Center and server editions 7.9 and later can use personal access tokens without a username
# See https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html
auth_header = {'Authorization': 'Bearer ' + api_token}
else:
# For Confluence Cloud, username and token are required
# See https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/
auth_encoded = base64.b64encode((user + ':' + api_token).encode('utf-8')).decode('utf-8')
auth_header = {'Authorization': 'Basic ' + auth_encoded}

super().__init__(base_url.rstrip('/'),
archive=archive,
from_archive=from_archive,
ssl_verify=ssl_verify,
extra_headers=auth_header)
self.spaces = spaces
self.max_contents = max_contents

Expand Down
9 changes: 9 additions & 0 deletions releases/unreleased/add-token-auth-for-confluence.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
title: Clonfluence authentication with personal access tokens
category: added
author: devpod.cn <[email protected]>
issue:
notes: >
Authentication in `confluence` backend is supported using
personal access tokens. Confluence Data Center and server
editions 7.9 and later can use personal access tokens without
a username. For Confluence Cloud, username and token are required.