Skip to content

Commit

Permalink
Merge 0fbf9fc into 2af5e5f
Browse files Browse the repository at this point in the history
  • Loading branch information
hgy59 committed Apr 1, 2018
2 parents 2af5e5f + 0fbf9fc commit 88432f5
Show file tree
Hide file tree
Showing 20 changed files with 197 additions and 72 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Expand Up @@ -6,8 +6,6 @@ python:

install:
- sudo add-apt-repository ppa:travis-ci/sqlite3 -y
- sudo apt-get update -q
- sudo apt-get install sqlite3
- pip install -r requirements.txt
- pip install coverage coveralls

Expand Down
20 changes: 12 additions & 8 deletions manage.py
Expand Up @@ -6,12 +6,12 @@
import shutil
from unittest import TextTestRunner

from flask import current_app
from flask.ext.migrate import MigrateCommand
from flask.ext.script import Manager, Option
from flask.ext.security.script import (CreateUserCommand, DeactivateUserCommand, ActivateUserCommand, CreateRoleCommand,
RemoveRoleCommand, AddRoleCommand, commit)
from flask.ext.security.utils import encrypt_password
from flask import Flask, current_app
from flask_migrate import MigrateCommand
from flask_script import Manager, Option
from flask_security.script import (CreateUserCommand, DeactivateUserCommand, ActivateUserCommand,
CreateRoleCommand, RemoveRoleCommand, AddRoleCommand, commit)
from flask_security.utils import encrypt_password

from spkrepo import create_app
from spkrepo.ext import db
Expand Down Expand Up @@ -168,8 +168,12 @@ def depopulate():
@manager.command
def clean():
"""Clean data path"""
shutil.rmtree(os.path.join(current_app.config['DATA_PATH']))
os.mkdir(current_app.config['DATA_PATH'])
# do not remove and recreate the path since it may be a docker volume
for root, dirs, files in os.walk(os.path.join(current_app.config['DATA_PATH']), topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))


@manager.command
Expand Down
23 changes: 23 additions & 0 deletions migrations/versions/a41b2b645a3c_.py
@@ -0,0 +1,23 @@
"""Update for DSM6
Revision ID: a41b2b645a3c
Revises: 26b4c36c11e
Create Date: 2016-12-20 18:30:15.449680
"""
revision = 'a41b2b645a3c'
down_revision = '26b4c36c11e'

from alembic import op
import sqlalchemy as sa



def upgrade():
op.add_column('version', sa.Column('conf_privilege', sa.Unicode(length=255), nullable=True))
op.add_column('version', sa.Column('conf_resource', sa.Unicode(length=255), nullable=True))


def downgrade():
op.drop_column('version', 'conf_resource')
op.drop_column('version', 'conf_privilege')
1 change: 0 additions & 1 deletion requirements.txt
@@ -1,2 +1 @@
-e git+https://github.com/Diaoul/flask-login.git@0.2.11-fix-session-creation#egg=Flask-Login
-e .
19 changes: 12 additions & 7 deletions setup.py
Expand Up @@ -3,22 +3,27 @@


tests_require = ['Flask-Testing',
'factory-boy', 'fake-factory',
'lxml', 'urltools',
'factory-boy', 'Faker',
'lxml', 'urltools', 'mock',
'coveralls']

install_requires = ['Flask',
'Flask-SQLAlchemy',
'Flask-Security',
'Flask-Admin==1.0.8', 'Pillow',
'Flask-Security', 'passlib',
'Flask-Babelex',
'Flask-WTF', 'Flask-Mail', 'configparser',
'Flask-Principal',
'Flask-Admin==1.0.8', 'sqlalchemy<1.2', # ValueError: too many values to unpack (until flask-admin is fixed)
'Pillow',
'Flask-RESTful',
'Flask-Login',
'Flask-Cache', 'redis',
'python-gnupg', 'requests',
'python-gnupg', 'requests', 'click',
'Flask-Migrate', 'alembic>=0.7.0',
'Flask-Script',
'Flask-Script', 'Text-Unidecode', 'ipaddress',
'Flask-DebugToolbar']

