Exemplo n.º 1
0
    def render(self):

        login_url = resource_url(self.request.context, self.request, 'login')
        referrer = self.request.url
        # never use the login form itself as came_from
        if referrer == login_url:
            referrer = '/'
        came_from = self.request.params.get('came_from', referrer)
        login = self.request.params.get('user.login', '')
        if 'form.submitted' in self.request.params:
            password = self.request.params.get('user.password', u'')
            if password:
                if User.by_ldap_credentials(
                        self.session, login, password,
                        self.request.registry.settings) is not None:
                    log.info('login %r succeed', login)
                    headers = remember(self.request, login)
                    return HTTPFound(location=came_from, headers=headers)

                if User.by_credentials(self.session, login,
                                       password) is not None:
                    log.info('login %r succeed', login)
                    headers = remember(self.request, login)
                    return HTTPFound(location=came_from, headers=headers)

        return {
            'came_from': came_from,
            'user': User(login=login),
        }
Exemplo n.º 2
0
    def authenticated_userid(self, request):

        auth = request.environ.get('HTTP_AUTHORIZATION')
        try:
            authmeth, auth = auth.split(' ', 1)
        except AttributeError:  # not enough values to unpack
            return None

        if authmeth.lower() != 'basic':
            return None

        try:
            # Python 3's string is already unicode
            auth = base64.b64decode(auth.strip())
        except binascii.Error:  # can't decode
            return None

        if not isinstance(auth, unicode):
            auth = auth.decode('utf-8')

        try:
            login, password = auth.split(':', 1)
        except ValueError:  # not enough values to unpack
            return None

        if User.by_credentials(DBSession(), login, password):
            return login

        if User.by_ldap_credentials(DBSession(), login, password,
                                    request.registry.settings):
            return login

        return None
Exemplo n.º 3
0
def populate(engine, interactive=True):

    Base.metadata.create_all(engine)
    session = DBSession()
    user_perm = Permission(name=u'user_view')
    admin_perm = Permission(name=u'admin_view')
    download_perm = Permission(name=u'download_releasefile')
    upload_perm = Permission(name=u'upload_releasefile')
    session.add(user_perm)
    session.add(upload_perm)
    session.add(download_perm)
    session.add(admin_perm)

    admin_group = Group(name=u'admin')
    admin_group.permissions.append(user_perm)
    admin_group.permissions.append(download_perm)
    admin_group.permissions.append(upload_perm)
    admin_group.permissions.append(admin_perm)
    session.add(admin_group)

    user_group = Group(name=u'developer')
    user_group.permissions.append(user_perm)
    user_group.permissions.append(download_perm)
    user_group.permissions.append(upload_perm)
    session.add(user_group)

    pip_group = Group(name=u'installer')
    pip_group.permissions.append(download_perm)
    session.add(pip_group)

    if interactive:
        login = (input('administrator login [admin]:')
                 or 'admin')
        password = (input('administrator password [changeme]:')
                    or 'changeme')
        email = (input('administrator email [[email protected]]')
                 or '*****@*****.**')
        piplogin = (input('installer login [pip]:') or 'pip')
        pippassword = (input('installer password [changeme]:') or
                       'changeme')
    else:
        login = '******'
        password = '******'
        email = '*****@*****.**'

        piplogin = '******'
        pippassword = '******'

    admin = User(login=unicode(login),
                 password=unicode(password),
                 email=unicode(email))
    admin.groups.append(admin_group)
    session.add(admin)
    pip = User(login=unicode(piplogin),
               password=unicode(pippassword),
               )
    pip.groups.append(pip_group)
    session.add(pip)

    session.commit()
Exemplo n.º 4
0
    def authenticated_userid(self, request):

        auth = request.environ.get('HTTP_AUTHORIZATION')
        try:
            authmeth, auth = auth.split(' ', 1)
        except AttributeError:  # not enough values to unpack
            return None

        if authmeth.lower() != 'basic':
            return None

        try:
            # Python 3's string is already unicode
            auth = base64.b64decode(auth.strip())
        except binascii.Error:  # can't decode
            return None

        if not isinstance(auth, unicode):
            auth = auth.decode('utf-8')

        try:
            login, password = auth.split(':', 1)
        except ValueError:  # not enough values to unpack
            return None

        if User.by_credentials(DBSession(), login, password):
            return login
        
        if User.by_ldap_credentials(DBSession(), login, password,request.registry.settings):
            return login
        
        return None
Exemplo n.º 5
0
    def render(self):

        login_url = resource_url(self.request.context, self.request, 'login')
        referrer = self.request.url
        # never use the login form itself as came_from
        if referrer == login_url:
            referrer = '/'
        came_from = self.request.params.get('came_from', referrer)
        login = self.request.params.get('user.login', '')
        if 'form.submitted' in self.request.params:
            password = self.request.params.get('user.password', u'')
            if password:
                if User.by_ldap_credentials(
                        self.session, login, password,
                        self.request.registry.settings) is not None:
                    log.info('login %r succeed', login)
                    headers = remember(self.request, login)
                    return HTTPFound(location=came_from,
                                     headers=headers)
 
                if User.by_credentials(
                        self.session, login, password) is not None:
                    log.info('login %r succeed', login)
                    headers = remember(self.request, login)
                    return HTTPFound(location=came_from,
                                     headers=headers)

        return {'came_from': came_from,
                'user': User(login=login),
                }
Exemplo n.º 6
0
    def render(self):

        package = Package.by_name(self.session, self.request.matchdict["package_name"])
        if not package:
            raise HTTPNotFound()

        if "form.refresh_package" in self.request.params:
            package.update_at = None
            self.session.add(package)

        owners = dict((usr.login, usr) for usr in package.owners)
        can_edit_role = self.login in owners.keys() and package.local

        if "form.add_role" in self.request.params:

            if not can_edit_role:
                raise HTTPForbidden()

            user = User.by_login(self.session, self.request.params["login"])
            if user and user.has_permission("upload_releasefile"):
                if self.request.params["role"] == "owner":
                    if user.login not in owners:
                        package.owners.append(user)
                else:
                    maintainers = [usr.login for usr in package.owners]
                    if user.login not in maintainers:
                        package.maintainers.append(user)
                self.session.add(package)

        if "form.remove_maintainer" in self.request.params:
            if not can_edit_role:
                raise HTTPForbidden()

            user = User.by_login(self.session, self.request.params["login"])
            if user:
                maintainers = dict((usr.login, usr) for usr in package.maintainers)
                if user.login in maintainers:
                    package.maintainers.remove(maintainers[user.login])
                    self.session.add(package)

        if "form.remove_owner" in self.request.params:
            if not can_edit_role:
                raise HTTPForbidden()

            user = User.by_login(self.session, self.request.params["login"])
            if user:
                if user.login in owners:
                    package.owners.remove(owners[user.login])
                    self.session.add(package)

        if "release_version" in self.request.matchdict:
            release = Release.by_version(self.session, package.name, self.request.matchdict["release_version"])
        else:
            release = package.sorted_releases[0]

        return {u"package": package, u"release": release, u"can_edit_role": can_edit_role}
