Merge remote-tracking branch 'origin/autobot'
This commit is contained in:
commit
3e67e39e61
9 changed files with 590 additions and 320 deletions
138
endpoints/api.py
138
endpoints/api.py
|
@ -26,7 +26,7 @@ from auth.permissions import (ReadRepositoryPermission,
|
||||||
OrganizationMemberPermission,
|
OrganizationMemberPermission,
|
||||||
ViewTeamPermission)
|
ViewTeamPermission)
|
||||||
from endpoints import registry
|
from endpoints import registry
|
||||||
from endpoints.web import common_login
|
from endpoints.common import common_login
|
||||||
from util.cache import cache_control
|
from util.cache import cache_control
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
@ -35,6 +35,38 @@ store = app.config['STORAGE']
|
||||||
user_files = app.config['USERFILES']
|
user_files = app.config['USERFILES']
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
route_data = None
|
||||||
|
|
||||||
|
def get_route_data():
|
||||||
|
global route_data
|
||||||
|
if route_data:
|
||||||
|
return route_data
|
||||||
|
|
||||||
|
routes = []
|
||||||
|
for rule in app.url_map.iter_rules():
|
||||||
|
if rule.rule.startswith('/api/'):
|
||||||
|
endpoint_method = globals()[rule.endpoint]
|
||||||
|
is_internal = '__internal_call' in dir(endpoint_method)
|
||||||
|
is_org_api = '__user_call' in dir(endpoint_method)
|
||||||
|
methods = list(rule.methods.difference(['HEAD', 'OPTIONS']))
|
||||||
|
|
||||||
|
route = {
|
||||||
|
'name': rule.endpoint,
|
||||||
|
'methods': methods,
|
||||||
|
'path': rule.rule,
|
||||||
|
'parameters': list(rule.arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_org_api:
|
||||||
|
route['user_method'] = endpoint_method.__user_call
|
||||||
|
|
||||||
|
routes.append(route)
|
||||||
|
|
||||||
|
route_data = {
|
||||||
|
'endpoints': routes
|
||||||
|
}
|
||||||
|
return route_data
|
||||||
|
|
||||||
|
|
||||||
def log_action(kind, user_or_orgname, metadata={}, repo=None):
|
def log_action(kind, user_or_orgname, metadata={}, repo=None):
|
||||||
performer = current_user.db_user()
|
performer = current_user.db_user()
|
||||||
|
@ -60,6 +92,26 @@ def api_login_required(f):
|
||||||
return decorated_view
|
return decorated_view
|
||||||
|
|
||||||
|
|
||||||
|
def internal_api_call(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_view(*args, **kwargs):
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
|
decorated_view.__internal_call = True
|
||||||
|
return decorated_view
|
||||||
|
|
||||||
|
|
||||||
|
def org_api_call(user_call_name):
|
||||||
|
def internal_decorator(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_view(*args, **kwargs):
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
|
decorated_view.__user_call = user_call_name
|
||||||
|
return decorated_view
|
||||||
|
|
||||||
|
return internal_decorator
|
||||||
|
|
||||||
@app.errorhandler(model.DataModelException)
|
@app.errorhandler(model.DataModelException)
|
||||||
def handle_dme(ex):
|
def handle_dme(ex):
|
||||||
return make_response(ex.message, 400)
|
return make_response(ex.message, 400)
|
||||||
|
@ -70,13 +122,19 @@ def handle_dme_key_error(ex):
|
||||||
return make_response(ex.message, 400)
|
return make_response(ex.message, 400)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/discovery')
|
||||||
|
def discovery():
|
||||||
|
return jsonify(get_route_data())
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/')
|
@app.route('/api/')
|
||||||
|
@internal_api_call
|
||||||
def welcome():
|
def welcome():
|
||||||
return make_response('welcome', 200)
|
return make_response('welcome', 200)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/plans/')
|
@app.route('/api/plans/')
|
||||||
def plans_list():
|
def list_plans():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'plans': PLANS,
|
'plans': PLANS,
|
||||||
})
|
})
|
||||||
|
@ -108,6 +166,7 @@ def user_view(user):
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/user/', methods=['GET'])
|
@app.route('/api/user/', methods=['GET'])
|
||||||
|
@internal_api_call
|
||||||
def get_logged_in_user():
|
def get_logged_in_user():
|
||||||
if current_user.is_anonymous():
|
if current_user.is_anonymous():
|
||||||
return jsonify({'anonymous': True})
|
return jsonify({'anonymous': True})
|
||||||
|
@ -121,6 +180,7 @@ def get_logged_in_user():
|
||||||
|
|
||||||
@app.route('/api/user/private', methods=['GET'])
|
@app.route('/api/user/private', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@internal_api_call
|
||||||
def get_user_private_count():
|
def get_user_private_count():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
private_repos = model.get_private_repo_count(user.username)
|
private_repos = model.get_private_repo_count(user.username)
|
||||||
|
@ -141,6 +201,7 @@ def get_user_private_count():
|
||||||
|
|
||||||
@app.route('/api/user/convert', methods=['POST'])
|
@app.route('/api/user/convert', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@internal_api_call
|
||||||
def convert_user_to_organization():
|
def convert_user_to_organization():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
convert_data = request.get_json()
|
convert_data = request.get_json()
|
||||||
|
@ -177,6 +238,7 @@ def convert_user_to_organization():
|
||||||
|
|
||||||
@app.route('/api/user/', methods=['PUT'])
|
@app.route('/api/user/', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@internal_api_call
|
||||||
def change_user_details():
|
def change_user_details():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
|
|
||||||
|
@ -203,7 +265,8 @@ def change_user_details():
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/user/', methods=['POST'])
|
@app.route('/api/user/', methods=['POST'])
|
||||||
def create_user_api():
|
@internal_api_call
|
||||||
|
def create_new_user():
|
||||||
user_data = request.get_json()
|
user_data = request.get_json()
|
||||||
|
|
||||||
existing_user = model.get_user(user_data['username'])
|
existing_user = model.get_user(user_data['username'])
|
||||||
|
@ -229,7 +292,8 @@ def create_user_api():
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/signin', methods=['POST'])
|
@app.route('/api/signin', methods=['POST'])
|
||||||
def signin_api():
|
@internal_api_call
|
||||||
|
def signin_user():
|
||||||
signin_data = request.get_json()
|
signin_data = request.get_json()
|
||||||
|
|
||||||
username = signin_data['username']
|
username = signin_data['username']
|
||||||
|
@ -263,6 +327,7 @@ def conduct_signin(username, password):
|
||||||
|
|
||||||
@app.route("/api/signout", methods=['POST'])
|
@app.route("/api/signout", methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@internal_api_call
|
||||||
def logout():
|
def logout():
|
||||||
logout_user()
|
logout_user()
|
||||||
identity_changed.send(app, identity=AnonymousIdentity())
|
identity_changed.send(app, identity=AnonymousIdentity())
|
||||||
|
@ -270,7 +335,8 @@ def logout():
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/recovery", methods=['POST'])
|
@app.route("/api/recovery", methods=['POST'])
|
||||||
def send_recovery():
|
@internal_api_call
|
||||||
|
def request_recovery_email():
|
||||||
email = request.get_json()['email']
|
email = request.get_json()['email']
|
||||||
code = model.create_reset_password_email_code(email)
|
code = model.create_reset_password_email_code(email)
|
||||||
send_recovery_email(email, code.code)
|
send_recovery_email(email, code.code)
|
||||||
|
@ -355,7 +421,8 @@ def team_view(orgname, team):
|
||||||
|
|
||||||
@app.route('/api/organization/', methods=['POST'])
|
@app.route('/api/organization/', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def create_organization_api():
|
@internal_api_call
|
||||||
|
def create_organization():
|
||||||
org_data = request.get_json()
|
org_data = request.get_json()
|
||||||
existing = None
|
existing = None
|
||||||
|
|
||||||
|
@ -419,6 +486,7 @@ def get_organization(orgname):
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>', methods=['PUT'])
|
@app.route('/api/organization/<orgname>', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@org_api_call('change_user_details')
|
||||||
def change_organization_details(orgname):
|
def change_organization_details(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
|
@ -496,6 +564,7 @@ def get_organization_member(orgname, membername):
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>/private', methods=['GET'])
|
@app.route('/api/organization/<orgname>/private', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@internal_api_call
|
||||||
def get_organization_private_allowed(orgname):
|
def get_organization_private_allowed(orgname):
|
||||||
permission = CreateRepositoryPermission(orgname)
|
permission = CreateRepositoryPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
|
@ -657,7 +726,7 @@ def delete_organization_team_member(orgname, teamname, membername):
|
||||||
|
|
||||||
@app.route('/api/repository', methods=['POST'])
|
@app.route('/api/repository', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def create_repo_api():
|
def create_repo():
|
||||||
owner = current_user.db_user()
|
owner = current_user.db_user()
|
||||||
req = request.get_json()
|
req = request.get_json()
|
||||||
namespace_name = req['namespace'] if 'namespace' in req else owner.username
|
namespace_name = req['namespace'] if 'namespace' in req else owner.username
|
||||||
|
@ -690,7 +759,7 @@ def create_repo_api():
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/find/repository', methods=['GET'])
|
@app.route('/api/find/repository', methods=['GET'])
|
||||||
def match_repos_api():
|
def find_repos():
|
||||||
prefix = request.args.get('query', '')
|
prefix = request.args.get('query', '')
|
||||||
|
|
||||||
def repo_view(repo):
|
def repo_view(repo):
|
||||||
|
@ -713,7 +782,7 @@ def match_repos_api():
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/repository/', methods=['GET'])
|
@app.route('/api/repository/', methods=['GET'])
|
||||||
def list_repos_api():
|
def list_repos():
|
||||||
def repo_view(repo_obj):
|
def repo_view(repo_obj):
|
||||||
return {
|
return {
|
||||||
'namespace': repo_obj.namespace,
|
'namespace': repo_obj.namespace,
|
||||||
|
@ -756,7 +825,7 @@ def list_repos_api():
|
||||||
@app.route('/api/repository/<path:repository>', methods=['PUT'])
|
@app.route('/api/repository/<path:repository>', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def update_repo_api(namespace, repository):
|
def update_repo(namespace, repository):
|
||||||
permission = ModifyRepositoryPermission(namespace, repository)
|
permission = ModifyRepositoryPermission(namespace, repository)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
repo = model.get_repository(namespace, repository)
|
repo = model.get_repository(namespace, repository)
|
||||||
|
@ -779,7 +848,7 @@ def update_repo_api(namespace, repository):
|
||||||
methods=['POST'])
|
methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def change_repo_visibility_api(namespace, repository):
|
def change_repo_visibility(namespace, repository):
|
||||||
permission = AdministerRepositoryPermission(namespace, repository)
|
permission = AdministerRepositoryPermission(namespace, repository)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
repo = model.get_repository(namespace, repository)
|
repo = model.get_repository(namespace, repository)
|
||||||
|
@ -823,7 +892,7 @@ def image_view(image):
|
||||||
|
|
||||||
@app.route('/api/repository/<path:repository>', methods=['GET'])
|
@app.route('/api/repository/<path:repository>', methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def get_repo_api(namespace, repository):
|
def get_repo(namespace, repository):
|
||||||
logger.debug('Get repo: %s/%s' % (namespace, repository))
|
logger.debug('Get repo: %s/%s' % (namespace, repository))
|
||||||
|
|
||||||
def tag_view(tag):
|
def tag_view(tag):
|
||||||
|
@ -1006,6 +1075,7 @@ def delete_webhook(namespace, repository, public_id):
|
||||||
|
|
||||||
@app.route('/api/filedrop/', methods=['POST'])
|
@app.route('/api/filedrop/', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@internal_api_call
|
||||||
def get_filedrop_url():
|
def get_filedrop_url():
|
||||||
mime_type = request.get_json()['mimeType']
|
mime_type = request.get_json()['mimeType']
|
||||||
(url, file_id) = user_files.prepare_for_drop(mime_type)
|
(url, file_id) = user_files.prepare_for_drop(mime_type)
|
||||||
|
@ -1436,14 +1506,17 @@ def subscription_view(stripe_subscription, used_repos):
|
||||||
|
|
||||||
@app.route('/api/user/card', methods=['GET'])
|
@app.route('/api/user/card', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_user_card_api():
|
@internal_api_call
|
||||||
|
def get_user_card():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
return get_card(user)
|
return get_card(user)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>/card', methods=['GET'])
|
@app.route('/api/organization/<orgname>/card', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_org_card_api(orgname):
|
@internal_api_call
|
||||||
|
@org_api_call('get_user_card')
|
||||||
|
def get_org_card(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
organization = model.get_organization(orgname)
|
organization = model.get_organization(orgname)
|
||||||
|
@ -1454,7 +1527,8 @@ def get_org_card_api(orgname):
|
||||||
|
|
||||||
@app.route('/api/user/card', methods=['POST'])
|
@app.route('/api/user/card', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def set_user_card_api():
|
@internal_api_call
|
||||||
|
def set_user_card():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
token = request.get_json()['token']
|
token = request.get_json()['token']
|
||||||
response = set_card(user, token)
|
response = set_card(user, token)
|
||||||
|
@ -1464,7 +1538,8 @@ def set_user_card_api():
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>/card', methods=['POST'])
|
@app.route('/api/organization/<orgname>/card', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def set_org_card_api(orgname):
|
@org_api_call('set_user_card')
|
||||||
|
def set_org_card(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
organization = model.get_organization(orgname)
|
organization = model.get_organization(orgname)
|
||||||
|
@ -1515,7 +1590,8 @@ def get_card(user):
|
||||||
|
|
||||||
@app.route('/api/user/plan', methods=['PUT'])
|
@app.route('/api/user/plan', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def subscribe_api():
|
@internal_api_call
|
||||||
|
def update_user_subscription():
|
||||||
request_data = request.get_json()
|
request_data = request.get_json()
|
||||||
plan = request_data['plan']
|
plan = request_data['plan']
|
||||||
token = request_data['token'] if 'token' in request_data else None
|
token = request_data['token'] if 'token' in request_data else None
|
||||||
|
@ -1607,7 +1683,7 @@ def subscribe(user, plan, token, require_business_plan):
|
||||||
|
|
||||||
@app.route('/api/user/invoices', methods=['GET'])
|
@app.route('/api/user/invoices', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def user_invoices_api():
|
def list_user_invoices():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
if not user.stripe_id:
|
if not user.stripe_id:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
@ -1617,7 +1693,8 @@ def user_invoices_api():
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>/invoices', methods=['GET'])
|
@app.route('/api/organization/<orgname>/invoices', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def org_invoices_api(orgname):
|
@org_api_call('list_user_invoices')
|
||||||
|
def list_org_invoices(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
organization = model.get_organization(orgname)
|
organization = model.get_organization(orgname)
|
||||||
|
@ -1653,7 +1730,9 @@ def get_invoices(customer_id):
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>/plan', methods=['PUT'])
|
@app.route('/api/organization/<orgname>/plan', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def subscribe_org_api(orgname):
|
@internal_api_call
|
||||||
|
@org_api_call('update_user_subscription')
|
||||||
|
def update_org_subscription(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
request_data = request.get_json()
|
request_data = request.get_json()
|
||||||
|
@ -1667,7 +1746,8 @@ def subscribe_org_api(orgname):
|
||||||
|
|
||||||
@app.route('/api/user/plan', methods=['GET'])
|
@app.route('/api/user/plan', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_subscription():
|
@internal_api_call
|
||||||
|
def get_user_subscription():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
private_repos = model.get_private_repo_count(user.username)
|
private_repos = model.get_private_repo_count(user.username)
|
||||||
|
|
||||||
|
@ -1685,6 +1765,8 @@ def get_subscription():
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>/plan', methods=['GET'])
|
@app.route('/api/organization/<orgname>/plan', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@internal_api_call
|
||||||
|
@org_api_call('get_user_subscription')
|
||||||
def get_org_subscription(orgname):
|
def get_org_subscription(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
|
@ -1723,6 +1805,7 @@ def get_user_robots():
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>/robots', methods=['GET'])
|
@app.route('/api/organization/<orgname>/robots', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@org_api_call('get_user_robots')
|
||||||
def get_org_robots(orgname):
|
def get_org_robots(orgname):
|
||||||
permission = OrganizationMemberPermission(orgname)
|
permission = OrganizationMemberPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
|
@ -1736,7 +1819,7 @@ def get_org_robots(orgname):
|
||||||
|
|
||||||
@app.route('/api/user/robots/<robot_shortname>', methods=['PUT'])
|
@app.route('/api/user/robots/<robot_shortname>', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def create_robot(robot_shortname):
|
def create_user_robot(robot_shortname):
|
||||||
parent = current_user.db_user()
|
parent = current_user.db_user()
|
||||||
robot, password = model.create_robot(robot_shortname, parent)
|
robot, password = model.create_robot(robot_shortname, parent)
|
||||||
resp = jsonify(robot_view(robot.username, password))
|
resp = jsonify(robot_view(robot.username, password))
|
||||||
|
@ -1748,6 +1831,7 @@ def create_robot(robot_shortname):
|
||||||
@app.route('/api/organization/<orgname>/robots/<robot_shortname>',
|
@app.route('/api/organization/<orgname>/robots/<robot_shortname>',
|
||||||
methods=['PUT'])
|
methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@org_api_call('create_user_robot')
|
||||||
def create_org_robot(orgname, robot_shortname):
|
def create_org_robot(orgname, robot_shortname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
|
@ -1763,7 +1847,7 @@ def create_org_robot(orgname, robot_shortname):
|
||||||
|
|
||||||
@app.route('/api/user/robots/<robot_shortname>', methods=['DELETE'])
|
@app.route('/api/user/robots/<robot_shortname>', methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def delete_robot(robot_shortname):
|
def delete_user_robot(robot_shortname):
|
||||||
parent = current_user.db_user()
|
parent = current_user.db_user()
|
||||||
model.delete_robot(format_robot_username(parent.username, robot_shortname))
|
model.delete_robot(format_robot_username(parent.username, robot_shortname))
|
||||||
log_action('delete_robot', parent.username, {'robot': robot_shortname})
|
log_action('delete_robot', parent.username, {'robot': robot_shortname})
|
||||||
|
@ -1773,6 +1857,7 @@ def delete_robot(robot_shortname):
|
||||||
@app.route('/api/organization/<orgname>/robots/<robot_shortname>',
|
@app.route('/api/organization/<orgname>/robots/<robot_shortname>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
@org_api_call('delete_user_robot')
|
||||||
def delete_org_robot(orgname, robot_shortname):
|
def delete_org_robot(orgname, robot_shortname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
|
@ -1804,7 +1889,7 @@ def log_view(log):
|
||||||
@app.route('/api/repository/<path:repository>/logs', methods=['GET'])
|
@app.route('/api/repository/<path:repository>/logs', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def repo_logs_api(namespace, repository):
|
def list_repo_logs(namespace, repository):
|
||||||
permission = AdministerRepositoryPermission(namespace, repository)
|
permission = AdministerRepositoryPermission(namespace, repository)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
repo = model.get_repository(namespace, repository)
|
repo = model.get_repository(namespace, repository)
|
||||||
|
@ -1820,7 +1905,8 @@ def repo_logs_api(namespace, repository):
|
||||||
|
|
||||||
@app.route('/api/organization/<orgname>/logs', methods=['GET'])
|
@app.route('/api/organization/<orgname>/logs', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def org_logs_api(orgname):
|
@org_api_call('list_user_logs')
|
||||||
|
def list_org_logs(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
performer_name = request.args.get('performer', None)
|
performer_name = request.args.get('performer', None)
|
||||||
|
@ -1835,7 +1921,7 @@ def org_logs_api(orgname):
|
||||||
|
|
||||||
@app.route('/api/user/logs', methods=['GET'])
|
@app.route('/api/user/logs', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def user_logs_api():
|
def list_user_logs():
|
||||||
performer_name = request.args.get('performer', None)
|
performer_name = request.args.get('performer', None)
|
||||||
start_time = request.args.get('starttime', None)
|
start_time = request.args.get('starttime', None)
|
||||||
end_time = request.args.get('endtime', None)
|
end_time = request.args.get('endtime', None)
|
||||||
|
|
48
endpoints/common.py
Normal file
48
endpoints/common.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from flask.ext.login import login_user, UserMixin
|
||||||
|
from flask.ext.principal import identity_changed
|
||||||
|
|
||||||
|
from data import model
|
||||||
|
from app import app, login_manager
|
||||||
|
from auth.permissions import QuayDeferredPermissionUser
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@login_manager.user_loader
|
||||||
|
def load_user(username):
|
||||||
|
logger.debug('Loading user: %s' % username)
|
||||||
|
return _LoginWrappedDBUser(username)
|
||||||
|
|
||||||
|
class _LoginWrappedDBUser(UserMixin):
|
||||||
|
def __init__(self, db_username, db_user=None):
|
||||||
|
|
||||||
|
self._db_username = db_username
|
||||||
|
self._db_user = db_user
|
||||||
|
|
||||||
|
def db_user(self):
|
||||||
|
if not self._db_user:
|
||||||
|
self._db_user = model.get_user(self._db_username)
|
||||||
|
return self._db_user
|
||||||
|
|
||||||
|
def is_authenticated(self):
|
||||||
|
return self.db_user() is not None
|
||||||
|
|
||||||
|
def is_active(self):
|
||||||
|
return self.db_user().verified
|
||||||
|
|
||||||
|
def get_id(self):
|
||||||
|
return unicode(self._db_username)
|
||||||
|
|
||||||
|
|
||||||
|
def common_login(db_user):
|
||||||
|
if login_user(_LoginWrappedDBUser(db_user.username, db_user)):
|
||||||
|
logger.debug('Successfully signed in as: %s' % db_user.username)
|
||||||
|
new_identity = QuayDeferredPermissionUser(db_user.username, 'username')
|
||||||
|
identity_changed.send(app, identity=new_identity)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.debug('User could not be logged in, inactive?.')
|
||||||
|
return False
|
|
@ -4,53 +4,30 @@ import stripe
|
||||||
|
|
||||||
from flask import (abort, redirect, request, url_for, render_template,
|
from flask import (abort, redirect, request, url_for, render_template,
|
||||||
make_response, Response)
|
make_response, Response)
|
||||||
from flask.ext.login import login_user, UserMixin, current_user
|
from flask.ext.login import current_user
|
||||||
from flask.ext.principal import identity_changed
|
|
||||||
from urlparse import urlparse
|
from urlparse import urlparse
|
||||||
|
|
||||||
from data import model
|
from data import model
|
||||||
from app import app, login_manager, mixpanel
|
from app import app, mixpanel
|
||||||
from auth.permissions import (QuayDeferredPermissionUser,
|
from auth.permissions import AdministerOrganizationPermission
|
||||||
AdministerOrganizationPermission)
|
|
||||||
from util.invoice import renderInvoiceToPdf
|
from util.invoice import renderInvoiceToPdf
|
||||||
from util.seo import render_snapshot
|
from util.seo import render_snapshot
|
||||||
|
from endpoints.api import get_route_data
|
||||||
|
from endpoints.common import common_login
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class _LoginWrappedDBUser(UserMixin):
|
def render_page_template(name):
|
||||||
def __init__(self, db_username, db_user=None):
|
return render_template(name, route_data = get_route_data())
|
||||||
|
|
||||||
self._db_username = db_username
|
|
||||||
self._db_user = db_user
|
|
||||||
|
|
||||||
def db_user(self):
|
|
||||||
if not self._db_user:
|
|
||||||
self._db_user = model.get_user(self._db_username)
|
|
||||||
return self._db_user
|
|
||||||
|
|
||||||
def is_authenticated(self):
|
|
||||||
return self.db_user() is not None
|
|
||||||
|
|
||||||
def is_active(self):
|
|
||||||
return self.db_user().verified
|
|
||||||
|
|
||||||
def get_id(self):
|
|
||||||
return unicode(self._db_username)
|
|
||||||
|
|
||||||
|
|
||||||
@login_manager.user_loader
|
|
||||||
def load_user(username):
|
|
||||||
logger.debug('Loading user: %s' % username)
|
|
||||||
return _LoginWrappedDBUser(username)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/', methods=['GET'], defaults={'path': ''})
|
@app.route('/', methods=['GET'], defaults={'path': ''})
|
||||||
@app.route('/repository/<path:path>', methods=['GET'])
|
@app.route('/repository/<path:path>', methods=['GET'])
|
||||||
@app.route('/organization/<path:path>', methods=['GET'])
|
@app.route('/organization/<path:path>', methods=['GET'])
|
||||||
def index(path):
|
def index(path):
|
||||||
return render_template('index.html')
|
return render_page_template('index.html')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/snapshot', methods=['GET'])
|
@app.route('/snapshot', methods=['GET'])
|
||||||
|
@ -81,6 +58,7 @@ def guide():
|
||||||
def organizations():
|
def organizations():
|
||||||
return index('')
|
return index('')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/user/')
|
@app.route('/user/')
|
||||||
def user():
|
def user():
|
||||||
return index('')
|
return index('')
|
||||||
|
@ -119,17 +97,17 @@ def status():
|
||||||
|
|
||||||
@app.route('/tos', methods=['GET'])
|
@app.route('/tos', methods=['GET'])
|
||||||
def tos():
|
def tos():
|
||||||
return render_template('tos.html')
|
return render_page_template('tos.html')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/disclaimer', methods=['GET'])
|
@app.route('/disclaimer', methods=['GET'])
|
||||||
def disclaimer():
|
def disclaimer():
|
||||||
return render_template('disclaimer.html')
|
return render_page_template('disclaimer.html')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/privacy', methods=['GET'])
|
@app.route('/privacy', methods=['GET'])
|
||||||
def privacy():
|
def privacy():
|
||||||
return render_template('privacy.html')
|
return render_page_template('privacy.html')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/receipt', methods=['GET'])
|
@app.route('/receipt', methods=['GET'])
|
||||||
|
@ -162,17 +140,6 @@ def receipt():
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
|
||||||
def common_login(db_user):
|
|
||||||
if login_user(_LoginWrappedDBUser(db_user.username, db_user)):
|
|
||||||
logger.debug('Successfully signed in as: %s' % db_user.username)
|
|
||||||
new_identity = QuayDeferredPermissionUser(db_user.username, 'username')
|
|
||||||
identity_changed.send(app, identity=new_identity)
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logger.debug('User could not be logged in, inactive?.')
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/oauth2/github/callback', methods=['GET'])
|
@app.route('/oauth2/github/callback', methods=['GET'])
|
||||||
def github_oauth_callback():
|
def github_oauth_callback():
|
||||||
code = request.args.get('code')
|
code = request.args.get('code')
|
||||||
|
@ -228,12 +195,12 @@ def github_oauth_callback():
|
||||||
mixpanel.alias(to_login.username, state)
|
mixpanel.alias(to_login.username, state)
|
||||||
|
|
||||||
except model.DataModelException, ex:
|
except model.DataModelException, ex:
|
||||||
return render_template('githuberror.html', error_message=ex.message)
|
return render_page_template('githuberror.html', error_message=ex.message)
|
||||||
|
|
||||||
if common_login(to_login):
|
if common_login(to_login):
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
return render_template('githuberror.html')
|
return render_page_template('githuberror.html')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/confirm', methods=['GET'])
|
@app.route('/confirm', methods=['GET'])
|
||||||
|
|
330
static/js/app.js
330
static/js/app.js
|
@ -1,6 +1,18 @@
|
||||||
var TEAM_PATTERN = '^[a-zA-Z][a-zA-Z0-9]+$';
|
var TEAM_PATTERN = '^[a-zA-Z][a-zA-Z0-9]+$';
|
||||||
var ROBOT_PATTERN = '^[a-zA-Z][a-zA-Z0-9]+$';
|
var ROBOT_PATTERN = '^[a-zA-Z][a-zA-Z0-9]+$';
|
||||||
|
|
||||||
|
function getRestUrl(args) {
|
||||||
|
var url = '';
|
||||||
|
for (var i = 0; i < arguments.length; ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
url += '/';
|
||||||
|
}
|
||||||
|
url += encodeURI(arguments[i])
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function getFirstTextLine(commentString) {
|
function getFirstTextLine(commentString) {
|
||||||
if (!commentString) { return ''; }
|
if (!commentString) { return ''; }
|
||||||
|
|
||||||
|
@ -34,11 +46,8 @@ function getFirstTextLine(commentString) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRobotAccount(Restangular, is_org, orgname, name, callback) {
|
function createRobotAccount(ApiService, is_org, orgname, name, callback) {
|
||||||
var url = is_org ? getRestUrl('organization', orgname, 'robots', name) :
|
ApiService.createRobot(is_org ? orgname : null, null, {'robot_shortname': name}).then(callback, function(resp) {
|
||||||
getRestUrl('user/robots', name);
|
|
||||||
var createRobot = Restangular.one(url);
|
|
||||||
createRobot.customPUT().then(callback, function(resp) {
|
|
||||||
bootbox.dialog({
|
bootbox.dialog({
|
||||||
"message": resp.data ? resp.data : 'The robot account could not be created',
|
"message": resp.data ? resp.data : 'The robot account could not be created',
|
||||||
"title": "Cannot create robot account",
|
"title": "Cannot create robot account",
|
||||||
|
@ -52,14 +61,18 @@ function createRobotAccount(Restangular, is_org, orgname, name, callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createOrganizationTeam(Restangular, orgname, teamname, callback) {
|
function createOrganizationTeam(ApiService, orgname, teamname, callback) {
|
||||||
var createTeam = Restangular.one(getRestUrl('organization', orgname, 'team', teamname));
|
|
||||||
var data = {
|
var data = {
|
||||||
'name': teamname,
|
'name': teamname,
|
||||||
'role': 'member'
|
'role': 'member'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
'orgname': orgname,
|
||||||
|
'teamname': teamname
|
||||||
|
};
|
||||||
|
|
||||||
createTeam.customPOST(data).then(callback, function() {
|
ApiService.updateOrganizationTeam(data, params).then(callback, function() {
|
||||||
bootbox.dialog({
|
bootbox.dialog({
|
||||||
"message": resp.data ? resp.data : 'The team could not be created',
|
"message": resp.data ? resp.data : 'The team could not be created',
|
||||||
"title": "Cannot create team",
|
"title": "Cannot create team",
|
||||||
|
@ -73,17 +86,6 @@ function createOrganizationTeam(Restangular, orgname, teamname, callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRestUrl(args) {
|
|
||||||
var url = '';
|
|
||||||
for (var i = 0; i < arguments.length; ++i) {
|
|
||||||
if (i > 0) {
|
|
||||||
url += '/';
|
|
||||||
}
|
|
||||||
url += encodeURI(arguments[i])
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMarkedDown(string) {
|
function getMarkedDown(string) {
|
||||||
return Markdown.getSanitizingConverter().makeHtml(string || '');
|
return Markdown.getSanitizingConverter().makeHtml(string || '');
|
||||||
}
|
}
|
||||||
|
@ -91,6 +93,137 @@ function getMarkedDown(string) {
|
||||||
// Start the application code itself.
|
// Start the application code itself.
|
||||||
quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'restangular', 'angularMoment', 'angulartics', /*'angulartics.google.analytics',*/ 'angulartics.mixpanel', '$strap.directives', 'ngCookies'], function($provide, cfpLoadingBarProvider) {
|
quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'restangular', 'angularMoment', 'angulartics', /*'angulartics.google.analytics',*/ 'angulartics.mixpanel', '$strap.directives', 'ngCookies'], function($provide, cfpLoadingBarProvider) {
|
||||||
cfpLoadingBarProvider.includeSpinner = false;
|
cfpLoadingBarProvider.includeSpinner = false;
|
||||||
|
|
||||||
|
$provide.factory('ApiService', ['Restangular', function(Restangular) {
|
||||||
|
var apiService = {};
|
||||||
|
|
||||||
|
var getResource = function(path) {
|
||||||
|
var resource = {};
|
||||||
|
resource.url = path;
|
||||||
|
resource.withOptions = function(options) {
|
||||||
|
this.options = options;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
resource.get = function(processor, opt_errorHandler) {
|
||||||
|
var options = this.options;
|
||||||
|
var performer = Restangular.one(this.url);
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
'loading': true,
|
||||||
|
'value': null,
|
||||||
|
'hasError': false
|
||||||
|
};
|
||||||
|
|
||||||
|
performer.get(options).then(function(resp) {
|
||||||
|
result.value = processor(resp);
|
||||||
|
result.loading = false;
|
||||||
|
}, function(resp) {
|
||||||
|
result.hasError = true;
|
||||||
|
result.loading = false;
|
||||||
|
if (opt_errorHandler) {
|
||||||
|
opt_errorHandler(resp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
};
|
||||||
|
|
||||||
|
var formatMethodName = function(endpointName) {
|
||||||
|
var formatted = '';
|
||||||
|
for (var i = 0; i < endpointName.length; ++i) {
|
||||||
|
var c = endpointName[i];
|
||||||
|
if (c == '_') {
|
||||||
|
c = endpointName[i + 1].toUpperCase();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
formatted += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatted;
|
||||||
|
};
|
||||||
|
|
||||||
|
var buildUrl = function(path, parameters) {
|
||||||
|
// We already have /api/ on the URLs, so remove them from the paths.
|
||||||
|
path = path.substr('/api/'.length, path.length);
|
||||||
|
|
||||||
|
var url = '';
|
||||||
|
for (var i = 0; i < path.length; ++i) {
|
||||||
|
var c = path[i];
|
||||||
|
if (c == '<') {
|
||||||
|
var end = path.indexOf('>', i);
|
||||||
|
var varName = path.substr(i + 1, end - i - 1);
|
||||||
|
var colon = varName.indexOf(':');
|
||||||
|
var isPathVar = false;
|
||||||
|
if (colon > 0) {
|
||||||
|
isPathVar = true;
|
||||||
|
varName = varName.substr(colon + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parameters[varName]) {
|
||||||
|
throw new Error('Missing parameter: ' + varName);
|
||||||
|
}
|
||||||
|
|
||||||
|
url += isPathVar ? parameters[varName] : encodeURI(parameters[varName]);
|
||||||
|
i = end;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
url += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getGenericMethodName = function(userMethodName) {
|
||||||
|
return formatMethodName(userMethodName.replace('_user', ''));
|
||||||
|
};
|
||||||
|
|
||||||
|
var buildMethodsForEndpoint = function(endpoint) {
|
||||||
|
var method = endpoint.methods[0].toLowerCase();
|
||||||
|
var methodName = formatMethodName(endpoint['name']);
|
||||||
|
apiService[methodName] = function(opt_options, opt_parameters) {
|
||||||
|
return Restangular.one(buildUrl(endpoint['path'], opt_parameters))['custom' + method.toUpperCase()](opt_options);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (method == 'get') {
|
||||||
|
apiService[methodName + 'AsResource'] = function(opt_parameters) {
|
||||||
|
return getResource(buildUrl(endpoint['path'], opt_parameters));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endpoint['user_method']) {
|
||||||
|
apiService[getGenericMethodName(endpoint['user_method'])] = function(orgname, opt_options, opt_parameters) {
|
||||||
|
if (orgname) {
|
||||||
|
if (orgname.name) {
|
||||||
|
orgname = orgname.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = jQuery.extend({'orgname' : orgname}, opt_parameters || {});
|
||||||
|
return apiService[methodName](opt_options, params);
|
||||||
|
} else {
|
||||||
|
return apiService[formatMethodName(endpoint['user_method'])](opt_options, opt_parameters);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Construct the methods for each API endpoint.
|
||||||
|
if (!window.__endpoints) {
|
||||||
|
return apiService;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < window.__endpoints.length; ++i) {
|
||||||
|
var endpoint = window.__endpoints[i];
|
||||||
|
buildMethodsForEndpoint(endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiService;
|
||||||
|
}]);
|
||||||
|
|
||||||
$provide.factory('CookieService', ['$cookies', '$cookieStore', function($cookies, $cookieStore) {
|
$provide.factory('CookieService', ['$cookies', '$cookieStore', function($cookies, $cookieStore) {
|
||||||
var cookieService = {};
|
var cookieService = {};
|
||||||
|
@ -113,7 +246,7 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
return cookieService;
|
return cookieService;
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
$provide.factory('UserService', ['Restangular', 'CookieService', function(Restangular, CookieService) {
|
$provide.factory('UserService', ['ApiService', 'CookieService', function(ApiService, CookieService) {
|
||||||
var userResponse = {
|
var userResponse = {
|
||||||
verified: false,
|
verified: false,
|
||||||
anonymous: true,
|
anonymous: true,
|
||||||
|
@ -139,8 +272,7 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
};
|
};
|
||||||
|
|
||||||
userService.load = function(opt_callback) {
|
userService.load = function(opt_callback) {
|
||||||
var userFetch = Restangular.one('user/');
|
ApiService.getLoggedInUser().then(function(loadedUser) {
|
||||||
userFetch.get().then(function(loadedUser) {
|
|
||||||
userResponse = loadedUser;
|
userResponse = loadedUser;
|
||||||
|
|
||||||
if (!userResponse.anonymous) {
|
if (!userResponse.anonymous) {
|
||||||
|
@ -198,48 +330,6 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
return userService;
|
return userService;
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
|
||||||
$provide.factory('ApiService', ['Restangular', function(Restangular) {
|
|
||||||
var apiService = {}
|
|
||||||
apiService.at = function(locationPieces) {
|
|
||||||
var location = getRestUrl.apply(this, arguments);
|
|
||||||
var info = {
|
|
||||||
'url': location,
|
|
||||||
'caller': Restangular.one(location),
|
|
||||||
'withOptions': function(options) {
|
|
||||||
info.options = options;
|
|
||||||
return info;
|
|
||||||
},
|
|
||||||
'get': function(processor, opt_errorHandler) {
|
|
||||||
var options = info.options;
|
|
||||||
var caller = info.caller;
|
|
||||||
var result = {
|
|
||||||
'loading': true,
|
|
||||||
'value': null,
|
|
||||||
'hasError': false
|
|
||||||
};
|
|
||||||
|
|
||||||
caller.get(options).then(function(resp) {
|
|
||||||
result.value = processor(resp);
|
|
||||||
result.loading = false;
|
|
||||||
}, function(resp) {
|
|
||||||
result.hasError = true;
|
|
||||||
result.loading = false;
|
|
||||||
if (opt_errorHandler) {
|
|
||||||
opt_errorHandler(resp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return info;
|
|
||||||
};
|
|
||||||
|
|
||||||
return apiService;
|
|
||||||
}]);
|
|
||||||
|
|
||||||
$provide.factory('KeyService', ['$location', function($location) {
|
$provide.factory('KeyService', ['$location', function($location) {
|
||||||
var keyService = {}
|
var keyService = {}
|
||||||
|
|
||||||
|
@ -254,8 +344,8 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
return keyService;
|
return keyService;
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
$provide.factory('PlanService', ['Restangular', 'KeyService', 'UserService', 'CookieService',
|
$provide.factory('PlanService', ['KeyService', 'UserService', 'CookieService', 'ApiService',
|
||||||
function(Restangular, KeyService, UserService, CookieService) {
|
function(KeyService, UserService, CookieService, ApiService) {
|
||||||
var plans = null;
|
var plans = null;
|
||||||
var planDict = {};
|
var planDict = {};
|
||||||
var planService = {};
|
var planService = {};
|
||||||
|
@ -353,8 +443,7 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var getPlans = Restangular.one('plans');
|
ApiService.listPlans().then(function(data) {
|
||||||
getPlans.get().then(function(data) {
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
for(i = 0; i < data.plans.length; i++) {
|
for(i = 0; i < data.plans.length; i++) {
|
||||||
planDict[data.plans[i].stripeId] = data.plans[i];
|
planDict[data.plans[i].stripeId] = data.plans[i];
|
||||||
|
@ -412,13 +501,7 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
};
|
};
|
||||||
|
|
||||||
planService.getSubscription = function(orgname, success, failure) {
|
planService.getSubscription = function(orgname, success, failure) {
|
||||||
var url = planService.getSubscriptionUrl(orgname);
|
ApiService.getSubscription(orgname).then(success, failure);
|
||||||
var getSubscription = Restangular.one(url);
|
|
||||||
getSubscription.get().then(success, failure);
|
|
||||||
};
|
|
||||||
|
|
||||||
planService.getSubscriptionUrl = function(orgname) {
|
|
||||||
return orgname ? getRestUrl('organization', orgname, 'plan') : 'user/plan';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
planService.setSubscription = function(orgname, planId, success, failure, opt_token) {
|
planService.setSubscription = function(orgname, planId, success, failure, opt_token) {
|
||||||
|
@ -430,9 +513,7 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
subscriptionDetails['token'] = opt_token.id;
|
subscriptionDetails['token'] = opt_token.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = planService.getSubscriptionUrl(orgname);
|
ApiService.updateSubscription(orgname, subscriptionDetails).then(function(resp) {
|
||||||
var createSubscriptionRequest = Restangular.one(url);
|
|
||||||
createSubscriptionRequest.customPUT(subscriptionDetails).then(function(resp) {
|
|
||||||
success(resp);
|
success(resp);
|
||||||
planService.getPlan(planId, function(plan) {
|
planService.getPlan(planId, function(plan) {
|
||||||
for (var i = 0; i < listeners.length; ++i) {
|
for (var i = 0; i < listeners.length; ++i) {
|
||||||
|
@ -443,9 +524,7 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
};
|
};
|
||||||
|
|
||||||
planService.getCardInfo = function(orgname, callback) {
|
planService.getCardInfo = function(orgname, callback) {
|
||||||
var url = orgname ? getRestUrl('organization', orgname, 'card') : 'user/card';
|
ApiService.getCard(orgname).then(function(resp) {
|
||||||
var getCard = Restangular.one(url);
|
|
||||||
getCard.customGET().then(function(resp) {
|
|
||||||
callback(resp.card);
|
callback(resp.card);
|
||||||
}, function() {
|
}, function() {
|
||||||
callback({'is_valid': false});
|
callback({'is_valid': false});
|
||||||
|
@ -492,12 +571,10 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
|
||||||
'token': token.id
|
'token': token.id
|
||||||
};
|
};
|
||||||
|
|
||||||
var url = orgname ? getRestUrl('organization', orgname, 'card') : 'user/card';
|
ApiService.setCard(orgname, cardInfo).then(callbacks['success'], function(resp) {
|
||||||
var changeCardRequest = Restangular.one(url);
|
planService.handleCardError(resp);
|
||||||
changeCardRequest.customPOST(cardInfo).then(callbacks['success'], function(resp) {
|
callbacks['failure'](resp);
|
||||||
planService.handleCardError(resp);
|
});
|
||||||
callbacks['failure'](resp);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -739,10 +816,9 @@ quayApp.directive('userSetup', function () {
|
||||||
'signInStarted': '&signInStarted',
|
'signInStarted': '&signInStarted',
|
||||||
'signedIn': '&signedIn'
|
'signedIn': '&signedIn'
|
||||||
},
|
},
|
||||||
controller: function($scope, $location, $timeout, Restangular, KeyService, UserService) {
|
controller: function($scope, $location, $timeout, ApiService, KeyService, UserService) {
|
||||||
$scope.sendRecovery = function() {
|
$scope.sendRecovery = function() {
|
||||||
var signinPost = Restangular.one('recovery');
|
ApiService.requestRecoveryEmail($scope.recovery).then(function() {
|
||||||
signinPost.customPOST($scope.recovery).then(function() {
|
|
||||||
$scope.invalidEmail = false;
|
$scope.invalidEmail = false;
|
||||||
$scope.sent = true;
|
$scope.sent = true;
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
|
@ -772,7 +848,7 @@ quayApp.directive('signinForm', function () {
|
||||||
'signInStarted': '&signInStarted',
|
'signInStarted': '&signInStarted',
|
||||||
'signedIn': '&signedIn'
|
'signedIn': '&signedIn'
|
||||||
},
|
},
|
||||||
controller: function($scope, $location, $timeout, Restangular, KeyService, UserService) {
|
controller: function($scope, $location, $timeout, ApiService, KeyService, UserService) {
|
||||||
$scope.showGithub = function() {
|
$scope.showGithub = function() {
|
||||||
$scope.markStarted();
|
$scope.markStarted();
|
||||||
|
|
||||||
|
@ -799,8 +875,7 @@ quayApp.directive('signinForm', function () {
|
||||||
$scope.signin = function() {
|
$scope.signin = function() {
|
||||||
$scope.markStarted();
|
$scope.markStarted();
|
||||||
|
|
||||||
var signinPost = Restangular.one('signin');
|
ApiService.signinUser($scope.user).then(function() {
|
||||||
signinPost.customPOST($scope.user).then(function() {
|
|
||||||
$scope.needsEmailVerification = false;
|
$scope.needsEmailVerification = false;
|
||||||
$scope.invalidCredentials = false;
|
$scope.invalidCredentials = false;
|
||||||
|
|
||||||
|
@ -840,7 +915,7 @@ quayApp.directive('signupForm', function () {
|
||||||
scope: {
|
scope: {
|
||||||
|
|
||||||
},
|
},
|
||||||
controller: function($scope, $location, $timeout, Restangular, KeyService, UserService) {
|
controller: function($scope, $location, $timeout, ApiService, KeyService, UserService) {
|
||||||
$('.form-signup').popover();
|
$('.form-signup').popover();
|
||||||
|
|
||||||
angulartics.waitForVendorApi(mixpanel, 500, function(loadedMixpanel) {
|
angulartics.waitForVendorApi(mixpanel, 500, function(loadedMixpanel) {
|
||||||
|
@ -857,8 +932,7 @@ quayApp.directive('signupForm', function () {
|
||||||
$('.form-signup').popover('hide');
|
$('.form-signup').popover('hide');
|
||||||
$scope.registering = true;
|
$scope.registering = true;
|
||||||
|
|
||||||
var newUserPost = Restangular.one('user/');
|
ApiService.createNewUser($scope.newUser).then(function() {
|
||||||
newUserPost.customPOST($scope.newUser).then(function() {
|
|
||||||
$scope.awaitingConfirmation = true;
|
$scope.awaitingConfirmation = true;
|
||||||
$scope.registering = false;
|
$scope.registering = false;
|
||||||
|
|
||||||
|
@ -911,7 +985,7 @@ quayApp.directive('dockerAuthDialog', function () {
|
||||||
'shown': '=shown',
|
'shown': '=shown',
|
||||||
'counter': '=counter'
|
'counter': '=counter'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, Restangular) {
|
controller: function($scope, $element) {
|
||||||
$scope.isDownloadSupported = function() {
|
$scope.isDownloadSupported = function() {
|
||||||
try { return !!new Blob(); } catch(e){}
|
try { return !!new Blob(); } catch(e){}
|
||||||
return false;
|
return false;
|
||||||
|
@ -981,7 +1055,7 @@ quayApp.directive('billingInvoices', function () {
|
||||||
'user': '=user',
|
'user': '=user',
|
||||||
'visible': '=visible'
|
'visible': '=visible'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, $sce, Restangular) {
|
controller: function($scope, $element, $sce, ApiService) {
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
$scope.invoiceExpanded = {};
|
$scope.invoiceExpanded = {};
|
||||||
|
|
||||||
|
@ -1000,13 +1074,7 @@ quayApp.directive('billingInvoices', function () {
|
||||||
|
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
|
|
||||||
var url = getRestUrl('user/invoices');
|
ApiService.listInvoices($scope.organization).then(function(resp) {
|
||||||
if ($scope.organization) {
|
|
||||||
url = getRestUrl('organization', $scope.organization.name, 'invoices');
|
|
||||||
}
|
|
||||||
|
|
||||||
var getInvoices = Restangular.one(url);
|
|
||||||
getInvoices.get().then(function(resp) {
|
|
||||||
$scope.invoices = resp.invoices;
|
$scope.invoices = resp.invoices;
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
});
|
});
|
||||||
|
@ -1036,7 +1104,7 @@ quayApp.directive('logsView', function () {
|
||||||
'repository': '=repository',
|
'repository': '=repository',
|
||||||
'performer': '=performer'
|
'performer': '=performer'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, $sce, Restangular) {
|
controller: function($scope, $element, $sce, Restangular, ApiService) {
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
$scope.logs = null;
|
$scope.logs = null;
|
||||||
$scope.kindsAllowed = null;
|
$scope.kindsAllowed = null;
|
||||||
|
@ -1152,6 +1220,8 @@ quayApp.directive('logsView', function () {
|
||||||
|
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
|
|
||||||
|
// Note: We construct the URLs here manually because we also use it for the download
|
||||||
|
// path.
|
||||||
var url = getRestUrl('user/logs');
|
var url = getRestUrl('user/logs');
|
||||||
if ($scope.organization) {
|
if ($scope.organization) {
|
||||||
url = getRestUrl('organization', $scope.organization.name, 'logs');
|
url = getRestUrl('organization', $scope.organization.name, 'logs');
|
||||||
|
@ -1255,7 +1325,7 @@ quayApp.directive('robotsManager', function () {
|
||||||
'organization': '=organization',
|
'organization': '=organization',
|
||||||
'user': '=user'
|
'user': '=user'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, Restangular) {
|
controller: function($scope, $element, ApiService) {
|
||||||
$scope.ROBOT_PATTERN = ROBOT_PATTERN;
|
$scope.ROBOT_PATTERN = ROBOT_PATTERN;
|
||||||
$scope.robots = null;
|
$scope.robots = null;
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
|
@ -1280,7 +1350,7 @@ quayApp.directive('robotsManager', function () {
|
||||||
$scope.createRobot = function(name) {
|
$scope.createRobot = function(name) {
|
||||||
if (!name) { return; }
|
if (!name) { return; }
|
||||||
|
|
||||||
createRobotAccount(Restangular, !!$scope.organization, $scope.organization ? $scope.organization.name : '', name,
|
createRobotAccount(ApiService, !!$scope.organization, $scope.organization ? $scope.organization.name : '', name,
|
||||||
function(created) {
|
function(created) {
|
||||||
$scope.robots.push(created);
|
$scope.robots.push(created);
|
||||||
});
|
});
|
||||||
|
@ -1288,11 +1358,7 @@ quayApp.directive('robotsManager', function () {
|
||||||
|
|
||||||
$scope.deleteRobot = function(info) {
|
$scope.deleteRobot = function(info) {
|
||||||
var shortName = $scope.getShortenedName(info.name);
|
var shortName = $scope.getShortenedName(info.name);
|
||||||
var url = $scope.organization ? getRestUrl('organization', $scope.organization.name, 'robots', shortName) :
|
ApiService.deleteRobot($scope.organization, null, {'robot_shortname': shortName}).then(function(resp) {
|
||||||
getRestUrl('user/robots', shortName);
|
|
||||||
|
|
||||||
var deleteRobot = Restangular.one(url);
|
|
||||||
deleteRobot.customDELETE().then(function(resp) {
|
|
||||||
for (var i = 0; i < $scope.robots.length; ++i) {
|
for (var i = 0; i < $scope.robots.length; ++i) {
|
||||||
if ($scope.robots[i].name == info.name) {
|
if ($scope.robots[i].name == info.name) {
|
||||||
$scope.robots.splice(i, 1);
|
$scope.robots.splice(i, 1);
|
||||||
|
@ -1318,9 +1384,7 @@ quayApp.directive('robotsManager', function () {
|
||||||
if ($scope.loading) { return; }
|
if ($scope.loading) { return; }
|
||||||
|
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
var url = $scope.organization ? getRestUrl('organization', $scope.organization.name, 'robots') : 'user/robots';
|
ApiService.getRobots($scope.organization).then(function(resp) {
|
||||||
var getRobots = Restangular.one(url);
|
|
||||||
getRobots.customGET($scope.obj).then(function(resp) {
|
|
||||||
$scope.robots = resp.robots;
|
$scope.robots = resp.robots;
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
});
|
});
|
||||||
|
@ -1553,7 +1617,7 @@ quayApp.directive('headerBar', function () {
|
||||||
restrict: 'C',
|
restrict: 'C',
|
||||||
scope: {
|
scope: {
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, $location, UserService, PlanService, Restangular) {
|
controller: function($scope, $element, $location, UserService, PlanService, ApiService) {
|
||||||
$scope.overPlan = false;
|
$scope.overPlan = false;
|
||||||
|
|
||||||
var checkOverPlan = function() {
|
var checkOverPlan = function() {
|
||||||
|
@ -1562,8 +1626,7 @@ quayApp.directive('headerBar', function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkPrivate = Restangular.one('user/private');
|
ApiService.getUserPrivateCount().then(function(resp) {
|
||||||
checkPrivate.customGET().then(function(resp) {
|
|
||||||
$scope.overPlan = resp.privateCount > resp.reposAllowed;
|
$scope.overPlan = resp.privateCount > resp.reposAllowed;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1575,10 +1638,9 @@ quayApp.directive('headerBar', function () {
|
||||||
PlanService.registerListener(this, checkOverPlan);
|
PlanService.registerListener(this, checkOverPlan);
|
||||||
|
|
||||||
$scope.signout = function() {
|
$scope.signout = function() {
|
||||||
var signoutPost = Restangular.one('signout');
|
ApiService.logout().then(function() {
|
||||||
signoutPost.customPOST().then(function() {
|
UserService.load();
|
||||||
UserService.load();
|
$location.path('/');
|
||||||
$location.path('/');
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1609,7 +1671,7 @@ quayApp.directive('entitySearch', function () {
|
||||||
'includeTeams': '=includeTeams',
|
'includeTeams': '=includeTeams',
|
||||||
'isOrganization': '=isOrganization'
|
'isOrganization': '=isOrganization'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, Restangular, UserService) {
|
controller: function($scope, $element, Restangular, UserService, ApiService) {
|
||||||
$scope.lazyLoading = true;
|
$scope.lazyLoading = true;
|
||||||
$scope.isAdmin = false;
|
$scope.isAdmin = false;
|
||||||
|
|
||||||
|
@ -1619,16 +1681,12 @@ quayApp.directive('entitySearch', function () {
|
||||||
$scope.isAdmin = UserService.isNamespaceAdmin($scope.namespace);
|
$scope.isAdmin = UserService.isNamespaceAdmin($scope.namespace);
|
||||||
|
|
||||||
if ($scope.isOrganization && $scope.includeTeams) {
|
if ($scope.isOrganization && $scope.includeTeams) {
|
||||||
var url = getRestUrl('organization', $scope.namespace);
|
ApiService.getOrganization(null, {'orgname': $scope.namespace}).then(function(resp) {
|
||||||
var getOrganization = Restangular.one(url);
|
|
||||||
getOrganization.customGET().then(function(resp) {
|
|
||||||
$scope.teams = resp.teams;
|
$scope.teams = resp.teams;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = $scope.isOrganization ? getRestUrl('organization', $scope.namespace, 'robots') : 'user/robots';
|
ApiService.getRobots($scope.isOrganization ? $scope.namespace : null).then(function(resp) {
|
||||||
var getRobots = Restangular.one(url);
|
|
||||||
getRobots.customGET().then(function(resp) {
|
|
||||||
$scope.robots = resp.robots;
|
$scope.robots = resp.robots;
|
||||||
$scope.lazyLoading = false;
|
$scope.lazyLoading = false;
|
||||||
}, function() {
|
}, function() {
|
||||||
|
@ -1648,7 +1706,7 @@ quayApp.directive('entitySearch', function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
createOrganizationTeam(Restangular, $scope.namespace, teamname, function(created) {
|
createOrganizationTeam(ApiService, $scope.namespace, teamname, function(created) {
|
||||||
$scope.setEntity(created.name, 'team', false);
|
$scope.setEntity(created.name, 'team', false);
|
||||||
$scope.teams[teamname] = created;
|
$scope.teams[teamname] = created;
|
||||||
});
|
});
|
||||||
|
@ -1667,7 +1725,7 @@ quayApp.directive('entitySearch', function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
createRobotAccount(Restangular, $scope.isOrganization, $scope.namespace, robotname, function(created) {
|
createRobotAccount(ApiService, $scope.isOrganization, $scope.namespace, robotname, function(created) {
|
||||||
$scope.setEntity(created.name, 'user', true);
|
$scope.setEntity(created.name, 'user', true);
|
||||||
$scope.robots.push(created);
|
$scope.robots.push(created);
|
||||||
});
|
});
|
||||||
|
@ -1793,7 +1851,7 @@ quayApp.directive('billingOptions', function () {
|
||||||
'user': '=user',
|
'user': '=user',
|
||||||
'organization': '=organization'
|
'organization': '=organization'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, PlanService, Restangular) {
|
controller: function($scope, $element, PlanService, ApiService) {
|
||||||
$scope.invoice_email = false;
|
$scope.invoice_email = false;
|
||||||
$scope.currentCard = null;
|
$scope.currentCard = null;
|
||||||
|
|
||||||
|
@ -1863,9 +1921,7 @@ quayApp.directive('billingOptions', function () {
|
||||||
|
|
||||||
var save = function() {
|
var save = function() {
|
||||||
$scope.working = true;
|
$scope.working = true;
|
||||||
var url = $scope.organization ? getRestUrl('organization', $scope.organization.name) : 'user/';
|
ApiService.changeDetails($scope.organization, $scope.obj).then(function(resp) {
|
||||||
var conductSave = Restangular.one(url);
|
|
||||||
conductSave.customPUT($scope.obj).then(function(resp) {
|
|
||||||
$scope.working = false;
|
$scope.working = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1900,7 +1956,7 @@ quayApp.directive('planManager', function () {
|
||||||
'readyForPlan': '&readyForPlan',
|
'readyForPlan': '&readyForPlan',
|
||||||
'planChanged': '&planChanged'
|
'planChanged': '&planChanged'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, PlanService, Restangular) {
|
controller: function($scope, $element, PlanService, ApiService) {
|
||||||
var hasSubscription = false;
|
var hasSubscription = false;
|
||||||
|
|
||||||
$scope.isPlanVisible = function(plan, subscribedPlan) {
|
$scope.isPlanVisible = function(plan, subscribedPlan) {
|
||||||
|
|
13
static/js/bootstrap.js
vendored
Normal file
13
static/js/bootstrap.js
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
async: false,
|
||||||
|
url: '/api/discovery',
|
||||||
|
success: function(data) {
|
||||||
|
window.__endpoints = data.endpoints;
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
$('#couldnotloadModal').modal({});
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
});
|
|
@ -67,14 +67,15 @@ function RepoListCtrl($scope, Restangular, UserService, ApiService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = {'public': false, 'sort': true, 'namespace': namespace};
|
var options = {'public': false, 'sort': true, 'namespace': namespace};
|
||||||
$scope.user_repositories = ApiService.at('repository').withOptions(options).get(function(resp) {
|
|
||||||
|
$scope.user_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
|
||||||
return resp.repositories;
|
return resp.repositories;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadPublicRepos = function() {
|
var loadPublicRepos = function() {
|
||||||
var options = {'public': true, 'private': false, 'sort': true, 'limit': 10};
|
var options = {'public': true, 'private': false, 'sort': true, 'limit': 10};
|
||||||
$scope.public_repositories = ApiService.at('repository').withOptions(options).get(function(resp) {
|
$scope.public_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
|
||||||
return resp.repositories;
|
return resp.repositories;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -118,7 +119,7 @@ function LandingCtrl($scope, UserService, ApiService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = {'limit': 4, 'public': false, 'sort': true, 'namespace': namespace };
|
var options = {'limit': 4, 'public': false, 'sort': true, 'namespace': namespace };
|
||||||
$scope.my_repositories = ApiService.at('repository').withOptions(options).get(function(resp) {
|
$scope.my_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
|
||||||
return resp.repositories;
|
return resp.repositories;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -169,7 +170,8 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.loadImageChanges = function(image) {
|
$scope.loadImageChanges = function(image) {
|
||||||
$scope.currentImageChangeResource = ApiService.at('repository', namespace, name, 'image', image.id, 'changes').get(function(ci) {
|
var params = {'repository': namespace + '/' + name, 'image_id': image.id};
|
||||||
|
$scope.currentImageChangeResource = ApiService.getImageChangesAsResource(params).get(function(ci) {
|
||||||
$scope.currentImageChanges = ci;
|
$scope.currentImageChanges = ci;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -240,8 +242,9 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
|
||||||
};
|
};
|
||||||
|
|
||||||
var fetchRepository = function() {
|
var fetchRepository = function() {
|
||||||
|
var params = {'repository': namespace + '/' + name};
|
||||||
$rootScope.title = 'Loading Repository...';
|
$rootScope.title = 'Loading Repository...';
|
||||||
$scope.repository = ApiService.at('repository', namespace, name).get(function(repo) {
|
$scope.repository = ApiService.getRepoAsResource(params).get(function(repo) {
|
||||||
// Set the repository object.
|
// Set the repository object.
|
||||||
$scope.repo = repo;
|
$scope.repo = repo;
|
||||||
|
|
||||||
|
@ -283,6 +286,7 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
|
||||||
};
|
};
|
||||||
|
|
||||||
var getBuildInfo = function(repo) {
|
var getBuildInfo = function(repo) {
|
||||||
|
// Note: We use restangular manually here because we need to turn off the loading bar.
|
||||||
var buildInfo = Restangular.one('repository/' + repo.namespace + '/' + repo.name + '/build/');
|
var buildInfo = Restangular.one('repository/' + repo.namespace + '/' + repo.name + '/build/');
|
||||||
buildInfo.withHttpConfig({
|
buildInfo.withHttpConfig({
|
||||||
'ignoreLoadingBar': true
|
'ignoreLoadingBar': true
|
||||||
|
@ -312,7 +316,8 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
|
||||||
};
|
};
|
||||||
|
|
||||||
var listImages = function() {
|
var listImages = function() {
|
||||||
$scope.imageHistory = ApiService.at('repository', namespace, name, 'image').get(function(resp) {
|
var params = {'repository': namespace + '/' + name};
|
||||||
|
$scope.imageHistory = ApiService.listRepositoryImagesAsResource(params).get(function(resp) {
|
||||||
// Dispose of any existing tree.
|
// Dispose of any existing tree.
|
||||||
if ($scope.tree) {
|
if ($scope.tree) {
|
||||||
$scope.tree.dispose();
|
$scope.tree.dispose();
|
||||||
|
@ -352,11 +357,6 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
|
||||||
}
|
}
|
||||||
|
|
||||||
function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope) {
|
function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope) {
|
||||||
$('.info-icon').popover({
|
|
||||||
'trigger': 'hover',
|
|
||||||
'html': true
|
|
||||||
});
|
|
||||||
|
|
||||||
var namespace = $routeParams.namespace;
|
var namespace = $routeParams.namespace;
|
||||||
var name = $routeParams.name;
|
var name = $routeParams.name;
|
||||||
|
|
||||||
|
@ -443,8 +443,8 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
'friendlyName': $scope.newToken.friendlyName
|
'friendlyName': $scope.newToken.friendlyName
|
||||||
};
|
};
|
||||||
|
|
||||||
var permissionPost = Restangular.one('repository/' + namespace + '/' + name + '/tokens/');
|
var params = {'repository': namespace + '/' + name};
|
||||||
permissionPost.customPOST(friendlyName).then(function(newToken) {
|
ApiService.createToken(friendlyName, params).then(function(newToken) {
|
||||||
$scope.newToken.friendlyName = '';
|
$scope.newToken.friendlyName = '';
|
||||||
$scope.createTokenForm.$setPristine();
|
$scope.createTokenForm.$setPristine();
|
||||||
$scope.tokens[newToken.code] = newToken;
|
$scope.tokens[newToken.code] = newToken;
|
||||||
|
@ -452,8 +452,12 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteToken = function(tokenCode) {
|
$scope.deleteToken = function(tokenCode) {
|
||||||
var deleteAction = Restangular.one('repository/' + namespace + '/' + name + '/tokens/' + tokenCode);
|
var params = {
|
||||||
deleteAction.customDELETE().then(function() {
|
'repository': namespace + '/' + name,
|
||||||
|
'code': tokenCode
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.deleteToken(null, params).then(function() {
|
||||||
delete $scope.tokens[tokenCode];
|
delete $scope.tokens[tokenCode];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -463,8 +467,12 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
'role': newAccess
|
'role': newAccess
|
||||||
};
|
};
|
||||||
|
|
||||||
var deleteAction = Restangular.one('repository/' + namespace + '/' + name + '/tokens/' + tokenCode);
|
var params = {
|
||||||
deleteAction.customPUT(role).then(function(updated) {
|
'repository': namespace + '/' + name,
|
||||||
|
'code': tokenCode
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.changeToken(role, params).then(function(updated) {
|
||||||
$scope.tokens[updated.code] = updated;
|
$scope.tokens[updated.code] = updated;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -486,8 +494,12 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
var visibility = {
|
var visibility = {
|
||||||
'visibility': newAccess
|
'visibility': newAccess
|
||||||
};
|
};
|
||||||
var visibilityPost = Restangular.one('repository/' + namespace + '/' + name + '/changevisibility');
|
|
||||||
visibilityPost.customPOST(visibility).then(function() {
|
var params = {
|
||||||
|
'repository': namespace + '/' + name
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.changeRepoVisibility(visibility, params).then(function() {
|
||||||
$scope.repo.is_public = newAccess == 'public';
|
$scope.repo.is_public = newAccess == 'public';
|
||||||
}, function() {
|
}, function() {
|
||||||
$('#cannotchangeModal').modal({});
|
$('#cannotchangeModal').modal({});
|
||||||
|
@ -501,8 +513,11 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
$scope.deleteRepo = function() {
|
$scope.deleteRepo = function() {
|
||||||
$('#confirmdeleteModal').modal('hide');
|
$('#confirmdeleteModal').modal('hide');
|
||||||
|
|
||||||
var deleteAction = Restangular.one('repository/' + namespace + '/' + name);
|
var params = {
|
||||||
deleteAction.customDELETE().then(function() {
|
'repository': namespace + '/' + name
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.deleteRepository(null, params).then(function() {
|
||||||
$scope.repo = null;
|
$scope.repo = null;
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
@ -514,8 +529,12 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.loadWebhooks = function() {
|
$scope.loadWebhooks = function() {
|
||||||
|
var params = {
|
||||||
|
'repository': namespace + '/' + name
|
||||||
|
};
|
||||||
|
|
||||||
$scope.newWebhook = {};
|
$scope.newWebhook = {};
|
||||||
$scope.webhooksResource = ApiService.at('repository', namespace, name, 'webhook').get(function(resp) {
|
$scope.webhooksResource = ApiService.listWebhooksAsResource(params).get(function(resp) {
|
||||||
$scope.webhooks = resp.webhooks;
|
$scope.webhooks = resp.webhooks;
|
||||||
return $scope.webhooks;
|
return $scope.webhooks;
|
||||||
});
|
});
|
||||||
|
@ -526,8 +545,11 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newWebhook = Restangular.one('repository/' + namespace + '/' + name + '/webhook/');
|
var params = {
|
||||||
newWebhook.customPOST($scope.newWebhook).then(function(resp) {
|
'repository': namespace + '/' + name
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.createWebhook($scope.newWebhook, params).then(function(resp) {
|
||||||
$scope.webhooks.push(resp);
|
$scope.webhooks.push(resp);
|
||||||
$scope.newWebhook.url = '';
|
$scope.newWebhook.url = '';
|
||||||
$scope.createWebhookForm.$setPristine();
|
$scope.createWebhookForm.$setPristine();
|
||||||
|
@ -535,15 +557,22 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteWebhook = function(webhook) {
|
$scope.deleteWebhook = function(webhook) {
|
||||||
var deleteWebhookReq = Restangular.one('repository/' + namespace + '/' + name + '/webhook/' + webhook.public_id);
|
var params = {
|
||||||
deleteWebhookReq.customDELETE().then(function(resp) {
|
'repository': namespace + '/' + name,
|
||||||
|
'public_id': webhook.public_id
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.deleteWebhook(null, params).then(function(resp) {
|
||||||
$scope.webhooks.splice($scope.webhooks.indexOf(webhook), 1);
|
$scope.webhooks.splice($scope.webhooks.indexOf(webhook), 1);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var fetchTokens = function() {
|
var fetchTokens = function() {
|
||||||
var tokensFetch = Restangular.one('repository/' + namespace + '/' + name + '/tokens/');
|
var params = {
|
||||||
tokensFetch.get().then(function(resp) {
|
'repository': namespace + '/' + name
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.listRepoTokens(null, params).then(function(resp) {
|
||||||
$scope.tokens = resp.tokens;
|
$scope.tokens = resp.tokens;
|
||||||
}, function() {
|
}, function() {
|
||||||
$scope.tokens = null;
|
$scope.tokens = null;
|
||||||
|
@ -560,7 +589,11 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
};
|
};
|
||||||
|
|
||||||
var fetchRepository = function() {
|
var fetchRepository = function() {
|
||||||
$scope.repository = ApiService.at('repository', namespace, name).get(function(repo) {
|
var params = {
|
||||||
|
'repository': namespace + '/' + name
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.repository = ApiService.getRepoAsResource(params).get(function(repo) {
|
||||||
$scope.repo = repo;
|
$scope.repo = repo;
|
||||||
|
|
||||||
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
||||||
|
@ -572,6 +605,11 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
fetchPermissions('team');
|
fetchPermissions('team');
|
||||||
fetchTokens();
|
fetchTokens();
|
||||||
|
|
||||||
|
$('.info-icon').popover({
|
||||||
|
'trigger': 'hover',
|
||||||
|
'html': true
|
||||||
|
});
|
||||||
|
|
||||||
return $scope.repo;
|
return $scope.repo;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -580,13 +618,14 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
fetchRepository();
|
fetchRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
function UserAdminCtrl($scope, $timeout, $location, Restangular, PlanService, UserService, KeyService, $routeParams) {
|
function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, UserService, KeyService, $routeParams) {
|
||||||
if ($routeParams['migrate']) {
|
if ($routeParams['migrate']) {
|
||||||
$('#migrateTab').tab('show')
|
$('#migrateTab').tab('show')
|
||||||
}
|
}
|
||||||
|
|
||||||
UserService.updateUserIn($scope, function(user) {
|
UserService.updateUserIn($scope, function(user) {
|
||||||
$scope.askForPassword = user.askForPassword;
|
$scope.askForPassword = user.askForPassword;
|
||||||
|
$scope.cuser = jQuery.extend({}, user);
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.readyForPlan = function() {
|
$scope.readyForPlan = function() {
|
||||||
|
@ -645,8 +684,7 @@ function UserAdminCtrl($scope, $timeout, $location, Restangular, PlanService, Us
|
||||||
'plan': $scope.org.plan.stripeId
|
'plan': $scope.org.plan.stripeId
|
||||||
};
|
};
|
||||||
|
|
||||||
var convertAccount = Restangular.one('user/convert');
|
ApiService.convertUserToOrganization(data).then(function(resp) {
|
||||||
convertAccount.customPOST(data).then(function(resp) {
|
|
||||||
UserService.load();
|
UserService.load();
|
||||||
$location.path('/');
|
$location.path('/');
|
||||||
}, function(resp) {
|
}, function(resp) {
|
||||||
|
@ -663,14 +701,14 @@ function UserAdminCtrl($scope, $timeout, $location, Restangular, PlanService, Us
|
||||||
$('.form-change-pw').popover('hide');
|
$('.form-change-pw').popover('hide');
|
||||||
$scope.updatingUser = true;
|
$scope.updatingUser = true;
|
||||||
$scope.changePasswordSuccess = false;
|
$scope.changePasswordSuccess = false;
|
||||||
var changePasswordPost = Restangular.one('user/');
|
|
||||||
changePasswordPost.customPUT($scope.user).then(function() {
|
ApiService.changeUserDetails($scope.cuser).then(function() {
|
||||||
$scope.updatingUser = false;
|
$scope.updatingUser = false;
|
||||||
$scope.changePasswordSuccess = true;
|
$scope.changePasswordSuccess = true;
|
||||||
|
|
||||||
// Reset the form
|
// Reset the form
|
||||||
$scope.user.password = '';
|
$scope.cuser.password = '';
|
||||||
$scope.user.repeatPassword = '';
|
$scope.cuser.repeatPassword = '';
|
||||||
$scope.changePasswordForm.$setPristine();
|
$scope.changePasswordForm.$setPristine();
|
||||||
|
|
||||||
// Reload the user.
|
// Reload the user.
|
||||||
|
@ -686,7 +724,7 @@ function UserAdminCtrl($scope, $timeout, $location, Restangular, PlanService, Us
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, Restangular) {
|
function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService) {
|
||||||
var namespace = $routeParams.namespace;
|
var namespace = $routeParams.namespace;
|
||||||
var name = $routeParams.name;
|
var name = $routeParams.name;
|
||||||
var imageid = $routeParams.image;
|
var imageid = $routeParams.image;
|
||||||
|
@ -742,7 +780,12 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, R
|
||||||
};
|
};
|
||||||
|
|
||||||
var fetchImage = function() {
|
var fetchImage = function() {
|
||||||
$scope.image = ApiService.at('repository', namespace, name, 'image', imageid).get(function(image) {
|
var params = {
|
||||||
|
'repository': namespace + '/' + name,
|
||||||
|
'image_id': imageid
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.image = ApiService.getImageAsResource(params).get(function(image) {
|
||||||
$scope.repo = {
|
$scope.repo = {
|
||||||
'name': name,
|
'name': name,
|
||||||
'namespace': namespace
|
'namespace': namespace
|
||||||
|
@ -762,8 +805,12 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, R
|
||||||
};
|
};
|
||||||
|
|
||||||
var fetchChanges = function() {
|
var fetchChanges = function() {
|
||||||
var changesFetch = Restangular.one('repository/' + namespace + '/' + name + '/image/' + imageid + '/changes');
|
var params = {
|
||||||
changesFetch.get().then(function(changes) {
|
'repository': namespace + '/' + name,
|
||||||
|
'image_id': imageid
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.getImageChanges(null, params).then(function(changes) {
|
||||||
var combinedChanges = [];
|
var combinedChanges = [];
|
||||||
var addCombinedChanges = function(c, kind) {
|
var addCombinedChanges = function(c, kind) {
|
||||||
for (var i = 0; i < c.length; ++i) {
|
for (var i = 0; i < c.length; ++i) {
|
||||||
|
@ -791,7 +838,7 @@ function V1Ctrl($scope, $location, UserService) {
|
||||||
UserService.updateUserIn($scope);
|
UserService.updateUserIn($scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangular, PlanService) {
|
function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService, PlanService) {
|
||||||
UserService.updateUserIn($scope);
|
UserService.updateUserIn($scope);
|
||||||
|
|
||||||
$scope.repo = {
|
$scope.repo = {
|
||||||
|
@ -822,8 +869,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangula
|
||||||
if (isUserNamespace) {
|
if (isUserNamespace) {
|
||||||
// Load the user's subscription information in case they want to create a private
|
// Load the user's subscription information in case they want to create a private
|
||||||
// repository.
|
// repository.
|
||||||
var checkPrivateAllowed = Restangular.one('user/private');
|
ApiService.getUserPrivateCount().then(function(resp) {
|
||||||
checkPrivateAllowed.get().then(function(resp) {
|
|
||||||
if (resp.privateCount + 1 > resp.reposAllowed) {
|
if (resp.privateCount + 1 > resp.reposAllowed) {
|
||||||
PlanService.getMinimumPlan(resp.privateCount + 1, false, function(minimum) {
|
PlanService.getMinimumPlan(resp.privateCount + 1, false, function(minimum) {
|
||||||
$scope.planRequired = minimum;
|
$scope.planRequired = minimum;
|
||||||
|
@ -836,8 +882,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangula
|
||||||
$scope.checkingPlan = false;
|
$scope.checkingPlan = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var checkPrivateAllowed = Restangular.one('organization/' + namespace + '/private');
|
ApiService.getOrganizationPrivateAllowed(null, {'orgname': namespace}).then(function(resp) {
|
||||||
checkPrivateAllowed.get().then(function(resp) {
|
|
||||||
$scope.planRequired = resp.privateAllowed ? null : {};
|
$scope.planRequired = resp.privateAllowed ? null : {};
|
||||||
$scope.checkingPlan = false;
|
$scope.checkingPlan = false;
|
||||||
}, function() {
|
}, function() {
|
||||||
|
@ -868,8 +913,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangula
|
||||||
'description': repo.description
|
'description': repo.description
|
||||||
};
|
};
|
||||||
|
|
||||||
var createPost = Restangular.one('repository');
|
ApiService.createRepo(data).then(function(created) {
|
||||||
createPost.customPOST(data).then(function(created) {
|
|
||||||
$scope.creating = false;
|
$scope.creating = false;
|
||||||
$scope.created = created;
|
$scope.created = created;
|
||||||
|
|
||||||
|
@ -912,9 +956,12 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangula
|
||||||
'file_id': fileId
|
'file_id': fileId
|
||||||
};
|
};
|
||||||
|
|
||||||
var startBuildCall = Restangular.one('repository/' + repo.namespace + '/' + repo.name + '/build/');
|
var params = {
|
||||||
startBuildCall.customPOST(data).then(function(resp) {
|
'repository': repo.namespace + '/' + repo.name
|
||||||
$location.path('/repository/' + repo.namespace + '/' + repo.name);
|
};
|
||||||
|
|
||||||
|
ApiService.requestRepoBuild(data, params).then(function(resp) {
|
||||||
|
$location.path('/repository/' + params.repository);
|
||||||
}, function() {
|
}, function() {
|
||||||
$('#couldnotbuildModal').modal();
|
$('#couldnotbuildModal').modal();
|
||||||
});
|
});
|
||||||
|
@ -963,8 +1010,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangula
|
||||||
'mimeType': mimeType
|
'mimeType': mimeType
|
||||||
};
|
};
|
||||||
|
|
||||||
var getUploadUrl = Restangular.one('filedrop/');
|
var getUploadUrl = ApiService.getFiledropUrl(data).then(function(resp) {
|
||||||
getUploadUrl.customPOST(data).then(function(resp) {
|
|
||||||
conductUpload(repo, file, resp.url, resp.file_id, mimeType);
|
conductUpload(repo, file, resp.url, resp.file_id, mimeType);
|
||||||
}, function() {
|
}, function() {
|
||||||
$('#couldnotbuildModal').modal();
|
$('#couldnotbuildModal').modal();
|
||||||
|
@ -992,7 +1038,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangula
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function OrgViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams) {
|
function OrgViewCtrl($rootScope, $scope, ApiService, $routeParams) {
|
||||||
var orgname = $routeParams.orgname;
|
var orgname = $routeParams.orgname;
|
||||||
|
|
||||||
$scope.TEAM_PATTERN = TEAM_PATTERN;
|
$scope.TEAM_PATTERN = TEAM_PATTERN;
|
||||||
|
@ -1008,10 +1054,14 @@ function OrgViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
var previousRole = $scope.organization.teams[teamname].role;
|
var previousRole = $scope.organization.teams[teamname].role;
|
||||||
$scope.organization.teams[teamname].role = role;
|
$scope.organization.teams[teamname].role = role;
|
||||||
|
|
||||||
var updateTeam = Restangular.one(getRestUrl('organization', orgname, 'team', teamname));
|
var params = {
|
||||||
|
'orgname': orgname,
|
||||||
|
'teamname': teamname
|
||||||
|
};
|
||||||
|
|
||||||
var data = $scope.organization.teams[teamname];
|
var data = $scope.organization.teams[teamname];
|
||||||
|
|
||||||
updateTeam.customPUT(data).then(function(resp) {
|
ApiService.updateOrganizationTeam(data, params).then(function(resp) {
|
||||||
}, function(resp) {
|
}, function(resp) {
|
||||||
$scope.organization.teams[teamname].role = previousRole;
|
$scope.organization.teams[teamname].role = previousRole;
|
||||||
$scope.roleError = resp.data || '';
|
$scope.roleError = resp.data || '';
|
||||||
|
@ -1032,7 +1082,7 @@ function OrgViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
createOrganizationTeam(Restangular, orgname, teamname, function(created) {
|
createOrganizationTeam(ApiService, orgname, teamname, function(created) {
|
||||||
$scope.organization.teams[teamname] = created;
|
$scope.organization.teams[teamname] = created;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1047,8 +1097,12 @@ function OrgViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
if (!$scope.currentDeleteTeam) { return; }
|
if (!$scope.currentDeleteTeam) { return; }
|
||||||
|
|
||||||
var teamname = $scope.currentDeleteTeam;
|
var teamname = $scope.currentDeleteTeam;
|
||||||
var deleteAction = Restangular.one(getRestUrl('organization', orgname, 'team', teamname));
|
var params = {
|
||||||
deleteAction.customDELETE().then(function() {
|
'orgname': orgname,
|
||||||
|
'teamname': teamname
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.deleteOrganizationTeam(null, params).then(function() {
|
||||||
delete $scope.organization.teams[teamname];
|
delete $scope.organization.teams[teamname];
|
||||||
$scope.currentDeleteTeam = null;
|
$scope.currentDeleteTeam = null;
|
||||||
}, function() {
|
}, function() {
|
||||||
|
@ -1058,7 +1112,7 @@ function OrgViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadOrganization = function() {
|
var loadOrganization = function() {
|
||||||
$scope.orgResource = ApiService.at('organization', orgname).get(function(org) {
|
$scope.orgResource = ApiService.getOrganizationAsResource({'orgname': orgname}).get(function(org) {
|
||||||
$scope.organization = org;
|
$scope.organization = org;
|
||||||
$rootScope.title = orgname;
|
$rootScope.title = orgname;
|
||||||
$rootScope.description = 'Viewing organization ' + orgname;
|
$rootScope.description = 'Viewing organization ' + orgname;
|
||||||
|
@ -1109,9 +1163,12 @@ function OrgAdminCtrl($rootScope, $scope, Restangular, $routeParams, UserService
|
||||||
$scope.loadMembers = function() {
|
$scope.loadMembers = function() {
|
||||||
if ($scope.membersFound) { return; }
|
if ($scope.membersFound) { return; }
|
||||||
$scope.membersLoading = true;
|
$scope.membersLoading = true;
|
||||||
|
|
||||||
var getMembers = Restangular.one(getRestUrl('organization', orgname, 'members'));
|
var params = {
|
||||||
getMembers.get().then(function(resp) {
|
'orgname': orgname
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.getOrganizationMembers(null, params).then(function(resp) {
|
||||||
var membersArray = [];
|
var membersArray = [];
|
||||||
for (var key in resp.members) {
|
for (var key in resp.members) {
|
||||||
if (resp.members.hasOwnProperty(key)) {
|
if (resp.members.hasOwnProperty(key)) {
|
||||||
|
@ -1125,7 +1182,7 @@ function OrgAdminCtrl($rootScope, $scope, Restangular, $routeParams, UserService
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadOrganization = function() {
|
var loadOrganization = function() {
|
||||||
$scope.orgResource = ApiService.at('organization', orgname).get(function(org) {
|
$scope.orgResource = ApiService.getOrganizationAsResource({'orgname': orgname}).get(function(org) {
|
||||||
if (org && org.is_admin) {
|
if (org && org.is_admin) {
|
||||||
$scope.organization = org;
|
$scope.organization = org;
|
||||||
$rootScope.title = orgname + ' (Admin)';
|
$rootScope.title = orgname + ' (Admin)';
|
||||||
|
@ -1139,11 +1196,6 @@ function OrgAdminCtrl($rootScope, $scope, Restangular, $routeParams, UserService
|
||||||
}
|
}
|
||||||
|
|
||||||
function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams) {
|
function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams) {
|
||||||
$('.info-icon').popover({
|
|
||||||
'trigger': 'hover',
|
|
||||||
'html': true
|
|
||||||
});
|
|
||||||
|
|
||||||
var teamname = $routeParams.teamname;
|
var teamname = $routeParams.teamname;
|
||||||
var orgname = $routeParams.orgname;
|
var orgname = $routeParams.orgname;
|
||||||
|
|
||||||
|
@ -1155,8 +1207,13 @@ function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
$scope.addNewMember = function(member) {
|
$scope.addNewMember = function(member) {
|
||||||
if ($scope.members[member.name]) { return; }
|
if ($scope.members[member.name]) { return; }
|
||||||
|
|
||||||
var addMember = Restangular.one(getRestUrl('organization', $scope.orgname, 'team', teamname, 'members', member.name));
|
var params = {
|
||||||
addMember.customPOST().then(function(resp) {
|
'orgname': orgname,
|
||||||
|
'teamname': teamname,
|
||||||
|
'membername': member.name
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.updateOrganizationTeamMember(null, params).then(function(resp) {
|
||||||
$scope.members[member.name] = resp;
|
$scope.members[member.name] = resp;
|
||||||
}, function() {
|
}, function() {
|
||||||
$('#cannotChangeMembersModal').modal({});
|
$('#cannotChangeMembersModal').modal({});
|
||||||
|
@ -1164,8 +1221,13 @@ function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.removeMember = function(username) {
|
$scope.removeMember = function(username) {
|
||||||
var removeMember = Restangular.one(getRestUrl('organization', $scope.orgname, 'team', teamname, 'members', username));
|
var params = {
|
||||||
removeMember.customDELETE().then(function(resp) {
|
'orgname': orgname,
|
||||||
|
'teamname': teamname,
|
||||||
|
'membername': username
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.deleteOrganizationTeamMember(null, params).then(function(resp) {
|
||||||
delete $scope.members[username];
|
delete $scope.members[username];
|
||||||
}, function() {
|
}, function() {
|
||||||
$('#cannotChangeMembersModal').modal({});
|
$('#cannotChangeMembersModal').modal({});
|
||||||
|
@ -1175,16 +1237,20 @@ function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
$scope.updateForDescription = function(content) {
|
$scope.updateForDescription = function(content) {
|
||||||
$scope.organization.teams[teamname].description = content;
|
$scope.organization.teams[teamname].description = content;
|
||||||
|
|
||||||
var updateTeam = Restangular.one(getRestUrl('organization', $scope.orgname, 'team', teamname));
|
var params = {
|
||||||
var data = $scope.organization.teams[teamname];
|
'orgname': orgname,
|
||||||
updateTeam.customPUT(data).then(function(resp) {
|
'teamname': teamname
|
||||||
|
};
|
||||||
|
|
||||||
|
var teaminfo = $scope.organization.teams[teamname];
|
||||||
|
ApiService.updateOrganizationTeam(teaminfo, params).then(function(resp) {
|
||||||
}, function() {
|
}, function() {
|
||||||
$('#cannotChangeTeamModal').modal({});
|
$('#cannotChangeTeamModal').modal({});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadOrganization = function() {
|
var loadOrganization = function() {
|
||||||
$scope.orgResource = ApiService.at('organization', orgname).get(function(org) {
|
$scope.orgResource = ApiService.getOrganizationAsResource({'orgname': orgname}).get(function(org) {
|
||||||
$scope.organization = org;
|
$scope.organization = org;
|
||||||
$scope.team = $scope.organization.teams[teamname];
|
$scope.team = $scope.organization.teams[teamname];
|
||||||
$rootScope.title = teamname + ' (' + $scope.orgname + ')';
|
$rootScope.title = teamname + ' (' + $scope.orgname + ')';
|
||||||
|
@ -1195,11 +1261,22 @@ function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadMembers = function() {
|
var loadMembers = function() {
|
||||||
$scope.membersResource = ApiService.at('organization', $scope.orgname, 'team', teamname, 'members').get(function(resp) {
|
var params = {
|
||||||
|
'orgname': orgname,
|
||||||
|
'teamname': teamname
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.membersResource = ApiService.getOrganizationTeamMembersAsResource(params).get(function(resp) {
|
||||||
$scope.members = resp.members;
|
$scope.members = resp.members;
|
||||||
$scope.canEditMembers = resp.can_edit;
|
$scope.canEditMembers = resp.can_edit;
|
||||||
|
|
||||||
|
$('.info-icon').popover({
|
||||||
|
'trigger': 'hover',
|
||||||
|
'html': true
|
||||||
|
});
|
||||||
|
|
||||||
return resp.members;
|
return resp.members;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load the organization.
|
// Load the organization.
|
||||||
|
@ -1208,11 +1285,10 @@ function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
|
||||||
|
|
||||||
function OrgsCtrl($scope, UserService) {
|
function OrgsCtrl($scope, UserService) {
|
||||||
UserService.updateUserIn($scope);
|
UserService.updateUserIn($scope);
|
||||||
|
|
||||||
browserchrome.update();
|
browserchrome.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
function NewOrgCtrl($scope, $routeParams, $timeout, $location, UserService, PlanService, Restangular) {
|
function NewOrgCtrl($scope, $routeParams, $timeout, $location, UserService, PlanService, ApiService) {
|
||||||
UserService.updateUserIn($scope);
|
UserService.updateUserIn($scope);
|
||||||
|
|
||||||
var requested = $routeParams['plan'];
|
var requested = $routeParams['plan'];
|
||||||
|
@ -1252,8 +1328,7 @@ function NewOrgCtrl($scope, $routeParams, $timeout, $location, UserService, Plan
|
||||||
'email': org.email
|
'email': org.email
|
||||||
};
|
};
|
||||||
|
|
||||||
var createPost = Restangular.one('organization/');
|
ApiService.createOrganization(data).then(function(created) {
|
||||||
createPost.customPOST(data).then(function(created) {
|
|
||||||
$scope.created = created;
|
$scope.created = created;
|
||||||
|
|
||||||
// Reset the organizations list.
|
// Reset the organizations list.
|
||||||
|
@ -1300,14 +1375,19 @@ function OrgMemberLogsCtrl($scope, $routeParams, $rootScope, $timeout, Restangul
|
||||||
$scope.ready = false;
|
$scope.ready = false;
|
||||||
|
|
||||||
var loadOrganization = function() {
|
var loadOrganization = function() {
|
||||||
$scope.orgResource = ApiService.at('organization', orgname).get(function(org) {
|
$scope.orgResource = ApiService.getOrganizationAsResource({'orgname': orgname}).get(function(org) {
|
||||||
$scope.organization = org;
|
$scope.organization = org;
|
||||||
return org;
|
return org;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadMemberInfo = function() {
|
var loadMemberInfo = function() {
|
||||||
$scope.memberResource = ApiService.at('organization', $scope.orgname, 'members', membername).get(function(resp) {
|
var params = {
|
||||||
|
'orgname': orgname,
|
||||||
|
'membername': membername
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.memberResource = ApiService.getOrganizationMemberAsResource(params).get(function(resp) {
|
||||||
$scope.memberInfo = resp.member;
|
$scope.memberInfo = resp.member;
|
||||||
|
|
||||||
$rootScope.title = 'Logs for ' + $scope.memberInfo.username + ' (' + $scope.orgname + ')';
|
$rootScope.title = 'Logs for ' + $scope.memberInfo.username + ' (' + $scope.orgname + ')';
|
||||||
|
|
|
@ -60,9 +60,9 @@
|
||||||
<div ng-show="!updatingUser">
|
<div ng-show="!updatingUser">
|
||||||
<form class="form-change-pw col-md-6" name="changePasswordForm" ng-submit="changePassword()" data-trigger="manual"
|
<form class="form-change-pw col-md-6" name="changePasswordForm" ng-submit="changePassword()" data-trigger="manual"
|
||||||
data-content="{{ changePasswordError }}" data-placement="right" ng-show="!awaitingConfirmation && !registering">
|
data-content="{{ changePasswordError }}" data-placement="right" ng-show="!awaitingConfirmation && !registering">
|
||||||
<input type="password" class="form-control" placeholder="Your new password" ng-model="user.password" required>
|
<input type="password" class="form-control" placeholder="Your new password" ng-model="cuser.password" required>
|
||||||
<input type="password" class="form-control" placeholder="Verify your new password" ng-model="user.repeatPassword"
|
<input type="password" class="form-control" placeholder="Verify your new password" ng-model="cuser.repeatPassword"
|
||||||
match="user.password" required>
|
match="cuser.password" required>
|
||||||
<button class="btn btn-danger" ng-disabled="changePasswordForm.$invalid" type="submit"
|
<button class="btn btn-danger" ng-disabled="changePasswordForm.$invalid" type="submit"
|
||||||
analytics-on analytics-event="change_pass">Change Password</button>
|
analytics-on analytics-event="change_pass">Change Password</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -65,6 +65,10 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.__endpoints = {{ route_data|safe }}.endpoints;
|
||||||
|
</script>
|
||||||
|
|
||||||
<script src="static/js/app.js"></script>
|
<script src="static/js/app.js"></script>
|
||||||
<script src="static/js/controllers.js"></script>
|
<script src="static/js/controllers.js"></script>
|
||||||
<script src="static/js/graphing.js"></script>
|
<script src="static/js/graphing.js"></script>
|
||||||
|
@ -122,6 +126,22 @@ var isProd = document.location.hostname === 'quay.io';
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal message dialog -->
|
||||||
|
<div class="modal fade" id="couldnotloadModal" data-backdrop="static">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Uh Oh...</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Something went wrong when trying to load Quay.io! Please report this to <a href="mailto:support@quay.io">support@quay.io</a>.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
</div>
|
||||||
|
</div><!-- /.modal-content -->
|
||||||
|
</div><!-- /.modal-dialog -->
|
||||||
|
</div><!-- /.modal -->
|
||||||
|
|
||||||
<!-- begin olark code -->
|
<!-- begin olark code -->
|
||||||
{% if request.host == 'quay.io' %}
|
{% if request.host == 'quay.io' %}
|
||||||
<script data-cfasync="false" type='text/javascript'>/*<![CDATA[*/window.olark||(function(c){var f=window,d=document,l=f.location.protocol=="https:"?"https:":"http:",z=c.name,r="load";var nt=function(){
|
<script data-cfasync="false" type='text/javascript'>/*<![CDATA[*/window.olark||(function(c){var f=window,d=document,l=f.location.protocol=="https:"?"https:":"http:",z=c.name,r="load";var nt=function(){
|
||||||
|
|
|
@ -105,20 +105,20 @@ def build_specs():
|
||||||
return [
|
return [
|
||||||
TestSpec(url_for('welcome'), 200, 200, 200, 200),
|
TestSpec(url_for('welcome'), 200, 200, 200, 200),
|
||||||
|
|
||||||
TestSpec(url_for('plans_list'), 200, 200, 200, 200),
|
TestSpec(url_for('list_plans'), 200, 200, 200, 200),
|
||||||
|
|
||||||
TestSpec(url_for('get_logged_in_user'), 200, 200, 200, 200),
|
TestSpec(url_for('get_logged_in_user'), 200, 200, 200, 200),
|
||||||
|
|
||||||
TestSpec(url_for('change_user_details'),
|
TestSpec(url_for('change_user_details'),
|
||||||
401, 200, 200, 200).set_method('PUT'),
|
401, 200, 200, 200).set_method('PUT'),
|
||||||
|
|
||||||
TestSpec(url_for('create_user_api'), 201, 201, 201,
|
TestSpec(url_for('create_new_user'), 201, 201, 201,
|
||||||
201).set_method('POST').set_data_from_obj(NEW_USER_DETAILS),
|
201).set_method('POST').set_data_from_obj(NEW_USER_DETAILS),
|
||||||
|
|
||||||
TestSpec(url_for('signin_api'), 200, 200, 200,
|
TestSpec(url_for('signin_user'), 200, 200, 200,
|
||||||
200).set_method('POST').set_data_from_obj(SIGNIN_DETAILS),
|
200).set_method('POST').set_data_from_obj(SIGNIN_DETAILS),
|
||||||
|
|
||||||
TestSpec(url_for('send_recovery'), 201, 201, 201,
|
TestSpec(url_for('request_recovery_email'), 201, 201, 201,
|
||||||
201).set_method('POST').set_data_from_obj(SEND_RECOVERY_DETAILS),
|
201).set_method('POST').set_data_from_obj(SEND_RECOVERY_DETAILS),
|
||||||
|
|
||||||
TestSpec(url_for('get_matching_users', prefix='dev'), 401, 200, 200, 200),
|
TestSpec(url_for('get_matching_users', prefix='dev'), 401, 200, 200, 200),
|
||||||
|
@ -161,29 +161,29 @@ def build_specs():
|
||||||
teamname=ORG_READERS, membername=ORG_OWNER),
|
teamname=ORG_READERS, membername=ORG_OWNER),
|
||||||
admin_code=400).set_method('DELETE'),
|
admin_code=400).set_method('DELETE'),
|
||||||
|
|
||||||
(TestSpec(url_for('create_repo_api'))
|
(TestSpec(url_for('create_repo'))
|
||||||
.set_method('POST')
|
.set_method('POST')
|
||||||
.set_data_from_obj(NEW_ORG_REPO_DETAILS)),
|
.set_data_from_obj(NEW_ORG_REPO_DETAILS)),
|
||||||
|
|
||||||
TestSpec(url_for('match_repos_api'), 200, 200, 200, 200),
|
TestSpec(url_for('find_repos'), 200, 200, 200, 200),
|
||||||
|
|
||||||
TestSpec(url_for('list_repos_api'), 200, 200, 200, 200),
|
TestSpec(url_for('list_repos'), 200, 200, 200, 200),
|
||||||
|
|
||||||
TestSpec(url_for('update_repo_api', repository=PUBLIC_REPO),
|
TestSpec(url_for('update_repo', repository=PUBLIC_REPO),
|
||||||
admin_code=403).set_method('PUT'),
|
admin_code=403).set_method('PUT'),
|
||||||
(TestSpec(url_for('update_repo_api', repository=ORG_REPO))
|
(TestSpec(url_for('update_repo', repository=ORG_REPO))
|
||||||
.set_method('PUT')
|
.set_method('PUT')
|
||||||
.set_data_from_obj(UPDATE_REPO_DETAILS)),
|
.set_data_from_obj(UPDATE_REPO_DETAILS)),
|
||||||
(TestSpec(url_for('update_repo_api', repository=PRIVATE_REPO))
|
(TestSpec(url_for('update_repo', repository=PRIVATE_REPO))
|
||||||
.set_method('PUT')
|
.set_method('PUT')
|
||||||
.set_data_from_obj(UPDATE_REPO_DETAILS)),
|
.set_data_from_obj(UPDATE_REPO_DETAILS)),
|
||||||
|
|
||||||
(TestSpec(url_for('change_repo_visibility_api', repository=PUBLIC_REPO),
|
(TestSpec(url_for('change_repo_visibility', repository=PUBLIC_REPO),
|
||||||
admin_code=403).set_method('POST')
|
admin_code=403).set_method('POST')
|
||||||
.set_data_from_obj(CHANGE_VISIBILITY_DETAILS)),
|
.set_data_from_obj(CHANGE_VISIBILITY_DETAILS)),
|
||||||
(TestSpec(url_for('change_repo_visibility_api', repository=ORG_REPO))
|
(TestSpec(url_for('change_repo_visibility', repository=ORG_REPO))
|
||||||
.set_method('POST').set_data_from_obj(CHANGE_VISIBILITY_DETAILS)),
|
.set_method('POST').set_data_from_obj(CHANGE_VISIBILITY_DETAILS)),
|
||||||
(TestSpec(url_for('change_repo_visibility_api', repository=PRIVATE_REPO))
|
(TestSpec(url_for('change_repo_visibility', repository=PRIVATE_REPO))
|
||||||
.set_method('POST').set_data_from_obj(CHANGE_VISIBILITY_DETAILS)),
|
.set_method('POST').set_data_from_obj(CHANGE_VISIBILITY_DETAILS)),
|
||||||
|
|
||||||
TestSpec(url_for('delete_repository', repository=PUBLIC_REPO),
|
TestSpec(url_for('delete_repository', repository=PUBLIC_REPO),
|
||||||
|
@ -193,11 +193,11 @@ def build_specs():
|
||||||
TestSpec(url_for('delete_repository', repository=PRIVATE_REPO),
|
TestSpec(url_for('delete_repository', repository=PRIVATE_REPO),
|
||||||
admin_code=204).set_method('DELETE'),
|
admin_code=204).set_method('DELETE'),
|
||||||
|
|
||||||
TestSpec(url_for('get_repo_api', repository=PUBLIC_REPO),
|
TestSpec(url_for('get_repo', repository=PUBLIC_REPO),
|
||||||
200, 200, 200,200),
|
200, 200, 200,200),
|
||||||
TestSpec(url_for('get_repo_api', repository=ORG_REPO),
|
TestSpec(url_for('get_repo', repository=ORG_REPO),
|
||||||
403, 403, 200, 200),
|
403, 403, 200, 200),
|
||||||
TestSpec(url_for('get_repo_api', repository=PRIVATE_REPO),
|
TestSpec(url_for('get_repo', repository=PRIVATE_REPO),
|
||||||
403, 403, 200, 200),
|
403, 403, 200, 200),
|
||||||
|
|
||||||
TestSpec(url_for('get_repo_builds', repository=PUBLIC_REPO),
|
TestSpec(url_for('get_repo_builds', repository=PUBLIC_REPO),
|
||||||
|
@ -403,20 +403,20 @@ def build_specs():
|
||||||
TestSpec(url_for('delete_token', repository=PRIVATE_REPO,
|
TestSpec(url_for('delete_token', repository=PRIVATE_REPO,
|
||||||
code=FAKE_TOKEN), admin_code=400).set_method('DELETE'),
|
code=FAKE_TOKEN), admin_code=400).set_method('DELETE'),
|
||||||
|
|
||||||
TestSpec(url_for('subscribe_api'), 401, 400, 400, 400).set_method('PUT'),
|
TestSpec(url_for('update_user_subscription'), 401, 400, 400, 400).set_method('PUT'),
|
||||||
|
|
||||||
TestSpec(url_for('subscribe_org_api', orgname=ORG),
|
TestSpec(url_for('update_org_subscription', orgname=ORG),
|
||||||
401, 403, 403, 400).set_method('PUT'),
|
401, 403, 403, 400).set_method('PUT'),
|
||||||
|
|
||||||
TestSpec(url_for('get_subscription'), 401, 200, 200, 200),
|
TestSpec(url_for('get_user_subscription'), 401, 200, 200, 200),
|
||||||
|
|
||||||
TestSpec(url_for('get_org_subscription', orgname=ORG)),
|
TestSpec(url_for('get_org_subscription', orgname=ORG)),
|
||||||
|
|
||||||
TestSpec(url_for('repo_logs_api', repository=PUBLIC_REPO), admin_code=403),
|
TestSpec(url_for('list_repo_logs', repository=PUBLIC_REPO), admin_code=403),
|
||||||
TestSpec(url_for('repo_logs_api', repository=ORG_REPO)),
|
TestSpec(url_for('list_repo_logs', repository=ORG_REPO)),
|
||||||
TestSpec(url_for('repo_logs_api', repository=PRIVATE_REPO)),
|
TestSpec(url_for('list_repo_logs', repository=PRIVATE_REPO)),
|
||||||
|
|
||||||
TestSpec(url_for('org_logs_api', orgname=ORG)),
|
TestSpec(url_for('list_org_logs', orgname=ORG)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue