Beispiel #1
0
 def validate_python(self, value, state):
     try:
         User.query().filter(User.active == True) \
             .filter(User.username == value).one()
     except sqlalchemy.exc.InvalidRequestError: # NoResultFound/MultipleResultsFound
         msg = M(self, 'invalid_username', state, username=value)
         raise formencode.Invalid(msg, value, state,
             error_dict=dict(username=msg)
         )
Beispiel #2
0
 def validate_python(self, value, state):
     try:
         User.query().filter(User.active == True) \
             .filter(User.username == value).one()
     except sqlalchemy.exc.InvalidRequestError:  # NoResultFound/MultipleResultsFound
         msg = self.message('invalid_username', state, username=value)
         raise formencode.Invalid(msg,
                                  value,
                                  state,
                                  error_dict=dict(username=msg))
Beispiel #3
0
    def index(self, format='html'):
        """GET /users: All items in the collection"""
        # url('users')

        c.users_list = User.query().order_by(User.username)\
                        .filter(User.username != User.DEFAULT_USER)\
                        .order_by(func.lower(User.username))\
                        .all()

        users_data = []
        total_records = len(c.users_list)
        _tmpl_lookup = kallithea.CONFIG['pylons.app_globals'].mako_lookup
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')

        grav_tmpl = '<div class="gravatar">%s</div>'

        username = lambda user_id, username: (template.get_def(
            "user_name").render(user_id, username, _=_, h=h, c=c))

        user_actions = lambda user_id, username: (template.get_def(
            "user_actions").render(user_id, username, _=_, h=h, c=c))

        for user in c.users_list:
            users_data.append({
                "gravatar":
                grav_tmpl % h.gravatar(user.email, size=20),
                "raw_name":
                user.username,
                "username":
                username(user.user_id, user.username),
                "firstname":
                user.name,
                "lastname":
                user.lastname,
                "last_login":
                h.fmt_date(user.last_login),
                "last_login_raw":
                datetime_to_time(user.last_login),
                "active":
                h.boolicon(user.active),
                "admin":
                h.boolicon(user.admin),
                "extern_type":
                user.extern_type,
                "extern_name":
                user.extern_name,
                "action":
                user_actions(user.user_id, user.username),
            })

        c.data = json.dumps({
            "totalRecords": total_records,
            "startIndex": 0,
            "sort": None,
            "dir": "asc",
            "records": users_data
        })

        return render('admin/users/users.html')
    def __load_data(self, user_group_id):
        c.group_members_obj = sorted((x.user for x in c.user_group.members),
                                     key=lambda u: u.username.lower())

        c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
        c.available_members = sorted(((x.user_id, x.username) for x in
                                      User.query().all()),
                                     key=lambda u: u[1].lower())
Beispiel #5
0
    def __load_data(self, user_group_id):
        c.group_members_obj = sorted((x.user for x in c.user_group.members),
                                     key=lambda u: u.username.lower())

        c.group_members = [(x.user_id, x.username)
                           for x in c.group_members_obj]
        c.available_members = sorted(
            ((x.user_id, x.username) for x in User.query().all()),
            key=lambda u: u[1].lower())
Beispiel #6
0
    def _get_defaults(self, repo_name):
        """
        Gets information about repository, and returns a dict for
        usage in forms

        :param repo_name:
        """

        repo_info = Repository.get_by_repo_name(repo_name)

        if repo_info is None:
            return None

        defaults = repo_info.get_dict()
        group, repo_name, repo_name_full = repo_info.groups_and_repo
        defaults['repo_name'] = repo_name
        defaults['repo_group'] = getattr(group[-1] if group else None,
                                         'group_id', None)

        for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
                         (1, 'repo_description'), (1, 'repo_enable_locking'),
                         (1, 'repo_landing_rev'), (0, 'clone_uri'),
                         (1, 'repo_private'), (1, 'repo_enable_statistics')]:
            attr = k
            if strip:
                attr = remove_prefix(k, 'repo_')

            val = defaults[attr]
            if k == 'repo_landing_rev':
                val = ':'.join(defaults[attr])
            defaults[k] = val
            if k == 'clone_uri':
                defaults['clone_uri_hidden'] = repo_info.clone_uri_hidden

        # fill owner
        if repo_info.user:
            defaults.update({'user': repo_info.user.username})
        else:
            replacement_user = User.query().filter(
                User.admin == True).first().username
            defaults.update({'user': replacement_user})

        # fill repository users
        for p in repo_info.repo_to_perm:
            defaults.update(
                {'u_perm_%s' % p.user.username: p.permission.permission_name})

        # fill repository groups
        for p in repo_info.users_group_to_perm:
            defaults.update({
                'g_perm_%s' % p.users_group.users_group_name:
                p.permission.permission_name
            })

        return defaults
