summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/__init__.py1
-rw-r--r--app/models.py6
-rw-r--r--app/views.py73
-rwxr-xr-xclient/bug.py1
-rwxr-xr-xclient/bug_list.py39
-rwxr-xr-xclient/bug_open.py6
-rwxr-xr-xclient/bug_show.py8
-rw-r--r--config.py6
-rwxr-xr-xrun.py2
9 files changed, 72 insertions, 70 deletions
diff --git a/app/__init__.py b/app/__init__.py
index f441218..d698823 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -3,6 +3,7 @@ from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object('config')
+app.secret_key = 'SUPERSEEKRITKEY'
db = SQLAlchemy(app)
from app import views, models
diff --git a/app/models.py b/app/models.py
index 4df6689..dc6a7cd 100644
--- a/app/models.py
+++ b/app/models.py
@@ -5,8 +5,7 @@ class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
nickname = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
- opened = db.relationship('Ticket', backref='opened_by', lazy='dynamic', primaryjoin = 'Ticket.opened_by_user_id == User.id')
- assigned = db.relationship('Ticket', backref='assigned_to', lazy='dynamic', primaryjoin = 'Ticket.assigned_to_user_id == User.id')
+ opened = db.relationship('Ticket', backref='opened_by', lazy='dynamic')
def __repr__(self):
@@ -22,12 +21,9 @@ class Ticket(db.Model):
updated_at = db.Column(db.DateTime)
status = db.Column(db.String(64), nullable=False, default='open')
- resolution = db.Column(db.String(64))
reason = db.Column(db.String(140))
- deleted = db.Column(db.Boolean, default=False)
opened_by_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
- assigned_to_user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return '<Ticket %r>' % (self.id)
diff --git a/app/views.py b/app/views.py
index 2e6ba6f..3cc8891 100644
--- a/app/views.py
+++ b/app/views.py
@@ -1,6 +1,8 @@
-from flask import jsonify, abort, make_response, request, url_for
+from flask import jsonify, abort, make_response, request, url_for, redirect, session
+from requests_oauthlib import OAuth2Session
from datetime import datetime
from app import app, db, models
+import json
def make_public_ticket(ticket):
new_ticket = ticket.copy()
@@ -11,8 +13,6 @@ def ticket_to_dict(ticket):
nt = {}
nt['id'] = ticket.id
- nt['deleted'] = ticket.deleted
-
nt['summary'] = ticket.summary
nt['body'] = ticket.body
@@ -25,7 +25,6 @@ def ticket_to_dict(ticket):
nt['status'] = ticket.status
- nt['resolution'] = ticket.resolution
nt['reason'] = ticket.reason
if ticket.opened_by:
@@ -37,29 +36,61 @@ def ticket_to_dict(ticket):
else:
nt['opened_by'] = {'id': None, 'nickname': None, 'email': None}
- if ticket.assigned_to:
- nt['assigned_to'] = {
- 'id': ticket.assigned_to.id,
- 'nickname': ticket.assigned_to.nickname,
- 'email': ticket.assigned_to.email,
- }
- else:
- nt['assigned_to'] = None
-
return nt
+@app.route('/authorized')
+def authorized_callback():
+ github = OAuth2Session(app.config['GITHUB_CLIENT_ID'], state=session['oauth_state'])
+
+ token = github.fetch_token(app.config['TOKEN_URL'], client_secret=app.config['GITHUB_CLIENT_SECRET'],
+ authorization_response=request.url)
+
+ session['oauth_token'] = token
+
+ user_data = github.get('https://api.github.com/user')
+
+ if user_data.status_code == 401:
+ abort(401)
+
+ json_data = user_data.json()
+ user = models.User.query.filter(models.User.id == json_data['id']).first()
+ if not user:
+ user = models.User(
+ id = json_data['id'],
+ nickname = json_data['login'],
+ email = json_data['email']
+ )
+ db.session.add(user)
+ db.session.commit()
+
+ return "Your access token is: {}".format(token['access_token'])
+
+@app.route('/login')
+def login():
+ github = OAuth2Session(app.config['GITHUB_CLIENT_ID'])
+ authorization_url, state = github.authorization_url(app.config['AUTHORIZATION_BASE_URL'])
+
+ session['oauth_state'] = state
+ return redirect(authorization_url)
+
@app.route('/tbt/api/1.0/tickets', methods=['GET'])
def get_tickets():
- ts = models.Ticket.query.filter(models.Ticket.deleted != True).all()
+ ts = models.Ticket.query.all()
tickets = map(ticket_to_dict, ts)
return jsonify({'tickets': list(map(make_public_ticket, tickets))})
@app.route('/tbt/api/1.0/ticket', methods=['POST'])
def create_ticket():
- if not request.json or not ('summary' and 'body' and 'user_nickname') in request.json:
+ if not request.json or not ('summary' and 'body' and 'token') in request.json:
abort(400)
- user = models.User.query.filter(models.User.nickname == request.json['user_nickname']).first()
+ token = {"scope": [""], "access_token": request.json['token'], "token_type": "bearer"}
+ github = OAuth2Session(app.config['GITHUB_CLIENT_ID'], token=token)
+ user_data = github.get('https://api.github.com/user')
+ if user_data.status_code == 401:
+ abort(401)
+
+ user = models.User.query.get(user_data.json()['id'])
ticket = models.Ticket(summary=request.json['summary'],
body=request.json['body'],
@@ -90,18 +121,18 @@ def update_ticket(ticket_id):
ticket['summary'] = request.json.get('summary', ticket['summary'])
ticket['body'] = request.json.get('body', ticket['body'])
ticket['status'] = request.json.get('status', ticket['status'])
- ticket['resolution'] = request.json.get('resolution', ticket['resolution'])
ticket['reason'] = request.json.get('reason', ticket['reason'])
- ticket['assigned-to'] = request.json.get('assigned-to', ticket['assigned-to'])
return jsonify({'ticket': make_public_ticket(ticket)})
@app.route('/tbt/api/1.0/ticket/<int:ticket_id>', methods=['DELETE'])
def delete_ticket(ticket_id):
- ticket = next((t for t in tickets if t['id'] == ticket_id), None)
+ ticket = models.Ticket.query.get(ticket_id)
if not ticket:
abort(404)
- #tickets.remove(ticket)
- ticket['deleted'] = True
+
+ db.session.delete(ticket)
+ db.session.commit()
+
return jsonify({'result': True})
@app.errorhandler(404)
diff --git a/client/bug.py b/client/bug.py
index 24a523c..ff7958f 100755
--- a/client/bug.py
+++ b/client/bug.py
@@ -13,7 +13,6 @@ commands:
show Show a specific ticket by ID
[Not implemented yet:]
- resolution Set the resolution status of a ticket
edit Edit a ticket
reopen Reopen a previously closed ticket
close Close a ticket
diff --git a/client/bug_list.py b/client/bug_list.py
index 6084414..701b327 100755
--- a/client/bug_list.py
+++ b/client/bug_list.py
@@ -11,6 +11,7 @@ required.
from docopt import docopt
from textwrap import indent
from datetime import datetime
+from bug_show import show_ticket
import json, requests
if __name__ == '__main__':
@@ -20,37 +21,13 @@ def call(args):
print(args)
api_endpoint = args['--uri'] + '/api/1.0/tickets'
- r = requests.get(api_endpoint)
+ r = requests.get(api_endpoint, verify=False)
- tickets = json.loads(r.text).get('tickets')
+ tickets = json.loads(r.text)
+ if not tickets:
+ exit("No tickets found.")
- for ticket in tickets:
- output = '[TBT#{}] '.format(ticket['id'])
-
- if 'deleted' in ticket and ticket['deleted'] == True:
- output += '[DELETED] '
-
- output += '[{}] '.format(ticket['status'])
-
- output += '{}\n'.format(ticket['summary'])
-
- if ticket['status'] != 'open':
- output += 'Resolution: {}\n'.format(ticket['resolution'])
-
- if ticket['reason']:
- output += 'Reason: {}\n'.format(ticket['reason'])
+ tickets = tickets.get('tickets')
- output += 'Opened by: {} <{}>\n'.format(ticket['opened_by']['nickname'], ticket['opened_by']['email'])
- output += 'Opened at: {} UTC\n'.format(datetime.strptime( ticket['opened_at'], "%Y-%m-%dT%H:%M:%S" ))
-
- if ticket['assigned_to']:
- output += 'Assigned to: {} <{}>\n'.format(ticket['assigned_to']['nickname'], ticket['assigned_to']['email'])
- else:
- output += 'Assigned to: Unassigned\n'
-
- if ticket['updated_at']:
- output += 'Updated at: {} UTC\n'.format(datetime.strptime(ticket['opened_at'], "%Y-%m-%dT%H:%M:%S" ))
-
- output += '\n' + indent('{}'.format(ticket['body']), ' ') + '\n'
-
- print(output)
+ for ticket in tickets:
+ print(show_ticket(ticket))
diff --git a/client/bug_open.py b/client/bug_open.py
index 17a3e4f..e9ecb19 100755
--- a/client/bug_open.py
+++ b/client/bug_open.py
@@ -38,16 +38,16 @@ def call(args):
ticket = {
'summary': summary,
'body': body,
- 'user_nickname': 'demi'
+ 'token': 'TOKENHERE'
}
headers = {
'Content-Type': 'application/json',
- 'Accept': 'text/plain'
+ 'Accept': 'text/plain',
}
payload = json.dumps(ticket)
- r = requests.post(api_endpoint, data=payload, headers=headers)
+ r = requests.post(api_endpoint, data=payload, headers=headers, verify=False)
t = json.loads(r.text).get('ticket')
diff --git a/client/bug_show.py b/client/bug_show.py
index 0c3c9b8..18175ef 100755
--- a/client/bug_show.py
+++ b/client/bug_show.py
@@ -34,19 +34,11 @@ def show_ticket(ticket):
if ticket['status'] != 'open':
- output += 'Resolution: {}\n'.format(ticket['resolution'])
-
- if ticket['reason']:
output += 'Reason: {}\n'.format(ticket['reason'])
output += 'Opened by: {} <{}>\n'.format(ticket['opened_by']['nickname'], ticket['opened_by']['email'])
output += 'Opened at: {} UTC\n'.format(datetime.strptime( ticket['opened_at'], "%Y-%m-%dT%H:%M:%S" ))
- if ticket['assigned_to']:
- output += 'Assigned to: {} <{}>\n'.format(ticket['assigned_to']['nickname'], ticket['assigned_to']['email'])
- else:
- output += 'Assigned to: Unassigned\n'
-
if ticket['updated_at']:
output += 'Updated at: {} UTC\n'.format(datetime.strptime(ticket['opened_at'], "%Y-%m-%dT%H:%M:%S" ))
diff --git a/config.py b/config.py
index 7160e5d..f27b5fc 100644
--- a/config.py
+++ b/config.py
@@ -4,3 +4,9 @@ basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
+
+TOKEN_URL = 'https://github.com/login/oauth/access_token'
+AUTHORIZATION_BASE_URL = 'https://github.com/login/oauth/authorize'
+
+GITHUB_CLIENT_ID = 'SEEKRIT'
+GITHUB_CLIENT_SECRET = 'SEEKRIT'
diff --git a/run.py b/run.py
index 178fd8a..b21a2c5 100755
--- a/run.py
+++ b/run.py
@@ -1,3 +1,3 @@
#!flask/bin/python
from app import app
-app.run(debug=True)
+app.run(debug=True, ssl_context='adhoc')