Exemplo n.º 7
0
    def _create_release(self, package, data):
        data = self._to_unicode(data)
        release = Release(
            package=package,
            summary=data.get('summary'),
            version=data.get('version'),
            stable_version=data.get('stable_version'),
            home_page=data.get('home_page'),
            license=data.get('license'),
            description=data.get('description'),
            keywords=data.get('keywords'),
            platform=data.get('platform'),
            download_url=data.get('download_url'),
            bugtrack_url=data.get('bugtrack_url'),
            docs_url=data.get('docs_url'),
        )
        if data.get('author'):
            author = User.by_login(self.session, data['author'], local=False)
            if not author:
                author = User(login=data['author'],
                              local=False,
                              email=data.get('author_email'))
                self.session.add(author)
            release.author = author
        self.session.flush()
        if data.get('maintainer'):
            maintainer = User.by_login(self.session,
                                       data['maintainer'],
                                       local=False)
            if not maintainer:
                maintainer = User(login=data['maintainer'],
                                  local=False,
                                  email=data.get('maintainer_email'))
                self.session.add(maintainer)
            release.maintainer = maintainer
        self.session.flush()

        for name in data.get('classifiers', []):
            classifier = Classifier.by_name(self.session, name.decode('utf-8'))

            while classifier:
                release.classifiers.append(classifier)
                if classifier not in package.classifiers:
                    package.classifiers.append(classifier)
                classifier = classifier.parent

        self.session.flush()
        return release
Exemplo n.º 8
0
    def test_update_post_ok(self):
        from pyshop.models import User
        from pyshop.views.user import Edit

        view = Edit(
            self.create_request(
                {
                    "form.submitted": u"1",
                    "user.login": u"root",
                    "user.firstname": u"Admin",
                    "user.lastname": u"Istrator",
                }
            )
        )()
        self.assertIsRedirect(view)
        self.session.flush()
        admin = User.by_credentials(self.session, u"root", u"changeme")
        self.assertIsInstance(admin, User)
        self.assertEqual(admin.login, u"root")
        self.assertEqual(admin.firstname, u"Admin")
        self.assertEqual(admin.lastname, u"Istrator")
        admin.login = u"admin"
        admin.password = u"changeme"
        admin.firstname = None
        admin.lastname = None
        self.session.add(admin)
Exemplo n.º 9
0
    def authenticated_userid(self, request):

        auth = request.environ.get('HTTP_AUTHORIZATION')
        try:
            authmeth, auth = auth.split(' ', 1)
        except AttributeError as ValueError:  # not enough values to unpack
            return None

        if authmeth.lower() != 'basic':
            return None

        try:
            # Python 3's string is already unicode
            auth = auth.strip().decode('base64')
            if sys.version_info[0] == 2:
                auth = unicode(auth)
        except binascii.Error:  # can't decode
            return None
        try:
            login, password = auth.split(':', 1)
        except ValueError:  # not enough values to unpack
            return None

        if User.by_credentials(DBSession(), login, password):
            return login

        return None
Exemplo n.º 10
0
    def _create_release(self, package, data):

        release = Release(package=package,
                          summary=data.get('summary'),
                          version=data.get('version'),
                          stable_version=data.get('stable_version'),
                          home_page=data.get('home_page'),
                          license=data.get('license'),
                          description=data.get('description'),
                          keywords=data.get('keywords'),
                          platform=data.get('platform'),
                          download_url=data.get('download_url'),
                          bugtrack_url=data.get('bugtrack_url'),
                          docs_url=data.get('docs_url'),
                          )
        if data.get('author'):
            author = User.by_login(self.session, data['author'], local=False)
            if not author:
                author = User(login=data['author'],
                              local=False,
                              email=data.get('author_email'))
                self.session.add(author)
            release.author = author
        self.session.flush()
        if data.get('maintainer'):
            maintainer = User.by_login(self.session, data['maintainer'],
                                       local=False)
            if not maintainer:
                maintainer = User(login=data['maintainer'],
                                  local=False,
                                  email=data.get('maintainer_email'))
                self.session.add(maintainer)
            release.maintainer = maintainer
        self.session.flush()

        for name in data.get('classifiers', []):
            classifier = Classifier.by_name(self.session, name)

            while classifier:
                release.classifiers.append(classifier)
                if classifier not in package.classifiers:
                    package.classifiers.append(classifier)
                classifier = classifier.parent

        self.session.flush()
        return release
Exemplo n.º 11
0
 def test_post_delete_ok(self):
     from pyshop.views.account import Delete
     from pyshop.models import User
     view = Delete(self.create_request({'form.submitted': '1',
                                        },
                                       matchdict={'user_id': self.account_id
                                                  },))()
     self.assertIsRedirect(view)
     account = User.by_id(self.session, self.account_id)
     self.assertIsNone(account)
     self.account_todelete = []
Exemplo n.º 12
0
 def setUp(self):
     super(AccountTestCase, self).setUp()
     import uuid
     from pyshop.models import User, Group
     self.account_login = unicode(uuid.uuid4())
     u = User(login=self.account_login, password=u'secret')
     u.groups.append(Group.by_name(self.session, u'developer'))
     self.session.add(u)
     self.session.flush()
     self.account_id = u.id
     self.account_todelete = [self.account_id]
Exemplo n.º 13
0
 def test_change_password_post_ok(self):
     from pyshop.models import User
     from pyshop.views.user import ChangePassword as ChangePwd
     view = ChangePwd(self.create_request({'form.submitted': u'1',
                                           'current_password': u'changeme',
                                           'user.password': u'newpassw',
                                           'confirm_password': u'newpassw',
                                           }))()
     admin = User.by_credentials(self.session, u'admin', u'newpassw')
     self.assertIsInstance(admin, User)
     admin.password = u'changeme'
     self.session.add(admin)
Exemplo n.º 14
0
 def test_change_password_post_ko_unchanged(self):
     from pyshop.models import User
     from pyshop.views.user import ChangePassword as ChangePwd
     view = ChangePwd(self.create_request({'form.submitted': u'1',
                                           'current_password': u'changeme',
                                           'user.password': u'changeme',
                                           'confirm_password': u'changeme',
                                           }))()
     self.assertEqual(view['errors'],
                      [u'password is inchanged'])
     admin = User.by_credentials(self.session, u'admin', u'changeme')
     self.assertIsInstance(admin, User)