Beispiel #7
0
    def _get_defaults(self, repo_name):
        """
        Gets information about repository, and returns a dict for
        usage in forms

        :param repo_name:
        """

        repo_info = Repository.get_by_repo_name(repo_name)

        if repo_info is None:
            return None

        defaults = repo_info.get_dict()
        group, repo_name, repo_name_full = repo_info.groups_and_repo
        defaults['repo_name'] = repo_name
        defaults['repo_group'] = getattr(group[-1] if group else None,
                                         'group_id', None)

        for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
                         (1, 'repo_description'), (1, 'repo_enable_locking'),
                         (1, 'repo_landing_rev'), (0, 'clone_uri'),
                         (1, 'repo_private'), (1, 'repo_enable_statistics')]:
            attr = k
            if strip:
                attr = remove_prefix(k, 'repo_')

            val = defaults[attr]
            if k == 'repo_landing_rev':
                val = ':'.join(defaults[attr])
            defaults[k] = val
            if k == 'clone_uri':
                defaults['clone_uri_hidden'] = repo_info.clone_uri_hidden

        # fill owner
        if repo_info.user:
            defaults.update({'user': repo_info.user.username})
        else:
            replacement_user = User.query().filter(User.admin ==
                                                   True).first().username
            defaults.update({'user': replacement_user})

        # fill repository users
        for p in repo_info.repo_to_perm:
            defaults.update({'u_perm_%s' % p.user.username:
                                 p.permission.permission_name})

        # fill repository groups
        for p in repo_info.users_group_to_perm:
            defaults.update({'g_perm_%s' % p.users_group.users_group_name:
                                 p.permission.permission_name})

        return defaults
Beispiel #8
0
    def fix_default_user(self):
        """
        Fixes a old default user with some 'nicer' default values,
        used mostly for anonymous access
        """
        def_user = User.query().filter_by(is_default_user=True).one()

        def_user.name = 'Anonymous'
        def_user.lastname = 'User'
        def_user.email = '*****@*****.**'

        self.sa.commit()
Beispiel #9
0
    def fix_default_user(self):
        """
        Fixes a old default user with some 'nicer' default values,
        used mostly for anonymous access
        """
        def_user = User.query().filter_by(is_default_user=True).one()

        def_user.name = 'Anonymous'
        def_user.lastname = 'User'
        def_user.email = '*****@*****.**'

        self.sa.commit()
Beispiel #10
0
def send_email(recipients, subject, body='', html_body='', headers=None):
    """
    Sends an email with defined parameters from the .ini files.

    :param recipients: list of recipients, if this is None, the defined email
        address from field 'email_to' and all admins is used instead
    :param subject: subject of the mail
    :param body: body of the mail
    :param html_body: html version of body
    """
    log = get_logger(send_email)
    assert isinstance(recipients, list), recipients

    email_config = config
    email_prefix = email_config.get('email_prefix', '')
    if email_prefix:
        subject = "%s %s" % (email_prefix, subject)
    if recipients is None:
        # if recipients are not defined we send to email_config + all admins
        admins = [u.email for u in User.query()
                  .filter(User.admin == True).all()]
        recipients = [email_config.get('email_to')] + admins
        log.warning("recipients not specified for '%s' - sending to admins %s", subject, ' '.join(recipients))
    elif not recipients:
        log.error("No recipients specified")
        return False

    mail_from = email_config.get('app_email_from', 'Kallithea')
    user = email_config.get('smtp_username')
    passwd = email_config.get('smtp_password')
    mail_server = email_config.get('smtp_server')
    mail_port = email_config.get('smtp_port')
    tls = str2bool(email_config.get('smtp_use_tls'))
    ssl = str2bool(email_config.get('smtp_use_ssl'))
    debug = str2bool(email_config.get('debug'))
    smtp_auth = email_config.get('smtp_auth')

    if not mail_server:
        log.error("SMTP mail server not configured - cannot send mail '%s' to %s", subject, ' '.join(recipients))
        log.warning("body:\n%s", body)
        log.warning("html:\n%s", html_body)
        return False

    try:
        m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
                       mail_port, ssl, tls, debug=debug)
        m.send(recipients, subject, body, html_body, headers=headers)
    except:
        log.error('Mail sending failed')
        log.error(traceback.format_exc())
        return False
    return True
