[copr] master: Move the API token length in the config file and adjust db accordingly Up to now the API token length was hard-coded in the code to 30 chars long. With this commit this limit is now set in the configuration file of the application. In order for this to make sense, we need to bump the size of the field in the database to 255 (should be more than enough). (f6dc2ef)
by bkabrda@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit f6dc2efe1d749a50732f3ee72caac42df9854158
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jan 9 07:31:37 2013 +0100
Move the API token length in the config file and adjust db accordingly
Up to now the API token length was hard-coded in the code to 30 chars
long. With this commit this limit is now set in the configuration
file of the application.
In order for this to make sense, we need to bump the size of the field
in the database to 255 (should be more than enough).
NOTE: the alembic upgrade won't work on sqlite which consider pretty
much only two types of field: numeric or text. So it has no problem
storing a 100 chars long string in a varchar(40).
>---------------------------------------------------------------
.../versions/2e30169e58ce_change_api_token_len.py | 28 ++++++++++++++++++++
coprs_frontend/coprs/config.py | 3 ++
coprs_frontend/coprs/views/misc.py | 4 +-
3 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/coprs_frontend/alembic/versions/2e30169e58ce_change_api_token_len.py b/coprs_frontend/alembic/versions/2e30169e58ce_change_api_token_len.py
new file mode 100644
index 0000000..14b2708
--- /dev/null
+++ b/coprs_frontend/alembic/versions/2e30169e58ce_change_api_token_len.py
@@ -0,0 +1,28 @@
+"""Change api_token length from varchar(40) to varchar(255)
+
+Revision ID: 2e30169e58ce
+Revises: 32ba137a3d56
+Create Date: 2013-01-08 19:42:16.562926
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '2e30169e58ce'
+down_revision = '32ba137a3d56'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ """ Change the api_token field from the user table from varchar(40) to
+ varchar(255).
+ """
+ op.alter_column("user", "api_token", type_=sa.String(255))
+
+
+def downgrade():
+ """ Change the api_token field from the user table from varchar(255) to
+ varchar(40).
+ """
+ op.alter_column("user", "api_token", type_=sa.String(40))
diff --git a/coprs_frontend/coprs/config.py b/coprs_frontend/coprs/config.py
index bbc6c0a..ef1578f 100644
--- a/coprs_frontend/coprs/config.py
+++ b/coprs_frontend/coprs/config.py
@@ -14,6 +14,9 @@ class Config(object):
# SQLAlchemy
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.abspath(DATABASE)
+ # Token length, defaults to 30, DB set to varchar 255
+ API_TOKEN_LENGTH = 30
+
class ProductionConfig(Config):
DEBUG = False
diff --git a/coprs_frontend/coprs/views/misc.py b/coprs_frontend/coprs/views/misc.py
index 54e7ff3..78c9721 100644
--- a/coprs_frontend/coprs/views/misc.py
+++ b/coprs_frontend/coprs/views/misc.py
@@ -55,7 +55,7 @@ def create_or_login(resp):
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 = generate_api_token(app.config['API_TOKEN_LENGTH']),
api_token_expiration = expiration_date_token)
db.session.add(user)
db.session.commit()
@@ -114,7 +114,7 @@ def api():
@login_required
def api_new_token():
user = flask.g.user
- user.api_token = generate_api_token()
+ user.api_token = generate_api_token(app.config['API_TOKEN_LENGTH'])
user.api_token_expiration = datetime.date.today() \
+ datetime.timedelta(days=30)
db.session.add(user)
11 years, 3 months
[copr] master: We need to accept 'GET' for the UI to work (d011104)
by bkabrda@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit d011104802655adb807be464e8407e1da8a11785
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jan 9 07:30:58 2013 +0100
We need to accept 'GET' for the UI to work
>---------------------------------------------------------------
coprs_frontend/coprs/views/misc.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/coprs_frontend/coprs/views/misc.py b/coprs_frontend/coprs/views/misc.py
index b2fc08c..54e7ff3 100644
--- a/coprs_frontend/coprs/views/misc.py
+++ b/coprs_frontend/coprs/views/misc.py
@@ -110,7 +110,7 @@ def api():
user=flask.g.user)
-(a)misc.route('/api/new/', methods = ["POST"])
+(a)misc.route('/api/new/', methods = ["GET", "POST"])
@login_required
def api_new_token():
user = flask.g.user
11 years, 3 months
[PATCH 1/2] We need to accept 'GET' for the UI to work
by Pierre-Yves Chibon
---
coprs_frontend/coprs/views/misc.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/coprs_frontend/coprs/views/misc.py b/coprs_frontend/coprs/views/misc.py
index b2fc08c..54e7ff3 100644
--- a/coprs_frontend/coprs/views/misc.py
+++ b/coprs_frontend/coprs/views/misc.py
@@ -110,7 +110,7 @@ def api():
user=flask.g.user)
-(a)misc.route('/api/new/', methods = ["POST"])
+(a)misc.route('/api/new/', methods = ["GET", "POST"])
@login_required
def api_new_token():
user = flask.g.user
--
1.7.1
11 years, 3 months
[PATCH 1/6] Small layout change and add .gitignore and requirements.txt files
by Pierre-Yves Chibon
- 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(-)
create mode 100644 .gitignore
create mode 100644 requirements.txt
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
--
1.7.1
11 years, 3 months
[copr] master: Properly use login_required decorator (264f317)
by bkabrda@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 264f317df156a2d9704cb5da653afab58aa789cf
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Tue Jan 8 14:45:05 2013 +0100
Properly use login_required decorator
>---------------------------------------------------------------
.../coprs/views/coprs_ns/coprs_general.py | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
index f616ccc..4086fea 100644
--- a/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
+++ b/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
@@ -46,10 +46,9 @@ def coprs_by_allowed(username = None, page = 1):
@coprs_ns.route('/add/')
+@login_required
def copr_add():
form = forms.CoprForm()
- if flask.g.user is None:
- return flask.redirect(flask.url_for('misc.login'))
return flask.render_template('coprs/add.html', form = form)
11 years, 3 months
[copr] master: We want the main page to have 'coprs_ns.coprs_show' endpoint associated (50d610e)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 50d610e9440cda6f5144fcead39ad664f388745a
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Tue Jan 8 14:11:05 2013 +0100
We want the main page to have 'coprs_ns.coprs_show' endpoint associated
>---------------------------------------------------------------
coprs_frontend/coprs/__init__.py | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/coprs_frontend/coprs/__init__.py b/coprs_frontend/coprs/__init__.py
index b921968..f2ea8d4 100644
--- a/coprs_frontend/coprs/__init__.py
+++ b/coprs_frontend/coprs/__init__.py
@@ -43,6 +43,4 @@ app.register_blueprint(coprs_ns.coprs_ns)
app.register_blueprint(misc.misc)
app.register_blueprint(backend_ns.backend_ns)
-(a)app.route("/")
-def start():
- return coprs_general.coprs_show()
+app.add_url_rule('/', 'coprs_ns.coprs_show', coprs_general.coprs_show)
11 years, 3 months
[copr] master: Use explicit enumeration for serialialized user attributes to prevent possible exposure of credentials (3dc860e)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 3dc860ed701a363d872f1f2d2504b095d73dc2bf
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Tue Jan 8 13:33:33 2013 +0100
Use explicit enumeration for serialialized user attributes to prevent possible exposure of credentials
>---------------------------------------------------------------
coprs_frontend/coprs/models.py | 3 ++-
.../coprs/views/backend_ns/backend_general.py | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index c7120a1..cf1397e 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -95,7 +95,8 @@ class User(db.Model, Serializer):
@property
def serializable_attributes(self):
- return super(User, self).serializable_attributes + ['name']
+ # enumerate here to prevent exposing credentials
+ return ['id', 'name']
class Copr(db.Model, Serializer):
diff --git a/coprs_frontend/coprs/views/backend_ns/backend_general.py b/coprs_frontend/coprs/views/backend_ns/backend_general.py
index 1c15595..c315cde 100644
--- a/coprs_frontend/coprs/views/backend_ns/backend_general.py
+++ b/coprs_frontend/coprs/views/backend_ns/backend_general.py
@@ -13,7 +13,7 @@ def waiting_builds():
query = builds_logic.BuildsLogic.get_waiting_builds(None)
builds = query[0:10]
- return flask.jsonify({'builds': [build.to_dict(options = {'copr': {'owner': {'__columns_except__': ['openid_name', 'proven', 'admin', 'mail'] },
+ return flask.jsonify({'builds': [build.to_dict(options = {'copr': {'owner': {},
'__columns_except__': ['chroots', 'repos', 'build_count'],
'__included_ids__': False},
'__included_ids__': False}) for build in builds]})
11 years, 3 months
[copr] master: Fix permissions changes (refactored code but not renamed variables) (31458ea)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 31458eae773590c2004a0ee748eecff62d49caae
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Tue Jan 8 13:14:53 2013 +0100
Fix permissions changes (refactored code but not renamed variables)
>---------------------------------------------------------------
coprs_frontend/coprs/logic/coprs_logic.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/coprs_frontend/coprs/logic/coprs_logic.py b/coprs_frontend/coprs/logic/coprs_logic.py
index 08bf3e7..2d8c200 100644
--- a/coprs_frontend/coprs/logic/coprs_logic.py
+++ b/coprs_frontend/coprs/logic/coprs_logic.py
@@ -107,8 +107,8 @@ class CoprsPermissionLogic(object):
def update_permissions_by_applier(cls, user, copr, copr_permission, new_builder, new_admin):
approved_num = helpers.PermissionEnum.num('Approved')
if copr_permission:
- prev_builder = permission.copr_builder
- prev_admin = permission.copr_admin
+ prev_builder = copr_permission.copr_builder
+ prev_admin = copr_permission.copr_admin
# if we had Approved before, we can have it now, otherwise not
if new_builder == approved_num and prev_builder != new_builder or \
new_admin == approved_num and prev_admin != new_admin:
11 years, 3 months
[copr] master: Provide, initial values for not-null columns, fix the migration to work. Alembic currently doesn't support adding default values for date columns (340d05a)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 340d05a69142e867662d24523db71e177a66ef0e
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Tue Jan 8 13:14:09 2013 +0100
Provide, initial values for not-null columns, fix the migration to work.
Alembic currently doesn't support adding default values for date columns
>---------------------------------------------------------------
.../versions/32ba137a3d56_add_token_informatio.py | 5 +++--
coprs_frontend/coprs/models.py | 6 ++++--
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/coprs_frontend/alembic/versions/32ba137a3d56_add_token_informatio.py b/coprs_frontend/alembic/versions/32ba137a3d56_add_token_informatio.py
index 64c7515..43451a9 100644
--- a/coprs_frontend/alembic/versions/32ba137a3d56_add_token_informatio.py
+++ b/coprs_frontend/alembic/versions/32ba137a3d56_add_token_informatio.py
@@ -20,9 +20,10 @@ 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')
+ nullable=False, server_default='default_token'))
op.add_column('user', sa.Column('api_token_expiration', sa.Date,
- nullable=False, default=datetime.date(2000, 1, 1)))
+ nullable=False, server_default='2000-1-1'))
+
def downgrade():
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index 4429554..c7120a1 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -1,3 +1,5 @@
+import datetime
+
from coprs import constants
from coprs import db
from coprs import helpers
@@ -54,8 +56,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)
+ api_token = db.Column(db.String(40), nullable = False, default = 'abc')
+ api_token_expiration = db.Column(db.Date, nullable = False, default = datetime.date(2000, 1, 1))
@property
def name(self):
11 years, 3 months
[copr] master: Rework the login_required decorator to allow token login With the current mechanism, one can either login via the website or provide a "token" and "username" POST or GET parameters. (789c2f9)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 789c2f94f2900315d04bf0aa91435b2c8839a491
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Jan 8 11:42:08 2013 +0100
Rework the login_required decorator to allow token login
With the current mechanism, one can either login via the website or
provide a "token" and "username" POST or GET parameters.
By providing the "token" and "username" parameters, one can access
to all the functions of coprs and pretty do as much as via the
website (assuming the other needed parameters are also given).
>---------------------------------------------------------------
coprs_frontend/coprs/views/misc.py | 21 +++++++++++++++++----
1 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/coprs_frontend/coprs/views/misc.py b/coprs_frontend/coprs/views/misc.py
index 430604d..b2fc08c 100644
--- a/coprs_frontend/coprs/views/misc.py
+++ b/coprs_frontend/coprs/views/misc.py
@@ -56,7 +56,7 @@ def create_or_login(resp):
+ 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)
+ api_token_expiration = expiration_date_token)
db.session.add(user)
db.session.commit()
flask.flash(u'Welcome, {0}'.format(user.name))
@@ -74,8 +74,21 @@ def logout():
def login_required(f):
@functools.wraps(f)
def decorated_function(*args, **kwargs):
- if flask.g.user is None:
- return flask.redirect(flask.url_for('misc.login', next = flask.request.url))
+ token = flask.request.form.get('token')
+ username = flask.request.form.get('username')
+ token_auth = False
+ if token and username:
+ user = models.User.query.filter(
+ models.User.openid_name == models.User.openidize_name(username)
+ ).first()
+ if user \
+ and user.api_token == token \
+ and user.api_token_expiration >= datetime.date.today():
+ token_auth = True
+ flask.g.user = user
+ if not token_auth and flask.g.user is None:
+ return flask.redirect(flask.url_for('misc.login',
+ next = flask.request.url))
return f(*args, **kwargs)
return decorated_function
@@ -97,7 +110,7 @@ def api():
user=flask.g.user)
-(a)misc.route('/api/new')
+(a)misc.route('/api/new/', methods = ["POST"])
@login_required
def api_new_token():
user = flask.g.user
11 years, 3 months