Exemplo n.º 15
0
def authbasic(request):
    """
    Authentification basic, Upload pyshop repository access
    """
    if len(request.environ.get('HTTP_AUTHORIZATION','')) > 0:
        auth = request.environ.get('HTTP_AUTHORIZATION')
        scheme, data = auth.split(None, 1)
        assert scheme.lower() == 'basic'
        data = base64.b64decode(data)
        if not isinstance(data, unicode):
            data = data.decode('utf-8')
        username, password = data.split(':', 1)
        if User.by_ldap_credentials(DBSession(), username, password, request.registry.settings):
            return HTTPFound(location=request.url)
        if User.by_credentials(DBSession(), username, password):
            return HTTPFound(location=request.url)
    return Response(status=401,
                    headerlist=[(b'WWW-Authenticate',
                                 b'Basic realm="pyshop repository access"'
                                 )],
                    )
Exemplo n.º 16
0
 def test_change_password_post_ko_not_matched(self):
     from pyshop.models import User
     from pyshop.views.user import ChangePassword as ChangePwd
     view = ChangePwd(self.create_request({'form.submitted': u'1',
                                           'current_password': u'CHANGEME',
                                           'user.password': u'newpassw',
                                           'confirm_password': u'NEWPASSW',
                                           }))()
     self.assertEqual(view['errors'],
                      [u'current password is not correct',
                       u'passwords do not match'])
     admin = User.by_credentials(self.session, u'admin', u'changeme')
     self.assertIsInstance(admin, User)
Exemplo n.º 17
0
 def test_change_password_post_ko_unchanged(self):
     from pyshop.models import User
     from pyshop.views.user import ChangePassword as ChangePwd
     view = ChangePwd(
         self.create_request({
             'form.submitted': u'1',
             'current_password': u'changeme',
             'user.password': u'changeme',
             'confirm_password': u'changeme',
         }))()
     self.assertEqual(view['errors'], [u'password is inchanged'])
     admin = User.by_credentials(self.session, u'admin', u'changeme')
     self.assertIsInstance(admin, User)
Exemplo n.º 18
0
    def validate(self, model, errors):
        r = self.request

        if not User.by_credentials(self.session, model.login,
                                   r.params['current_password']):
            errors.append(_(u'current password is not correct'))
        elif r.params['user.password'] == r.params['current_password']:
            errors.append(_(u'password is inchanged'))

        if r.params['user.password'] != r.params['confirm_password']:
            errors.append(_(u'passwords do not match'))

        return len(errors) == 0
Exemplo n.º 19
0
    def validate(self, model, errors):
        r = self.request

        if not User.by_credentials(self.session, model.login,
                                   r.params['current_password']):
            errors.append(_(u'current password is not correct'))
        elif r.params['user.password'] == r.params['current_password']:
            errors.append(_(u'password is inchanged'))

        if r.params['user.password'] != r.params['confirm_password']:
            errors.append(_(u'passwords do not match'))

        return len(errors) == 0
Exemplo n.º 20
0
 def test_change_password_post_ok(self):
     from pyshop.models import User
     from pyshop.views.user import ChangePassword as ChangePwd
     view = ChangePwd(
         self.create_request({
             'form.submitted': u'1',
             'current_password': u'changeme',
             'user.password': u'newpassw',
             'confirm_password': u'newpassw',
         }))()
     admin = User.by_credentials(self.session, u'admin', u'newpassw')
     self.assertIsInstance(admin, User)
     admin.password = u'changeme'
     self.session.add(admin)
Exemplo n.º 21
0
 def test_post_delete_ok(self):
     from pyshop.views.account import Delete
     from pyshop.models import User
     view = Delete(
         self.create_request(
             {
                 'form.submitted': '1',
             },
             matchdict={'user_id': self.account_id},
         ))()
     self.assertIsRedirect(view)
     account = User.by_id(self.session, self.account_id)
     self.assertIsNone(account)
     self.account_todelete = []
Exemplo n.º 22
0
 def test_post_create_ok(self):
     from pyshop.views.account import Create
     from pyshop.models import User, Group
     view = Create(self.create_request({'form.submitted': u'1',
                                        'user.login': u'dummy_new',
                                        'user.password': u'secret',
                                        'user.firstname': u'',
                                        'user.lastname': u'',
                                        'user.email': u'*****@*****.**',
                                        'confirm_password': u'secret',
                                        'groups': [u'1', u'2']
                                        }))()
     self.assertIsRedirect(view)
     self.account_todelete.append(User.by_login(self.session,
                                                u'dummy_new').id)
Exemplo n.º 23
0
 def test_change_password_post_ko_not_matched(self):
     from pyshop.models import User
     from pyshop.views.user import ChangePassword as ChangePwd
     view = ChangePwd(
         self.create_request({
             'form.submitted': u'1',
             'current_password': u'CHANGEME',
             'user.password': u'newpassw',
             'confirm_password': u'NEWPASSW',
         }))()
     self.assertEqual(
         view['errors'],
         [u'current password is not correct', u'passwords do not match'])
     admin = User.by_credentials(self.session, u'admin', u'changeme')
     self.assertIsInstance(admin, User)
Exemplo n.º 24
0
 def test_post_edit_ok(self):
     from pyshop.views.account import Edit
     from pyshop.models import User, Group
     view = Edit(self.create_request({'form.submitted': '1',
                                      'user.login': u'dummy_edited',
                                      'user.firstname': u'',
                                      'user.lastname': u'',
                                      'user.email': u'*****@*****.**',
                                      'groups': [u'1']
                                      },
                                     matchdict={'user_id': self.account_id
                                                }))()
     self.assertIsRedirect(view)
     self.session.flush()
     user = User.by_id(self.session, self.account_id)
     self.assertEqual(user.login, u'dummy_edited')
     self.assertEqual([g.id for g in user.groups], [1])
Exemplo n.º 25
0
    def test_change_password_post_ko_not_matched(self):
        from pyshop.models import User
        from pyshop.views.user import ChangePassword as ChangePwd

        view = ChangePwd(
            self.create_request(
                {
                    "form.submitted": u"1",
                    "current_password": u"CHANGEME",
                    "user.password": u"newpassw",
                    "confirm_password": u"NEWPASSW",
                }
            )
        )()
        self.assertEqual(view["errors"], [u"current password is not correct", u"passwords do not match"])
        admin = User.by_credentials(self.session, u"admin", u"changeme")
        self.assertIsInstance(admin, User)
Exemplo n.º 26
0
    def test_change_password_post_ko_unchanged(self):
        from pyshop.models import User
        from pyshop.views.user import ChangePassword as ChangePwd

        view = ChangePwd(
            self.create_request(
                {
                    "form.submitted": u"1",
                    "current_password": u"changeme",
                    "user.password": u"changeme",
                    "confirm_password": u"changeme",
                }
            )
        )()
        self.assertEqual(view["errors"], [u"password is inchanged"])
        admin = User.by_credentials(self.session, u"admin", u"changeme")
        self.assertIsInstance(admin, User)