Beispiel #11
0
 def get_users_js(self):
     users = User.query() \
         .filter(User.active == True) \
         .order_by(User.name, User.lastname) \
         .all()
     return [
         {
             'id': u.user_id,
             'fname': h.escape(u.name),
             'lname': h.escape(u.lastname),
             'nname': u.username,
             'gravatar_lnk': h.gravatar_url(u.email, size=28, default='default'),
             'gravatar_size': 14,
         } for u in users]
Beispiel #12
0
    def index(self, format='html'):
        """GET /users: All items in the collection"""
        # url('users')

        c.users_list = User.query().order_by(User.username) \
                        .filter(User.username != User.DEFAULT_USER) \
                        .order_by(func.lower(User.username)) \
                        .all()

        users_data = []
        total_records = len(c.users_list)
        _tmpl_lookup = kallithea.CONFIG['pylons.app_globals'].mako_lookup
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')

        grav_tmpl = '<div class="gravatar">%s</div>'

        username = lambda user_id, username: (
                template.get_def("user_name")
                .render(user_id, username, _=_, h=h, c=c))

        user_actions = lambda user_id, username: (
                template.get_def("user_actions")
                .render(user_id, username, _=_, h=h, c=c))

        for user in c.users_list:
            users_data.append({
                "gravatar": grav_tmpl % h.gravatar(user.email, size=20),
                "raw_name": user.username,
                "username": username(user.user_id, user.username),
                "firstname": h.escape(user.name),
                "lastname": h.escape(user.lastname),
                "last_login": h.fmt_date(user.last_login),
                "last_login_raw": datetime_to_time(user.last_login),
                "active": h.boolicon(user.active),
                "admin": h.boolicon(user.admin),
                "extern_type": user.extern_type,
                "extern_name": user.extern_name,
                "action": user_actions(user.user_id, user.username),
            })

        c.data = json.dumps({
            "totalRecords": total_records,
            "startIndex": 0,
            "sort": None,
            "dir": "asc",
            "records": users_data
        })

        return render('admin/users/users.html')
Beispiel #13
0
    def index(self, format='html'):
        c.users_list = User.query().order_by(User.username) \
                        .filter_by(is_default_user=False) \
                        .order_by(func.lower(User.username)) \
                        .all()

        users_data = []
        total_records = len(c.users_list)
        _tmpl_lookup = app_globals.mako_lookup
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')

        grav_tmpl = '<div class="gravatar">%s</div>'

        username = lambda user_id, username: (
                template.get_def("user_name")
                .render(user_id, username, _=_, h=h, c=c))

        user_actions = lambda user_id, username: (
                template.get_def("user_actions")
                .render(user_id, username, _=_, h=h, c=c))

        for user in c.users_list:
            users_data.append({
                "gravatar": grav_tmpl % h.gravatar(user.email, size=20),
                "raw_name": user.username,
                "username": username(user.user_id, user.username),
                "firstname": h.escape(user.name),
                "lastname": h.escape(user.lastname),
                "last_login": h.fmt_date(user.last_login),
                "last_login_raw": datetime_to_time(user.last_login),
                "active": h.boolicon(user.active),
                "admin": h.boolicon(user.admin),
                "extern_type": user.extern_type,
                "extern_name": user.extern_name,
                "action": user_actions(user.user_id, user.username),
            })

        c.data = {
            "totalRecords": total_records,
            "startIndex": 0,
            "sort": None,
            "dir": "asc",
            "records": users_data
        }

        return render('admin/users/users.html')
Beispiel #14
0
 def get_users_js(self):
     users = User.query() \
         .filter(User.active == True) \
         .order_by(User.name, User.lastname) \
         .all()
     return [{
         'id':
         u.user_id,
         'fname':
         h.escape(u.name),
         'lname':
         h.escape(u.lastname),
         'nname':
         u.username,
         'gravatar_lnk':
         h.gravatar_url(u.email, size=28, default='default'),
         'gravatar_size':
         14,
     } for u in users]
