Exemple #1
0
 def save_edit(self, builds, notes, expiration=None, **kw):
     log.debug(repr(locals()))
     if len(builds) > 1:
         flash("Unable to add builds to an existing override")
         raise redirect("/override")
     builds = builds[0]
     if expiration:
         if datetime.utcnow() > expiration:
             flash("Cannot set an expiration in the past")
             if request_format() == "json":
                 return dict()
             raise redirect("/override/edit?build=" + builds)
     try:
         override = BuildRootOverride.byBuild(builds)
     except SQLObjectNotFound:
         flash("Cannot find override to edit %r" % builds)
         raise redirect("/override")
     override.notes = notes
     override.expiration = expiration
     if override.date_expired:
         log.debug("Retagging expired override: %s" % override.build)
         override.date_expired = None
         override.tag()
     flash("%s successfully edited" % builds)
     if request_format() == "json":
         return override.__json__()
     raise redirect("/override")
Exemple #2
0
 def save_edit(self, builds, notes, expiration=None, **kw):
     log.debug(repr(locals()))
     if len(builds) > 1:
         flash('Unable to add builds to an existing override')
         raise redirect('/override')
     builds = builds[0]
     if expiration:
         if datetime.utcnow() > expiration:
             flash('Cannot set an expiration in the past')
             if request_format() == 'json': return dict()
             raise redirect('/override/edit?build=' + builds)
     try:
         override = BuildRootOverride.byBuild(builds)
     except SQLObjectNotFound:
         flash('Cannot find override to edit %r' % builds)
         raise redirect('/override')
     override.notes = notes
     override.expiration = expiration
     if override.date_expired:
         log.debug('Retagging expired override: %s' % override.build)
         override.date_expired = None
         override.tag()
     flash('%s successfully edited' % builds)
     if request_format() == 'json': return override.__json__()
     raise redirect('/override')
Exemple #3
0
    def login(self, forward_url=None, *args, **kwargs):
        '''Page to become authenticated to the Account System.

        This shows a small login box to type in your username and password
        from the Fedora Account System.

        :kwarg forward_url: The url to send to once authentication succeeds
        '''
        login_dict = f_ctrlers.login(forward_url=forward_url, *args, **kwargs)

        if not identity.current.anonymous and identity.was_login_attempted() \
                and not identity.get_identity_errors():
            # Success that needs to be passed back via json
            return login_dict

        if identity.was_login_attempted() and request.fas_provided_username:
            if request.fas_identity_failure_reason == 'status_inactive':
                turbogears.flash(_('Your old password has expired.  Please'
                    ' reset your password below.'))
                if request_format() != 'json':
                    redirect('/user/resetpass')
            if request.fas_identity_failure_reason == 'status_account_disabled':
                turbogears.flash(_('Your account is currently disabled.  For'
                        ' more information, please contact %(admin_email)s' %
                        {'admin_email': config.get('accounts_email')}))
                if request_format() != 'json':
                    redirect('/login')

        return login_dict
Exemple #4
0
    def login(self, forward_url=None, *args, **kwargs):
        '''Page to become authenticated to the Account System.

        This shows a small login box to type in your username and password
        from the Fedora Account System.

        :kwarg forward_url: The url to send to once authentication succeeds
        '''
        login_dict = f_ctrlers.login(forward_url=forward_url, *args, **kwargs)

        if not identity.current.anonymous and identity.was_login_attempted() \
                and not identity.get_identity_errors():
            # Success that needs to be passed back via json
            return login_dict

        if identity.was_login_attempted() and request.fas_provided_username:
            if request.fas_identity_failure_reason == 'status_inactive':
                turbogears.flash(
                    _('Your old password has expired.  Please'
                      ' reset your password below.'))
                if request_format() != 'json':
                    redirect('/user/resetpass')
            if request.fas_identity_failure_reason == 'status_account_disabled':
                turbogears.flash(
                    _('Your account is currently disabled.  For'
                      ' more information, please contact %(admin_email)s' %
                      {'admin_email': config.get('accounts_email')}))
                if request_format() != 'json':
                    redirect('/login')

        return login_dict
Exemple #5
0
    def list(self,
             build=None,
             tg_errors=None,
             mine=False,
             release=None,
             show_expired=False,
             **kw):
        query = []
        title = '%d Buildroot Overrides'
        if mine:
            query.append(
                BuildRootOverride.q.submitter == identity.current.user_name)
            title += ' submitted by %s' % identity.current.user_name
        if release:
            rel = Release.byName(release)
            query.append(BuildRootOverride.q.releaseID == rel.id)
            title += ' for %s' % rel.long_name
        if not show_expired:
            query.append(BuildRootOverride.q.date_expired == None)

        overrides = BuildRootOverride.select(AND(*query))

        if request_format() == 'json':
            overrides = [o.__json__() for o in overrides]
            num_items = len(overrides)
        else:
            num_items = overrides.count()
        return dict(overrides=overrides,
                    title=title % num_items,
                    num_items=num_items,
                    show_expired=show_expired,
                    mine=mine)
