[copr] master: Add alembic revision to update the database scheme (e6d24e5)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit e6d24e582bea3d0e12d70500742a9772c99b6894
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Jan 8 11:41:31 2013 +0100
Add alembic revision to update the database scheme
>---------------------------------------------------------------
.../versions/32ba137a3d56_add_token_informatio.py | 33 ++++++++++++++++++++
1 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/coprs_frontend/alembic/versions/32ba137a3d56_add_token_informatio.py b/coprs_frontend/alembic/versions/32ba137a3d56_add_token_informatio.py
new file mode 100644
index 0000000..64c7515
--- /dev/null
+++ b/coprs_frontend/alembic/versions/32ba137a3d56_add_token_informatio.py
@@ -0,0 +1,33 @@
+"""Add token information to the user table
+
+Revision ID: 32ba137a3d56
+Revises: 595a31c145fb
+Create Date: 2013-01-07 20:56:14.698735
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '32ba137a3d56'
+down_revision = '595a31c145fb'
+
+from alembic import op
+import sqlalchemy as sa
+
+import datetime
+
+
+def upgrade():
+ """ Add the coluns api_token and api_token_expiration to the user table.
+ """
+ op.add_column('user', sa.Column('api_token', sa.String(40),
+ nullable=False), default='default_token')
+ op.add_column('user', sa.Column('api_token_expiration', sa.Date,
+ nullable=False, default=datetime.date(2000, 1, 1)))
+
+
+def downgrade():
+ """ Drop the coluns api_token and api_token_expiration to the user table.
+ """
+ op.drop_column('user', 'api_token')
+ op.drop_column('user', 'api_token_expiration')
+
11 years, 3 months
[copr] master: Create the /api/ page providing the API token and information The API page aims at providing information about the API itself and how to use it. Additionally, if you are logged-in, this page gives you your own API token (needed to call the API), its expiration date (as each token is valid only 30 days) and a way to generate a new token. (99528ea)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 99528ea80089f17ef9dacd72df4ab9c42fbd1f0f
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Jan 8 11:40:51 2013 +0100
Create the /api/ page providing the API token and information
The API page aims at providing information about the API itself and
how to use it.
Additionally, if you are logged-in, this page gives you your own
API token (needed to call the API), its expiration date (as each
token is valid only 30 days) and a way to generate a new token.
>---------------------------------------------------------------
coprs_frontend/coprs/models.py | 3 ++
coprs_frontend/coprs/templates/api.html | 39 +++++++++++++++++++++++++++
coprs_frontend/coprs/views/misc.py | 44 ++++++++++++++++++++++++++++--
3 files changed, 83 insertions(+), 3 deletions(-)
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index 69f446e..4429554 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -54,6 +54,8 @@ class User(db.Model, Serializer):
mail = db.Column(db.String(150), nullable = False)
proven = db.Column(db.Boolean, default = False)
admin = db.Column(db.Boolean, default = False)
+ api_token = db.Column(db.String(40), nullable = False)
+ api_token_expiration = db.Column(db.Date, nullable = False)
@property
def name(self):
@@ -93,6 +95,7 @@ class User(db.Model, Serializer):
def serializable_attributes(self):
return super(User, self).serializable_attributes + ['name']
+
class Copr(db.Model, Serializer):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(100), nullable = False)
diff --git a/coprs_frontend/coprs/templates/api.html b/coprs_frontend/coprs/templates/api.html
new file mode 100644
index 0000000..fb20f0d
--- /dev/null
+++ b/coprs_frontend/coprs/templates/api.html
@@ -0,0 +1,39 @@
+{% extends "layout.html" %}
+{% block title %}API for Coprs{% endblock %}
+{% block header %}API for the Coprs Build System{% endblock %}
+{% block body %}
+ {% if error %}<p class="error"><strong>Error:</strong> {{ error }}</p>{% endif %}
+
+ <div>
+ <h2>Coprs API</h2>
+
+ <h3> API Token </h3>
+ <p>In order to access the API, you will need to provide an API token.
+ This token is unique, specific to you and <span style="font-weight:bold;">
+ should not be shared!</span>.
+ </p>
+
+ <p>The API token is valid for 30 days after you generated it, this
+ in order to ensure you are you every 30 days.
+ </p>
+
+ {% if user %}
+ <p>Your information:</p>
+ <pre style="font-size:120%">
+ API token : {{ user.api_token }}
+ Expiration date : {{ user.api_token_expiration }}
+ </pre>
+
+ <a href="{{ url_for('misc.api_new_token') }}">
+ <input type="button" value="Generate a new token" />
+ </a>
+ {% else %}
+ <p style="font-style:italic">You need to be logged in to see you API token.</p>
+ {% endif %}
+
+ <h3>The API</h3>
+
+ <p>To come here, more information about the API itself.</p>
+
+ </div>
+{% endblock %}
diff --git a/coprs_frontend/coprs/views/misc.py b/coprs_frontend/coprs/views/misc.py
index be4be05..430604d 100644
--- a/coprs_frontend/coprs/views/misc.py
+++ b/coprs_frontend/coprs/views/misc.py
@@ -1,4 +1,7 @@
+import datetime
import functools
+import random
+import string
import flask
@@ -12,6 +15,18 @@ from coprs import oid
misc = flask.Blueprint('misc', __name__)
+def generate_api_token(size=30):
+ """ Generate a random string used as token to access the API
+ remotely.
+
+ :kwarg: size, the size of the token to generate, defaults to 30
+ chars.
+ :return: a string, the API token for the user.
+
+ """
+ return ''.join(random.choice(string.ascii_lowercase) for x in range(size))
+
+
@misc.route('/login/', methods=['GET', 'POST'])
@oid.loginhandler
def login():
@@ -31,13 +46,17 @@ def login():
next=oid.get_next_url(),
error=oid.fetch_error())
-
@oid.after_login
def create_or_login(resp):
flask.session['openid'] = resp.identity_url
- user = models.User.query.filter(models.User.openid_name == resp.identity_url).first()
+ user = models.User.query.filter(
+ models.User.openid_name == resp.identity_url).first()
if not user: # create if not created already
- user = models.User(openid_name = resp.identity_url, mail = resp.email)
+ expiration_date_token = datetime.date.today() \
+ + datetime.timedelta(days=30)
+ user = models.User(openid_name = resp.identity_url, mail = resp.email,
+ api_token = generate_api_token(),
+ api_token_expiration = expiration_date_token)
db.session.add(user)
db.session.commit()
flask.flash(u'Welcome, {0}'.format(user.name))
@@ -70,3 +89,22 @@ def backend_authenticated(f):
return 'You have to provide the correct password', 401
return f(*args, **kwargs)
return decorated_function
+
+
+(a)misc.route('/api/')
+def api():
+ return flask.render_template('api.html',
+ user=flask.g.user)
+
+
+(a)misc.route('/api/new')
+@login_required
+def api_new_token():
+ user = flask.g.user
+ user.api_token = generate_api_token()
+ user.api_token_expiration = datetime.date.today() \
+ + datetime.timedelta(days=30)
+ db.session.add(user)
+ db.session.commit()
+ flask.g.user = user
+ return flask.redirect(flask.url_for('misc.api'))
11 years, 3 months
[copr] master: Insert the alembic revision at the DB creation (prevent future crash) (f1bb3e5)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit f1bb3e5a8d6f563c235055b297e30d9558d63741
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Jan 8 08:17:32 2013 +0100
Insert the alembic revision at the DB creation (prevent future crash)
>---------------------------------------------------------------
coprs_frontend/manage.py | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/coprs_frontend/manage.py b/coprs_frontend/manage.py
index d032f26..7716e86 100755
--- a/coprs_frontend/manage.py
+++ b/coprs_frontend/manage.py
@@ -16,9 +16,16 @@ class DBManager(object):
if not os.path.exists(datadir_name):
os.makedirs(datadir_name)
- def create_db(self):
+ def create_db(self, alembic_ini=None):
self.create_sqlite_file()
self.db.create_all()
+ if alembic_ini is not None:
+ # then, load the Alembic configuration and generate the
+ # version table, "stamping" it with the most recent rev:
+ from alembic.config import Config
+ from alembic import command
+ alembic_cfg = Config(alembic_ini)
+ command.stamp(alembic_cfg, "head")
def delete_db(self):
self.db.drop_all()
@@ -39,12 +46,19 @@ parser.add_argument('-d', '--delete-db',
help = 'Delete DB',
action = 'store_true')
+parser.add_argument('-f', '--alembic',
+ required = False,
+ help = 'Path to the alembic configuration file (alembic.ini)')
+
args = parser.parse_args()
manager = DBManager(db)
if args.create_sqlite_file:
manager.create_sqlite_file()
elif args.create_db:
- manager.create_db()
+ if not args.alembic:
+ print "Please provide the path to the alembic configuration file."
+ else:
+ manager.create_db(args.alembic)
elif args.delete_db:
manager.delete_db()
11 years, 3 months
[copr] master: Warn when user not in the allowed list. At the moment when a user is not in the list of allowed user, the application fails silently. This commit adds an information message to the user explaining that something happens but that he cannot log in as he is just not allowed. (e8d9af5)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit e8d9af5e57e32d86d347afa3b58d03bdbe593622
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Jan 8 08:11:25 2013 +0100
Warn when user not in the allowed list.
At the moment when a user is not in the list of allowed user, the
application fails silently.
This commit adds an information message to the user explaining that
something happens but that he cannot log in as he is just not
allowed.
>---------------------------------------------------------------
coprs_frontend/coprs/views/misc.py | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/coprs_frontend/coprs/views/misc.py b/coprs_frontend/coprs/views/misc.py
index ca67c75..be4be05 100644
--- a/coprs_frontend/coprs/views/misc.py
+++ b/coprs_frontend/coprs/views/misc.py
@@ -19,8 +19,14 @@ def login():
return flask.redirect(oid.get_next_url())
if flask.request.method == 'POST':
fasusername = flask.request.form.get('fasuname')
- if fasusername and ((app.config['USE_ALLOWED_USERS'] and fasusername in app.config['ALLOWED_USERS']) or not app.config['USE_ALLOWED_USERS']):
+ if fasusername and ((app.config['USE_ALLOWED_USERS'] \
+ and fasusername in app.config['ALLOWED_USERS']) \
+ or not app.config['USE_ALLOWED_USERS']):
return oid.try_login('http://{0}.id.fedoraproject.org/'.format(fasusername), ask_for = ["email"])
+ else:
+ return flask.render_template('login.html',
+ error='User "{0}" is not allowed'.format(
+ fasusername))
return flask.render_template('login.html',
next=oid.get_next_url(),
error=oid.fetch_error())
11 years, 3 months
[copr] master: Small layout change and add .gitignore and requirements.txt files - Small layout change (more pep8 style) on forms.py - Add a first (small) .gitignore file - Add a requirements.txt file, handy to keep track of the dependencies of the project and while working in virtualenv (d914b0c)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit d914b0cde2dbe94d91ab930a54d2118179cefc4a
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Jan 8 08:00:39 2013 +0100
Small layout change and add .gitignore and requirements.txt files
- Small layout change (more pep8 style) on forms.py
- Add a first (small) .gitignore file
- Add a requirements.txt file, handy to keep track of the dependencies
of the project and while working in virtualenv
>---------------------------------------------------------------
.gitignore | 1 +
coprs_frontend/coprs/forms.py | 6 ++++++
requirements.txt | 7 +++++++
3 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/coprs_frontend/coprs/forms.py b/coprs_frontend/coprs/forms.py
index 69e6f69..0010d72 100644
--- a/coprs_frontend/coprs/forms.py
+++ b/coprs_frontend/coprs/forms.py
@@ -33,6 +33,7 @@ class UrlListValidator(object):
return is_url
+
class AllowedArchesValidator(object):
def __init__(self, message = None):
if not message:
@@ -45,6 +46,7 @@ class AllowedArchesValidator(object):
if a not in constants.CHROOTS[form.release.data]:
raise wtf.ValidationError(self.message.format(a))
+
class CoprUniqueNameValidator(object):
def __init__(self, message = None):
if not message:
@@ -69,6 +71,7 @@ class StringListFilter(object):
regex = re.compile(r'\s+')
return regex.sub(lambda x: '\n', result)
+
class CoprForm(wtf.Form):
# also use id here, to be able to find out whether user is updating a copr
# if so, we don't want to shout that name already exists
@@ -94,6 +97,7 @@ class CoprForm(wtf.Form):
def chroots(self):
return ['{0}-{1}'.format(self.release.data, arch) for arch in self.arches.data ]
+
class BuildForm(wtf.Form):
pkgs = wtf.TextAreaField('Pkgs',
validators = [wtf.Required(), UrlListValidator()],
@@ -105,6 +109,7 @@ class BuildForm(wtf.Form):
validators = [wtf.NumberRange(min = constants.MIN_BUILD_TIMEOUT, max = constants.MAX_BUILD_TIMEOUT)],
default = constants.DEFAULT_BUILD_TIMEOUT)
+
class PermissionsApplierFormFactory(object):
@staticmethod
def create_form_cls(permission = None):
@@ -133,6 +138,7 @@ class PermissionsApplierFormFactory(object):
return F
+
class DynamicPermissionsFormFactory(object):
"""Creates a dynamic form for given set of copr permissions"""
@staticmethod
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..3b7b12b
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,7 @@
+# Used for when working from a virtualenv.
+# Use this file by running "$ pip install -r requirements.txt"
+argparse
+flask-sqlalchemy
+flask-openid
+flask-wtf
+alembic
11 years, 3 months
access from cron jobs?
by Troy Dawson
Hi,
Is there any way I can submit new pkgs to a copr by hand, instead of
through the web interface?
Here's my scenario I'm shooting for.
We would have a copr called "openshift-nightly". We already have a cron
job that builds tar balls of any new point release of our code. That
same cron job would then create a src.rpm from the tarball (we have the
spec inside), put it in it's public url area. Then submit the new
package to copr, pointing to the URL.
Even something like "wget
http://copr-fe.cloud.fedoraproject.org/coprs/detail/tdawson/OpenShift_Tes..."
would be fine.
If there isn't any way to submit via the command line, that's fine, as
long as you put it down for a feature request. :)
Another feature request, though a lower priority, would be to accept tar
balls as submissions. This isn't as high a priority, because I am able
to create the src.rpm myself. Just would be nice.
Thanks
Troy
11 years, 3 months