Exemplo n.º 27
0
def authbasic(request):
    """
    Authentification basic, Upload pyshop repository access
    """
    if len(request.environ.get('HTTP_AUTHORIZATION','')) > 0:
        auth = request.environ.get('HTTP_AUTHORIZATION')
        scheme, data = auth.split(None, 1)
        assert scheme.lower() == 'basic'
        username, password = data.decode('base64').split(':', 1)
        if User.by_credentials(DBSession(), username, password):
            return HTTPFound(location=request.url)
    return Response(status=401,
                    headerlist=[('WWW-Authenticate',
                                 ('Basic realm="%s"' %
                                 _('pyshop repository access')).encode('utf-8')
                                 )],
                    )
Exemplo n.º 28
0
 def test_post_create_ok(self):
     from pyshop.views.account import Create
     from pyshop.models import User, Group
     view = Create(
         self.create_request({
             'form.submitted': u'1',
             'user.login': u'dummy_new',
             'user.password': u'secret',
             'user.firstname': u'',
             'user.lastname': u'',
             'user.email': u'*****@*****.**',
             'confirm_password': u'secret',
             'groups': [u'1', u'2']
         }))()
     self.assertIsRedirect(view)
     self.account_todelete.append(
         User.by_login(self.session, u'dummy_new').id)
Exemplo n.º 29
0
    def test_change_password_post_ok(self):
        from pyshop.models import User
        from pyshop.views.user import ChangePassword as ChangePwd

        view = ChangePwd(
            self.create_request(
                {
                    "form.submitted": u"1",
                    "current_password": u"changeme",
                    "user.password": u"newpassw",
                    "confirm_password": u"newpassw",
                }
            )
        )()
        admin = User.by_credentials(self.session, u"admin", u"newpassw")
        self.assertIsInstance(admin, User)
        admin.password = u"changeme"
        self.session.add(admin)
Exemplo n.º 30
0
 def test_post_edit_ok(self):
     from pyshop.views.account import Edit
     from pyshop.models import User, Group
     view = Edit(
         self.create_request(
             {
                 'form.submitted': '1',
                 'user.login': u'dummy_edited',
                 'user.firstname': u'',
                 'user.lastname': u'',
                 'user.email': u'*****@*****.**',
                 'groups': [u'1']
             },
             matchdict={'user_id': self.account_id}))()
     self.assertIsRedirect(view)
     self.session.flush()
     user = User.by_id(self.session, self.account_id)
     self.assertEqual(user.login, u'dummy_edited')
     self.assertEqual([g.id for g in user.groups], [1])
Exemplo n.º 31
0
 def test_update_post_ok(self):
     from pyshop.models import User
     from pyshop.views.user import Edit
     view = Edit(self.create_request({'form.submitted': u'1',
                                      'user.login': u'root',
                                      'user.firstname': u'Admin',
                                      'user.lastname': u'Istrator',
                                      }))()
     self.assertIsRedirect(view)
     self.session.flush()
     admin = User.by_credentials(self.session, u'root', u'changeme')
     self.assertIsInstance(admin, User)
     self.assertEqual(admin.login, u'root')
     self.assertEqual(admin.firstname, u'Admin')
     self.assertEqual(admin.lastname, u'Istrator')
     admin.login = u'admin'
     admin.password = u'changeme'
     admin.firstname = None
     admin.lastname = None
     self.session.add(admin)
Exemplo n.º 32
0
 def test_update_post_ok(self):
     from pyshop.models import User
     from pyshop.views.user import Edit
     view = Edit(
         self.create_request({
             'form.submitted': u'1',
             'user.login': u'root',
             'user.firstname': u'Admin',
             'user.lastname': u'Istrator',
         }))()
     self.assertIsRedirect(view)
     self.session.flush()
     admin = User.by_credentials(self.session, u'root', u'changeme')
     self.assertIsInstance(admin, User)
     self.assertEqual(admin.login, u'root')
     self.assertEqual(admin.firstname, u'Admin')
     self.assertEqual(admin.lastname, u'Istrator')
     admin.login = u'admin'
     admin.password = u'changeme'
     admin.firstname = None
     admin.lastname = None
     self.session.add(admin)
Exemplo n.º 33
0
    def render(self):

        api = pypi.proxy
        settings = self.request.registry.settings
        sanitize = asbool(settings['pyshop.mirror.sanitize'])

        package_name = self.request.matchdict['package_name']
        pkg = Package.by_name(self.session, package_name)
        if pkg is None:
            pkg = Package.by_name(self.session, package_name.replace('-', '_'))
        if pkg is None:
            pkg = Package.by_name(self.session, package_name.replace('-', '.'))

        refresh = True
        session_users = {}

        if pkg:
            if pkg.local:
                refresh = False
            else:
                if pkg.update_at:
                    log.debug('validating cache interval')
                    current_td = datetime.now() - pkg.update_at
                    max_td = timedelta(
                        hours=int(settings.get('pyshop.mirror.cache.ttl',
                                               '24')))
                    refresh = current_td > max_td
                    log.debug('"%s" > "%s": %s',
                              current_td, max_td, refresh)

        if refresh:
            log.info('refresh package %s', package_name)
            pypi_versions = api.package_releases(package_name, True)
            # XXX package_releases is case sensitive
            # but dependencies declaration not...
            if not pypi_versions:
                pkg_info = self._search_package(package_name)
                if not pkg_info and '-' in package_name:
                    tmp_name = package_name.replace('-', '_')
                    pkg_info = self._search_package(tmp_name)

                if not pkg_info and '-' in package_name:
                    tmp_name = package_name.replace('-', '.')
                    pkg_info = self._search_package(tmp_name)

                if not pkg_info and '_' in package_name:
                    tmp_name = package_name.replace('_', '-')
                    pkg_info = self._search_package(tmp_name)

                if pkg_info:
                    package_name, pypi_versions = pkg_info
            pypi_versions = [ver.decode('utf-8') for ver in pypi_versions]
        else:
            pypi_versions = []

        if not pkg:
            if not pypi_versions:
                log.info('package %s has no versions', package_name)
                return {'package': None,
                        'package_name': package_name}

            if sanitize:
                re_sanitize = re.compile(settings['pyshop.mirror.'
                                                  'sanitize.regex'])
                pypi_versions = [v for v in pypi_versions
                                 if re_sanitize.match(v)]

            # mirror the package now
            log.info('mirror package %s now', package_name)
            pkg = Package.by_name(self.session, package_name)
            if not pkg:
                pkg = Package(name=package_name, local=False)
                self.session.add(pkg)
                self.session.flush()
            roles = api.package_roles(package_name)
            for role, login in roles:
                login = login.decode('utf-8')  # XMLRPC should return utf-8
                log.info('Looking for non local user %s', login)
                if _sanitize(login) in session_users:
                    user = session_users[_sanitize(login)]
                else:
                    user = User.by_login(self.session, login, local=False)
                if not user:
                    log.info('Not found. creating user {0}'.format(login))
                    user = User(login=login, local=False)
                    self.session.add(user)
                if role == 'Owner':
                    pkg.owners.append(user)
                    self.session.add(pkg)
                elif role == 'Maintainer':
                    pkg.maintainers.append(user)
                    self.session.add(pkg)
                session_users[_sanitize(login)] = user
                self.session.flush()

        self.session.flush()
        if not pkg.local and refresh:
            log.debug('refreshing %s package', package_name)
            pkg_versions = set(pypi_versions).difference(pkg.versions)
            if not pkg_versions:
                log.info('No new version to mirror')
                log.debug('pypi versions: %s', pypi_versions)
                log.debug('mirrored versions: %s', pkg.versions)
            for version in pkg_versions:
                log.info('Mirroring version %s', version)
                release_data = api.release_data(package_name, version)
                release = self._create_release(pkg, release_data,
                                               session_users)

                release_files = api.release_urls(package_name, version)

                for data in release_files:
                    filename = data['filename'].decode('utf-8')
                    rf = ReleaseFile.by_filename(self.session, release,
                                                 filename)
                    if not rf:
                        rf = self._create_release_file(release, data)

            pkg.update_at = func.now()
            self.session.add(pkg)
            log.info('package %s mirrored' % package_name)
        return {'package': pkg,
                'whlify': asbool(settings.get('pyshop.mirror.wheelify', '0'))}