Exemple #6
0
    def list(self, build=None, tg_errors=None, mine=False, release=None, 
             show_expired=False, **kw):
        query = []
        title = '%d Buildroot Overrides'
        if mine:
            show_expired = True
            query.append(
                BuildRootOverride.q.submitter == identity.current.user_name)
            title += ' submitted by %s' % identity.current.user_name
        if release:
            rel = Release.byName(release)
            query.append(
                BuildRootOverride.q.releaseID == rel.id)
            title += ' for %s' % rel.long_name
        if not show_expired:
            query.append(
                BuildRootOverride.q.date_expired == None)

        overrides = BuildRootOverride.select(AND(*query))

        if request_format() == 'json':
            overrides = [o.__json__() for o in overrides]
            num_items = len(overrides)
        else:
            num_items = overrides.count()
        return dict(overrides=overrides,
                    title=title % num_items,
                    num_items=num_items,
                    show_expired=show_expired,
                    mine=mine)
Exemple #7
0
    def index(self, release=None):
        # /updates/metrics?tg_format=json API
        if request_format() == 'json':
            json = {}
            query = release and [Release.byName(release)] or Release.select()
            for release in query:
                json[release.name] = release.metrics
            return json

        try:
            if not release:
                rel = Release.select()[0]
                release = rel.name
            else:
                rel = Release.byName(release)
        except SQLObjectNotFound:
            flash("Unknown Release")
            raise redirect('/metrics')
        widgets = MetricData().get_widgets(release)
        if not widgets:
            return dict(metrics=[], title="Metrics currently unavailable")
        return dict(metrics=[
            widgets[name.__name__] for name in metrics
            if name.__name__ in widgets
        ],
                    title="%s Update Metrics" % rel.long_name)
Exemple #8
0
    def index(self, release=None):
        # /updates/metrics?tg_format=json API
        if request_format() == "json":
            json = {}
            query = release and [Release.byName(release)] or Release.select()
            for release in query:
                json[release.name] = release.metrics
            return json

        try:
            if not release:
                rel = Release.select()[0]
                release = rel.name
            else:
                rel = Release.byName(release)
        except SQLObjectNotFound:
            flash("Unknown Release")
            raise redirect("/metrics")
        widgets = MetricData().get_widgets(release)
        if not widgets:
            return dict(metrics=[], title="Metrics currently unavailable")
        return dict(
            metrics=[widgets[name.__name__] for name in metrics if name.__name__ in widgets],
            title="%s Update Metrics" % rel.long_name,
        )
Exemple #9
0
 def index(self):
     if turbogears.identity.not_anonymous():
         if request_format() == 'json':
             # redirects don't work with JSON calls.  This is a bit of a
             # hack until we can figure out something better.
             return dict()
         turbogears.redirect('/home')
     return dict(now=time.ctime())
Exemple #10
0
    def save(self, builds, notes, expiration=None, *args, **kw):
        log.debug(repr(locals()))
        last_release = None  # for our koji wait-repo example

        if expiration:
            if datetime.utcnow() > expiration:
                flash('Cannot set an expiration in the past')
                if request_format() == 'json': return dict()
                raise redirect('/override/new')

        try:
            koji = get_session()
        except Exception, e:
            flash('Unable to connect to Koji')
            if request_format() == 'json':
                return dict()
            raise redirect('/override/new')
Exemple #11
0
def json_redirect(f, *args, **kw):
    try:
        return f(*args, **kw)
    except InvalidUpdateException, e:
        if request_format() == 'json':
            return dict()
        else:
            raise redirect('/new', **e.args[0])
Exemple #12
0
 def index(self):
     if turbogears.identity.not_anonymous():
         if request_format() == 'json':
             # redirects don't work with JSON calls.  This is a bit of a
             # hack until we can figure out something better.
             return dict()
         turbogears.redirect('/home')
     return dict(now=time.ctime())
Exemple #13
0
def json_redirect(f, *args, **kw):
    try:
        return f(*args, **kw)
    except InvalidUpdateException, e:
        if request_format() == 'json':
            return dict()
        else:
            raise redirect('/new', **e.args[0])