dev_requires = ['sphinx', 'sphinx_rtd_theme']
dev_requires = ['sphinx', 'sphinx-rtd-theme']


setup(
Expand Down
2 changes: 1 addition & 1 deletion spkrepo/app.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import jinja2
from flask import Flask
from flask.ext.admin import Admin
from flask_admin import Admin
from wtforms import HiddenField

from . import config as default_config
Expand Down
3 changes: 3 additions & 0 deletions spkrepo/config.py
Expand Up @@ -19,10 +19,13 @@
SECURITY_REGISTERABLE = True
SECURITY_RECOVERABLE = True
SECURITY_CHANGEABLE = True
SECURITY_PASSWORD_HASH = 'sha512_crypt'
SECURITY_PASSWORD_SALT = 'password-salt'

# SQLAlchemy
SQLALCHEMY_ECHO = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///%s/spkrepo.db' % DATA_PATH
SQLALCHEMY_TRACK_MODIFICATIONS = False

# Restful
HTTP_BASIC_AUTH_REALM = 'spkrepo'
Expand Down
12 changes: 6 additions & 6 deletions spkrepo/ext.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
from flask.ext.cache import Cache
from flask.ext.debugtoolbar import DebugToolbarExtension
from flask.ext.mail import Mail
from flask.ext.migrate import Migrate
from flask.ext.security import Security
from flask.ext.sqlalchemy import SQLAlchemy
from flask_cache import Cache
from flask_debugtoolbar import DebugToolbarExtension
from flask_mail import Mail
from flask_migrate import Migrate
from flask_security import Security
from flask_sqlalchemy import SQLAlchemy

# Cache
cache = Cache()
Expand Down
24 changes: 13 additions & 11 deletions spkrepo/models.py
Expand Up @@ -5,8 +5,8 @@
from datetime import datetime, timedelta

from flask import current_app
from flask.ext.security import UserMixin, RoleMixin, SQLAlchemyUserDatastore
from flask.ext.sqlalchemy import before_models_committed, models_committed
from flask_security import UserMixin, RoleMixin, SQLAlchemyUserDatastore
from flask_sqlalchemy import before_models_committed, models_committed
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm.collections import attribute_mapped_collection

Expand Down Expand Up @@ -35,7 +35,7 @@ class User(db.Model, UserMixin):
active = db.Column(db.Boolean(), nullable=False)
confirmed_at = db.Column(db.DateTime())

# Relationhips
# Relationships
roles = db.relationship('Role', secondary='user_role', back_populates='users', lazy=False)
authored_packages = db.relationship('Package', back_populates='author')
maintained_packages = db.relationship('Package', secondary='package_user_maintainer',
Expand All @@ -56,7 +56,7 @@ class Role(db.Model, RoleMixin):
name = db.Column(db.Unicode(50), unique=True, nullable=False)
description = db.Column(db.Unicode(255))

# Relationhips
# Relationships
users = db.relationship('User', secondary='user_role', back_populates='roles')

@classmethod
Expand All @@ -80,7 +80,7 @@ class Architecture(db.Model):
id = db.Column(db.Integer, primary_key=True)
code = db.Column(db.Unicode(20), unique=True, nullable=False)

# Relationhips
# Relationships
builds = db.relationship('Build', secondary='build_architecture', back_populates='architectures')

# Other
Expand Down Expand Up @@ -150,7 +150,7 @@ class Screenshot(db.Model):
package_id = db.Column(db.Integer, db.ForeignKey('package.id'), nullable=False)
path = db.Column(db.Unicode(200), nullable=False)

# Relationhips
# Relationships
package = db.relationship('Package', back_populates='screenshots')

def save(self, stream):
Expand Down Expand Up @@ -184,7 +184,7 @@ class Icon(db.Model):
# Constraints
__table_args__ = (db.UniqueConstraint(version_id, size),)

# Relationhips
# Relationships
version = db.relationship('Version', back_populates='icons')

def save(self, stream):
Expand Down Expand Up @@ -232,7 +232,7 @@ class DisplayName(db.Model):
language_id = db.Column(db.Integer, db.ForeignKey('language.id'), nullable=False)
displayname = db.Column(db.Unicode(50), nullable=False)

# Relationhips
# Relationships
language = db.relationship('Language')

# Constraints
Expand All @@ -253,7 +253,7 @@ class Description(db.Model):
language_id = db.Column(db.Integer, db.ForeignKey('language.id'), nullable=False)
description = db.Column(db.UnicodeText, nullable=False)

# Relationhips
# Relationships
language = db.relationship('Language')

# Constraints
Expand Down Expand Up @@ -363,13 +363,15 @@ class Version(db.Model):
conf_dependencies = db.Column(db.Unicode(255))
conflicts = db.Column(db.Unicode(255))
conf_conflicts = db.Column(db.Unicode(255))
conf_privilege = db.Column(db.Unicode(255))
conf_resource = db.Column(db.Unicode(255))
install_wizard = db.Column(db.Boolean)
upgrade_wizard = db.Column(db.Boolean)
startable = db.Column(db.Boolean)
license = db.Column(db.UnicodeText)
insert_date = db.Column(db.DateTime, default=db.func.now(), nullable=False)

# Relationhips
# Relationships
package = db.relationship('Package', back_populates='versions', lazy=False)
service_dependencies = db.relationship('Service', secondary='version_service_dependency')
displaynames = db.relationship('DisplayName', cascade='all, delete-orphan',
Expand Down Expand Up @@ -440,7 +442,7 @@ class Package(db.Model):
Download.date >= datetime.now() - timedelta(days=90))).
correlate_except(Download), deferred=True)