Exemplo n.º 34
0
def setUpModule():

    engine = create_engine(settings)
    populate(engine, interactive=False)

    session = DBSession()
    admin_user = User.by_login(session, u'admin')
    local_user = User(login=u'local_user',
                      password=u'secret',
                      local=True,
                      firstname=u'Local',
                      lastname=u'User')
    local_user.groups.append(Group.by_name(session, u'developer'))
    jdo = User(login=u'johndo', local=False)
    jdoe = User(login=u'janedoe', local=False)

    session.add(jdo)
    session.add(jdoe)
    session.add(local_user)

    classifiers_names = [
        u'Programming Language :: Python',
        u'Programming Language :: Python :: 2.6',
        u'Programming Language :: Python :: 2.7',
        u'Topic :: Software Development',
        u'Topic :: System :: Archiving :: Mirroring',
        u'Topic :: System :: Archiving :: Packaging',
        u'Intended Audience :: Developers',
        u'Intended Audience :: System Administrators'
    ]
    classifiers = [
        Classifier.by_name(session, name=c, create_if_not_exists=True)
        for c in classifiers_names
    ]

    pack1 = Package(name=u'mirrored_package1')
    pack1.owners.append(jdo)
    pack1.owners.append(jdoe)
    pack1.downloads = 7
    session.add(pack1)

    release1 = Release(package=pack1,
                       version=u'0.1',
                       summary=u'Common Usage Library',
                       author=jdoe)
    for c in classifiers[:3]:
        release1.classifiers.append(c)
    session.add(release1)
    release1.files.append(
        ReleaseFile(filename=u'mirrored_package1-0.1.tar.gz',
                    package_type=u'sdist'))
    session.add(release1)

    release2 = Release(package=pack1,
                       version=u'0.2',
                       summary=u'Common Usage Library')
    for c in classifiers[:5]:
        release2.classifiers.append(c)
    release2.files.append(
        ReleaseFile(filename=u'mirrored_package1-0.2.tar.gz',
                    package_type=u'sdist'))
    release2.files.append(
        ReleaseFile(filename=u'mirrored_package1-0.2.egg',
                    package_type=u'bdist_egg'))
    session.add(release2)

    pack2 = Package(name=u'mirrored_package2')
    pack2.owners.append(jdo)
    pack2.maintainers.append(jdoe)
    pack2.downloads = 1
    session.add(pack2)

    release3 = Release(package=pack2,
                       version=u'1.0',
                       summary=u'Web Framework For Everybody')
    for c in classifiers[:3] + classifiers[-2:-2]:
        release3.classifiers.append(c)
    session.add(release3)
    release3.files.append(
        ReleaseFile(filename=u'mirrored_package2-1.0.tar.gz',
                    package_type=u'sdist'))
    session.add(release3)

    pack3 = Package(name=u'local_package1', local=True)
    pack3.owners.append(local_user)
    pack3.owners.append(admin_user)
    session.add(pack3)

    release4 = Release(package=pack3,
                       version=u'0.1',
                       summary=u'Pet Shop Application')
    for c in classifiers:
        release4.classifiers.append(c)
    release4.files.append(
        ReleaseFile(filename=u'local_package1-0.1.tar.gz',
                    package_type=u'sdist'))
    session.add(release4)

    session.commit()
Exemplo n.º 35
0
 def test_by_credentials_ok(self):
     from pyshop.models import User
     user = User.by_credentials(self.session, u'local_user', 'secret')
     self.assertIsInstance(user, User)
     self.assertEqual(user.login, u'local_user')
     self.assertEqual(user.name, u'Local User')
Exemplo n.º 36
0
 def tearDown(self):
     from pyshop.models import User
     for id in self.account_todelete:
         u = User.by_id(self.session, id)
         self.session.delete(u)
     super(AccountTestCase, self).tearDown()
Exemplo n.º 37
0
 def test_by_login_ok_local(self):
     from pyshop.models import User
     user = User.by_login(self.session, u'local_user')
     self.assertIsInstance(user, User)
Exemplo n.º 38
0
 def test_by_credentials_ko_mirrored(self):
     from pyshop.models import User
     user = User.by_credentials(self.session, u'johndo', '')
     self.assertEqual(user, None)
Exemplo n.º 39
0
 def test_by_login_ok_mirrored(self):
     from pyshop.models import User
     user = User.by_login(self.session, u'johndo', local=False)
     self.assertIsInstance(user, User)
     self.assertEqual(user.login, u'johndo')
Exemplo n.º 40
0
 def test_by_login_ko_mirrored(self):
     from pyshop.models import User
     user = User.by_login(self.session, u'johndo')
     self.assertEqual(user, None)
Exemplo n.º 41
0
    def render(self):

        return {u'user_count': User.get_locals(self.session, count=True),
                u'users': User.get_locals(self.session),
                }