Exemple #14
0
    def save(self, builds, notes, expiration=None, *args, **kw):
        log.debug(repr(locals()))
        last_release = None # for our koji wait-repo example

        if expiration:
            if datetime.utcnow() > expiration:
                flash('Cannot set an expiration in the past')
                if request_format() == 'json': return dict()
                raise redirect('/override/new')

        try:
            koji = get_session()
        except Exception, e:
            flash('Unable to connect to Koji')
            if request_format() == 'json':
                return dict()
            raise redirect('/override/new')
Exemple #15
0
    def error(self, tg_errors=None):
        '''Show a friendly error message'''
        # Only tg controller methods are served via the web so we have to have
        # methods even if they could be functions. (R0201)
        # pylint: disable-msg=R0201

        ### FIXME: This can be made simpler once we have a new python-fedora
        # with jsonify_validation_errors()
        if tg_errors:
            if request_format() == 'json':
                message = '\n'.join([u'%s: %s' % (param, msg) for param, msg in
                    tg_errors.items()])
                return dict(exc='Invalid', tg_flash=message, tg_template='json')
        if not tg_errors:
            # We should only reach this if the user hit the url manually.
            if request_format() == 'json':
                return dict()
            else:
                redirect('/')
        return dict(tg_errors=tg_errors)
Exemple #16
0
 def expire(self, build, *args, **kw):
     """ Expire a given override """
     override = BuildRootOverride.byBuild(build)
     if identity.current.user_name != override.submitter and "releng" not in identity.current.groups:
         flash("Only the submitter or a releng memeber can " + "expire this buildroot override")
         if request_format() == "json":
             return dict()
         raise redirect("/override")
     if override.date_expired:
         flash("Override %s already expired!" % build)
         if request_format() == "json":
             return dict()
         raise redirect("/override")
     override.date_expired = datetime.utcnow()
     try:
         override.untag()
     except Exception, e:
         log.error(str(e))
         flash(str(e))
         raise redirect("/override")
Exemple #17
0
 def expire(self, build, *args, **kw):
     """ Expire a given override """
     override = BuildRootOverride.byBuild(build)
     if identity.current.user_name != override.submitter and \
        'releng' not in identity.current.groups:
         flash('Only the submitter or a releng memeber can ' +
               'expire this buildroot override')
         if request_format() == 'json': return dict()
         raise redirect('/override')
     if override.date_expired:
         flash('Override %s already expired!' % build)
         if request_format() == 'json': return dict()
         raise redirect('/override')
     override.date_expired = datetime.utcnow()
     try:
         override.untag()
     except Exception, e:
         log.error(str(e))
         flash(str(e))
         raise redirect('/override')
Exemple #18
0
 def save_edit_cli(self, builds, notes, expiration=None, **kw):
     log.debug(repr(locals()))
     if expiration:
         if datetime.utcnow() > expiration:
             flash('Cannot set an expiration in the past')
             if request_format() == 'json': return dict()
             raise redirect('/override/edit?build=' + builds)
     try:
         override = BuildRootOverride.byBuild(builds)
     except SQLObjectNotFound:
         flash('Cannot find override to edit %r' % builds)
         raise redirect('/override')
     override.notes = notes
     override.expiration = expiration
     if override.date_expired:
         log.debug('Retagging expired override: %s' % override.build)
         override.date_expired = None
         override.tag()
     flash('%s successfully edited' % builds)
     if request_format() == 'json': return override.__json__()
     raise redirect('/override')
Exemple #19
0
 def expire(self, build, *args, **kw):
     """ Expire a given override """
     override = BuildRootOverride.byBuild(build)
     if override.date_expired:
         flash('Override %s already expired!' % build)
         if request_format() == 'json': return dict()
         raise redirect('/override')
     override.date_expired = datetime.utcnow()
     try:
         override.untag()
     except Exception, e:
         log.error(str(e))
         flash(str(e))
         raise redirect('/override')
