Implement AUTHINFO

This commit is contained in:
XANTRONIX Development 2024-11-29 23:45:14 -05:00
parent 031b4d9617
commit a2acd9c108

View file

@ -13,6 +13,7 @@ from nntp.tiny.buffer import LineBuffer, OutputBuffer, BufferOverflow
from nntp.tiny.db import Database from nntp.tiny.db import Database
from nntp.tiny.response import Response, ResponseCode from nntp.tiny.response import Response, ResponseCode
from nntp.tiny.newsgroup import Newsgroup from nntp.tiny.newsgroup import Newsgroup
from nntp.tiny.user import User, UserPermission
from nntp.tiny.message import Message, MessageRange, MessagePart from nntp.tiny.message import Message, MessageRange, MessagePart
class SessionMode(enum.Enum): class SessionMode(enum.Enum):
@ -26,7 +27,8 @@ class Session():
'HDR', 'HDR',
'NEWNEWS', 'NEWNEWS',
'LIST ACTIVE NEWSGROUP OVERVIEW.FMT SUBSCRIPTIONS', 'LIST ACTIVE NEWSGROUP OVERVIEW.FMT SUBSCRIPTIONS',
'OVER MSGID' 'OVER MSGID',
'AUTHINFO USER',
] ]
RE_SPLIT = re.compile(r'\s+') RE_SPLIT = re.compile(r'\s+')
@ -40,8 +42,10 @@ class Session():
self.mode: SessionMode = SessionMode.READER self.mode: SessionMode = SessionMode.READER
self.active: bool = True self.active: bool = True
self.newsgroup: Optional[Newsgroup] = None self.newsgroup: Optional[Newsgroup] = None
self.article_id: Optional[int] = None self.user: Optional[User] = None
self.perms: Optional[UserPermission] = None
self.article_id: Optional[int] = None
def readline(self): def readline(self):
return self.buf.readline(self.sock) return self.buf.readline(self.sock)
@ -60,10 +64,45 @@ class Session():
return self.print(str(response)) return self.print(str(response))
def _cmd_authinfo_user(self, username):
if self.user is not None:
return self.respond(ResponseCode.NNTP_AUTH_BAD_SEQUENCE)
self.user = self.db.get(User, {'username': username})
return self.respond(ResponseCode.NNTP_INQUIRY_PASSPHRASE)
def _cmd_authinfo_pass(self, password):
if self.user is None or not self.user.auth(password):
return self.respond(ResponseCode.NNTP_AUTH_FAILED)
self.perms = self.user.permissions(self.db)
return self.respond(ResponseCode.NNTP_AUTH_ACCEPTED)
AUTHINFO_SUBCOMMANDS = {
'USER': _cmd_authinfo_user,
'PASS': _cmd_authinfo_pass
}
def _cmd_authinfo(self, *args):
if len(args) == 0:
return self.respond(ResponseCode.NNTP_SYNTAX_ERROR, "No subcommand provided")
subcmd, *subargs = args
fn = self.AUTHINFO_SUBCOMMANDS.get(subcmd.upper())
if fn is None:
return self.respond(ResponseCode.NNTP_COMMAND_UNKNOWN)
return fn(self, *subargs)
def _cmd_capabilities(self, *args): def _cmd_capabilities(self, *args):
self.respond(ResponseCode.NNTP_CAPABILITIES_FOLLOW) self.respond(ResponseCode.NNTP_CAPABILITIES_FOLLOW)
self.print('AUTHUSER INFO') if self.perms and self.perms & UserPermission.POST:
self.print('POST')
for item in self.NNTP_CAPABILITIES: for item in self.NNTP_CAPABILITIES:
self.print(item) self.print(item)
@ -653,6 +692,7 @@ class Session():
return self.respond(ResponseCode.NNTP_CONNECTION_CLOSING) return self.respond(ResponseCode.NNTP_CONNECTION_CLOSING)
COMMANDS = { COMMANDS = {
'AUTHINFO': _cmd_authinfo,
'CAPABILITIES': _cmd_capabilities, 'CAPABILITIES': _cmd_capabilities,
'MODE': _cmd_mode, 'MODE': _cmd_mode,
'GROUP': _cmd_group, 'GROUP': _cmd_group,