Exemplo n.º 1
0
def sendVerificationMail(db, user, email_id=None):
    cursor = db.cursor()

    if email_id is None:
        cursor.execute("""SELECT email
                            FROM users
                           WHERE id=%s""",
                       (user.id,))

        email_id, = cursor.fetchone()

    cursor.execute("""SELECT email, verification_token
                        FROM useremails
                       WHERE id=%s""",
                   (email_id,))

    email, verification_token = cursor.fetchone()

    if verification_token is None:
        verification_token = auth.getToken(encode=base64.b16encode)

        with db.updating_cursor("useremails") as cursor:
            cursor.execute("""UPDATE useremails
                                 SET verification_token=%s
                               WHERE id=%s""",
                           (verification_token, email_id))

    if configuration.base.ACCESS_SCHEME == "http":
        protocol = "http"
    else:
        protocol = "https"

    administrators = dbutils.getAdministratorContacts(db, indent=2)

    if administrators:
        administrators = ":\n\n%s" % administrators
    else:
        administrators = "."

    recipients = [mailutils.User(user.name, email, user.fullname)]
    subject = "[Critic] Please verify your email: %s" % email
    body = textutils.reflow("""
This is a message from the Critic code review system at %(hostname)s.  The user
'%(username)s' on this system has added this email address to his/her account.
If this is you, please confirm this by following this link:

  %(url_prefix)s/verifyemail?email=%(email)s&token=%(verification_token)s

If this is not you, you can safely ignore this email.  If you wish to report
abuse, please contact the Critic system's administrators%(administrators)s
""" % { "hostname": configuration.base.HOSTNAME,
        "username": user.name,
        "email": email,
        "url_prefix": "%s://%s" % (protocol, configuration.base.HOSTNAME),
        "verification_token": verification_token,
        "administrators": administrators })

    mailutils.sendMessage(recipients, subject, body)
Exemplo n.º 2
0
def sendVerificationMail(db, user, email_id=None):
    cursor = db.cursor()

    if email_id is None:
        cursor.execute("""SELECT email
                            FROM users
                           WHERE id=%s""",
                       (user.id,))

        email_id, = cursor.fetchone()

    cursor.execute("""SELECT email, verification_token
                        FROM useremails
                       WHERE id=%s""",
                   (email_id,))

    email, verification_token = cursor.fetchone()

    if verification_token is None:
        verification_token = auth.getToken(encode=base64.b16encode)

        cursor.execute("""UPDATE useremails
                             SET verification_token=%s
                           WHERE id=%s""",
                       (verification_token, email_id))

    if configuration.base.ACCESS_SCHEME == "http":
        protocol = "http"
    else:
        protocol = "https"

    administrators = dbutils.getAdministratorContacts(db, indent=2)

    if administrators:
        administrators = ":\n\n%s" % administrators
    else:
        administrators = "."

    recipients = [mailutils.User(user.name, email, user.fullname)]
    subject = "[Critic] Please verify your email: %s" % email
    body = textutils.reflow("""
This is a message from the Critic code review system at %(hostname)s.  The user
'%(username)s' on this system has added this email address to his/her account.
If this is you, please confirm this by following this link:

  %(url_prefix)s/verifyemail?email=%(email)s&token=%(verification_token)s

If this is not you, you can safely ignore this email.  If you wish to report
abuse, please contact the Critic system's administrators%(administrators)s
""" % { "hostname": configuration.base.HOSTNAME,
        "username": user.name,
        "email": email,
        "url_prefix": "%s://%s" % (protocol, configuration.base.HOSTNAME),
        "verification_token": verification_token,
        "administrators": administrators })

    mailutils.sendMessage(recipients, subject, body)