Exemple #20
0
def login(forward_url=None, *args, **kwargs):
    '''Page to become authenticated to the Account System.

    This shows a small login box to type in your username and password
    from the Fedora Account System.

    To use this, replace your current login controller method with::

        from fedora.controllers import login as fc_login

        @expose(template='yourapp.yourlogintemplate', allow_json=True)
        def login(self, forward_url=None, *args, **kwargs):
            login_dict = fc_login(forward_url, args, kwargs)
            # Add anything to the return dict that you need for your app
            return login_dict

    :kwarg: forward_url: The url to send to once authentication succeeds
    '''
    if forward_url:
        if isinstance(forward_url, list):
            forward_url = forward_url.pop(0)
        else:
            del request.params['forward_url']

    if not identity.current.anonymous and identity.was_login_attempted() \
            and not identity.get_identity_errors():
        # User is logged in
        flash(_('Welcome, %s') % identity.current.user_name)
        if request_format() == 'json':
            # When called as a json method, doesn't make any sense to redirect
            # to a page.  Returning the logged in identity is better.
            return dict(user=identity.current.user,
                    _csrf_token=identity.current.csrf_token)
        redirect(forward_url or '/')

    if identity.was_login_attempted():
        msg = _('The credentials you supplied were not correct or '
               'did not grant access to this resource.')
    elif identity.get_identity_errors():
        msg = _('You must provide your credentials before accessing '
               'this resource.')
    else:
        msg = _('Please log in.')
        if not forward_url:
            forward_url = request.headers.get('Referer', '/')

    response.status = 403
    return dict(logging_in=True, message=msg,
        forward_url=forward_url, previous_url=request.path_info,
        original_parameters=request.params)
Exemple #21
0
 def expire(self, build, *args, **kw):
     """ Expire a given override """
     override = BuildRootOverride.byBuild(build)
     if override.date_expired:
         flash('Override %s already expired!' % build)
         if request_format() == 'json': return dict()
         raise redirect('/override')
     override.date_expired = datetime.utcnow()
     try:
         override.untag()
     except Exception, e:
         log.error(str(e))
         flash(str(e))
         raise redirect('/override')
Exemple #22
0
    def error(self, tg_errors=None):
        '''Show a friendly error message'''
        # Only tg controller methods are served via the web so we have to have
        # methods even if they could be functions. (R0201)
        # pylint: disable-msg=R0201

        ### FIXME: This can be made simpler once we have a new python-fedora
        # with jsonify_validation_errors()
        if tg_errors:
            if request_format() == 'json':
                message = '\n'.join([
                    u'%s: %s' % (param, msg)
                    for param, msg in tg_errors.items()
                ])
                return dict(exc='Invalid',
                            tg_flash=message,
                            tg_template='json')
        if not tg_errors:
            # We should only reach this if the user hit the url manually.
            if request_format() == 'json':
                return dict()
            else:
                redirect('/')
        return dict(tg_errors=tg_errors)
Exemple #23
0
    def set(self, username, application, attribute, value=None):
        '''Retrieve configs for a user and application.

        Arguments:
        :username: owner of the configs we're searching for
        :application: program that the configs are for
        :attribute: name of the option we're setting
        :value: value to set in the db.  If ths is None, we won't set anything
        '''
        # Only tg controller methods are served via the web so we have to have
        # methods even if they could be functions. (R0201)
        # pylint: disable-msg=R0201

        # Verify user is allowed to set this config
        target = People.by_username(username)
        if not can_edit_user(identity.current.user, target):
            flash(_('You cannot edit configs for %s') % username)
            if request_format() == 'json':
                return dict(exc='AuthorizationError')
            else:
                redirect('/')

        # Retrieve the data and reformat it as a dict keyed on attribute
        try:
            # pylint: disable-msg=E1101
            config = Configs.query.filter_by(
                application=application,
                attribute=attribute).filter(People.username == username).one()
            config.value = value
        except InvalidRequestError:
            # There was no Config, create a new one
            config = Configs(application=application,
                             attribute=attribute,
                             value=value)
            # pylint: disable-msg=E1101
            config.person = People.query.filter_by(username=username).one()

        try:
            # ScopedSession really does have a flush() method
            # pylint: disable-msg=E1101
            session.flush()
        except SQLError, error:
            flash(_('Error saving the config to the database: %s' % (error)))
            return dict(exc='SQLError')
Exemple #24
0
    def set(self, username, application, attribute, value=None):
        '''Retrieve configs for a user and application.

        Arguments:
        :username: owner of the configs we're searching for
        :application: program that the configs are for
        :attribute: name of the option we're setting
        :value: value to set in the db.  If ths is None, we won't set anything
        '''
        # Only tg controller methods are served via the web so we have to have
        # methods even if they could be functions. (R0201)
        # pylint: disable-msg=R0201

        # Verify user is allowed to set this config
        target = People.by_username(username)
        if not can_edit_user(identity.current.user, target):
            flash(_('You cannot edit configs for %s') % username)
            if request_format() == 'json':
                return dict(exc='AuthorizationError')
            else:
                redirect('/')

        # Retrieve the data and reformat it as a dict keyed on attribute
        try:
            # pylint: disable-msg=E1101
            config = Configs.query.filter_by(application=application,
                    attribute=attribute).filter(People.username==username).one()
            config.value = value
        except InvalidRequestError:
            # There was no Config, create a new one
            config = Configs(application=application, attribute=attribute,
                    value=value)
            # pylint: disable-msg=E1101
            config.person = People.query.filter_by(username=username).one()

        try:
            # ScopedSession really does have a flush() method
            # pylint: disable-msg=E1101
            session.flush()
        except SQLError, error:
            flash(_('Error saving the config to the database: %s' % (error)))
            return dict(exc='SQLError')
