<commit_before>#
# Copyright (c) 2005 rpath, Inc.
#
# All Rights Reserved
#
import random
import string
import re
import sys
import time

import email
from email import MIMEText
import smtplib
import socket
from string import find

from repository import netclient
from repository.repository import OpenError
import repository.netrepos.netauth
from lib import sha1helper

from mint_error import MintError
from mint_error import PermissionDenied
import database
import userlevels
import searcher
import userlisting

class MailError(MintError):
    def __str__(self):
        return context
    def __init__(self,context="there was a problem sending email"):
        self.context=context

class ConfirmError(MintError):
    def __str__(self):
        return "your registration could not be confirmed"

class AlreadyConfirmed(MintError):
    def __str__(self):
        return "registration already confirmed"

class UserAlreadyExists(MintError):
    def __str__(self):
        return "user already exists"

class GroupAlreadyExists(MintError):
    def __str__(self):
        return "group already exists"

class ConfirmationsTable(database.KeyedTable):
    name = 'Confirmations'
    key = 'userid'
    createSQL = """
                CREATE TABLE Confirmations (
                    userId          INTEGER PRIMARY KEY,
                    timeRequested   INT,
                    confirmation    STR
                )"""
    fields = ['userId', 'timeRequested', 'confirmation']

class UsersTable(database.KeyedTable):
    name = 'Users'
    key = 'userId'
    createSQL = """
                CREATE TABLE Users (
                    userId          INTEGER PRIMARY KEY,
                    username        STR UNIQUE,
                    fullName        STR,
                    email           STR,
                    displayEmail    STR DEFAULT "",
                    timeCreated     INT,
                    timeAccessed    INT,
                    active          INT,
                    blurb           STR DEFAULT ""
                )"""

    fields = ['userId', 'username', 'fullName', 'email',
              'displayEmail', 'timeCreated', 'timeAccessed',
              'active', 'blurb']

    indexes = {"UsersUsernameIdx": "CREATE INDEX UsersUsernameIdx ON Users(username)",
               "UsersActiveIdx":   "CREATE INDEX UsersActiveIdx ON Users(username, active)"}

    def __init__(self, db, cfg):
        database.DatabaseTable.__init__(self, db)
        self.cfg = cfg
        self.confirm_table = ConfirmationsTable(db)

    def checkAuth(self, authToken, checkRepo = True):
        username, password = authToken
        cu = self.db.cursor()
        cu.execute("""SELECT userId, email, displayEmail, fullName, blurb FROM Users 
                      WHERE username=? AND active=1""", username)
        r = cu.fetchone()
   
        noAuth = {'authorized': False, 'userId': -1}
        if r:
            groups = []
            if checkRepo:
                authUrl = self.cfg.authRepoUrl % (username, password)
                authLabel = self.cfg.authRepoMap.keys()[0]

                authRepo = {authLabel: authUrl}
                repo = netclient.NetworkRepositoryClient(authRepo)
                try:
                    groups = repo.getUserGroups(authLabel)
                except OpenError:
                    auth = noAuth

            if username in groups or not checkRepo:
                auth = {'authorized':   True,
                        'userId':       r[0],
                        'username':     username,
                        'email':        r[1],
                        'displayEmail': r[2],
                        'fullName':     r[3],
                        'blurb':        r[4]}
            else:
                auth = noAuth
        else:
            auth = noAuth
        return auth

    def registerNewUser(self, username, password, fullName, email, displayEmail, blurb, active):
        def confirmString():
            hash = sha1helper.sha1String(str(random.random()) + str(time.time()))
            return sha1helper.sha1ToString(hash)

        # XXX this should be an atomic operation if possible:
        #     it would be nice to roll back previous operations
        #     if one in the chain fails
        authRepo = netclient.NetworkRepositoryClient(self.cfg.authRepoMap)
        confirm = confirmString()
        repoLabel = self.cfg.authRepoMap.keys()[0]

        try: 
            authRepo.addUser(repoLabel, username, password)
            authRepo.addAcl(repoLabel, username, None, None, False, False, False)
        except repository.netrepos.netauth.UserAlreadyExists:
            raise UserAlreadyExists
        except repository.netrepos.netauth.GroupAlreadyExists:
            raise GroupAlreadyExists

        if self.cfg.hostName:
            confirmDomain = "%s.%s" % (self.cfg.hostName, self.cfg.domainName)
        else:
            confirmDomain = self.cfg.domainName
            
        if not active:
            message = "\n".join(["Thank you for registering for the rpath Linux customized",
                                 "distribution tool.",
                                 "",
                                 "Please follow the link below to confirm your registration",
                                 "for username %s:" % username,
                                 "",
                                 "http://%s/confirm?id=%s" % (confirmDomain, confirm),
                                 "",
                                 "Contact <EMAIL> for help, or join the IRC channel #conary",
                                 "on the Freenode IRC network (http://www.freenode.net/) for live help."])
            try:
                socket.gethostbyname(email[find(email,'@')+1:])
                sendMail(self.cfg.adminMail, "rpath.com", email, "rpath.com registration", message)
            except smtplib.SMTPRecipientsRefused:
                authRepo.deleteUserByName(repoLabel,username)
                raise MailError("Email could not be sent: Recipient refused by server.")
            except socket.gaierror:
                authRepo.deleteUserByName(repoLabel,username)
                raise MailError("Email could not be sent: Bad domain name.")
        try:
            userId = self.new(username = username,
                              fullName = fullName,
                              email = email,
                              displayEmail = displayEmail,
                              timeCreated = time.time(),
                              timeAccessed = 0,
                              blurb = blurb,
                              active = active)
        except database.DuplicateItem:
            raise UserAlreadyExists
        self.confirm_table.new(userId = userId,<commit_msg>Code cleanup to adhere to standards.<commit_after>#
# Copyright (c) 2005 rpath, Inc.
#
# All Rights Reserved
#
import random
import string
import re
import sys
import time

import email
from email import MIMEText
import smtplib
import socket
from string import find

from repository import netclient
from repository.repository import OpenError
import repository.netrepos.netauth
from lib import sha1helper

from mint_error import MintError
from mint_error import PermissionDenied
import database
import userlevels
import searcher
import userlisting

class MailError(MintError):
    def __str__(self):
        return context
    def __init__(self, context="there was a problem sending email"):
        self.context=context

class ConfirmError(MintError):
    def __str__(self):
        return "your registration could not be confirmed"

class AlreadyConfirmed(MintError):
    def __str__(self):
        return "registration already confirmed"

class UserAlreadyExists(MintError):
    def __str__(self):
        return "user already exists"

class GroupAlreadyExists(MintError):
    def __str__(self):
        return "group already exists"

class ConfirmationsTable(database.KeyedTable):
    name = 'Confirmations'
    key = 'userid'
    createSQL = """
                CREATE TABLE Confirmations (
                    userId          INTEGER PRIMARY KEY,
                    timeRequested   INT,
                    confirmation    STR
                )"""
    fields = ['userId', 'timeRequested', 'confirmation']

class UsersTable(database.KeyedTable):
    name = 'Users'
    key = 'userId'
    createSQL = """
                CREATE TABLE Users (
                    userId          INTEGER PRIMARY KEY,
                    username        STR UNIQUE,
                    fullName        STR,
                    email           STR,
                    displayEmail    STR DEFAULT "",
                    timeCreated     INT,
                    timeAccessed    INT,
                    active          INT,
                    blurb           STR DEFAULT ""
                )"""

    fields = ['userId', 'username', 'fullName', 'email',
              'displayEmail', 'timeCreated', 'timeAccessed',
              'active', 'blurb']

    indexes = {"UsersUsernameIdx": "CREATE INDEX UsersUsernameIdx ON Users(username)",
               "UsersActiveIdx":   "CREATE INDEX UsersActiveIdx ON Users(username, active)"}

    def __init__(self, db, cfg):
        database.DatabaseTable.__init__(self, db)
        self.cfg = cfg
        self.confirm_table = ConfirmationsTable(db)

    def checkAuth(self, authToken, checkRepo = True):
        username, password = authToken
        cu = self.db.cursor()
        cu.execute("""SELECT userId, email, displayEmail, fullName, blurb FROM Users 
                      WHERE username=? AND active=1""", username)
        r = cu.fetchone()
   
        noAuth = {'authorized': False, 'userId': -1}
        if r:
            groups = []
            if checkRepo:
                authUrl = self.cfg.authRepoUrl % (username, password)
                authLabel = self.cfg.authRepoMap.keys()[0]

                authRepo = {authLabel: authUrl}
                repo = netclient.NetworkRepositoryClient(authRepo)
                try:
                    groups = repo.getUserGroups(authLabel)
                except OpenError:
                    auth = noAuth

            if username in groups or not checkRepo:
                auth = {'authorized':   True,
                        'userId':       r[0],
                        'username':     username,
                        'email':        r[1],
                        'displayEmail': r[2],
                        'fullName':     r[3],
                        'blurb':        r[4]}
            else:
                auth = noAuth
        else:
            auth = noAuth
        return auth

    def registerNewUser(self, username, password, fullName, email, displayEmail, blurb, active):
        def confirmString():
            hash = sha1helper.sha1String(str(random.random()) + str(time.time()))
            return sha1helper.sha1ToString(hash)

        # XXX this should be an atomic operation if possible:
        #     it would be nice to roll back previous operations
        #     if one in the chain fails
        authRepo = netclient.NetworkRepositoryClient(self.cfg.authRepoMap)
        confirm = confirmString()
        repoLabel = self.cfg.authRepoMap.keys()[0]

        try: 
            authRepo.addUser(repoLabel, username, password)
            authRepo.addAcl(repoLabel, username, None, None, False, False, False)
        except repository.netrepos.netauth.UserAlreadyExists:
            raise UserAlreadyExists
        except repository.netrepos.netauth.GroupAlreadyExists:
            raise GroupAlreadyExists

        if self.cfg.hostName:
            confirmDomain = "%s.%s" % (self.cfg.hostName, self.cfg.domainName)
        else:
            confirmDomain = self.cfg.domainName
            
        if not active:
            message = "\n".join(["Thank you for registering for the rpath Linux customized",
                                 "distribution tool.",
                                 "",
                                 "Please follow the link below to confirm your registration",
                                 "for username %s:" % username,
                                 "",
                                 "http://%s/confirm?id=%s" % (confirmDomain, confirm),
                                 "",
                                 "Contact <EMAIL> for help, or join the IRC channel #conary",
                                 "on the Freenode IRC network (http://www.freenode.net/) for live help."])
            try:
                socket.gethostbyname(email[find(email, '@')+1:])
                sendMail(self.cfg.adminMail, "rpath.com", email, "rpath.com registration", message)
            except smtplib.SMTPRecipientsRefused:
                authRepo.deleteUserByName(repoLabel, username)
                raise MailError("Email could not be sent: Recipient refused by server.")
            except socket.gaierror:
                authRepo.deleteUserByName(repoLabel, username)
                raise MailError("Email could not be sent: Bad domain name.")
        try:
            userId = self.new(username = username,
                              fullName = fullName,
                              email = email,
                              displayEmail = displayEmail,
                              timeCreated = time.time(),
                              timeAccessed = 0,
                              blurb = blurb,
                              active = active)
        except database.DuplicateItem:
            raise UserAlreadyExists
        self.confirm_table.new(userId = userId,
{'fraction_non_alphanumeric': 0.08225108225108226, 'fraction_numerical': 0.002934918189155477, 'mean_word_length': 1.603629417382999, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2586059', 'n_tokens_mistral': 3389, 'n_tokens_neox': 3303, 'n_words': 938}