def get_user(request): id = request.matchdict.get('name') user = User.get(id, request.db) if not user: request.errors.add('body', 'name', 'No such user') request.errors.status = HTTPNotFound.code return user = user.__json__(request) # Throw some extra information in there rurl = request.route_url # Just shorthand urls = { 'comments_by': rurl('comments') + '?user=%s' % id, 'comments_on': rurl('comments') + '?update_owner=%s' % id, 'recent_updates': rurl('updates') + '?user=%s' % id, 'recent_overrides': rurl('overrides') + '?user=%s' % id, 'comments_by_rss': rurl('comments_rss') + '?user=%s' % id, 'comments_on_rss': rurl('comments_rss') + '?update_owner=%s' % id, 'recent_updates_rss': rurl('updates_rss') + '?user=%s' % id, 'recent_overrides_rss': rurl('overrides_rss') + '?user=%s' % id, } return dict(user=user, urls=urls)
def test_remember_me_with_bad_endpoint(self): """Test the post-login hook with a bad openid endpoint""" req = DummyRequest(params={ 'openid.op_endpoint': 'bad_endpoint', }) req.db = self.db def flash(msg): pass req.session.flash = flash info = { 'identity_url': 'http://lmacken.id.fedoraproject.org', 'groups': [u'releng'], } req.registry.settings = self.app_settings try: resp = remember_me(None, req, info) assert False, 'remember_me should have thrown an exception' except Exception: # A ComponentLookupError is thrown because we're doing this outside # of the webapp pass # The user should not exist self.assertIsNone(User.get(u'lmacken', self.db))
def test_list_comments_by_update_owner_with_none(self): user = User(name=u'ralph') self.db.add(user) self.db.flush() res = self.app.get('/comments/', {"update_owner": "ralph"}) body = res.json_body self.assertEquals(len(body['comments']), 0) self.assertNotIn('errors', body)
def test_list_overrides_by_username_without_override(self): self.db.add(User(name=u'bochecha')) self.db.flush() res = self.app.get('/overrides/', {'user': '******'}) body = res.json_body self.assertEquals(len(body['overrides']), 0)
def test_remember_me(self): """Test the post-login hook""" req = DummyRequest( params={ 'openid.op_endpoint': self.app_settings['openid.provider'], }) req.db = self.db req.session = {'came_from': '/'} info = { 'identity_url': 'http://lmacken.id.fedoraproject.org', 'groups': [u'releng'], 'sreg': { 'email': u'[email protected]' }, } req.registry.settings = self.app_settings # Ensure the user doesn't exist yet self.assertIsNone(User.get(u'lmacken', self.db)) self.assertIsNone(Group.get(u'releng', self.db)) resp = remember_me(None, req, info) # The user should now exist, and be a member of the releng group user = User.get(u'lmacken', self.db) self.assertEquals(user.name, u'lmacken') self.assertEquals(user.email, u'[email protected]') self.assertEquals(len(user.groups), 1) self.assertEquals(user.groups[0].name, u'releng') # Pretend the user has been removed from the releng group info['groups'] = [] req.session = {'came_from': '/'} resp = remember_me(None, req, info) user = User.get(u'lmacken', self.db) self.assertEquals(len(user.groups), 0) self.assertEquals(len(Group.get(u'releng', self.db).users), 0)
def test_remember_me(self): """Test the post-login hook""" db = DBSession() req = DummyRequest(params={ 'openid.op_endpoint': self.app_settings['openid.provider'], }) req.db = db req.session = {'came_from': '/'} info = { 'identity_url': 'http://lmacken.id.fedoraproject.org', 'groups': [u'releng'], 'sreg': {'email': u'[email protected]'}, } req.registry.settings = self.app_settings # Ensure the user doesn't exist yet self.assertIsNone(User.get(u'lmacken', db)) self.assertIsNone(Group.get(u'releng', db)) resp = remember_me(None, req, info) # The user should now exist, and be a member of the releng group user = User.get(u'lmacken', db) self.assertEquals(user.name, u'lmacken') self.assertEquals(user.email, u'[email protected]') self.assertEquals(len(user.groups), 1) self.assertEquals(user.groups[0].name, u'releng') # Pretend the user has been removed from the releng group info['groups'] = [] req.session = {'came_from': '/'} resp = remember_me(None, req, info) user = User.get(u'lmacken', db) self.assertEquals(len(user.groups), 0) self.assertEquals(len(Group.get(u'releng', db).users), 0)
def test_edit_stack_with_no_user_privs(self, *args): user = User(name=u'bob') self.db.add(user) self.db.flush() self.stack.users.append(user) self.db.flush() attrs = { 'name': 'GNOME', 'packages': 'gnome-music gnome-shell', 'csrf_token': self.get_csrf_token() } res = self.app.post("/stacks/", attrs, status=403) body = res.json_body self.assertEquals(body['status'], 'error') self.assertEquals( body['errors'][0]['description'], 'guest does not have privileges to modify the GNOME stack')
def setUp(self, *args, **kwargs): super(TestCommentsService, self).setUp(*args, **kwargs) # Add a second update owned by somebody else so we can test karma # policy stuff user2 = User(name=u'lmacken') self.db.flush() self.db.add(user2) release = self.db.query(Release).filter_by(name=u'F17').one() update = Update( title=someone_elses_update, #builds=[build], user=user2, request=UpdateRequest.testing, type=UpdateType.enhancement, notes=u'Useful details!', release=release, date_submitted=datetime(1984, 11, 02), requirements=u'rpmlint', stable_karma=3, unstable_karma=-3, ) self.db.add(update) self.db.flush()
def save_override(request): """Save a buildroot override This entails either creating a new buildroot override, or editing an existing one. To edit an existing buildroot override, the buildroot override's original id needs to be specified in the ``edited`` parameter. """ data = request.validated edited = data.pop("edited") caveats = [] try: submitter = User.get(request.user.name, request.db) if edited is None: builds = data['builds'] overrides = [] if len(builds) > 1: caveats.append({ 'name': 'nvrs', 'description': 'Your override submission was ' 'split into %i.' % len(builds) }) for build in builds: log.info("Creating a new buildroot override: %s" % build.nvr) if BuildrootOverride.get(build.id, request.db): request.errors.add( 'body', 'builds', 'Buildroot override for %s already exists' % build.nvr) return else: overrides.append( BuildrootOverride.new( request, build=build, submitter=submitter, notes=data['notes'], expiration_date=data['expiration_date'], )) if len(builds) > 1: result = dict(overrides=overrides) else: result = overrides[0] else: log.info("Editing buildroot override: %s" % edited) edited = Build.get(edited, request.db) if edited is None: request.errors.add('body', 'edited', 'No such build') return result = BuildrootOverride.edit( request, edited=edited, submitter=submitter, notes=data["notes"], expired=data["expired"], expiration_date=data["expiration_date"]) if not result: # Some error inside .edit(...) return except Exception as e: log.exception(e) request.errors.add('body', 'override', 'Unable to save buildroot override: %s' % e) return if not isinstance(result, dict): result = result.__json__() result['caveats'] = caveats return result
def groupfinder(userid, request): from bodhi.models import User if request.user: user = User.get(request.user.name, request.db) return ['group:' + group.name for group in user.groups]
def setUp(self): super(TestUsersService, self).setUp() user = User(name=u'bodhi') self.db.add(user) self.db.flush()
def save_override(request): """Save a buildroot override This entails either creating a new buildroot override, or editing an existing one. To edit an existing buildroot override, the buildroot override's original id needs to be specified in the ``edited`` parameter. """ data = request.validated edited = data.pop("edited") caveats = [] try: submitter = User.get(request.user.name, request.db) if edited is None: builds = data['builds'] overrides = [] if len(builds) > 1: caveats.append({ 'name': 'nvrs', 'description': 'Your override submission was ' 'split into %i.' % len(builds) }) for build in builds: log.info("Creating a new buildroot override: %s" % build.nvr) if BuildrootOverride.get(build.id, request.db): request.errors.add('body', 'builds', 'Buildroot override for %s already exists' % build.nvr) return else: overrides.append(BuildrootOverride.new( request, build=build, submitter=submitter, notes=data['notes'], expiration_date=data['expiration_date'], )) if len(builds) > 1: result = dict(overrides=overrides) else: result = overrides[0] else: log.info("Editing buildroot override: %s" % edited) edited = Build.get(edited, request.db) if edited is None: request.errors.add('body', 'edited', 'No such build') return result = BuildrootOverride.edit( request, edited=edited, submitter=submitter, notes=data["notes"], expired=data["expired"], expiration_date=data["expiration_date"] ) if not result: # Some error inside .edit(...) return except Exception as e: log.exception(e) request.errors.add('body', 'override', 'Unable to save buildroot override: %s' % e) return if not isinstance(result, dict): result = result.__json__() result['caveats'] = caveats return result
def populate(db): user = User(name=u'guest') db.add(user) anonymous = User(name=u'anonymous') db.add(anonymous) provenpackager = Group(name=u'provenpackager') db.add(provenpackager) packager = Group(name=u'packager') db.add(packager) db.flush() user.groups.append(packager) release = Release(name=u'F17', long_name=u'Fedora 17', id_prefix=u'FEDORA', version=u'17', dist_tag=u'f17', stable_tag=u'f17-updates', testing_tag=u'f17-updates-testing', candidate_tag=u'f17-updates-candidate', pending_testing_tag=u'f17-updates-testing-pending', pending_stable_tag=u'f17-updates-pending', override_tag=u'f17-override', branch=u'f17') db.add(release) pkg = Package(name=u'bodhi') db.add(pkg) user.packages.append(pkg) build = Build(nvr=u'bodhi-2.0-1.fc17', release=release, package=pkg) db.add(build) testcase = TestCase(name=u'Wat') db.add(testcase) pkg.test_cases.append(testcase) update = Update( title=u'bodhi-2.0-1.fc17', builds=[build], user=user, request=UpdateRequest.testing, notes=u'Useful details!', release=release, date_submitted=datetime(1984, 11, 02), requirements=u'rpmlint', stable_karma=3, unstable_karma=-3, ) update.type = UpdateType.bugfix bug = Bug(bug_id=12345) db.add(bug) update.bugs.append(bug) cve = CVE(cve_id=u"CVE-1985-0110") db.add(cve) update.cves.append(cve) comment = Comment(karma=1, text=u"wow. amaze.") db.add(comment) comment.user = user update.comments.append(comment) update.karma = 1 comment = Comment(karma=0, text=u"srsly. pretty good.", anonymous=True) comment.user = anonymous db.add(comment) update.comments.append(comment) with mock.patch(target='uuid.uuid4', return_value='wat'): update.assign_alias() db.add(update) expiration_date = datetime.utcnow() expiration_date = expiration_date + timedelta(days=1) override = BuildrootOverride(build=build, submitter=user, notes=u'blah blah blah', expiration_date=expiration_date) db.add(override) db.flush()
def load_sqlalchemy_db(): print "\nLoading pickled database %s" % sys.argv[2] db = file(sys.argv[2], 'r') data = pickle.load(db) import transaction from bodhi.models import Base from bodhi.models import Release, Update, Build, Comment, User, Bug, CVE from bodhi.models import Package, Group from bodhi.models import UpdateType, UpdateStatus, UpdateRequest from sqlalchemy import create_engine from sqlalchemy.orm.exc import NoResultFound # Caches for quick lookup releases = {} packages = {} users = {} critpath = {} aliases = [] engine = bodhi.config['sqlalchemy.url'] Session = scoped_session( sessionmaker(extension=ZopeTransactionExtension())) Session.configure(bind=engine) db = Session() # Allow filtering of releases to load whitelist = [] if '--release' in sys.argv: for r in sys.argv[sys.argv.index('--release') + 1].split(','): whitelist.append(r) print('whitelist = %r' % whitelist) # Legacy format was just a list of update dictionaries # Now we'll pull things out into an organized dictionary: # {'updates': [], 'releases': []} if isinstance(data, dict): for release in data['releases']: try: db.query(Release).filter_by(name=release['name']).one() except NoResultFound: del (release['metrics']) del (release['locked']) r = Release(**release) r.stable_tag = "%s-updates" % r.dist_tag r.testing_tag = "%s-testing" % r.stable_tag r.candidate_tag = "%s-candidate" % r.stable_tag r.pending_testing_tag = "%s-pending" % r.testing_tag r.pending_stable_tag = "%s-pending" % r.stable_tag r.override_tag = "%s-override" % r.dist_tag db.add(r) data = data['updates'] progress = ProgressBar(widgets=[SimpleProgress(), Percentage(), Bar()]) for u in progress(data): try: release = releases[u['release'][0]] except KeyError: try: release = db.query(Release).filter_by( name=u['release'][0]).one() except NoResultFound: release = Release(name=u['release'][0], long_name=u['release'][1], id_prefix=u['release'][2], dist_tag=u['release'][3]) db.add(release) releases[u['release'][0]] = release if whitelist: if release.name in whitelist: critpath[release.name] = get_critpath_pkgs( release.name.lower()) print('%s critpath packages for %s' % (len(critpath[release.name]), release.name)) else: critpath[release.name] = get_critpath_pkgs( release.name.lower()) print('%s critpath packages for %s' % (len(critpath[release.name]), release.name)) if whitelist and release.name not in whitelist: continue ## Backwards compatbility request = u['request'] if u['request'] == 'move': u['request'] = 'stable' elif u['request'] == 'push': u['request'] = 'testing' elif u['request'] == 'unpush': u['request'] = 'obsolete' if u['approved'] not in (True, False): u['approved'] = None if u.has_key('update_id'): u['updateid'] = u['update_id'] u['alias'] = u['update_id'] if u['alias']: split = u['alias'].split('-') year, id = split[-2:] aliases.append((int(year), int(id))) if not u.has_key('date_modified'): u['date_modified'] = None # Port to new enum types if u['request']: if u['request'] == 'stable': u['request'] = UpdateRequest.stable elif u['request'] == 'testing': u['request'] = UpdateRequest.testing else: raise Exception("Unknown request: %s" % u['request']) if u['type'] == 'bugfix': u['type'] = UpdateType.bugfix elif u['type'] == 'newpackage': u['type'] = UpdateType.newpackage elif u['type'] == 'enhancement': u['type'] = UpdateType.enhancement elif u['type'] == 'security': u['type'] = UpdateType.security else: raise Exception("Unknown type: %r" % u['type']) if u['status'] == 'pending': u['status'] = UpdateStatus.pending elif u['status'] == 'testing': u['status'] = UpdateStatus.testing elif u['status'] == 'obsolete': u['status'] = UpdateStatus.obsolete elif u['status'] == 'stable': u['status'] = UpdateStatus.stable elif u['status'] == 'unpushed': u['status'] = UpdateStatus.unpushed else: raise Exception("Unknown status: %r" % u['status']) try: update = db.query(Update).filter_by(title=u['title']).one() continue except NoResultFound: update = Update( title=u['title'], date_submitted=u['date_submitted'], date_pushed=u['date_pushed'], date_modified=u['date_modified'], release=release, old_updateid=u['updateid'], alias=u['updateid'], pushed=u['pushed'], notes=u['notes'], karma=u['karma'], type=u['type'], status=u['status'], request=u['request'], ) #approved=u['approved']) db.add(update) db.flush() try: user = users[u['submitter']] except KeyError: try: user = db.query(User).filter_by(name=u['submitter']).one() except NoResultFound: user = User(name=u['submitter']) db.add(user) db.flush() users[u['submitter']] = user user.updates.append(update) ## Create Package and Build objects for pkg, nvr in u['builds']: try: package = packages[pkg] except KeyError: try: package = db.query(Package).filter_by(name=pkg).one() except NoResultFound: package = Package(name=pkg) db.add(package) packages[pkg] = package if package.name in critpath[update.release.name]: update.critpath = True try: build = db.query(Build).filter_by(nvr=nvr).one() except NoResultFound: build = Build(nvr=nvr, package=package) db.add(build) update.builds.append(build) ## Create all Bugzilla objects for this update for bug_num, bug_title, security, parent in u['bugs']: try: bug = db.query(Bug).filter_by(bug_id=bug_num).one() except NoResultFound: bug = Bug(bug_id=bug_num, security=security, parent=parent, title=bug_title) db.add(bug) update.bugs.append(bug) ## Create all CVE objects for this update for cve_id in u['cves']: try: cve = db.query(CVE).filter_by(cve_id=cve_id).one() except NoResultFound: cve = CVE(cve_id=cve_id) db.add(cve) update.cves.append(cve) ## Create all Comments for this update for c in u['comments']: try: timestamp, author, text, karma, anonymous = c except ValueError: timestamp, author, text, karma = c anonymous = '@' in author comment = Comment(timestamp=timestamp, text=text, karma=karma, anonymous=anonymous) db.add(comment) db.flush() update.comments.append(comment) if anonymous: name = u'anonymous' else: name = author group = None if not anonymous and ' (' in name: split = name.split(' (') name = split[0] group = split[1][:-1] assert group, name try: user = users[name] except KeyError: try: user = db.query(User).filter_by(name=name).one() except NoResultFound: user = User(name=name) db.add(user) db.flush() users[name] = user comment.user = user if group: try: group = db.query(Group).filter_by(name=group).one() except NoResultFound: group = Group(name=group) db.add(group) db.flush() user.groups.append(group) db.flush() # Hack to get the Bodhi2 alias generator working with bodhi1 data. # The new generator assumes that the alias is assigned at submission time, as opposed to push time. year, id = max(aliases) print('Highest alias = %r %r' % (year, id)) up = db.query(Update).filter_by(alias=u'FEDORA-%s-%s' % (year, id)).one() print(up.title) up.date_submitted = up.date_pushed db.flush() transaction.commit() print("\nDatabase migration complete!") print(" * %d updates" % db.query(Update).count()) print(" * %d builds" % db.query(Build).count()) print(" * %d comments" % db.query(Comment).count()) print(" * %d users" % db.query(User).count()) print(" * %d bugs" % db.query(Bug).count()) print(" * %d CVEs" % db.query(CVE).count())
def save_stack(request): """Save a stack""" data = request.validated db = request.db user = User.get(request.user.name, db) # Fetch or create the stack stack = Stack.get(data["name"], db) if not stack: stack = Stack(name=data["name"], users=[user]) db.add(stack) db.flush() if stack.users or stack.groups: if user in stack.users: log.info("%s is an owner of the %s", user.name, stack.name) else: for group in user.groups: if group in stack.groups: log.info("%s is a member of the %s group", user.name, stack.name) break else: log.warn("%s is not an owner of the %s stack", user.name, stack.name) log.debug("owners = %s; groups = %s", stack.users, stack.groups) request.errors.add( "body", "name", "%s does not have privileges" " to modify the %s stack" % (user.name, stack.name) ) request.errors.status = HTTPForbidden.code return # Update the stack description desc = data["description"] if desc: stack.description = desc # Update the stack requirements # If the user passed in no value at all for requirements, then use # the site defaults. If, however, the user passed in the empty string, we # assume they mean *really*, no requirements so we leave the value null. reqs = data["requirements"] if reqs is None: stack.requirements = request.registry.settings.get("site_requirements") elif reqs: stack.requirements = reqs stack.update_relationship("users", User, data, db) stack.update_relationship("groups", Group, data, db) # We make a special case out of packages here, since when a package is # added to a stack, we want to give it the same requirements as the stack # has. See https://github.com/fedora-infra/bodhi/issues/101 new, same, rem = stack.update_relationship("packages", Package, data, db) if stack.requirements: additional = list(tokenize(stack.requirements)) for name in new: package = Package.get(name, db) original = package.requirements original = [] if not original else list(tokenize(original)) package.requirements = " ".join(list(set(original + additional))) log.info("Saved %s stack", data["name"]) notifications.publish(topic="stack.save", msg=dict(stack=stack, agent=user.name)) return dict(stack=stack)
def save_stack(request): """Save a stack""" data = request.validated db = request.db user = User.get(request.user.name, db) # Fetch or create the stack stack = Stack.get(data['name'], db) if not stack: stack = Stack(name=data['name'], users=[user]) db.add(stack) db.flush() if stack.users or stack.groups: if user in stack.users: log.info('%s is an owner of the %s', user.name, stack.name) else: for group in user.groups: if group in stack.groups: log.info('%s is a member of the %s group', user.name, stack.name) break else: log.warn('%s is not an owner of the %s stack', user.name, stack.name) log.debug('owners = %s; groups = %s', stack.users, stack.groups) request.errors.add( 'body', 'name', '%s does not have privileges' ' to modify the %s stack' % (user.name, stack.name)) request.errors.status = HTTPForbidden.code return # Update the stack description desc = data['description'] if desc: stack.description = desc # Update the stack requirements # If the user passed in no value at all for requirements, then use # the site defaults. If, however, the user passed in the empty string, we # assume they mean *really*, no requirements so we leave the value null. reqs = data['requirements'] if reqs is None: stack.requirements = request.registry.settings.get('site_requirements') elif reqs: stack.requirements = reqs stack.update_relationship('users', User, data, db) stack.update_relationship('groups', Group, data, db) # We make a special case out of packages here, since when a package is # added to a stack, we want to give it the same requirements as the stack # has. See https://github.com/fedora-infra/bodhi/issues/101 new, same, rem = stack.update_relationship('packages', Package, data, db) if stack.requirements: additional = list(tokenize(stack.requirements)) for name in new: package = Package.get(name, db) original = package.requirements original = [] if not original else list(tokenize(original)) package.requirements = " ".join(list(set(original + additional))) log.info('Saved %s stack', data['name']) notifications.publish(topic='stack.save', msg=dict(stack=stack, agent=user.name)) return dict(stack=stack)