Beispiel #15
0
def send_email(recipients, subject, body='', html_body='', headers=None):
    """
    Sends an email with defined parameters from the .ini files.

    :param recipients: list of recipients, if this is None, the defined email
        address from field 'email_to' and all admins is used instead
    :param subject: subject of the mail
    :param body: body of the mail
    :param html_body: html version of body
    """
    log = get_logger(send_email)
    assert isinstance(recipients, list), recipients

    email_config = config
    email_prefix = email_config.get('email_prefix', '')
    if email_prefix:
        subject = "%s %s" % (email_prefix, subject)
    if recipients is None:
        # if recipients are not defined we send to email_config + all admins
        admins = [
            u.email for u in User.query().filter(User.admin == True).all()
        ]
        recipients = [email_config.get('email_to')] + admins
        log.warning("recipients not specified for '%s' - sending to admins %s",
                    subject, ' '.join(recipients))
    elif not recipients:
        log.error("No recipients specified")
        return False

    mail_from = email_config.get('app_email_from', 'Kallithea')
    user = email_config.get('smtp_username')
    passwd = email_config.get('smtp_password')
    mail_server = email_config.get('smtp_server')
    mail_port = email_config.get('smtp_port')
    tls = str2bool(email_config.get('smtp_use_tls'))
    ssl = str2bool(email_config.get('smtp_use_ssl'))
    debug = str2bool(email_config.get('debug'))
    smtp_auth = email_config.get('smtp_auth')

    if not mail_server:
        log.error(
            "SMTP mail server not configured - cannot send mail '%s' to %s",
            subject, ' '.join(recipients))
        log.warning("body:\n%s", body)
        log.warning("html:\n%s", html_body)
        return False

    try:
        m = SmtpMailer(mail_from,
                       user,
                       passwd,
                       mail_server,
                       smtp_auth,
                       mail_port,
                       ssl,
                       tls,
                       debug=debug)
        m.send(recipients, subject, body, html_body, headers=headers)
    except:
        log.error('Mail sending failed')
        log.error(traceback.format_exc())
        return False
    return True
Beispiel #16
0
    def users_and_groups_data(self):
        """
        Returns 'results' with a list of users and user groups.

        You can either use the 'key' GET parameter to get a user by providing
        the exact user key or you can use the 'query' parameter to
        search for users by user key, first name and last name.
        'types' defaults to just 'users' but can be set to 'users,groups' to
        get both users and groups.
        No more than 500 results (of each kind) will be returned.
        """
        types = request.GET.get('types', 'users').split(',')
        key = request.GET.get('key', '')
        query = request.GET.get('query', '')
        results = []
        if 'users' in types:
            user_list = []
            if key:
                u = User.get_by_username(key)
                if u:
                    user_list = [u]
            elif query:
                user_list = User.query() \
                    .filter(User.is_default_user == False) \
                    .filter(User.active == True) \
                    .filter(or_(
                        User.username.ilike("%%" + query + "%%"),
                        User.name.ilike("%%" + query + "%%"),
                        User.lastname.ilike("%%" + query + "%%"),
                    )) \
                    .order_by(User.username) \
                    .limit(500) \
                    .all()
            for u in user_list:
                results.append({
                    'type':
                    'user',
                    'id':
                    u.user_id,
                    'nname':
                    u.username,
                    'fname':
                    u.name,
                    'lname':
                    u.lastname,
                    'gravatar_lnk':
                    h.gravatar_url(u.email, size=28, default='default'),
                    'gravatar_size':
                    14,
                })
        if 'groups' in types:
            grp_list = []
            if key:
                grp = UserGroup.get_by_group_name(key)
                if grp:
                    grp_list = [grp]
            elif query:
                grp_list = UserGroup.query() \
                    .filter(UserGroup.users_group_name.ilike("%%" + query + "%%")) \
                    .filter(UserGroup.users_group_active == True) \
                    .order_by(UserGroup.users_group_name) \
                    .limit(500) \
                    .all()
            for g in UserGroupList(grp_list, perm_level='read'):
                results.append({
                    'type': 'group',
                    'id': g.users_group_id,
                    'grname': g.users_group_name,
                })
        return dict(results=results)