Exemplo n.º 42
0
    def render(self):

        package = Package.by_name(self.session,
                                  self.request.matchdict['package_name'])
        if not package:
            raise HTTPNotFound()

        if 'form.refresh_package' in self.request.params:
            package.update_at = None
            self.session.add(package)

        owners = dict((usr.login, usr) for usr in package.owners)
        can_edit_role = self.login in owners.keys() and package.local

        if 'form.add_role' in self.request.params:

            if not can_edit_role:
                raise HTTPForbidden()

            user = User.by_login(self.session, self.request.params['login'])
            if user and user.has_permission('upload_releasefile'):
                if self.request.params['role'] == 'owner':
                    if user.login not in owners:
                        package.owners.append(user)
                else:
                    maintainers = [usr.login for usr in package.owners]
                    if user.login not in maintainers:
                        package.maintainers.append(user)
                self.session.add(package)

        if 'form.remove_maintainer' in self.request.params:
            if not can_edit_role:
                raise HTTPForbidden()

            user = User.by_login(self.session, self.request.params['login'])
            if user:
                maintainers = dict((usr.login, usr)
                                   for usr in package.maintainers)
                if user.login in maintainers:
                    package.maintainers.remove(maintainers[user.login])
                    self.session.add(package)

        if 'form.remove_owner' in self.request.params:
            if not can_edit_role:
                raise HTTPForbidden()

            user = User.by_login(self.session, self.request.params['login'])
            if user:
                if user.login in owners:
                    package.owners.remove(owners[user.login])
                    self.session.add(package)

        if 'release_version' in self.request.matchdict:
            release = Release.by_version(self.session, package.name,
                self.request.matchdict['release_version'])
        else:
            release = package.sorted_releases[0]

        return {u'package': package,
                u'release': release,
                u'can_edit_role': can_edit_role,
                }
Exemplo n.º 43
0
    def render(self):
        settings = self.request.registry.settings
        username = authenticated_userid(self.request)
        if not username:
             raise exc.HTTPForbidden()

        remote_user = User.by_login(self.session, username)
        if not remote_user:
            raise exc.HTTPForbidden()


        params = self.request.params

        if (asbool(settings['pyshop.upload.satanize'])
            and not re.match(settings['pyshop.upload.satanize.regex'],
                            params['version']
                            )):
            raise exc.HTTPForbidden()

        pkg = Package.by_name(self.session, params['name'])
        if pkg:
            auth = [user for user in pkg.owners + pkg.maintainers
                    if user == remote_user]
            if not auth:
                raise exc.HTTPForbidden()
        else:
            pkg = Package(name=params['name'], local=True)
            pkg.owners.append(remote_user)

        content = self.request.POST['content']
        input_file = content.file
        # rewrite the filename, do not use the posted one for security
        filename = u'%s-%s.%s' % (params['name'], params['version'],
                                  {u'sdist': u'tar.gz',
                                   u'bdist_egg': u'egg',
                                   u'bdist_msi': u'msi',
                                   u'bdist_dmg': u'zip', # XXX or gztar ?
                                   u'bdist_rpm': u'rpm',
                                   u'bdist_dumb': u'msi',
                                   u'bdist_wininst': u'exe',
                                   }[params['filetype']])
        dir_ = os.path.join(settings['pyshop.repository'],
                            filename[0].lower())

        if not os.path.exists(dir_):
            os.mkdir(dir_, 0750)

        filepath = os.path.join(dir_, filename)
        while os.path.exists(filepath):
            log.warn('File %s exists but new upload self.request, deleting'
                     % filepath)
            os.unlink(filepath)

        size = 0
        with open(filepath, 'wb') as output_file:
            input_file.seek(0)
            while True:
                data = input_file.read(2<<16)
                if not data:
                    break
                size += len(data)
                output_file.write(data)


        release = Release.by_version(self.session, pkg.name,
                                     params['version'])
        if not release:
            release = Release(package=pkg,
                              version=params['version'],
                              summary=params.get('summary'),
                              author=remote_user,
                              home_page=params.get('home_page'),
                              license=params.get('license'),
                              description=params.get('description'),
                              keywords=params.get('keywords'),
                              platform=params.get('platform'),
                              download_url=params.get('download_url'),
                              docs_url=params.get('docs_url'),
                              )

        classifiers = params.getall('classifiers')
        for name in classifiers:
            classifier = Classifier.by_name(self.session, name)
            while classifier:
                if classifier not in release.classifiers:
                    release.classifiers.append(classifier)
                if classifier not in pkg.classifiers:
                    pkg.classifiers.append(classifier)
                classifier = classifier.parent

        rfile = ReleaseFile.by_filename(self.session, release, filename)
        if not rfile:
            rfile = ReleaseFile(release=release,
                                filename=filename,
                                size=size,
                                md5_digest=params.get('md5_digest'),
                                package_type=params['filetype'],
                                python_version=params.get('pyversion'),
                                comment_text=params.get('comment'),
                                )

        self.session.add(rfile)
        self.session.add(release)
        pkg.update_at = func.now()
        self.session.add(pkg)
        return {'release_file': rfile}
Exemplo n.º 44
0
    def render(self):


        api = pypi.proxy
        settings = self.request.registry.settings
        satanize = asbool(settings['pyshop.mirror.satanize'])

        package_name = self.request.matchdict['package_name']
        pkg = Package.by_name(self.session, package_name)
        refresh = True

        if pkg:
            if pkg.local:
                refresh = False
            else:
                if pkg.update_at:
                    td = datetime.now() - pkg.update_at
                    refresh = td.days > 0 or td.seconds > 10800

        if refresh:
            pypi_versions = api.package_releases(package_name, True)
            # XXX package_releases is case sensitive
            # but dependancies declaration not...
            if not pypi_versions:
                package_name = package_name.lower()
                search_result = api.search({'name': package_name}, True)
                search_result = [p for p in search_result
                                 if p['name'].lower() == package_name]
                if search_result:
                    package_name = search_result[0]['name']
                    pypi_versions = api.package_releases(package_name, True)
        else:
            pypi_versions = []

        if not pkg:
            if not pypi_versions:
                log.info('package %s has no versions' % package_name)
                return {'package': None,
                        'package_name': package_name}

            if satanize:
                re_satanize = re.compile(settings['pyshop.mirror.'
                                                  'satanize.regex'])
                pypi_versions = [v for v in pypi_versions
                                 if re_satanize.match(v)]

            # mirror the package now
            log.info('mirror package %s now' % package_name)
            pkg = Package(name=package_name, local=False)
            roles = api.package_roles(package_name)
            for role, login in roles:
                user = User.by_login(self.session, login, local=False)
                if not user:
                    user = User(login=login, local=False)
                    self.session.add(user)
                if role == 'Owner':
                    pkg.owners.append(user)
                elif role == 'Maintainer':
                    pkg.maintainers.append(user)

        self.session.flush()

        refresh = True
        if not pkg.local and refresh:
            pkg_versions = pkg.versions
            for version in pypi_versions:
                if version not in pkg_versions:
                    release_data = api.release_data(package_name, version)
                    release = self._create_release(pkg, release_data)

                    release_files = api.release_urls(package_name, version)

                    for data in release_files:
                        rf = ReleaseFile.by_filename(self.session, release,
                                                     data['filename'])
                        if not rf:
                            rf = self._create_release_file(release, data)

        pkg.update_at = func.now()
        self.session.add(pkg)
        log.info('package %s mirrored' % package_name)
        return {'package': pkg}
