def ldap_search_user(login, con, attrs=None): ''' Return the result of a ldap search for the login using the ldap connection con based on connection. The attributes values defined in attrs will be return. ''' _, dn, _, scope, filter_, _ = parse_ldap_url( config.get(section, 'uri')) scope = { 'base': ldap.SCOPE_BASE, 'onelevel': ldap.SCOPE_ONELEVEL, 'subtree': ldap.SCOPE_SUBTREE, }.get(scope) uid = config.get(section, 'uid', default='uid') if filter_: filter_ = '(&(%s=%s)%s)' % (uid, unicode2str(login), filter_) else: filter_ = '(%s=%s)' % (uid, unicode2str(login)) result = con.search_s(dn, scope, filter_, attrs) if config.get(section, 'active_directory'): result = [x for x in result if x[0]] if result and len(result) > 1: logger.info('ldap_search_user found more than 1 user') return result
def create(cls, vlist): parties = super(Party, cls).create(vlist) #pool = Pool() #Badge = pool.get('access.control.badge') #Badge.isonas_badge_sync([], parties) isonas = Isonasacs( config.get('Isonas', 'host'), config.get('Isonas', 'port')) isonas.logon( config.get('Isonas', 'clientid'), config.get('Isonas', 'password')) groupname = config.get('Isonas', 'groupname') # need to check if parties have badges # partiestocreatebadges for party in parties: if party.badges: name = party.name.encode('ascii', 'replace')[:20] try: isonas.add('IDFILE', name, '', '', party.code.encode('ascii')) isonas.add('GROUPS', party.code.encode('ascii'), groupname.encode('ascii')) except IsonasacsError: print 'Party Create IsonasacsError exception' pass return parties
def ldap_search_user(login, server, attrs=None): ''' Return the result of a ldap search for the login using the ldap server. The attributes values defined in attrs will be return. ''' _, dn, _, scope, filter_, extensions = parse_ldap_url( config.get(section, 'uri')) scope = { 'base': ldap3.BASE, 'onelevel': ldap3.LEVEL, 'subtree': ldap3.SUBTREE, }[scope] uid = config.get(section, 'uid', default='uid') if filter_: filter_ = '(&(%s=%s)%s)' % (uid, login, filter_) else: filter_ = '(%s=%s)' % (uid, login) bindpass = None bindname, = extensions.get('bindname', [None]) if not bindname: bindname, = extensions.get('!bindname', [None]) if bindname: # XXX find better way to get the password bindpass = config.get(section, 'bind_pass') with ldap3.Connection(server, bindname, bindpass) as con: con.search(dn, filter_, search_scope=scope, attributes=attrs) result = con.entries if result and len(result) > 1: logger.info('ldap_search_user found more than 1 user') return [(e.entry_dn, e.entry_attributes_as_dict) for e in result]
def send_magic_login_link(cls, email): """ Send a magic login email to the user """ EmailQueue = Pool().get("email.queue") try: nereid_user, = cls.search([("email", "=", email.lower()), ("company", "=", current_website.company.id)]) except ValueError: # This email was not found so, let user know about this message = "No user with email %s was found!" % email current_app.logger.debug(message) else: message = "Please check your mail and follow the link" email_message = render_email( config.get("email", "from"), email, _("Magic Signin Link"), text_template="emails/magic-login-text.jinja", html_template="emails/magic-login-html.jinja", nereid_user=nereid_user, ) EmailQueue.queue_mail(config.get("email", "from"), email, email_message.as_string()) return cls.build_response(message, redirect(url_for("nereid.website.home")), 200)
def SSLSocket(socket): # Let the import error raise only when used import ssl return ssl.wrap_socket(socket, server_side=True, certfile=config.get('ssl', 'certificate'), keyfile=config.get('ssl', 'privatekey'), ssl_version=ssl.PROTOCOL_SSLv23)
def get_s3_connection(self): """ Returns an active S3 connection object """ return connection.S3Connection( config.get('nereid_s3', 'access_key'), config.get('nereid_s3', 'secret_key') )
def get_bucket(cls): ''' Return an S3 bucket for the current instance ''' s3_conn = S3Connection( config.get('attachment_s3', 'access_key'), config.get('attachment_s3', 'secret_key') ) return s3_conn.get_bucket(config.get('attachment_s3', 'bucket_name'))
def get_webdav_url(): if config.get('ssl', 'privatekey'): protocol = 'https' else: protocol = 'http' hostname = (config.get('webdav', 'hostname') or unicode(socket.getfqdn(), 'utf8')) hostname = '.'.join(encodings.idna.ToASCII(part) for part in hostname.split('.')) return urlparse.urlunsplit((protocol, hostname, urllib.quote( Transaction().cursor.database_name.encode('utf-8') + '/'), None, None))
def get_url(self, name): """ Return the URL for the given static file :param name: Field name """ if self.folder.type != "s3": return super(NereidStaticFile, self).get_url(name) cloudfront = config.get("nereid_s3", "cloudfront") if cloudfront: return "/".join([cloudfront, self.s3_key]) return "https://s3.amazonaws.com/%s/%s" % (config.get("nereid_s3", "bucket"), self.s3_key)
def write(cls, *args): super(Badge, cls).write(*args) badges = sum(args[0:None:2], []) cls.isonas_badge_sync(badges, []) isonas = Isonasacs( config.get('Isonas', 'host'), config.get('Isonas', 'port')) isonas.logon( config.get('Isonas', 'clientid'), config.get('Isonas', 'password')) for badge in badges: if badge.disabled: isonas.update('BADGES', badge.code.encode('ascii'), 0, 0, '', '') else: isonas.update('BADGES', badge.code.encode('ascii'), 0, 0, 0, '')
def get_file_path(self, name): """ Returns path for given static file :param static_file: Browse record of the static file """ if self.folder.type != "s3": return super(NereidStaticFile, self).get_file_path(name) cloudfront = config.get("nereid_s3", "cloudfront") if cloudfront: return "/".join([cloudfront, self.s3_key]) return "https://s3.amazonaws.com/%s/%s" % (config.get("nereid_s3", "bucket"), self.s3_key)
def is_secure(cls): context = Transaction().context if context: request = context.get('_request') if request: return request['is_secure'] return bool(config.get('ssl', 'certificate'))
def get_login(cls, login, parameters): ''' Return user id if password matches ''' LoginAttempt = Pool().get('res.user.login.attempt') count_ip = LoginAttempt.count_ip() if count_ip > config.getint( 'session', 'max_attempt_ip_network', default=300): # Do not add attempt as the goal is to prevent flooding raise RateLimitException() count = LoginAttempt.count(login) if count > config.getint('session', 'max_attempt', default=5): LoginAttempt.add(login) raise RateLimitException() Transaction().atexit(time.sleep, random.randint(0, 2 ** count - 1)) for methods in config.get( 'session', 'authentications', default='password').split(','): user_ids = set() for method in methods.split('+'): try: func = getattr(cls, '_login_%s' % method) except AttributeError: logger.info('Missing login method: %s', method) break user_ids.add(func(login, parameters)) if len(user_ids) != 1 or not all(user_ids): break if len(user_ids) == 1 and all(user_ids): LoginAttempt.remove(login) return user_ids.pop() LoginAttempt.add(login)
def set_preferences(cls, values, parameters): if 'password' in values: if 'password' not in parameters: msg = cls.fields_get(['password'])['password']['string'] raise LoginException('password', msg, type='password') old_password = parameters['password'] try: server = ldap_server() if server: user = cls(Transaction().user) uid = config.get(section, 'uid', default='uid') users = cls.ldap_search_user(user.login, server, attrs=[uid]) if users and len(users) == 1: [(dn, attrs)] = users con = ldap3.Connection(server, dn, old_password) if con.bind(): con.extend.standard.modify_password( dn, old_password, values['password']) values = values.copy() del values['password'] else: cls.raise_user_error('wrong_password') except LDAPException: logger.error('LDAPError when setting preferences', exc_info=True) super(User, cls).set_preferences(values, parameters)
def setUp(self): super().setUp() activate_module('company') methods = config.get('session', 'authentications', default='') config.set('session', 'authentications', 'totp') self.addCleanup(config.set, 'session', 'authentications', methods)
def get_fernet_key(cls): fernet_key = config.get('cryptography', 'fernet_key') if not fernet_key: _logger.error('Missing Fernet key configuration') # raise UserError(gettext('aeat_sii.msg_missing_fernet_key')) else: return Fernet(fernet_key)
def validate_password(cls, password, users): password_b = password if isinstance(password, str): password_b = password.encode('utf-8') length = config.getint('password', 'length', default=0) if length > 0: if len(password_b) < length: raise PasswordError( gettext( 'res.msg_password_length', length=length, )) path = config.get('password', 'forbidden', default=None) if path: with open(path, 'r') as f: forbidden = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) if forbidden.find(password_b) >= 0: raise PasswordError(gettext('res.msg_password_forbidden')) entropy = config.getfloat('password', 'entropy', default=0) if entropy: if len(set(password)) / len(password) < entropy: raise PasswordError(gettext('res.msg_password_entropy')) for user in users: # Use getattr to allow to use non User instances for test, message in [ (getattr(user, 'name', ''), 'res.msg_password_name'), (getattr(user, 'login', ''), 'res.msg_password_login'), (getattr(user, 'email', ''), 'res.msg_password_email'), ]: if test and password.lower() == test.lower(): raise PasswordError(gettext(message))
def convert(cls, report, data): "converts the report data to another mimetype if necessary" input_format = report.template_extension output_format = report.extension or report.template_extension if output_format in MIMETYPES: return output_format, data fd, path = tempfile.mkstemp(suffix=(os.extsep + input_format), prefix='trytond_') oext = FORMAT2EXT.get(output_format, output_format) with os.fdopen(fd, 'wb+') as fp: fp.write(data) cmd = [ 'unoconv', '--connection=%s' % config.get('report', 'unoconv'), '-f', oext, '--stdout', path ] try: proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) stdoutdata, stderrdata = proc.communicate() if proc.wait() != 0: raise Exception(stderrdata) return oext, stdoutdata finally: os.remove(path)
def dump(database_name): from trytond.tools import exec_command_pipe cmd = ['pg_dump', '--format=c', '--no-owner'] env = {} uri = parse_uri(config.get('database', 'uri')) if uri.username: cmd.append('--username='******'--host=' + uri.hostname) if uri.port: cmd.append('--port=' + str(uri.port)) if uri.password: # if db_password is set in configuration we should pass # an environment variable PGPASSWORD to our subprocess # see libpg documentation env['PGPASSWORD'] = uri.password cmd.append(database_name) pipe = exec_command_pipe(*tuple(cmd), env=env) pipe.stdin.close() data = pipe.stdout.read() res = pipe.wait() if res: raise Exception('Couldn\'t dump database!') return data
def send_email(self, datamanager=None): pool = Pool() Configuration = pool.get('ir.configuration') Lang = pool.get('ir.lang') from_ = self.level.email_from or config.get('email', 'from') to = [] if self.party.email: name = str(Header(self.party.rec_name)) to.append(formataddr((name, self.party.email))) cc = [] bcc = [] languages = set() if self.party.lang: languages.add(self.party.lang) else: lang, = Lang.search([ ('code', '=', Configuration.get_language()), ], limit=1) languages.add(lang) msg = self._email(from_, to, cc, bcc, languages) to_addrs = [e for _, e in getaddresses(to + cc + bcc)] if to_addrs: if not pool.test: sendmail_transactional( from_, to_addrs, msg, datamanager=datamanager) return self._email_log(msg)
def convert_api(cls, report, data, timeout): # AKE: support printing via external api User = Pool().get('res.user') input_format = report.template_extension output_format = report.extension or report.template_extension if output_format in MIMETYPES: return output_format, data oext = FORMAT2EXT.get(output_format, output_format) url_tpl = config.get('report', 'api') url = url_tpl.format(oext=oext) files = {'file': ('doc.' + input_format, data)} for count in range(config.getint('report', 'unoconv_retry'), -1, -1): try: r = requests.post(url, files=files, timeout=timeout) if r.status_code < 300: return oext, r.content else: raise UnoConversionError('Conversion of "%s" failed. ' 'Unoconv responsed with "%s".' % (report.report_name, r.reason)) except UnoConversionError as e: if count: time.sleep(0.1) continue user = User(Transaction().user) logger.error(e.message + ' User: %s' % user.name or '') raise
def get_conf(cls, config=None, attachment=None, from_object=None): credential = config.credential if config else None res, credential = cls.get_authentification(credential) provider = res['provider'] if not config: Company = Pool().get('company.company') company = Company(Transaction().context.get('company')) if company.signature_configurations: config = company.signature_configurations[0] res['urls'] = {} for call in ['success', 'fail', 'cancel']: if credential and config and getattr( credential, 'prefix_url_%s' % call): url = getattr(credential, 'prefix_url_%s' % call) if getattr(config, 'suffix_url_%s' % call): url += getattr(config, 'suffix_url_%s' % call) else: url = config_parser.get(provider, '%s-url' % call) if url is not None: if attachment and '{att.' in url: url = url.format(att=attachment) elif from_object: url = cls.format_url(url, from_object) res['urls'][call] = url res['profile'] = config.profile \ if config and config.profile else 'default' res['level'] = config.level if config else 'simple' res['send_email_to_sign'] = config.send_email_to_sign \ if config else True res['send_signed_docs_by_email'] = config.send_signed_docs_by_email \ if config else True res['handwritten_signature'] = config.handwritten_signature \ if config else 'never' res['manual'] = config.manual if config else False return res, credential
def send_tryton_url(self, path): self.send_response(300) hostname = (config.get('jsonrpc', 'hostname') or unicode(socket.getfqdn(), 'utf8')) hostname = '.'.join(encodings.idna.ToASCII(part) for part in hostname.split('.')) values = { 'hostname': hostname, 'path': path, } content = StringIO() content.write('<html') content.write('<head>') content.write('<meta http-equiv="Refresh" ' 'content="0;url=tryton://%(hostname)s%(path)s"/>' % values) content.write('<title>Moved</title>') content.write('</head>') content.write('<body>') content.write('<h1>Moved</h1>') content.write('<p>This page has moved to ' '<a href="tryton://%(hostname)s%(path)s">' 'tryton://%(hostname)s%(path)s</a>.</p>' % values) content.write('</body>') content.write('</html>') length = content.tell() content.seek(0) self.send_header('Location', 'tryton://%(hostname)s%(path)s' % values) self.send_header('Content-type', 'text/html') self.send_header('Content-Length', str(length)) self.end_headers() self.copyfile(content, self.wfile) content.close()
def get_login(cls, login, password): pool = Pool() LoginAttempt = pool.get('res.user.login.attempt') try: con = ldap_connection() if con: uid = config.get(section, 'uid', default='uid') users = cls.ldap_search_user(login, con, attrs=[uid]) if users and len(users) == 1: [(dn, attrs)] = users if (password and con.simple_bind_s(dn, unicode2str(password))): # Use ldap uid so we always get the right case login = attrs.get(uid, [login])[0] user_id, _ = cls._get_login(login) if user_id: LoginAttempt.remove(login) return user_id elif config.getboolean(section, 'create_user'): user, = cls.create([{ 'name': login, 'login': login, }]) return user.id except ldap.LDAPError: logger.error('LDAPError when login', exc_info=True) return super(User, cls).get_login(login, password)
def test_authentication_option_ip_address(self): "Test authentication with ip_address option" pool = Pool() User = pool.get('res.user') user = User(login='******') user.save() ip_network = config.get('session', 'authentication_ip_network', default='') config.set('session', 'authentication_ip_network', '192.168.0.0/16,127.0.0.0/8') self.addCleanup(config.set, 'session', 'authentication_ip_network', ip_network) with patch.object(User, '_login_always', create=True) as always, \ patch.object(User, '_login_never', create=True) as never: always.return_value = user.id never.return_value = None with set_authentications('always+never?ip_address'): for address, result in [ ('192.168.0.1', user.id), ('172.17.0.1', None), ('127.0.0.1', user.id), ]: with self.subTest(address=address): with Transaction().set_context(_request={ 'remote_addr': address, }): self.assertEqual(User.get_login('user', {}), result)
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() pool = Pool() Line = pool.get('account.invoice.payment_term.line') sql_table = cls.__table__() line = Line.__table__() # Migration from 4.0: rename long table old_model_name = 'account.invoice.payment_term.line.relativedelta' old_table = config.get( 'table', old_model_name, default=old_model_name.replace('.', '_')) if TableHandler.table_exist(old_table): TableHandler.table_rename(old_table, cls._table) super(PaymentTermLineRelativeDelta, cls).__register__(module_name) line_table = Line.__table_handler__(module_name) # Migration from 3.4 fields = ['day', 'month', 'weekday', 'months', 'weeks', 'days'] if any(line_table.column_exist(f) for f in fields): columns = ([line.id.as_('line')] + [Column(line, f) for f in fields]) cursor.execute(*sql_table.insert( columns=[sql_table.line] + [Column(sql_table, f) for f in fields], values=line.select(*columns))) for field in fields: line_table.drop_column(field)
def convert(cls, report, data): "converts the report data to another mimetype if necessary" input_format = report.template_extension output_format = report.extension or report.template_extension if output_format in MIMETYPES: return output_format, data fd, path = tempfile.mkstemp(suffix=(os.extsep + input_format), prefix='trytond_') oext = FORMAT2EXT.get(output_format, output_format) with os.fdopen(fd, 'wb+') as fp: fp.write(data) cmd = ['unoconv', '--no-launch', '--connection=%s' % config.get( 'report', 'unoconv'), '-f', oext, '--stdout', path] logger = logging.getLogger(__name__) try: # JCA : Pipe stderr proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) stdoutdata, stderrdata = proc.communicate() # JCA : Use error code rather than wait twice if proc.returncode != 0: logger.info('unoconv.stdout : ' + stdoutdata) logger.error('unoconv.stderr : ' + stderrdata) raise Exception(stderrdata) else: logger.debug('unoconv.stdout : ' + stdoutdata) logger.debug('unoconv.stderr : ' + stderrdata) return oext, stdoutdata finally: os.remove(path)
def _login_ldap(cls, login, parameters): if 'password' not in parameters: msg = cls.fields_get(['password'])['password']['string'] raise LoginException('password', msg, type='password') password = parameters['password'] try: server = ldap_server() if server: uid = config.get(section, 'uid', default='uid') users = cls.ldap_search_user(login, server, attrs=[uid]) if users and len(users) == 1: [(dn, attrs)] = users con = ldap3.Connection(server, dn, password) if (password and con.bind()): # Use ldap uid so we always get the right case login = attrs.get(uid, [login])[0] user_id = cls._get_login(login)[0] if user_id: return user_id elif config.getboolean(section, 'create_user'): user, = cls.create([{ 'name': login, 'login': login, }]) return user.id except LDAPException: logger.error('LDAPError when login', exc_info=True)
def get_smtp_server(uri=None, strict=False): if uri is None: uri = config.get('email', 'uri') ini_uri = uri uri = parse_uri(uri) extra = {} if uri.query: cast = {'timeout': int} for key, value in parse_qs(uri.query, strict_parsing=True).items(): extra[key] = cast.get(key, lambda a: a)(value[0]) if uri.scheme.startswith('smtps'): connector = smtplib.SMTP_SSL else: connector = smtplib.SMTP try: server = connector(uri.hostname, uri.port, **extra) except Exception: if strict: raise logger.error('fail to connect to %s', uri, exc_info=True) return if 'tls' in uri.scheme: server.starttls() if uri.username and uri.password: server.login( unquote_plus(uri.username), unquote_plus(uri.password)) server.uri = ini_uri return server
def send_tryton_url(self, path): self.send_response(300) hostname = (config.get('jsonrpc', 'hostname') or unicode(socket.getfqdn(), 'utf8')) hostname = '.'.join(encodings.idna.ToASCII(part) for part in hostname.split('.')) values = { 'hostname': hostname, 'path': path, } content = BytesIO() def write(str_): content.write(str_.encode('utf-8')) write('<html') write('<head>') write('<meta http-equiv="Refresh" ' 'content="0;url=tryton://%(hostname)s%(path)s"/>' % values) write('<title>Moved</title>') write('</head>') write('<body>') write('<h1>Moved</h1>') write('<p>This page has moved to ' '<a href="tryton://%(hostname)s%(path)s">' 'tryton://%(hostname)s%(path)s</a>.</p>' % values) write('</body>') write('</html>') length = content.tell() content.seek(0) self.send_header('Location', 'tryton://%(hostname)s%(path)s' % values) self.send_header('Content-type', 'text/html') self.send_header('Content-Length', str(length)) self.end_headers() self.copyfile(content, self.wfile) content.close()
def connect(self): if self.name == ':memory:': path = ':memory:' else: db_filename = self.name + '.sqlite' path = os.path.join(config.get('database', 'path'), db_filename) if not os.path.isfile(path): raise IOError('Database "%s" doesn\'t exist!' % db_filename) if self._conn is not None: return self self._conn = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES | sqlite.PARSE_COLNAMES, factory=SQLiteConnection) self._conn.create_function('extract', 2, SQLiteExtract.extract) self._conn.create_function('date_trunc', 2, date_trunc) self._conn.create_function('split_part', 3, split_part) self._conn.create_function('position', 2, SQLitePosition.position) self._conn.create_function('overlay', 3, SQLiteOverlay.overlay) self._conn.create_function('overlay', 4, SQLiteOverlay.overlay) if sqlite.sqlite_version_info < (3, 3, 14): self._conn.create_function('replace', 3, replace) self._conn.create_function('now', 0, now) self._conn.create_function('sign', 1, sign) self._conn.create_function('greatest', -1, greatest) self._conn.create_function('least', -1, least) self._conn.execute('PRAGMA foreign_keys = ON') return self
def connect(self): if self.name == ':memory:': path = ':memory:' else: db_filename = self.name + '.sqlite' path = os.path.join(config.get('database', 'path'), db_filename) if not os.path.isfile(path): raise IOError('Database "%s" doesn\'t exist!' % db_filename) if self._conn is not None: return self self._conn = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES | sqlite.PARSE_COLNAMES, factory=SQLiteConnection) self._conn.create_function('extract', 2, SQLiteExtract.extract) self._conn.create_function('date_trunc', 2, date_trunc) self._conn.create_function('split_part', 3, split_part) self._conn.create_function('position', 2, SQLitePosition.position) self._conn.create_function('to_char', 2, to_char) self._conn.create_function('overlay', 3, SQLiteOverlay.overlay) self._conn.create_function('overlay', 4, SQLiteOverlay.overlay) if sqlite.sqlite_version_info < (3, 3, 14): self._conn.create_function('replace', 3, replace) self._conn.create_function('now', 0, now) self._conn.create_function('sign', 1, sign) self._conn.create_function('greatest', -1, greatest) self._conn.create_function('least', -1, least) if (hasattr(self._conn, 'set_trace_callback') and logger.isEnabledFor(logging.DEBUG)): self._conn.set_trace_callback(logger.debug) self._conn.execute('PRAGMA foreign_keys = ON') return self
class RegistrationForm(Form): "Simple Registration form" name = TextField(_('Name'), [validators.DataRequired(), ]) email = TextField(_('e-mail'), [validators.DataRequired(), validators.Email()]) # noqa password = PasswordField(_('New Password'), [ validators.DataRequired(), validators.EqualTo('confirm', message=_('Passwords must match'))]) confirm = PasswordField(_('Confirm Password')) if config.has_option('nereid', 're_captcha_public_key') and \ config.has_option('nereid', 're_captcha_private_key'): captcha = RecaptchaField( public_key=config.get('nereid', 're_captcha_public_key'), private_key=config.get('nereid', 're_captcha_private_key'), secure=True )
def send_reset_email(self): """ Send an account reset email to the user :param nereid_user: The browse record of the user """ EmailQueue = Pool().get('email.queue') email_message = render_email(config.get('email', 'from'), self.email, _('Account Password Reset'), text_template='emails/reset-text.jinja', html_template='emails/reset-html.jinja', nereid_user=self) EmailQueue.queue_mail(config.get('email', 'from'), self.email, email_message.as_string())
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() pool = Pool() Line = pool.get('account.invoice.payment_term.line') sql_table = cls.__table__() line = Line.__table__() # Migration from 4.0: rename long table old_model_name = 'account.invoice.payment_term.line.relativedelta' old_table = config.get('table', old_model_name, default=old_model_name.replace('.', '_')) if TableHandler.table_exist(old_table): TableHandler.table_rename(old_table, cls._table) super(PaymentTermLineRelativeDelta, cls).__register__(module_name) line_table = Line.__table_handler__(module_name) # Migration from 3.4 fields = ['day', 'month', 'weekday', 'months', 'weeks', 'days'] if any(line_table.column_exist(f) for f in fields): columns = ([line.id.as_('line')] + [Column(line, f) for f in fields]) cursor.execute( *sql_table.insert(columns=[sql_table.line] + [Column(sql_table, f) for f in fields], values=line.select(*columns))) for field in fields: line_table.drop_column(field)
def _filename(self, id, prefix): path = os.path.normpath(config.get('database', 'path')) filename = os.path.join(path, prefix, id[0:2], id[2:4], id) filename = os.path.normpath(filename) if not filename.startswith(path): raise ValueError('Bad prefix') return filename
def get_connection(self, autocommit=False, readonly=False): conv = MySQLdb.converters.conversions.copy() conv[float] = lambda value, _: repr(value) conv[MySQLdb.constants.FIELD_TYPE.TIME] = MySQLdb.times.Time_or_None args = { 'db': self.name, 'sql_mode': 'traditional,postgresql', 'use_unicode': True, 'charset': 'utf8', 'conv': conv, } uri = parse_uri(config.get('database', 'uri')) assert uri.scheme == 'mysql' if uri.hostname: args['host'] = uri.hostname if uri.port: args['port'] = uri.port if uri.username: args['user'] = uri.username if uri.password: args['passwd'] = urllib.unquote_plus(uri.password) conn = MySQLdb.connect(**args) cursor = conn.cursor() cursor.execute('SET time_zone = "+00:00"') return conn
def cursor(self, autocommit=False, readonly=False): conv = MySQLdb.converters.conversions.copy() conv[float] = lambda value, _: repr(value) conv[MySQLdb.constants.FIELD_TYPE.TIME] = MySQLdb.times.Time_or_None args = { 'db': self.database_name, 'sql_mode': 'traditional,postgresql', 'use_unicode': True, 'charset': 'utf8', 'conv': conv, } uri = parse_uri(config.get('database', 'uri')) assert uri.scheme == 'mysql' if uri.hostname: args['host'] = uri.hostname if uri.port: args['port'] = uri.port if uri.username: args['user'] = uri.username if uri.password: args['passwd'] = urllib.unquote_plus(uri.password) conn = MySQLdb.connect(**args) cursor = Cursor(conn, self.database_name) cursor.execute('SET time_zone = `UTC`') return cursor
def set_authentications(methods): saved_methods = config.get('session', 'authentications') config.set('session', 'authentications', methods) try: yield finally: config.set('session', 'authentications', saved_methods)
def wsgi_app(self, environ, start_response): for cls in self.protocols: if cls.content_type in environ.get('CONTENT_TYPE', ''): request = cls.request(environ) break else: request = Request(environ) origin = request.headers.get('Origin') origin_host = urllib.parse.urlparse(origin).netloc if origin else '' host = request.headers.get('Host') if origin and origin_host != host: cors = filter(None, config.get('web', 'cors', default='').splitlines()) if origin not in cors: abort(HTTPStatus.FORBIDDEN) data = self.dispatch_request(request) if not isinstance(data, (Response, HTTPException)): response = self.make_response(request, data) else: response = data if origin and isinstance(response, Response): response.headers['Access-Control-Allow-Origin'] = origin response.headers['Vary'] = 'Origin' method = request.headers.get('Access-Control-Request-Method') if method: response.headers['Access-Control-Allow-Methods'] = method headers = request.headers.get('Access-Control-Request-Headers') if headers: response.headers['Access-Control-Allow-Headers'] = headers response.headers['Access-Control-Max-Age'] = config.getint( 'web', 'cache_timeout') return response(environ, start_response)
def connect(self): if self.database_name == ':memory:': path = ':memory:' else: db_filename = self.database_name + '.sqlite' path = os.path.join(config.get('database', 'path'), db_filename) if not os.path.isfile(path): raise IOError('Database "%s" doesn\'t exist!' % db_filename) if self._conn is not None: return self self._conn = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES | sqlite.PARSE_COLNAMES) self._conn.create_function('extract', 2, SQLiteExtract.extract) self._conn.create_function('date_trunc', 2, date_trunc) self._conn.create_function('split_part', 3, split_part) self._conn.create_function('position', 2, SQLitePosition.position) self._conn.create_function('overlay', 3, SQLiteOverlay.overlay) self._conn.create_function('overlay', 4, SQLiteOverlay.overlay) if sqlite.sqlite_version_info < (3, 3, 14): self._conn.create_function('replace', 3, replace) self._conn.create_function('now', 0, now) self._conn.create_function('sign', 1, sign) self._conn.create_function('greatest', -1, max) self._conn.create_function('least', -1, min) self._conn.execute('PRAGMA foreign_keys = ON') return self
def get_login(cls, login, password): pool = Pool() LoginAttempt = pool.get('res.user.login.attempt') try: con = ldap_connection() if con: uid = config.get(section, 'uid', default='uid') users = cls.ldap_search_user(login, con, attrs=[uid]) if users and len(users) == 1: [(dn, attrs)] = users if password and con.simple_bind_s(dn, password): # Use ldap uid so we always get the right case login = attrs.get(uid, [login])[0] user_id, _ = cls._get_login(login) if user_id: LoginAttempt.remove(login) return user_id elif config.getboolean(section, 'create_user'): user, = cls.create([{ 'name': login, 'login': login, }]) return user.id except ldap.LDAPError: logger.error('LDAPError when login', exc_info=True) return super(User, cls).get_login(login, password)
def convert_unoconv(cls, report, data): # AKE: support printing via external api input_format = report.template_extension output_format = report.extension or report.template_extension if output_format in MIMETYPES: return output_format, data fd, path = tempfile.mkstemp(suffix=(os.extsep + input_format), prefix='trytond_') oext = FORMAT2EXT.get(output_format, output_format) with os.fdopen(fd, 'wb+') as fp: fp.write(data) cmd = [ 'unoconv', '--no-launch', '--connection=%s' % config.get('report', 'unoconv'), '-f', oext, '--stdout', path ] logger = logging.getLogger(__name__) try: # JCA : Pipe stderr proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) stdoutdata, stderrdata = proc.communicate() # JCA : Use error code rather than wait twice if proc.returncode != 0: logger.info('unoconv.stdout : ' + str(stdoutdata)) logger.error('unoconv.stderr : ' + str(stderrdata)) raise Exception(stderrdata) return oext, stdoutdata finally: os.remove(path)
def _check_update_needed(db_name, options): # Get current main module version main_module = config.get('version', 'module', default='coog_core') current_main_module_version = get_module_info(main_module)['version'] # Do the upgrade anyway if -u is activated if options.update: return True, current_main_module_version # Get main module version which stocked in the database version_control_table = Table('upgrade_version_control') cursor = Transaction().connection.cursor() cursor.execute( *version_control_table.select(version_control_table.current_version)) db_main_module_version = cursor.fetchone()[0] if (options.check_update and current_main_module_version != db_main_module_version): logger.warning( f'Current code version ({current_main_module_version}) is ' 'different from the last update version ' '({db_main_module_version}), updating') return True, current_main_module_version logger.warning(f'Current code version ({current_main_module_version}) ' 'matches last update version, nothing to do') return False, current_main_module_version
def drop(self, connection, database_name): if database_name == ':memory:': self._local.memory_database._conn = None return if os.sep in database_name: return os.remove(os.path.join(config.get('database', 'path'), database_name + '.sqlite'))
def send_reset_email(self): """ Send an account reset email to the user :param nereid_user: The browse record of the user """ EmailQueue = Pool().get("email.queue") email_message = render_email( config.get("email", "from"), self.email, _("Account Password Reset"), text_template="emails/reset-text.jinja", html_template="emails/reset-html.jinja", nereid_user=self, ) EmailQueue.queue_mail(config.get("email", "from"), self.email, email_message.as_string())
def get_bucket(self): ''' Return an S3 bucket for the static file ''' s3_conn = self.get_s3_connection() return s3_conn.get_bucket( config.get('nereid_s3', 'bucket'), )
def setUp(self): super(LDAPAuthenticationTestCase, self).setUp() methods = config.get('session', 'authentications') config.set('session', 'authentications', 'ldap') self.addCleanup(config.set, 'session', 'authentications', methods) config.add_section(section) config.set(section, 'uri', 'ldap://localhost/dc=tryton,dc=org') self.addCleanup(config.remove_section, section)
def get_config(names, section='html', default=None): names = names[:] while names: value = config.get(section, '-'.join(names)) if value is not None: return value names = names[:-1] return default
def drop(cls, cursor, database_name): if database_name == ':memory:': cls._local.memory_database._conn = None return if os.sep in database_name: return os.remove(os.path.join(config.get('database', 'path'), database_name + '.sqlite'))
def create(cls, vlist): badges = super(Badge, cls).create(vlist) #cls.isonas_badge_sync(badges, []) isonas = Isonasacs( config.get('Isonas', 'host'), config.get('Isonas', 'port')) isonas.logon( config.get('Isonas', 'clientid'), config.get('Isonas', 'password')) for badge in badges: if badge.disabled: isonas.add('BADGES', badge.party.code.encode('ascii'), badge.code.encode('ascii'), 0, 0, '', '', 2) else: isonas.add('BADGES', badge.party.code.encode('ascii'), badge.code.encode('ascii'), 0, 0, 0, '', 2) return badges
def _send_email(from_, users, email_func): from_cfg = config.get('email', 'from') for user in users: msg, title = email_func(user) set_from_header(msg, from_cfg, from_ or from_cfg) msg['To'] = user.email msg['Subject'] = Header(title, 'utf-8') sendmail_transactional(from_cfg, [user.email], msg)
def test_0010_test_email_on_confirm(self): """ Test if an email is sent when sale is confirmed """ Date = POOL.get('ir.date') EmailQueue = POOL.get('email.queue') with Transaction().start(DB_NAME, USER, context=CONTEXT): self.setup_defaults() sale, = self.Sale.create([{ 'reference': 'Test Sale', 'payment_term': self.payment_term.id, 'currency': self.company.currency.id, 'party': self.party.id, 'invoice_address': self.party.addresses[0].id, 'shipment_address': self.party.addresses[0].id, 'sale_date': Date.today(), 'company': self.company.id, }]) sale_line, = self.SaleLine.create([{ 'sale': sale, 'type': 'line', 'quantity': 2, 'unit': self.uom, 'unit_price': 20000, 'description': 'Test description', 'product': self.product.id }]) self.Sale.quote([sale]) self.assertEqual(len(EmailQueue.search([])), 0) # Confirm Sale self.Sale.confirm([sale]) emails = EmailQueue.search([]) self.assertEqual(len(emails), 1) self.assertEqual(emails[0].to_addrs, self.party.email) self.assertNotEqual( emails[0].msg.find(self.party.email), -1 ) self.assertNotEqual( emails[0].msg.find(config.get('email', 'from')), -1 ) self.assertNotEqual( emails[0].msg.find('Order Confirmed'), -1 ) self.assertTrue(sale.email_sent) # Try sending email for same sale and test if email is # not sent again sale.send_confirmation_email() self.assertEqual(len(EmailQueue.search([])), 1) # Test copying sale new_sale = self.Sale.copy([sale]) self.assertFalse(new_sale[0].email_sent)
def send_activation_email(self): """ Send an activation email to the user :param nereid_user: The browse record of the user """ EmailQueue = Pool().get('email.queue') email_message = render_email( config.get('email', 'from'), self.email, _('Account Activation'), text_template='emails/activation-text.jinja', html_template='emails/activation-html.jinja', nereid_user=self ) EmailQueue.queue_mail( config.get('email', 'from'), self.email, email_message.as_string() )
def get_data(self, name): """ Get the data from S3 instead of filesystem. The filename is built as '<DBNAME>/<FILENAME>' in the given S3 bucket :param name: name of field name :return: Bytearray of the file binary """ if not config.has_section('attachment_s3'): return super(Attachment, self).get_data(name) s3_conn = S3Connection( config.get('attachment_s3', 'access_key'), config.get('attachment_s3', 'secret_key') ) bucket = s3_conn.get_bucket(config.get('attachment_s3', 'bucket_name')) db_name = Transaction().database.name format_ = Transaction().context.pop( '%s.%s' % (self.__name__, name), '' ) value = None if name == 'data_size' or format_ == 'size': value = 0 if self.digest: filename = self.digest if self.collision: filename = filename + '-' + str(self.collision) filename = "/".join([db_name, filename]) if name == 'data_size' or format_ == 'size': key = bucket.lookup(filename) if key is not None: # Get the size only if bucket has key; value = key.size else: k = Key(bucket) k.key = filename try: value = bytearray(k.get_contents_as_string()) except S3ResponseError: self.raise_user_error( "no_such_key", error_args=(self.name, filename) ) return value
def _encrypt(cls, raw): """ Return encrypted raw_text """ if raw is None: return None key = os.environ.get('TRYTOND_ENCRYPTED_FIELD__SECRET_KEY') or \ config.get('encrypted_field', 'secret_key') return Fernet(key).encrypt(raw.encode('utf-8'))
def _decrypt(cls, encrypted): """ Return decrypted encrypted_text """ if encrypted is None: return None key = os.environ.get('TRYTOND_ENCRYPTED_FIELD__SECRET_KEY') or \ config.get('encrypted_field', 'secret_key') return Fernet(key).decrypt(encrypted.encode('utf-8'))