Exemple #25
0
    def list(self, username, application, pattern=u'*'):
        '''Retrieve configs for a user and application.

        Arguments:
        :username: owner of the configs we're searching for
        :application: program that the configs are for
        :pattern: Limit the configs to ones which match this pattern. '*' is a
            wildcard character

        Returns: dict that maps the name of the config attribute to the config
            value.
        '''
        # Only tg controller methods are served via the web so we have to have
        # methods even if they could be functions. (R0201)
        # pylint: disable-msg=R0201

        # Verify user is allowed to view this config
        target = People.by_username(username)
        if not can_edit_user(identity.current.user, target):
            flash(_('You cannot look at configs for %s') % username)
            if request_format() == 'json':
                return dict(exc='AuthorizationError')
            else:
                redirect('/')

        # This only works if pattern is unicode.  But it should be unicode
        # because of the validator.
        pattern = pattern.translate({ord(u'*'): ur'%'}).lower()

        # Retrieve the data and reformat it as a dict keyed on attribute
        # pylint: disable-msg=E1101
        cfgs = Configs.query.filter_by(application=application).filter(
            and_(Configs.attribute.like(pattern), People.username == username))
        # pylint: enable-msg=E1101
        results = dict((cfg.attribute, cfg.value) for cfg in cfgs.all())

        return dict(username=username,
                    application=application,
                    pattern=pattern,
                    configs=results)
Exemple #26
0
    def list(self, username, application, pattern=u'*'):
        '''Retrieve configs for a user and application.

        Arguments:
        :username: owner of the configs we're searching for
        :application: program that the configs are for
        :pattern: Limit the configs to ones which match this pattern. '*' is a
            wildcard character

        Returns: dict that maps the name of the config attribute to the config
            value.
        '''
        # Only tg controller methods are served via the web so we have to have
        # methods even if they could be functions. (R0201)
        # pylint: disable-msg=R0201

        # Verify user is allowed to view this config
        target = People.by_username(username)
        if not can_edit_user(identity.current.user, target):
            flash(_('You cannot look at configs for %s') % username)
            if request_format() == 'json':
                return dict(exc='AuthorizationError')
            else:
                redirect('/')

        # This only works if pattern is unicode.  But it should be unicode
        # because of the validator.
        pattern = pattern.translate({ord(u'*'): ur'%'}).lower()

        # Retrieve the data and reformat it as a dict keyed on attribute
        # pylint: disable-msg=E1101
        cfgs = Configs.query.filter_by(application=application).filter(
                and_(Configs.attribute.like(pattern),
                    People.username==username))
        # pylint: enable-msg=E1101
        results = dict((cfg.attribute, cfg.value) for cfg in cfgs.all())

        return dict(username=username, application=application,
                pattern=pattern, configs=results)
Exemple #27
0
def logout(url=None):
    '''Logout from the server.

    To use this, replace your current login controller method with::

        from fedora.controllers import logout as fc_logout

        @expose(allow_json=True)
        def logout(self):
            return fc_logout()

    :kwarg url: If provided, when the user logs out, they will always be taken
        to this url.  This defaults to taking the user to the URL they were
        at when they clicked logout.
    '''
    identity.current.logout()
    flash(_('You have successfully logged out.'))
    if request_format() == 'json':
        return dict()
    if not url:
        url = request.headers.get('Referer','/')
    redirect(url)
Exemple #28
0
    def mash(self, updates=None, resume=False, **kw):
        """ Mash a list of PackageUpdate objects.

        If this instance is deployed with a remote masher, then it simply
        proxies the request.  If we are the masher, then send these updates to
        our Mash instance.  This will then start a thread that takes care of
        handling all of the update requests, composing fresh repositories,
        generating and sending update notices, closing bugs, etc.
        """
        if not updates:
            updates = []
        if not isinstance(updates, list):
            if isinstance(updates, basestring):
                log.debug("Doing json hack")
                try:
                    updates = json.loads(
                        updates.replace("u'", "\"").replace("'", "\""))
                except:
                    log.debug("Didn't work, assuming it's a single update...")
                    updates = [updates]
            else:
                updates = [updates]

        # If we're not The Masher, then proxy this request to it
        if config.get('masher'):
            data = self._masher_request(
                '/admin/mash', updates=updates, resume=resume) or {}
            flash_log('Push request %s' %
                      (data.get('success') and 'succeeded' or 'failed'))
            raise redirect('/admin/masher')

        from bodhi.masher import masher
        masher.queue([PackageUpdate.byTitle(title) for title in updates],
                     resume=resume)
        if request_format() == 'json':
            return dict(success=True)
        flash("Updates queued for mashing")
        raise redirect('/admin/masher')