Beispiel #17
0
    def create(self,
               created_by,
               subject,
               body,
               recipients=None,
               type_=Notification.TYPE_MESSAGE,
               with_email=True,
               email_kwargs={}):
        """

        Creates notification of given type

        :param created_by: int, str or User instance. User who created this
            notification
        :param subject:
        :param body:
        :param recipients: list of int, str or User objects, when None
            is given send to all admins
        :param type_: type of notification
        :param with_email: send email with this notification
        :param email_kwargs: additional dict to pass as args to email template
        """
        from kallithea.lib.celerylib import tasks, run_task

        if recipients and not getattr(recipients, '__iter__', False):
            raise Exception('recipients must be a list or iterable')

        created_by_obj = self._get_user(created_by)

        recipients_objs = []
        if recipients:
            for u in recipients:
                obj = self._get_user(u)
                if obj:
                    recipients_objs.append(obj)
                else:
                    # TODO: inform user that requested operation couldn't be completed
                    log.error('cannot email unknown user %r', u)
            recipients_objs = set(recipients_objs)
            log.debug('sending notifications %s to %s' %
                      (type_, recipients_objs))
        elif recipients is None:
            # empty recipients means to all admins
            recipients_objs = User.query().filter(User.admin == True).all()
            log.debug('sending notifications %s to admins: %s' %
                      (type_, recipients_objs))
        #else: silently skip notification mails?

        # TODO: inform user who are notified
        notif = Notification.create(created_by=created_by_obj,
                                    subject=subject,
                                    body=body,
                                    recipients=recipients_objs,
                                    type_=type_)

        if not with_email:
            return notif

        #don't send email to person who created this comment
        rec_objs = set(recipients_objs).difference(set([created_by_obj]))

        headers = None
        if 'threading' in email_kwargs:
            headers = {
                'References':
                ' '.join('<%s>' % x for x in email_kwargs['threading'])
            }

        # send email with notification to all other participants
        for rec in rec_objs:
            ## this is passed into template
            html_kwargs = {
                'subject': subject,
                'body': h.rst_w_mentions(body),
                'when': h.fmt_date(notif.created_on),
                'user': notif.created_by_user.username,
            }

            txt_kwargs = {
                'subject': subject,
                'body': body,
                'when': h.fmt_date(notif.created_on),
                'user': notif.created_by_user.username,
            }

            html_kwargs.update(email_kwargs)
            txt_kwargs.update(email_kwargs)
            email_subject = EmailNotificationModel()\
                                .get_email_description(type_, **txt_kwargs)
            email_txt_body = EmailNotificationModel()\
                                .get_email_tmpl(type_, 'txt', **txt_kwargs)
            email_html_body = EmailNotificationModel()\
                                .get_email_tmpl(type_, 'html', **html_kwargs)

            run_task(tasks.send_email, [rec.email], email_subject,
                     email_txt_body, email_html_body, headers)

        return notif
Beispiel #18
0
    def create(self,
               created_by,
               subject,
               body,
               recipients=None,
               type_=TYPE_MESSAGE,
               with_email=True,
               email_kwargs=None,
               repo_name=None):
        """

        Creates notification of given type

        :param created_by: int, str or User instance. User who created this
            notification
        :param subject:
        :param body:
        :param recipients: list of int, str or User objects, when None
            is given send to all admins
        :param type_: type of notification
        :param with_email: send email with this notification
        :param email_kwargs: additional dict to pass as args to email template
        """
        from kallithea.lib.celerylib import tasks
        email_kwargs = email_kwargs or {}
        if recipients and not getattr(recipients, '__iter__', False):
            raise Exception('recipients must be a list or iterable')

        created_by_obj = User.guess_instance(created_by)

        recipients_objs = set()
        if recipients:
            for u in recipients:
                obj = User.guess_instance(u)
                if obj is not None:
                    recipients_objs.add(obj)
                else:
                    # TODO: inform user that requested operation couldn't be completed
                    log.error('cannot email unknown user %r', u)
            log.debug('sending notifications %s to %s', type_, recipients_objs)
        elif recipients is None:
            # empty recipients means to all admins
            recipients_objs = User.query().filter(User.admin == True).all()
            log.debug('sending notifications %s to admins: %s', type_,
                      recipients_objs)
        #else: silently skip notification mails?

        if not with_email:
            return

        headers = {}
        headers['X-Kallithea-Notification-Type'] = type_
        if 'threading' in email_kwargs:
            headers['References'] = ' '.join(
                '<%s>' % x for x in email_kwargs['threading'])

        # this is passed into template
        created_on = h.fmt_date(datetime.datetime.now())
        html_kwargs = {
            'subject': subject,
            'body': h.render_w_mentions(body, repo_name),
            'when': created_on,
            'user': created_by_obj.username,
        }

        txt_kwargs = {
            'subject': subject,
            'body': body,
            'when': created_on,
            'user': created_by_obj.username,
        }

        html_kwargs.update(email_kwargs)
        txt_kwargs.update(email_kwargs)
        email_subject = EmailNotificationModel() \
                            .get_email_description(type_, **txt_kwargs)
        email_txt_body = EmailNotificationModel() \
                            .get_email_tmpl(type_, 'txt', **txt_kwargs)
        email_html_body = EmailNotificationModel() \
                            .get_email_tmpl(type_, 'html', **html_kwargs)

        # don't send email to person who created this comment
        rec_objs = set(recipients_objs).difference(set([created_by_obj]))

        # send email with notification to all other participants
        for rec in rec_objs:
            tasks.send_email([rec.email],
                             email_subject,
                             email_txt_body,
                             email_html_body,
                             headers,
                             from_name=created_by_obj.full_name_or_username)
