GitHub integration

Flask GitHub Integration for Salesforce project


Now the time to add git integration to our Backup Service. Let's start with GitHub first as I like it. There are different types of authentication to GitHub (https://help.github.com/en/github/authenticating-to-github) but I want to start with Personal Token. So to connect to our git repository in GitHub we need: username, personal token, name of repository. With this data we can connect to GitHub API and use it in git command line tool via https.

To get and store connection data for GitHub I've created new JSONB field in the Task object (at this moment I don't want to reuse connection data between multiple Task, so we can store it in Task level, next we can decide to move it in separate level and join with Task)

GitHub integration modal

Before we store connection details to database we need to validate it. I'm going to do it with call to GitHub API to get repository details (repository details we can also store in DB alongside with git credentials and use in UI).

On github credentials save we run this backend handler in 
./backend/controllers/task.py
@task_bp.route('/git_settings', methods=['POST'])
@login_required
def update_git_settings():

    payload = request.get_json()

    task = (Task.query.filter(Task.id == payload['task']['id'],
                              Task.user_id == current_user.id)
                      .first_or_404())

    git_settings = payload['git_settings']

    if task.git is None:
        task.git = {}

    task.git['auth'] = git_settings

    # Git connection validation
    try:
        repo_details = GitService(task).get_github_repo_details()
    except ValueError as e:
        abort(400, str(e))

    task.git['repo_details'] = repo_details

    flag_modified(task, "git")

    db.session.commit()

    return jsonify(task)
./backend/services/git_service.py
import json
import requests
from models import Task


class GitService:

    task: Task = None

    def __init__(self, task: Task):
        self.task = task

    def get_github_repo_details(self):

        headers = self._get_github_headers()

        url = f"http://api.github.com/repos/{self.task.git['auth']['username']}/{self.task.git['auth']['repo_name']}"
        resp = self.get(url, headers, 200)

        try:
            repo_details = json.loads(resp)
            return repo_details
        except:  # NOQA
            raise ValueError(resp)

    def get(self, url, headers, expected_status_code=200):

        resp = requests.get(url, headers=headers)

        if resp.status_code != expected_status_code:
            print('=== RESPONSE ERROR:')
            print(resp.status_code, resp.text)
            raise ValueError('Unexpected status code: ' + str(resp.status_code) + ' ' + str(resp.text))

        return resp.text

    def _get_github_headers(self):

        if not self.task.git:
            raise ValueError('Git connection information not found')

        return {
            'Authorization': 'Token ' + self.task.git['auth']['token'],
            'Content-Type': 'application/json'
        }

I've updated Git Connection section to show information and if credentials are valid and available in Task then page should look this way

Git Connection details section

















Comments

Popular posts from this blog

Salesforce Authentication 2 (Token Validation and Refresh)

HTTPS in local environment for Angular + Flask project.

Salesforce Lightning Design System (SLDS)