Exemple #29
0
    def mash(self, updates=None, resume=False, **kw):
        """ Mash a list of PackageUpdate objects.

        If this instance is deployed with a remote masher, then it simply
        proxies the request.  If we are the masher, then send these updates to
        our Mash instance.  This will then start a thread that takes care of
        handling all of the update requests, composing fresh repositories,
        generating and sending update notices, closing bugs, etc.
        """
        if not updates:
            updates = []
        if not isinstance(updates, list):
            if isinstance(updates, basestring):
                log.debug("Doing json hack")
                try:
                    updates = json.loads(updates.replace("u'", "\"").replace("'", "\""))
                except:
                    log.debug("Didn't work, assuming it's a single update...")
                    updates = [updates]
            else:
                updates = [updates]

        # If we're not The Masher, then proxy this request to it
        if config.get('masher'):
            data = self._masher_request('/admin/mash', updates=updates, resume=resume) or {}
            flash_log('Push request %s'
                      % (data.get('success') and 'succeeded' or 'failed'))
            raise redirect('/admin/masher')

        from bodhi.masher import masher
        masher.queue([PackageUpdate.byTitle(title) for title in updates],
                     resume=resume)
        if request_format() == 'json':
            return dict(success=True)
        flash("Updates queued for mashing")
        raise redirect('/admin/masher')