# Relationhips
# Relationships
versions = db.relationship('Version', back_populates='package', cascade='all, delete-orphan',
cascade_backrefs=False, order_by='Version.version')
screenshots = db.relationship('Screenshot', back_populates='package', cascade='all, delete-orphan')
Expand Down
2 changes: 1 addition & 1 deletion spkrepo/templates/layout.html
Expand Up @@ -48,7 +48,7 @@
{% endfor %}
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated() %}
{% if current_user.is_authenticated %}
{% if current_user.has_role('developer') or current_user.has_role('package_admin') or
current_user.has_role('admin') %}
{% set right_nav = [
Expand Down
48 changes: 42 additions & 6 deletions spkrepo/tests/common.py
Expand Up @@ -20,7 +20,7 @@
import faker
from factory.alchemy import SQLAlchemyModelFactory
from flask import url_for, current_app
from flask.ext.testing import TestCase
from flask_testing import TestCase

from spkrepo import create_app
from spkrepo.ext import db
Expand Down Expand Up @@ -347,6 +347,17 @@ def assert302(self, response, message=None):

self.assertStatus(response, 302, message)

def assertRedirectsTo(self, response, location, message=None):
"""
Check if response is a redirect
:param response: Flask response
:param location: the redirect location
:param message: Message to display on test failure
"""

self.assertRedirects(response, location, message)

def assert409(self, response, message=None):
"""
Check if response status code is 409
Expand Down Expand Up @@ -457,7 +468,7 @@ def create_image(text, width=640, height=480):
def create_spk(build, info=None, signature=None, with_checksum=False, with_package_icons=True, with_info_icons=False,
with_info=True, with_package=True, with_scripts=True, with_conf=False, info_encoding='utf-8',
license_encoding='utf-8', signature_encoding='ascii', conf_dependencies_encoding='utf-8',
conf_conflicts_encoding='utf-8'):
conf_conflicts_encoding='utf-8', conf_privilege_encoding='utf-8', conf_resource_encoding='utf-8'):
"""
Create a valid SPK file
Expand All @@ -478,12 +489,14 @@ def create_spk(build, info=None, signature=None, with_checksum=False, with_packa
:param signature_encoding: encoding for the syno_signature.asc file
:param conf_dependencies_encoding: encoding for the conf/PKG_DEPS file
:param conf_conflicts_encoding: encoding for the conf/PKG_CONX file
:param conf_privilege_encoding: encoding for the conf/privilege file
:param conf_resource_encoding: encoding for the conf/resource file
:return: the created SPK stream
"""
# generate an info if none is given
info = info or create_info(build)

# open strucutre
# open structure
spk_stream = io.BytesIO()
spk = tarfile.TarFile(fileobj=spk_stream, mode='w')

Expand All @@ -506,7 +519,7 @@ def create_spk(build, info=None, signature=None, with_checksum=False, with_packa
spk.addfile(signature_tarinfo, fileobj=signature_stream)

# conf
if with_conf or build.version.conf_dependencies is not None or build.version.conf_conflicts is not None:
if with_conf or build.version.conf_dependencies is not None or build.version.conf_conflicts or build.version.conf_privilege is not None:
conf_folder_tarinfo = tarfile.TarInfo('conf')
conf_folder_tarinfo.type = tarfile.DIRTYPE
conf_folder_tarinfo.mode = 0o755
Expand All @@ -533,6 +546,28 @@ def create_spk(build, info=None, signature=None, with_checksum=False, with_packa
conf_tarinfo.size = conf_stream_bytes.tell()
conf_stream_bytes.seek(0)
spk.addfile(conf_tarinfo, fileobj=conf_stream_bytes)
if build.version.conf_privilege is not None:
conf_tarinfo = tarfile.TarInfo('conf/privilege')
config = ConfigParser()
config.read_dict(json.loads(build.version.conf_privilege))
conf_stream = io.StringIO()
config.write(conf_stream)
conf_stream_bytes = io.BytesIO(conf_stream.getvalue().encode(conf_privilege_encoding))
conf_stream_bytes.seek(0, io.SEEK_END)
conf_tarinfo.size = conf_stream_bytes.tell()
conf_stream_bytes.seek(0)
spk.addfile(conf_tarinfo, fileobj=conf_stream_bytes)
if build.version.conf_resource is not None:
conf_tarinfo = tarfile.TarInfo('conf/resource')
config = ConfigParser()
config.read_dict(json.loads(build.version.conf_resource))
conf_stream = io.StringIO()
config.write(conf_stream)
conf_stream_bytes = io.BytesIO(conf_stream.getvalue().encode(conf_resource_encoding))
conf_stream_bytes.seek(0, io.SEEK_END)
conf_tarinfo.size = conf_stream_bytes.tell()
conf_stream_bytes.seek(0)
spk.addfile(conf_tarinfo, fileobj=conf_stream_bytes)

# wizards
wizards = []
Expand Down Expand Up @@ -615,14 +650,15 @@ def create_spk(build, info=None, signature=None, with_checksum=False, with_packa
if isinstance(info, io.BytesIO):
info_stream = info
else:
info_stream = io.BytesIO('\n'.join(['%s="%s"' % (k, v) for k, v in info.items()]).encode(info_encoding))
b = '\n'.join(['%s="%s"' % (k, v) for k, v in info.items()]).encode(info_encoding)
info_stream = io.BytesIO(b)
info_tarinfo = tarfile.TarInfo('INFO')
info_stream.seek(0, io.SEEK_END)
info_tarinfo.size = info_stream.tell()
info_stream.seek(0)
spk.addfile(info_tarinfo, fileobj=info_stream)

# close strucutre
# close structure
spk.close()
spk_stream.seek(0)

Expand Down
5 changes: 4 additions & 1 deletion spkrepo/tests/test_admin.py
Expand Up @@ -11,7 +11,10 @@

class IndexTestCase(BaseTestCase):
def test_anonymous(self):
self.assert403(self.client.get(url_for('admin.index')))
self.assert302(self.client.get(url_for('admin.index'), follow_redirects=False))

def test_anonymous_redirects_to_login(self):
self.assertRedirectsTo(self.client.get(url_for('admin.index')),url_for('security.login'))

def test_user(self):
with self.logged_user():
Expand Down
2 changes: 1 addition & 1 deletion spkrepo/tests/test_frontend.py
Expand Up @@ -2,7 +2,7 @@
from unittest import TestSuite, TestLoader

from flask import url_for
from flask.ext.security import url_for_security
from flask_security import url_for_security
from lxml.html import fromstring

from spkrepo.ext import db
Expand Down

0 comments on commit 88432f5

Please sign in to comment.