Exemplo n.º 45
0
    def render(self):

        api = pypi.proxy
        settings = self.request.registry.settings
        sanitize = asbool(settings['pyshop.mirror.sanitize'])

        package_name = self.request.matchdict['package_name']
        pkg = Package.by_name(self.session, package_name)
        refresh = True

        if pkg:
            if pkg.local:
                refresh = False
            else:
                if pkg.update_at:
                    current_td = datetime.now() - pkg.update_at
                    max_td = timedelta(hours=int(
                        settings.get('pyshop.mirror.cache.ttl', '24')))
                    refresh = current_td > max_td
                    log.debug('"{cdt}" > "{max}": {refr}'.format(
                        cdt=current_td, max=max_td, refr=refresh))

        if refresh:
            log.info('refresh package {pkg}'.format(pkg=package_name))
            pypi_versions = api.package_releases(package_name, True)
            # XXX package_releases is case sensitive
            # but dependancies declaration not...
            if not pypi_versions:
                pkg_info = self._search_package(package_name)
                if not pkg_info and '-' in package_name:
                    tmp_name = package_name.replace('-', '_')
                    pkg_info = self._search_package(tmp_name)

                if not pkg_info and '_' in package_name:
                    tmp_name = package_name.replace('_', '-')
                    pkg_info = self._search_package(tmp_name)

                if pkg_info:
                    package_name, pypi_versions = pkg_info
        else:
            pypi_versions = []

        if not pkg:
            if not pypi_versions:
                log.info('package %s has no versions' % package_name)
                return {'package': None, 'package_name': package_name}

            if sanitize:
                re_sanitize = re.compile(settings['pyshop.mirror.'
                                                  'sanitize.regex'])
                pypi_versions = [
                    v for v in pypi_versions if re_sanitize.match(v)
                ]

            # mirror the package now
            log.info('mirror package %s now' % package_name)
            pkg = Package.by_name(self.session, package_name)
            if not pkg:
                pkg = Package(name=package_name, local=False)
                self.session.add(pkg)
                self.session.flush()
            roles = api.package_roles(package_name)
            for role, login in roles:
                login = login.decode('utf-8')  # XMLRPC should return utf-8
                user = User.by_login(self.session, login, local=False)
                if not user:
                    user = User(login=login, local=False)
                    self.session.add(user)
                if role == 'Owner':
                    pkg.owners.append(user)
                elif role == 'Maintainer':
                    pkg.maintainers.append(user)

        self.session.flush()

        refresh = True
        if not pkg.local and refresh:
            pkg_versions = pkg.versions
            for version in pypi_versions:
                if version not in pkg_versions:
                    release_data = api.release_data(package_name, version)
                    release = self._create_release(pkg, release_data)

                    release_files = api.release_urls(package_name, version)

                    for data in release_files:
                        filename = data['filename'].decode('utf-8')
                        rf = ReleaseFile.by_filename(self.session, release,
                                                     filename)
                        if not rf:
                            rf = self._create_release_file(release, data)

        pkg.update_at = func.now()
        self.session.add(pkg)
        log.info('package %s mirrored' % package_name)
        return {
            'package': pkg,
            'whlify': asbool(settings.get('pyshop.mirror.wheelify', '0'))
        }
Exemplo n.º 46
0
 def test_by_login_ok_mirrored(self):
     from pyshop.models import User
     user = User.by_login(self.session, u'johndo', local=False)
     self.assertIsInstance(user, User)
     self.assertEqual(user.login, u'johndo')
Exemplo n.º 47
0
 def test_by_login_ok_local(self):
     from pyshop.models import User
     user = User.by_login(self.session, u'local_user')
     self.assertIsInstance(user, User)
Exemplo n.º 48
0
 def test_by_login_ko_mirrored(self):
     from pyshop.models import User
     user = User.by_login(self.session, u'johndo')
     self.assertEqual(user, None)
Exemplo n.º 49
0
 def test_by_credentials_ko_unexists(self):
     from pyshop.models import User
     user = User.by_credentials(self.session, u'u404', u"' OR 1 = 1 #")
     self.assertEqual(user, None)
Exemplo n.º 50
0
 def test_by_credentials_ko_unexists(self):
     from pyshop.models import User
     user = User.by_credentials(self.session, u'u404', u"' OR 1 = 1 #")
     self.assertEqual(user, None)
Exemplo n.º 51
0
 def test_by_credentials_ko_mirrored(self):
     from pyshop.models import User
     user = User.by_credentials(self.session, u'johndo', '')
     self.assertEqual(user, None)
Exemplo n.º 52
0
 def test_by_credentials_ko_password(self):
     from pyshop.models import User
     user = User.by_credentials(self.session, u'admin', 'CHANGEME')
     self.assertIsNone(user)
Exemplo n.º 53
0
 def test_by_credentials_ko_password(self):
     from pyshop.models import User
     user = User.by_credentials(self.session, u'admin', 'CHANGEME')
     self.assertIsNone(user)
Exemplo n.º 54
0
 def test_hash_password(self):
     from pyshop.models import User
     u = User(login=u'test_password', password=u'secret')
     self.assertNotEqual(u.password, u'secret', 'password must be hashed')
Exemplo n.º 55
0
 def test_by_credentials_ok(self):
     from pyshop.models import User
     user = User.by_credentials(self.session, u'local_user', 'secret')
     self.assertIsInstance(user, User)
     self.assertEqual(user.login, u'local_user')
     self.assertEqual(user.name, u'Local User')
Exemplo n.º 56
0
 def tearDown(self):
     from pyshop.models import User
     for id in self.account_todelete:
         u = User.by_id(self.session, id)
         self.session.delete(u)
     super(AccountTestCase, self).tearDown()