Exemple #30
0
class CLA(controllers.Controller):
    ''' Processes CLA workflow '''
    # Group name for people having signed the CLA
    CLAGROUPNAME = config.get('cla_standard_group')
    # Meta group for everyone who has satisfied the requirements of the CLA
    # (By signing or having a corporate signatue or, etc)
    CLAMETAGROUPNAME = config.get('cla_done_group')

    # Values legal in phone numbers
    PHONEDIGITS = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+',
                   '-', ')', '(', ' ')

    def __init__(self):
        '''Create a CLA Controller.'''

    @identity.require(turbogears.identity.not_anonymous())
    @expose(template="fas.templates.cla.index")
    def index(self):
        '''Display the CLAs (and accept/do not accept buttons)'''
        show = {}
        show['show_postal_address'] = config.get('show_postal_address')

        username = turbogears.identity.current.user_name
        person = People.by_username(username)
        try:
            code_len = len(person.country_code)
        except TypeError:
            code_len = 0
        if show['show_postal_address']:
            contactInfo = person.telephone or person.postal_address
            if person.country_code == 'O1' and not person.telephone:
                turbogears.flash(_('A telephone number is required to ' + \
                    'complete the CLA.  Please fill out below.'))
            elif not person.country_code or not person.human_name \
                or not contactInfo:
                turbogears.flash(_('A valid country and telephone number ' + \
                    'or postal address is required to complete the CLA.  ' + \
                    'Please fill them out below.'))
        else:
            if not person.telephone or code_len != 2 or \
                person.country_code == '  ':
                turbogears.flash(
                    _('A valid country and telephone number are' +
                      ' required to complete the CLA.  Please fill them ' +
                      'out below.'))
        cla = cla_done(person)
        person = person.filter_private()
        return dict(cla=cla,
                    person=person,
                    date=datetime.utcnow().ctime(),
                    show=show)

    def _cla_dependent(self, group):
        '''
        Check whether a group has the cla in its prerequisite chain.

        Arguments:
        :group: group to check

        Returns: True if the group requires the cla_group_name otherwise
        '''
        if group.name in (self.CLAGROUPNAME, self.CLAMETAGROUPNAME):
            return True
        if group.prerequisite_id:
            return self._cla_dependent(group.prerequisite)
        return False

    def json_request(self):
        ''' Helps define if json is being used for this request

        :returns: 1 or 0 depending on if request is json or not
        '''

        return 'tg_format' in cherrypy.request.params and \
                cherrypy.request.params['tg_format'] == 'json'

    @expose(template="fas.templates.error")
    def error(self, tg_errors=None):
        '''Show a friendly error message'''
        if not tg_errors:
            turbogears.redirect('/')
        return dict(tg_errors=tg_errors)

    @identity.require(turbogears.identity.not_anonymous())
    @expose(template="genshi-text:fas.templates.cla.cla",
            format="text",
            content_type='text/plain; charset=utf-8')
    def text(self):
        '''View CLA as text'''
        username = turbogears.identity.current.user_name
        person = People.by_username(username)
        person = person.filter_private()
        return dict(person=person, date=datetime.utcnow().ctime())

    @identity.require(turbogears.identity.not_anonymous())
    @expose(template="genshi-text:fas.templates.cla.cla",
            format="text",
            content_type='text/plain; charset=utf-8')
    def download(self):
        '''Download CLA'''
        username = turbogears.identity.current.user_name
        person = People.by_username(username)
        person = person.filter_private()
        return dict(person=person, date=datetime.utcnow().ctime())

    @identity.require(turbogears.identity.not_anonymous())
    @expose(template="fas.templates.user.view", allow_json=True)
    def reject(self, person_name):
        '''Reject a user's CLA.

        This method will remove a user from the CLA group and any other groups
        that they are in that require the CLA.  It is used when a person has
        to fulfill some more legal requirements before having a valid CLA.

        Arguments
        :person_name: Name of the person to reject.
        '''
        show = {}
        show['show_postal_address'] = config.get('show_postal_address')
        exc = None
        user = People.by_username(turbogears.identity.current.user_name)
        if not is_admin(user):
            # Only admins can use this
            turbogears.flash(_('You are not allowed to reject CLAs.'))
            exc = 'NotAuthorized'
        else:
            # Unapprove the cla and all dependent groups
            person = People.by_username(person_name)
            for role in person.roles:
                if self._cla_dependent(role.group):
                    role.role_status = 'unapproved'
            try:
                session.flush()
            except SQLError, error:
                turbogears.flash(_('Error removing cla and dependent groups' \
                        ' for %(person)s\n Error was: %(error)s') %
                        {'person': person_name, 'error': str(error)})
                exc = 'sqlalchemy.SQLError'

        if not exc:
            # Send a message that the ICLA has been revoked
            date_time = datetime.utcnow()
            Log(author_id=user.id,
                description='Revoked %s CLA' % person.username,
                changetime=date_time)
            revoke_subject = _('Fedora ICLA Revoked')
            revoke_text = _('''
Hello %(human_name)s,

We're sorry to bother you but we had to reject your CLA for now because
information you provided has been deemed incorrect.  The most common cause
of this is people abbreviating their name like "B L Couper" instead of
providing their actual full name "Bill Lay Couper".  Other causes of this
include are using a country, or phone number that isn't accurate [1]_.
If you could edit your account [2]_ to fix any of these problems and resubmit
the CLA we would appreciate it.

.. [1]: Why does it matter that we have your real name and phone
        number?   It's because the CLA is a legal document and should we ever
        need to contact you about one of your contributions (as an example,
        because someone contacts *us* claiming that it was really they who
        own the copyright to the contribution) we might need to contact you
        for more information about what's going on.

.. [2]: Edit your account by logging in at this URL:
        %(editurl)s/accounts/user/edit/%(username)s

If you have questions about what specifically might be the problem with your
account, please contact us at [email protected].

Thanks!
    ''') % {
                'username': person.username,
                'human_name': person.human_name,
                'editurl': config.get('base_url_filter.base_url').rstrip('/')
            }

            send_mail(person.email, revoke_subject, revoke_text)

            # Yay, sweet success!
            turbogears.flash(_('CLA Successfully Removed.'))
        # and now we're done
        if request_format() == 'json':
            return_val = {}
            if exc:
                return_val['exc'] = exc
            return return_val
        else:
            turbogears.redirect('/user/view/%s' % person_name)
Exemple #31
0
        except Exception, e:
            flash("Unable to connect to Koji")
            if request_format() == "json":
                return dict()
            raise redirect("/override/new")

        for build in iterate(builds):
            release = None
            n, v, r = get_nvr(build)

            # Make sure the build is tagged correctly
            try:
                tags = [tag["name"] for tag in koji.listTags(build)]
            except Exception, e:
                flash(str(e))
                if request_format() == "json":
                    return dict()
                raise redirect("/override/new")

            # Determine the release by the tag, and sanity check the builds
            for tag in tags:
                for rel in Release.select():
                    if tag in (rel.candidate_tag, rel.testing_tag):
                        release = last_release = rel
                    elif tag == rel.stable_tag:
                        flash("Error: %s is already tagged with %s" % (build, tag))
                        if request_format() == "json":
                            return dict()
                        raise redirect("/override/new")

            if not release:
Exemple #32
0
        except Exception, e:
            flash('Unable to connect to Koji')
            if request_format() == 'json':
                return dict()
            raise redirect('/override/new')

        for build in iterate(builds):
            release = None
            n, v, r = get_nvr(build)

            # Make sure the build is tagged correctly
            try:
                tags = [tag['name'] for tag in koji.listTags(build)]
            except Exception, e:
                flash(str(e))
                if request_format() == 'json': return dict()
                raise redirect('/override/new')

            # Determine the release by the tag, and sanity check the builds
            for tag in tags:
                for rel in Release.select():
                    if tag in (rel.candidate_tag, rel.testing_tag):
                        release = last_release = rel
                    elif tag == rel.stable_tag:
                        flash('Error: %s is already tagged with %s' % (
                            build, tag))
                        if request_format() == 'json': return dict()
                        raise redirect('/override/new')

            if not release:
                flash('Error: Could not determine release for %s with tags %s' %
Exemple #33
0
        except Exception, e:
            flash('Unable to connect to Koji')
            if request_format() == 'json':
                return dict()
            raise redirect('/override/new')

        for build in iterate(builds):
            release = None
            n, v, r = get_nvr(build)

            # Make sure the build is tagged correctly
            try:
                tags = [tag['name'] for tag in koji.listTags(build)]
            except Exception, e:
                flash(str(e))
                if request_format() == 'json': return dict()
                raise redirect('/override/new')

            # Determine the release by the tag, and sanity check the builds
            for tag in tags:
                for rel in Release.select():
                    if tag in (rel.candidate_tag, rel.testing_tag):
                        release = last_release = rel
                    elif tag == rel.stable_tag:
                        flash('Error: %s is already tagged with %s' %
                              (build, tag))
                        if request_format() == 'json': return dict()
                        raise redirect('/override/new')

            if not release:
                flash(
Exemple #34
0
class BuildRootOverrideController(Controller):
    @identity.require(identity.not_anonymous())
    @expose()
    def index(self):
        raise redirect('/override/list')

    @identity.require(identity.not_anonymous())
    @expose(template="bodhi.templates.overrides", allow_json=True)
    @validate(
        validators={
            'build': validators.UnicodeString(),
            'mine': validators.StringBool(),
            'release': validators.UnicodeString(),
            'show_expired': validators.StringBool()
        })
    @paginate('overrides',
              default_order='-date_submitted',
              limit=20,
              max_limit=1000)
    def list(self,
             build=None,
             tg_errors=None,
             mine=False,
             release=None,
             show_expired=False,
             **kw):
        query = []
        title = '%d Buildroot Overrides'
        if mine:
            query.append(
                BuildRootOverride.q.submitter == identity.current.user_name)
            title += ' submitted by %s' % identity.current.user_name
        if release:
            rel = Release.byName(release)
            query.append(BuildRootOverride.q.releaseID == rel.id)
            title += ' for %s' % rel.long_name
        if not show_expired:
            query.append(BuildRootOverride.q.date_expired == None)

        overrides = BuildRootOverride.select(AND(*query))

        if request_format() == 'json':
            overrides = [o.__json__() for o in overrides]
            num_items = len(overrides)
        else:
            num_items = overrides.count()
        return dict(overrides=overrides,
                    title=title % num_items,
                    num_items=num_items,
                    show_expired=show_expired,
                    mine=mine)

    @identity.require(identity.not_anonymous())
    @expose(template="bodhi.templates.form")
    def new(self, tg_errors=None, *args, **kw):
        if tg_errors:
            flash(str(tg_errors))
        expiration = datetime.utcnow() + \
            timedelta(days=config.get('buildroot_overrides.expire_after', 1))
        return dict(form=override_form,
                    values={'expiration': expiration},
                    action=url('/override/save'),
                    title='Buildroot Overrides')

    @identity.require(identity.not_anonymous())
    @expose(allow_json=True)
    def expire(self, build, *args, **kw):
        """ Expire a given override """
        override = BuildRootOverride.byBuild(build)
        if override.date_expired:
            flash('Override %s already expired!' % build)
            if request_format() == 'json': return dict()
            raise redirect('/override')
        override.date_expired = datetime.utcnow()
        try:
            override.untag()
        except Exception, e:
            log.error(str(e))
            flash(str(e))
            raise redirect('/override')
        log.info('Buildroot override %s manually expired by %s' %
                 (build, identity.current.user_name))
        flash('Buildroot override for %s successful untagged' % build)
        if request_format() == 'json': return dict()
        raise redirect('/override')