Beispiel #19
0
def send_email(recipients,
               subject,
               body='',
               html_body='',
               headers=None,
               from_name=None):
    """
    Sends an email with defined parameters from the .ini files.

    :param recipients: list of recipients, if this is None, the defined email
        address from field 'email_to' and all admins is used instead
    :param subject: subject of the mail
    :param body: body of the mail
    :param html_body: html version of body
    :param headers: dictionary of prepopulated e-mail headers
    :param from_name: full name to be used as sender of this mail - often a
    .full_name_or_username value
    """
    assert isinstance(recipients, list), recipients
    if headers is None:
        headers = {}
    else:
        # do not modify the original headers object passed by the caller
        headers = headers.copy()

    email_config = config
    email_prefix = email_config.get('email_prefix', '')
    if email_prefix:
        subject = "%s %s" % (email_prefix, subject)

    if not recipients:
        # if recipients are not defined we send to email_config + all admins
        recipients = [
            u.email for u in User.query().filter(User.admin == True).all()
        ]
        if email_config.get('email_to') is not None:
            recipients += email_config.get('email_to').split(',')

        # If there are still no recipients, there are no admins and no address
        # configured in email_to, so return.
        if not recipients:
            log.error("No recipients specified and no fallback available.")
            return False

        log.warning("No recipients specified for '%s' - sending to admins %s",
                    subject, ' '.join(recipients))

    # SMTP sender
    envelope_from = email_config.get('app_email_from', 'Kallithea')
    # 'From' header
    if from_name is not None:
        # set From header based on from_name but with a generic e-mail address
        # In case app_email_from is in "Some Name <e-mail>" format, we first
        # extract the e-mail address.
        envelope_addr = author_email(envelope_from)
        headers['From'] = '"%s" <%s>' % (email.utils.quote(
            '%s (no-reply)' % from_name), envelope_addr)

    user = email_config.get('smtp_username')
    passwd = email_config.get('smtp_password')
    mail_server = email_config.get('smtp_server')
    mail_port = email_config.get('smtp_port')
    tls = str2bool(email_config.get('smtp_use_tls'))
    ssl = str2bool(email_config.get('smtp_use_ssl'))
    debug = str2bool(email_config.get('debug'))
    smtp_auth = email_config.get('smtp_auth')

    logmsg = ("Mail details:\n"
              "recipients: %s\n"
              "headers: %s\n"
              "subject: %s\n"
              "body:\n%s\n"
              "html:\n%s\n" %
              (' '.join(recipients), headers, subject, body, html_body))

    if mail_server:
        log.debug("Sending e-mail. " + logmsg)
    else:
        log.error("SMTP mail server not configured - cannot send e-mail.")
        log.warning(logmsg)
        return False

    try:
        m = SmtpMailer(envelope_from,
                       user,
                       passwd,
                       mail_server,
                       smtp_auth,
                       mail_port,
                       ssl,
                       tls,
                       debug=debug)
        m.send(recipients, subject, body, html_body, headers=headers)
    except:
        log.error('Mail sending failed')
        log.error(traceback.format_exc())
        return False
    return True
Beispiel #20
0
        def to_python(self, value, state):
            perms_update = OrderedSet()
            perms_new = OrderedSet()
            # build a list of permission to update and new permission to create

            #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using
            new_perms_group = defaultdict(dict)
            for k, v in value.copy().iteritems():
                if k.startswith('perm_new_member'):
                    del value[k]
                    _type, part = k.split('perm_new_member_')
                    args = part.split('_')
                    if len(args) == 1:
                        new_perms_group[args[0]]['perm'] = v
                    elif len(args) == 2:
                        _key, pos = args
                        new_perms_group[pos][_key] = v

            # fill new permissions in order of how they were added
            for k in sorted(map(int, new_perms_group.keys())):
                perm_dict = new_perms_group[str(k)]
                new_member = perm_dict.get('name')
                new_perm = perm_dict.get('perm')
                new_type = perm_dict.get('type')
                if new_member and new_perm and new_type:
                    perms_new.add((new_member, new_perm, new_type))

            for k, v in value.iteritems():
                if k.startswith('u_perm_') or k.startswith('g_perm_'):
                    member = k[7:]
                    t = {'u': 'user', 'g': 'users_group'}[k[0]]
                    if member == User.DEFAULT_USER:
                        if str2bool(value.get('repo_private')):
                            # set none for default when updating to
                            # private repo protects against form manipulation
                            v = EMPTY_PERM
                    perms_update.add((member, v, t))

            value['perms_updates'] = list(perms_update)
            value['perms_new'] = list(perms_new)

            # update permissions
            for k, v, t in perms_new:
                try:
                    if t is 'user':
                        self.user_db = User.query() \
                            .filter(User.active == True) \
                            .filter(User.username == k).one()
                    if t is 'users_group':
                        self.user_db = UserGroup.query() \
                            .filter(UserGroup.users_group_active == True) \
                            .filter(UserGroup.users_group_name == k).one()

                except Exception:
                    log.exception('Updated permission failed')
                    msg = self.message('perm_new_member_type', state)
                    raise formencode.Invalid(
                        msg,
                        value,
                        state,
                        error_dict=dict(perm_new_member_name=msg))
            return value