Exemplo n.º 3
0
    def generateContent(self):
        table = page.utils.PaleYellowTable(self.body, "Create user")

        if self.provider and self.token and self.provider in auth.PROVIDERS:
            provider = auth.PROVIDERS[self.provider]
            if not provider.validateToken(self.db, self.account, self.token):
                raise page.utils.DisplayMessage("Invalid OAuth2 token")
            allow_user_registration = \
                provider.configuration.get("allow_user_registration", False)
        else:
            provider = None
            allow_user_registration = configuration.base.ALLOW_USER_REGISTRATION

        if not allow_user_registration:
            administrators = dbutils.getAdministratorContacts(
                self.db, as_html=True)
            raise page.utils.DisplayMessage(
                title="User registration not enabled",
                body=(("<p>The administrator of this system has not enabled "
                       "registration of new users.</p>"
                       "<p>Contact %s if you want to use this system.</p>")
                      % administrators),
                html=True)

        def render(target):
            table = target.table("createuser", align="center")

            def header(label):
                row = table.tr("header")
                row.td(colspan=2).text(label)

            def item(key):
                row = table.tr("item")
                row.td("key").text("%s:" % key)
                return row.td("value")

            def button(class_name):
                row = table.tr("button")
                return row.td(colspan=2).button(class_name)

            def separator():
                table.tr("separator1").td(colspan=2)
                table.tr("separator2").td(colspan=2)

            if provider:
                self.document.addInternalScript(
                    "var external = { provider: %s, account: %s, token: %s };"
                    % (htmlutils.jsify(self.provider),
                       htmlutils.jsify(self.account),
                       htmlutils.jsify(self.token)))

                url = provider.getAccountURL(self.account)
                item(provider.getTitle()).a("external", href=url).text(self.account)
                separator()
            else:
                self.document.addInternalScript("var external = null;")

            message = table.tr("status disabled").td(colspan=2).div("message")

            if self.username:
                try:
                    dbutils.User.fromName(self.db, self.username)
                except dbutils.NoSuchUser:
                    try:
                        auth.validateUserName(self.username)
                    except auth.InvalidUserName as error:
                        message.u("Invalid user name")
                        message.br()
                        message.text(str(error))
                else:
                    message.text("A user named '%s' already exists!"
                                 % self.username)

            item("New user name").input(id="newusername", value=self.username, size=40)
            item("Display name").input(id="fullname", value=self.fullname, size=40)
            item("Email").input(id="email", value=self.email, size=40)

            if not provider:
                separator()

                item("Password").input(id="password1", type="password", size=40)
                item("Password (again)").input(id="password2", type="password", size=40)

            button("create").text("Create user")

        table.addCentered(render)
