def process(session_id, fields): msg_fields = fields[0].split(" ") if len(msg_fields) == 2: old_pwd, new_pwd = msg_fields ACTION(actions.registration.Registration).change_password( session_id, old_pwd, new_pwd) else: raise LtdErrorException("Usage: /cp {old password} {new password}")
def ipfilter(self, session_id, fields): action, argv = fields[0], fields[1:] fn = None if action == "deny": fn = self.__deny_login__ elif action == "drop": fn = self.__drop_ip_filter__ elif action == "flush": fn = self.__flush_ip_filters__ elif action == "show": fn = self.__show_ip_filters__ elif not action: raise LtdErrorException("Usage: ipfilter {action} {arguments}") else: raise LtdErrorException("Unsupported action.") fn(session_id, argv)
def __flush_ip_filters__(self, session_id, argv): if argv: raise LtdErrorException("Usage: ipfilter flush") with self.__ipfilter_connection.enter_scope() as scope: self.__ipfilters.flush(scope) scope.complete() self.broker.deliver(session_id, ltd.encode_status_msg("IP-Filter", "Flushed."))
def process(session_id, fields): msg_fields = fields[0].split(" ", 1) if len(msg_fields) == 2: receiver, message = [f.strip() for f in msg_fields] else: raise LtdErrorException("Usage: /m {nick} {message}") ACTION(actions.privatemessage.PrivateMessage).send( session_id, receiver, message)
def process(session_id, fields): msg_fields = fields[0].split(" ", 1) if len(msg_fields) == 2: receiver, message = [f.strip() for f in msg_fields] else: raise LtdErrorException("Usage: /write {nick} {message}") ACTION(actions.messagebox.MessageBox).send_message( session_id, receiver, message)
def process(session_id, fields): usage = "Usage: hush {-q} {-n nick|-s address}" if fields[0]: try: opts, target = ltd.get_opts(fields[0], quiet="q", mode="ns", msg_type="op") if not target: raise LtdErrorException(usage) except: raise LtdErrorException(usage) ACTION(actions.hush.Hush).toggle(session_id, target, **opts) else: ACTION(actions.hush.Hush).list(session_id)
def process(session_id, fields): msg_fields = fields[0].split(" ") if len(msg_fields) == 2: nick, password = msg_fields ACTION(actions.admin.Admin).change_password( session_id, nick, password) else: raise LtdErrorException("Usage: /passwd {nick} {new password}")
def process(session_id, fields): msg_fields = fields[0].split(" ", 1) if len(msg_fields) == 2: receiver, message = [f.strip() for f in msg_fields] else: raise LtdErrorException("Usage: /exclude {nick} {message}") ACTION(actions.openmessage.OpenMessage).send(session_id, message, exclude=receiver)
def __test_ip__(self, session_id): state = self.session.get(session_id) login = "******" % (state.loginid, state.ip) with self.__ipfilter_connection.enter_scope() as scope: for f, _ in self.__ipfilters.load_deny_filters(scope): if f.matches(login): self.log.info("Blocking IP address: %s", login) raise LtdErrorException("Access denied.")
def __drop_ip_filter__(self, session_id, argv): if len(argv) != 1: raise LtdErrorException("Usage: ipfilter drop {filter}") filter = None try: filter = ipfilter.Factory.create(argv[0]) except: raise LtdErrorException("Filter is malformed.") with self.__ipfilter_connection.enter_scope() as scope: if not self.__ipfilters.deny_filter_exists(scope, filter.expression): raise LtdErrorException("Filter not found.") self.__ipfilters.remove(scope, filter.expression) self.broker.deliver(session_id, ltd.encode_status_msg("IP-Filter", "%s dropped." % (argv[0],))) scope.complete()
def set_log_level(self, session_id, level, msgid): try: verbosity = Verbosity(level) except ValueError: raise LtdErrorException("Unsupported log level: %d" % level) self.log.info("Verbosity set to %s.", verbosity) for l in self.__registry.loggers: l.setLevel(log.LOG_LEVELS[verbosity]) self.broker.deliver(session_id, ltd.encode_co_output("The log level is %d." % level, msgid))
def get_reputation(self, session_id, nick, msgid=""): loggedin_session = self.session.find_nick(nick) if not loggedin_session: raise LtdErrorException("%s is not signed on." % nick) loggedin_state = self.session.get(loggedin_session) reputation = self.reputation.get(loggedin_session) self.broker.deliver(session_id, ltd.encode_co_output("%s (%s): %.2f" % (nick, loggedin_state.address, reputation), msgid))
def __test_admin__(self, session_id): is_admin = False state = self.session.get(session_id) if state.authenticated: with self.nickdb_connection.enter_scope() as scope: is_admin = self.nickdb.is_admin(scope, state.nick) if not is_admin: self.reputation.critical(session_id) raise LtdErrorException("You don't have administrative privileges.")
def delete(self, session_id, password, msgid=""): state = self.session.get(session_id) if not state.authenticated: raise LtdErrorException("You must be registered to delete your entry.") if not password: raise LtdErrorException("Usage: /delete {password}") if state.nick.lower() == core.ADMIN.lower(): raise LtdErrorException("Cannot delete default admin account.") with self.nickdb_connection.enter_scope() as scope: if not self.nickdb.check_password(scope, state.nick, password): raise LtdErrorException("Password incorrect.") self.nickdb.delete(scope, state.nick) self.broker.deliver(session_id, ltd.encode_co_output("Record deleted.", msgid)) self.session.update(session_id, authentication=False) scope.complete()
def query(self, session_id, q, msgid=""): domain = None if q.startswith("/"): domain = "Command" contents = self.__read_contents__(lambda: self.__manual.command(q[1:])) else: domain = "Topic" contents = self.__read_contents__(lambda: self.__manual.topic(q)) if not contents: raise LtdErrorException("%s '%s' not found." % (domain, q)) self.__send_contents__(session_id, contents, msgid)
def __get_group_if_can_moderate__(self, session_id, allow_public=False): info = self.__get_group__(session_id) if self.__is_protected_group__(info.key): self.reputation.critical(session_id) raise LtdErrorException("You aren't the moderator.") if not (allow_public and info.control == group.Control.PUBLIC): if info.moderator: self.log.debug("Group's moderator: %s", info.moderator) if info.moderator != session_id: self.log.debug("User isn't moderator, testing administrative privileges.") with self.nickdb_connection.enter_scope() as scope: state = self.session.get(session_id) if not self.nickdb.exists(scope, state.nick) or not self.nickdb.is_admin(scope, state.nick): self.reputation.critical(session_id) raise LtdErrorException("You aren't the moderator.") return info
def set_topic(self, session_id, topic): info = self.__get_group_if_can_moderate__(session_id, allow_public=True) if not validate.is_valid_topic(topic): raise LtdErrorException("Topic must consist of at least %d and at most %d characters." % (validate.TOPIC_MIN, validate.TOPIC_MAX)) info.topic = topic self.groups.update(info) if info.volume != group.Volume.QUIET: self.broker.to_channel(str(info), ltd.encode_status_msg("Topic", "%s changed the topic to \"%s\"" % (self.session.get(session_id).nick, topic)))
def set_security_mode(self, session_id, enabled, msgid=""): state = self.session.get(session_id) if not state.authenticated: raise LtdErrorException("You must be registered to change your security.") with self.nickdb_connection.enter_scope() as scope: self.nickdb.set_secure(scope, state.nick, enabled) if enabled: self.broker.deliver(session_id, ltd.encode_co_output("Security set to password required.", msgid)) else: self.broker.deliver(session_id, ltd.encode_co_output("Security set to automatic.", msgid)) scope.complete()
def set_protected(self, session_id, protected, msgid=""): state = self.session.get(session_id) if not state.authenticated: raise LtdErrorException("You must be registered to change your protection level.") with self.nickdb_connection.enter_scope() as scope: self.nickdb.set_protected(scope, state.nick, protected) if protected: self.broker.deliver(session_id, ltd.encode_co_output("Protection enabled.", msgid)) else: self.broker.deliver(session_id, ltd.encode_co_output("Protection disabled.", msgid)) scope.complete()
def set_mode(self, session_id, mode): if not mode in ["on", "off", "verbose"]: raise LtdErrorException("Usage: /nobeep on|off|verbose") real_mode = session.BeepMode.ON if mode == "on": real_mode = session.BeepMode.OFF elif mode == "verbose": real_mode = session.BeepMode.VERBOSE self.session.update(session_id, beep=real_mode) self.broker.deliver( session_id, ltd.encode_status_msg("No-Beep", "No-Beep is now %s." % mode))
def set_mode(self, session_id, mode): if not mode in ["on", "off", "verbose"]: raise LtdErrorException("Usage: /echoback on|off|verbose") real_mode = session.EchoMode.OFF if mode == "on": real_mode = session.EchoMode.ON elif mode == "verbose": real_mode = session.EchoMode.VERBOSE self.session.update(session_id, echo=real_mode) self.broker.deliver( session_id, ltd.encode_status_msg("Echo", "Echoback is now %s." % mode))
def __load_details_if_confirmed__(self, session_id): state = self.session.get(session_id) if not state.authenticated: raise LtdErrorException("You must be registered to confirm your email address.") with self.nickdb_connection.enter_scope() as scope: if self.nickdb.is_email_confirmed(scope, state.nick): raise LtdResponseException("Already already confirmed.", ltd.encode_co_output("Email address already confirmed.")) details = self.nickdb.lookup(scope, state.nick) if not details.email: raise LtdStatusException("Confirmation", "No email address set.") return state.nick, details
def change_field(self, session_id, field, text, msgid=""): state = self.session.get(session_id) if not state.authenticated: raise LtdErrorException("You must be registered to change your profile.") if not self.__validate_field__(field, text): raise LtdResponseException("Invalid attribute.", ltd.encode_co_output("'%s' format not valid." % self.__map_field__(field), msgid)) with self.nickdb_connection.enter_scope() as scope: details = self.nickdb.lookup(scope, state.nick) old_val = getattr(details, field) if not old_val: old_val = "" setattr(details, field, text) self.nickdb.update(scope, state.nick, details) if text: self.broker.deliver(session_id, ltd.encode_co_output("%s set to '%s'." % (self.__map_field__(field), text), msgid)) else: self.broker.deliver(session_id, ltd.encode_co_output("%s unset." % self.__map_field__(field), msgid)) if field == "email" and old_val.lower() != text.lower() and self.nickdb.is_email_confirmed(scope, state.nick): self.broker.deliver(session_id, ltd.encode_co_output("Email confirmation revoked.", msgid)) self.nickdb.set_email_confirmed(scope, state.nick, False) self.nickdb.enable_message_forwarding(scope, state.nick, False) scope.complete() if field == "avatar": with self.avatar_connection.enter_scope() as scope: if text: self.avatar_writer.put(scope, state.nick, text) else: self.avatar_writer.clear(scope, state.nick) scope.complete()
def __login_password__(self, session_id, loginid, nick, password): self.log.debug("Password set, trying to authenticate %s.", nick) registered = False is_admin = False with self.nickdb_connection.enter_scope() as scope: if self.nickdb.exists(scope, nick): registered = self.nickdb.check_password(scope, nick, password) is_admin = self.nickdb.is_admin(scope, nick) if not registered: self.log.debug("Password is invalid.") self.reputation.critical(session_id) self.broker.deliver( session_id, ltd.encode_str("e", "Authorization failure.")) self.broker.deliver( session_id, ltd.encode_status_msg( "Register", "Send password to authenticate your nickname.")) if is_admin: raise LtdErrorException( "You need a password to login as administrator.") loggedin_session = self.session.find_nick(nick) if loggedin_session and not registered: self.log.debug("%s already logged in, aborting login.", nick) raise LtdStatusException("Register", "Nick already in use.") if loggedin_session: self.__auto_rename__(loggedin_session) self.session.update(session_id, loginid=loginid, nick=nick) return registered
def list_group(self, session_id, group_name, msgid=""): is_admin = False state = self.session.get(session_id) if group_name == ".": group_name = state.group if not self.groups.exists(group_name): raise LtdErrorException("Group %s not found." % group_name) if state.authenticated: with self.nickdb_connection.enter_scope() as scope: is_admin = self.nickdb.is_admin(scope, state.nick) info = self.groups.get(group_name) logins = self.session.get_nicks() self.__show_group__(session_id, state, info, logins, is_admin, True, msgid)
def __show_ip_filters__(self, session_id, argv): if argv: raise LtdErrorException("Usage: ipfilter show") filters = [] with self.__ipfilter_connection.enter_scope() as scope: for f, l in self.__ipfilters.load_deny_filters(scope): lifetime = "forever" if l > -1: time_left = max(1, l - dateutils.timestamp()) lifetime = dateutils.elapsed_time(time_left) filters.append((f.expression, lifetime)) if filters: for entry in sorted(filters, key=lambda e: "@".join(reversed(e[0].split("@", 1))).lower()): self.broker.deliver(session_id, ltd.encode_status_msg("IP-Filter", "%s denied (%s)" % entry)) else: self.broker.deliver(session_id, ltd.encode_status_msg("IP-Filter", "List is empty."))
def process(session_id, fields): fn = None args = [] if fields[3] == "login": fn = ACTION(actions.usersession.UserSession).login password = fields[4] if len(fields) >= 5 else "" status = fields[5] if len(fields) >= 6 else "" address = fields[6] if len(fields) >= 7 else "" args = [ session_id, fields[0], fields[1], password, fields[2], status, address ] elif fields[3] == "w": fn = ACTION(actions.list.List).list_and_quit args = [session_id] if not fn: raise LtdErrorException("Unsupported login type: '%s'" % fields[3]) fn(*args)
def toggle(self, session_id, target, mode="n", quiet=None, msg_type=""): quiet = bool(quiet) state = self.session.get(session_id) try: if mode == "n": if not msg_type or msg_type == "o": if state.hushlist.hush_nick_public(target): if not quiet: self.broker.deliver(session_id, ltd.encode_status_msg("Hush", "%s added to nickname open hush list." % target)) elif not quiet: self.broker.deliver(session_id, ltd.encode_status_msg("Hush", "%s removed from nickname open hush list." % target)) if not msg_type or msg_type == "p": if state.hushlist.hush_nick_private(target): if not quiet: self.broker.deliver(session_id, ltd.encode_status_msg("Hush", "%s added to nickname personal hush list." % target)) elif not quiet: self.broker.deliver(session_id, ltd.encode_status_msg("Hush", "%s removed from nickname personal hush list." % target)) else: if not msg_type or msg_type == "o": if state.hushlist.hush_site_public(target): if not quiet: self.broker.deliver(session_id, ltd.encode_status_msg("Hush", "%s added to site open hush list." % target)) elif not quiet: self.broker.deliver(session_id, ltd.encode_status_msg("Hush", "%s removed from site open hush list." % target)) if not msg_type or msg_type == "p": if state.hushlist.hush_site_private(target): if not quiet: self.broker.deliver(session_id, ltd.encode_status_msg("Hush", "%s added to site personal hush list." % target)) elif not quiet: self.broker.deliver(session_id, ltd.encode_status_msg("Hush", "%s removed from site personal hush list." % target)) except OverflowError: raise LtdErrorException("Hush list is full.") self.session.set(session_id, state)
def beep(self, session_id, receiver): loggedin_session = self.session.find_nick(receiver) if not loggedin_session: raise LtdErrorException("%s is not signed on." % receiver) loggedin_state = self.session.get(loggedin_session) state = self.session.get(session_id) if state.echo == session.EchoMode.VERBOSE: self.broker.deliver( session_id, ltd.encode_co_output("<*to: %s*> [=Beep=]" % receiver)) if loggedin_state.beep != session.BeepMode.ON: if loggedin_state.beep == session.BeepMode.VERBOSE: self.broker.deliver( loggedin_session, ltd.encode_status_msg( "No-Beep", "%s attempted (and failed) to beep you." % state.nick)) raise LtdStatusException("Beep", "User has nobeep enabled.") self.broker.deliver(loggedin_session, ltd.encode_str("k", state.nick)) if loggedin_state.away: if not self.away_table.is_alive(session_id, receiver): self.broker.deliver( session_id, ltd.encode_status_msg( "Away", "%s (since %s)." % (loggedin_state.away, loggedin_state.t_away.elapsed_str()))) self.away_table.set_alive(session_id, receiver, self.config.timeouts_away_message)
def register(self, session_id, password): self.log.debug("Starting user registration.") state = self.session.get(session_id) registered = False with self.nickdb_connection.enter_scope() as scope: if self.nickdb.exists(scope, state.nick): self.log.debug("Nick found, validating password.") if not self.nickdb.check_password(scope, state.nick, password): self.reputation.fatal(session_id) raise LtdErrorException("Authorization failure.") registered = True else: self.log.debug("Creating new user profile for %s.", state.nick) if not validate.is_valid_password(password): raise LtdStatusException("Register", "Password format not valid. Password length must be between %d and %d characters." % (validate.PASSWORD_MIN, validate.PASSWORD_MAX)) self.nickdb.create(scope, state.nick) self.nickdb.set_secure(scope, state.nick, True) self.nickdb.set_admin(scope, state.nick, False) self.nickdb.set_password(scope, state.nick, password) self.nickdb.set_mbox_limit(scope, state.nick, self.config.mbox_limit) registered = True scope.complete() if registered: self.mark_registered(session_id) self.notify_messagebox(session_id)