Beispiel #21
0
def send_email(recipients, subject, body='', html_body='', headers=None, author=None):
    """
    Sends an email with defined parameters from the .ini files.

    :param recipients: list of recipients, if this is None, the defined email
        address from field 'email_to' and all admins is used instead
    :param subject: subject of the mail
    :param body: body of the mail
    :param html_body: html version of body
    :param headers: dictionary of prepopulated e-mail headers
    :param author: User object of the author of this mail, if known and relevant
    """
    log = get_logger(send_email)
    assert isinstance(recipients, list), recipients
    if headers is None:
        headers = {}
    else:
        # do not modify the original headers object passed by the caller
        headers = headers.copy()

    email_config = config
    email_prefix = email_config.get('email_prefix', '')
    if email_prefix:
        subject = "%s %s" % (email_prefix, subject)

    if not recipients:
        # if recipients are not defined we send to email_config + all admins
        recipients = [u.email for u in User.query()
                      .filter(User.admin == True).all()]
        if email_config.get('email_to') is not None:
            recipients += [email_config.get('email_to')]

        # If there are still no recipients, there are no admins and no address
        # configured in email_to, so return.
        if not recipients:
            log.error("No recipients specified and no fallback available.")
            return False

        log.warning("No recipients specified for '%s' - sending to admins %s", subject, ' '.join(recipients))

    # SMTP sender
    envelope_from = email_config.get('app_email_from', 'Kallithea')
    # 'From' header
    if author is not None:
        # set From header based on author but with a generic e-mail address
        # In case app_email_from is in "Some Name <e-mail>" format, we first
        # extract the e-mail address.
        envelope_addr = author_email(envelope_from)
        headers['From'] = '"%s" <%s>' % (
            rfc822.quote('%s (no-reply)' % author.full_name_or_username),
            envelope_addr)

    user = email_config.get('smtp_username')
    passwd = email_config.get('smtp_password')
    mail_server = email_config.get('smtp_server')
    mail_port = email_config.get('smtp_port')
    tls = str2bool(email_config.get('smtp_use_tls'))
    ssl = str2bool(email_config.get('smtp_use_ssl'))
    debug = str2bool(email_config.get('debug'))
    smtp_auth = email_config.get('smtp_auth')

    logmsg = ("Mail details:\n"
              "recipients: %s\n"
              "headers: %s\n"
              "subject: %s\n"
              "body:\n%s\n"
              "html:\n%s\n"
              % (' '.join(recipients), headers, subject, body, html_body))

    if mail_server:
        log.debug("Sending e-mail. " + logmsg)
    else:
        log.error("SMTP mail server not configured - cannot send e-mail.")
        log.warning(logmsg)
        return False

    try:
        m = SmtpMailer(envelope_from, user, passwd, mail_server, smtp_auth,
                       mail_port, ssl, tls, debug=debug)
        m.send(recipients, subject, body, html_body, headers=headers)
    except:
        log.error('Mail sending failed')
        log.error(traceback.format_exc())
        return False
    return True