Exemplo n.º 4
0
def renderManageExtensions(req, db, user):
    if not configuration.extensions.ENABLED:
        administrators = dbutils.getAdministratorContacts(db, as_html=True)
        raise page.utils.DisplayMessage(
            title="Extension support not enabled",
            body=(("<p>This Critic system does not support extensions.</p>"
                   "<p>Contact %s to have it enabled, or see the "
                   "<a href='/tutorial?item=administration#extensions'>"
                   "section on extensions</a> in the system administration "
                   "tutorial for more information.</p>")
                  % administrators),
            html=True)

    cursor = db.cursor()

    what = req.getParameter("what", "available")
    selected_versions = page.utils.json_decode(req.getParameter("select", "{}"))
    focused = req.getParameter("focus", None)

    if what == "installed":
        title = "Installed Extensions"
        listed_extensions = []
        for extension_id, _, _, _ in Extension.getInstalls(db, user):
            try:
                listed_extensions.append(Extension.fromId(db, extension_id))
            except ExtensionError as error:
                listed_extensions.append(error)
    else:
        title = "Available Extensions"
        listed_extensions = Extension.find(db)

    req.content_type = "text/html; charset=utf-8"

    document = htmlutils.Document(req)
    document.setTitle("Manage Extensions")

    html = document.html()
    head = html.head()
    body = html.body()

    def generateRight(target):
        target.a("button", href="tutorial?item=extensions").text("Tutorial")
        target.text(" ")
        target.a("button", href="tutorial?item=extensions-api").text("API Documentation")

    page.utils.generateHeader(body, db, user, current_page="extensions", generate_right=generateRight)

    document.addExternalStylesheet("resource/manageextensions.css")
    document.addExternalScript("resource/manageextensions.js")
    document.addInternalScript(user.getJS())

    table = page.utils.PaleYellowTable(body, title)

    def addTitleRightLink(url, label):
        if user.name != req.user:
            url += "&user=%s" % user.name
        table.titleRight.text(" ")
        table.titleRight.a(href=url).text("[" + label + " extensions]")

    if what != "installed" or focused:
        addTitleRightLink("/manageextensions?what=installed", "installed")
    if what != "available" or focused:
        addTitleRightLink("/manageextensions?what=available", "available")

    for item in listed_extensions:
        if isinstance(item, ExtensionError):
            extension_error = item
            extension = item.extension
        else:
            extension_error = None
            extension = item

        if focused and extension.getKey() != focused:
            continue

        extension_path = extension.getPath()

        if extension.isSystemExtension():
            hosting_user = None
        else:
            hosting_user = extension.getAuthor(db)

        selected_version = selected_versions.get(extension.getKey(), False)
        installed_sha1, installed_version = extension.getInstalledVersion(db, user)
        universal_sha1, universal_version = extension.getInstalledVersion(db, None)
        installed_upgradeable = universal_upgradeable = False

        if extension_error is None:
            if installed_sha1:
                current_sha1 = extension.getCurrentSHA1(installed_version)
                installed_upgradeable = installed_sha1 != current_sha1
            if universal_sha1:
                current_sha1 = extension.getCurrentSHA1(universal_version)
                universal_upgradeable = universal_sha1 != current_sha1

        def massage_version(version):
            if version is None:
                return "live"
            elif version:
                return "version/%s" % version
            else:
                return None

        if selected_version is False:
            selected_version = installed_version
        if selected_version is False:
            selected_version = universal_version

        install_version = massage_version(selected_version)
        installed_version = massage_version(installed_version)
        universal_version = massage_version(universal_version)

        manifest = None

        if extension_error is None:
            try:
                if selected_version is False:
                    manifest = extension.getManifest()
                else:
                    manifest = extension.getManifest(selected_version)
            except ManifestError as error:
                pass
        elif installed_sha1:
            manifest = extension.getManifest(installed_version, installed_sha1)
        elif universal_sha1:
            manifest = extension.getManifest(universal_version, universal_sha1)

        if manifest:
            if what == "available" and manifest.hidden:
                # Hide from view unless the user is hosting the extension, or is
                # an administrator and the extension is a system extension.
                if extension.isSystemExtension():
                    if not user.hasRole(db, "administrator"):
                        continue
                elif hosting_user != user:
                    continue
        else:
            if hosting_user != user:
                continue

        extension_id = extension.getExtensionID(db, create=False)

        if not user.isAnonymous():
            buttons = []

            if extension_id is not None:
                cursor.execute("""SELECT 1
                                    FROM extensionstorage
                                   WHERE extension=%s
                                     AND uid=%s""",
                               (extension_id, user.id))

                if cursor.fetchone():
                    buttons.append(("Clear storage",
                                    ("clearExtensionStorage(%s, %s)"
                                     % (htmlutils.jsify(extension.getAuthorName()),
                                        htmlutils.jsify(extension.getName())))))

            if not installed_version:
                if manifest and install_version and install_version != universal_version:
                    buttons.append(("Install",
                                    ("installExtension(%s, %s, %s)"
                                     % (htmlutils.jsify(extension.getAuthorName()),
                                        htmlutils.jsify(extension.getName()),
                                        htmlutils.jsify(install_version)))))
            else:
                buttons.append(("Uninstall",
                                ("uninstallExtension(%s, %s)"
                                 % (htmlutils.jsify(extension.getAuthorName()),
                                    htmlutils.jsify(extension.getName())))))

                if manifest and (install_version != installed_version
                                 or (installed_sha1 and installed_upgradeable)):
                    if install_version == installed_version:
                        label = "Upgrade"
                    else:
                        label = "Install"

                    buttons.append(("Upgrade",
                                    ("reinstallExtension(%s, %s, %s)"
                                     % (htmlutils.jsify(extension.getAuthorName()),
                                        htmlutils.jsify(extension.getName()),
                                        htmlutils.jsify(install_version)))))

            if user.hasRole(db, "administrator"):
                if not universal_version:
                    if manifest and install_version:
                        buttons.append(("Install (universal)",
                                        ("installExtension(%s, %s, %s, true)"
                                         % (htmlutils.jsify(extension.getAuthorName()),
                                            htmlutils.jsify(extension.getName()),
                                            htmlutils.jsify(install_version)))))
                else:
                    buttons.append(("Uninstall (universal)",
                                    ("uninstallExtension(%s, %s, true)"
                                     % (htmlutils.jsify(extension.getAuthorName()),
                                        htmlutils.jsify(extension.getName())))))

                    if manifest and (install_version != universal_version
                                     or (universal_sha1 and universal_upgradeable)):
                        if install_version == universal_version:
                            label = "Upgrade (universal)"
                        else:
                            label = "Install (universal)"

                        buttons.append((label,
                                        ("reinstallExtension(%s, %s, %s, true)"
                                         % (htmlutils.jsify(extension.getAuthorName()),
                                            htmlutils.jsify(extension.getName()),
                                            htmlutils.jsify(universal_version)))))
        else:
            buttons = None

        def renderItem(target):
            target.span("name").innerHTML(extension.getTitle(db, html=True))

            if hosting_user:
                is_author = manifest and manifest.isAuthor(db, hosting_user)
                is_sole_author = is_author and len(manifest.authors) == 1
            else:
                is_sole_author = False

            if extension_error is None:
                span = target.span("details")
                span.b().text("Details: ")
                select = span.select("details", critic_author=extension.getAuthorName(), critic_extension=extension.getName())
                select.option(value='', selected="selected" if selected_version is False else None).text("Select version")
                versions = extension.getVersions()
                if versions:
                    optgroup = select.optgroup(label="Official Versions")
                    for version in versions:
                        optgroup.option(value="version/%s" % version, selected="selected" if selected_version == version else None).text("%s" % version.upper())
                optgroup = select.optgroup(label="Development")
                optgroup.option(value='live', selected="selected" if selected_version is None else None).text("LIVE")

            if manifest:
                is_installed = bool(installed_version)

                if is_installed:
                    target.span("installed").text(" [installed]")
                else:
                    is_installed = bool(universal_version)

                    if is_installed:
                        target.span("installed").text(" [installed (universal)]")

                target.div("description").preformatted().text(manifest.description, linkify=True)

                if not is_sole_author:
                    authors = target.div("authors")
                    authors.b().text("Author%s:" % ("s" if len(manifest.authors) > 1 else ""))
                    authors.text(", ".join(author.name for author in manifest.getAuthors()))
            else:
                is_installed = False

                div = target.div("description broken").preformatted()

                if extension_error is None:
                    anchor = div.a(href="loadmanifest?key=%s" % extension.getKey())
                    anchor.text("[This extension has an invalid MANIFEST file]")
                else:
                    div.text("[This extension has been deleted or has become inaccessible]")

            if selected_version is False:
                return

            pages = []
            injects = []
            processcommits = []
            filterhooks = []
            scheduled = []

            if manifest:
                for role in manifest.roles:
                    if isinstance(role, PageRole):
                        pages.append(role)
                    elif isinstance(role, InjectRole):
                        injects.append(role)
                    elif isinstance(role, ProcessCommitsRole):
                        processcommits.append(role)
                    elif isinstance(role, FilterHookRole):
                        filterhooks.append(role)
                    elif isinstance(role, ScheduledRole):
                        scheduled.append(role)

            role_table = target.table("roles")

            if pages:
                role_table.tr().th(colspan=2).text("Pages")

                for role in pages:
                    row = role_table.tr()
                    url = "%s/%s" % (dbutils.getURLPrefix(db, user), role.pattern)
                    if is_installed and "*" not in url:
                        row.td("pattern").a(href=url).text(url)
                    else:
                        row.td("pattern").text(url)
                    td = row.td("description")
                    td.text(role.description)

            if injects:
                role_table.tr().th(colspan=2).text("Page Injections")

                for role in injects:
                    row = role_table.tr()
                    row.td("pattern").text("%s/%s" % (dbutils.getURLPrefix(db, user), role.pattern))
                    td = row.td("description")
                    td.text(role.description)

            if processcommits:
                role_table.tr().th(colspan=2).text("ProcessCommits hooks")
                ul = role_table.tr().td(colspan=2).ul()

                for role in processcommits:
                    li = ul.li()
                    li.text(role.description)

            if filterhooks:
                role_table.tr().th(colspan=2).text("FilterHook hooks")

                for role in filterhooks:
                    row = role_table.tr()
                    row.td("title").text(role.title)
                    row.td("description").text(role.description)

            if scheduled:
                role_table.tr().th(colspan=2).text("Scheduled hooks")

                for role in scheduled:
                    row = role_table.tr()
                    row.td("pattern").text("%s @ %s" % (role.frequency, role.at))
                    td = row.td("description")
                    td.text(role.description)

        installed_by = ""

        if extension_id is not None:
            cursor.execute("""SELECT uid
                                FROM extensioninstalls
                                JOIN extensions ON (extensions.id=extensioninstalls.extension)
                               WHERE extensions.id=%s""",
                           (extension.getExtensionID(db, create=False),))

            user_ids = set(user_id for user_id, in cursor.fetchall())
            if user_ids:
                installed_by = " (installed"
                if None in user_ids:
                    installed_by += " universally"
                    user_ids.remove(None)
                    if user_ids:
                        installed_by += " and"
                if user_ids:
                    installed_by += (" by %d user%s"
                                  % (len(user_ids),
                                     "s" if len(user_ids) > 1 else ""))
                installed_by += ")"

        table.addItem("Extension", renderItem, extension_path + "/" + installed_by, buttons)

    document.addInternalScript("var selected_versions = %s;" % page.utils.json_encode(selected_versions))

    return document