Exemplo n.º 57
0
    def _create_release(self, package, data, session_users):
        log.info('Create release %s for package %s',
                 data.get('version'), package.name)
        data = self._to_unicode(data)
        release = Release(package=package,
                          summary=data.get('summary'),
                          version=data.get('version'),
                          stable_version=data.get('stable_version'),
                          home_page=data.get('home_page'),
                          license=data.get('license'),
                          description=data.get('description'),
                          keywords=data.get('keywords'),
                          platform=data.get('platform'),
                          download_url=data.get('download_url'),
                          bugtrack_url=data.get('bugtrack_url'),
                          docs_url=data.get('docs_url'),
                          )
        if data.get('author'):

            log.info('Looking for author %s', data['author'])
            if _sanitize(data['author']) in session_users:
                author = session_users[_sanitize(data['author'])]
            else:
                author = User.by_login(self.session, data['author'],
                                       local=False)
            if not author:
                log.info('Author %s not found, creating',
                         data['author'])
                author = User(login=data['author'],
                              local=False,
                              email=data.get('author_email'))
                self.session.add(author)
                session_users[_sanitize(data['author'])] = author
            release.author = author
            self.session.flush()

        if data.get('maintainer'):
            log.info('Looking for maintainer {0}'.format(data['maintainer']))
            if _sanitize(data['maintainer']) in session_users:
                maintainer = session_users[_sanitize(data['maintainer'])]
            else:
                maintainer = User.by_login(self.session, data['maintainer'],
                                           local=False)
            if not maintainer:
                log.info('Maintainer not found, creating user {0}'
                         ''.format(data['maintainer']))
                maintainer = User(login=data['maintainer'],
                                  local=False,
                                  email=data.get('maintainer_email'))
                self.session.add(maintainer)
                session_users[_sanitize(data['maintainer'])] = maintainer
            release.maintainer = maintainer
            self.session.flush()

        for name in data.get('classifiers', []):
            classifier = Classifier.by_name(self.session, name.decode('utf-8'),
                                            create_if_not_exists=True)

            while classifier:
                if classifier not in release.classifiers:
                    release.classifiers.append(classifier)
                if classifier not in package.classifiers:
                    package.classifiers.append(classifier)
                classifier = classifier.parent

        self.session.flush()
        return release
Exemplo n.º 58
0
def authbasic(request):
    """
    Authentification basic, Upload pyshop repository access
    """
    if len(request.environ.get('HTTP_AUTHORIZATION', '')) > 0:
        transaction.manager
        auth = request.environ.get('HTTP_AUTHORIZATION')
        scheme, data = auth.split(None, 1)
        assert scheme.lower() == 'basic'
        data = base64.b64decode(data)
        if not isinstance(data, unicode):
            data = data.decode('utf-8')
        username, password = data.split(':', 1)
        # if User.by_ldap_credentials(
        #         DBSession(), username, password, request.registry.settings):
        #     return HTTPFound(location=request.url)
        # if User.by_credentials(DBSession(), username, password):
        #     return HTTPFound(location=request.url)

        # if user:
        #     return HTTPFound(location=request.url)
        user = None
        session = DBSession()
        if request.registry.settings["pyshop.ldap.use_for_auth"]:
            user = User.by_ldap_credentials(session, username, password,
                                            request.registry.settings)
            if user:
                user = User.by_login(session, username)
            else:
                user = User.by_login(session, username)
                if user:
                    session.delete(user)
                    user = None
        else:
            user = User.by_credentials(session, username, password)

        # if user:
        #     return HTTPFound(location=request.url)

        if user:
            group_names = []
            for group in user.groups:
                group_names.append(group.name)

            transaction.commit()

            if request.matched_route:
                print("*" * 200)
                print(request.matched_route.name)
                if request.matched_route.name in ["upload_releasefile"]:
                    if not "developer" in group_names:
                        return Response(
                            status=401,
                            headerlist=[
                                (b'WWW-Authenticate',
                                 b'Basic realm="pyshop repository access"')
                            ],
                        )

                return HTTPFound(location=request.url)

            else:
                return Response(
                    status=402,
                    headerlist=[(b'WWW-Authenticate',
                                 b'Basic realm="pyshop repository access"')],
                )

    return Response(
        status=401,
        headerlist=[(b'WWW-Authenticate',
                     b'Basic realm="pyshop repository access"')],
    )
Exemplo n.º 59
0
    def render(self):

        api = pypi.proxy
        settings = self.request.registry.settings
        sanitize = asbool(settings['pyshop.mirror.sanitize'])

        package_name = self.request.matchdict['package_name']
        pkg = Package.by_name(self.session, package_name)
        refresh = True

        if pkg:
            if pkg.local:
                refresh = False
            else:
                if pkg.update_at:
                    td = datetime.now() - pkg.update_at
                    # refresh if the package has not been update today
                    # XXX should be configurable
                    refresh = td.days > 0

        if refresh:
            pypi_versions = api.package_releases(package_name, True)
            # XXX package_releases is case sensitive
            # but dependancies declaration not...
            if not pypi_versions:
                search_result = api.search({'name': package_name}, True)
                search_count = len(search_result)
                search_result = [p for p in search_result
                                 if p['name'].lower() == package_name
                                 or p['name'].lower().replace('-', '_') == package_name]
                log.debug('Found {sc}, matched {mc}'.format(sc=search_count, mc=len(search_result)))

                if search_result:
                    package_name = search_result[0]['name']
                    pypi_versions = api.package_releases(package_name, True)
        else:
            pypi_versions = []

        if not pkg:
            if not pypi_versions:
                log.info('package %s has no versions' % package_name)
                return {'package': None,
                        'package_name': package_name}

            if sanitize:
                re_sanitize = re.compile(settings['pyshop.mirror.'
                                                  'sanitize.regex'])
                pypi_versions = [v for v in pypi_versions
                                 if re_sanitize.match(v)]

            # mirror the package now
            log.info('mirror package %s now' % package_name)
            pkg = Package(name=package_name, local=False)
            roles = api.package_roles(package_name)
            for role, login in roles:
                login = login.decode('utf-8')  # XMLRPC should return utf-8
                user = User.by_login(self.session, login, local=False)
                if not user:
                    user = User(login=login, local=False)
                    self.session.add(user)
                if role == 'Owner':
                    pkg.owners.append(user)
                elif role == 'Maintainer':
                    pkg.maintainers.append(user)

        self.session.flush()

        refresh = True
        if not pkg.local and refresh:
            pkg_versions = pkg.versions
            for version in pypi_versions:
                if version not in pkg_versions:
                    release_data = api.release_data(package_name, version)
                    release = self._create_release(pkg, release_data)

                    release_files = api.release_urls(package_name, version)

                    for data in release_files:
                        filename = data['filename'].decode('utf-8')
                        rf = ReleaseFile.by_filename(self.session, release,
                                                     filename)
                        if not rf:
                            rf = self._create_release_file(release, data)

        pkg.update_at = func.now()
        self.session.add(pkg)
        log.info('package %s mirrored' % package_name)
        return {'package': pkg}