Beispiel #22
0
        def to_python(self, value, state):
            perms_update = OrderedSet()
            perms_new = OrderedSet()
            # build a list of permission to update and new permission to create

            #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using
            new_perms_group = defaultdict(dict)
            for k, v in value.copy().iteritems():
                if k.startswith('perm_new_member'):
                    del value[k]
                    _type, part = k.split('perm_new_member_')
                    args = part.split('_')
                    if len(args) == 1:
                        new_perms_group[args[0]]['perm'] = v
                    elif len(args) == 2:
                        _key, pos = args
                        new_perms_group[pos][_key] = v

            # fill new permissions in order of how they were added
            for k in sorted(map(int, new_perms_group.keys())):
                perm_dict = new_perms_group[str(k)]
                new_member = perm_dict.get('name')
                new_perm = perm_dict.get('perm')
                new_type = perm_dict.get('type')
                if new_member and new_perm and new_type:
                    perms_new.add((new_member, new_perm, new_type))

            for k, v in value.iteritems():
                if k.startswith('u_perm_') or k.startswith('g_perm_'):
                    member = k[7:]
                    t = {'u': 'user',
                         'g': 'users_group'
                    }[k[0]]
                    if member == User.DEFAULT_USER:
                        if str2bool(value.get('repo_private')):
                            # set none for default when updating to
                            # private repo protects against form manipulation
                            v = EMPTY_PERM
                    perms_update.add((member, v, t))

            value['perms_updates'] = list(perms_update)
            value['perms_new'] = list(perms_new)

            # update permissions
            for k, v, t in perms_new:
                try:
                    if t is 'user':
                        self.user_db = User.query() \
                            .filter(User.active == True) \
                            .filter(User.username == k).one()
                    if t is 'users_group':
                        self.user_db = UserGroup.query() \
                            .filter(UserGroup.users_group_active == True) \
                            .filter(UserGroup.users_group_name == k).one()

                except Exception:
                    log.exception('Updated permission failed')
                    msg = M(self, 'perm_new_member_type', state)
                    raise formencode.Invalid(msg, value, state,
                        error_dict=dict(perm_new_member_name=msg)
                    )
            return value
Beispiel #23
0
    def create(self, created_by, subject, body, recipients=None,
               type_=Notification.TYPE_MESSAGE, with_email=True,
               email_kwargs=None, repo_name=None):
        """

        Creates notification of given type

        :param created_by: int, str or User instance. User who created this
            notification
        :param subject:
        :param body:
        :param recipients: list of int, str or User objects, when None
            is given send to all admins
        :param type_: type of notification
        :param with_email: send email with this notification
        :param email_kwargs: additional dict to pass as args to email template
        """
        from kallithea.lib.celerylib import tasks, run_task
        email_kwargs = email_kwargs or {}
        if recipients and not getattr(recipients, '__iter__', False):
            raise Exception('recipients must be a list or iterable')

        created_by_obj = self._get_user(created_by)

        recipients_objs = []
        if recipients:
            for u in recipients:
                obj = self._get_user(u)
                if obj is not None:
                    recipients_objs.append(obj)
                else:
                    # TODO: inform user that requested operation couldn't be completed
                    log.error('cannot email unknown user %r', u)
            recipients_objs = set(recipients_objs)
            log.debug('sending notifications %s to %s',
                type_, recipients_objs
            )
        elif recipients is None:
            # empty recipients means to all admins
            recipients_objs = User.query().filter(User.admin == True).all()
            log.debug('sending notifications %s to admins: %s',
                type_, recipients_objs
            )
        #else: silently skip notification mails?

        # TODO: inform user who are notified
        notif = Notification.create(
            created_by=created_by_obj, subject=subject,
            body=body, recipients=recipients_objs, type_=type_
        )

        if not with_email:
            return notif

        #don't send email to person who created this comment
        rec_objs = set(recipients_objs).difference(set([created_by_obj]))

        headers = None
        if 'threading' in email_kwargs:
            headers = {'References': ' '.join('<%s>' % x for x in email_kwargs['threading'])}

        # send email with notification to all other participants
        for rec in rec_objs:
            ## this is passed into template
            html_kwargs = {
                      'subject': subject,
                      'body': h.render_w_mentions(body, repo_name),
                      'when': h.fmt_date(notif.created_on),
                      'user': notif.created_by_user.username,
                      }

            txt_kwargs = {
                      'subject': subject,
                      'body': body,
                      'when': h.fmt_date(notif.created_on),
                      'user': notif.created_by_user.username,
                      }

            html_kwargs.update(email_kwargs)
            txt_kwargs.update(email_kwargs)
            email_subject = EmailNotificationModel() \
                                .get_email_description(type_, **txt_kwargs)
            email_txt_body = EmailNotificationModel() \
                                .get_email_tmpl(type_, 'txt', **txt_kwargs)
            email_html_body = EmailNotificationModel() \
                                .get_email_tmpl(type_, 'html', **html_kwargs)

            run_task(tasks.send_email, [rec.email], email_subject, email_txt_body,
                     email_html_body, headers, author=created_by_obj)

        return notif
Beispiel #24
0
 def get(self, user_id):
     user = User.query()
     return user.get(user_id)
Beispiel #25
0
 def get(self, user_id, cache=False):
     user = User.query()
     if cache:
         user = user.options(FromCache("sql_cache_short",
                                       "get_user_%s" % user_id))
     return user.get(user_id)