diff options
Diffstat (limited to 'src/jwebmail/webmail.py')
-rw-r--r-- | src/jwebmail/webmail.py | 139 |
1 files changed, 16 insertions, 123 deletions
diff --git a/src/jwebmail/webmail.py b/src/jwebmail/webmail.py index 4e47dbd..2cfc834 100644 --- a/src/jwebmail/webmail.py +++ b/src/jwebmail/webmail.py @@ -2,7 +2,7 @@ from urllib.parse import urlparse from flask import abort, current_app, flash, redirect, render_template, request, url_for from flask_babel import gettext, lazy_gettext -from flask_login import UserMixin, current_user, login_user, logout_user +from flask_login import current_user, login_user, logout_user from flask_paginate import Pagination, get_page_parameter, get_per_page_parameter from flask_wtf import FlaskForm from wtforms import ( @@ -16,15 +16,11 @@ from wtforms import ( ) from .model.read_mails import QMAuthError -from .read_mails import add_user, get_read_mails_logged_in +from .read_mails import JWebmailUser, add_user, get_read_mails_logged_in from .read_mails import login as rm_login from .render_mail import to_mime_type - -class JWebmailUser(UserMixin): - def __init__(self, mail_addr, password): - self.id = mail_addr - self.password = password +DEFAULT_LANGUAGE = "de" class LoginForm(FlaskForm): @@ -51,6 +47,7 @@ def login(): form = LoginForm() warn = "" + rc = 200 if form.validate_on_submit(): if rm_login(form.username.data, form.password.data): @@ -58,15 +55,17 @@ def login(): add_user(user) login_user(user) - next = request.args.get("next") + nxt = request.args.get("next") - if urlparse(next).netloc: + if urlparse(nxt).netloc: abort(401) - return redirect(next or url_for("displayheaders"), 303) + return redirect(nxt or url_for("displayheaders"), 303) else: - warn = gettext("login failed") + warn = gettext("login failed!") + elif request.method == "POST": + rc = 401 - return render_template("login.html", login_form=form, warn=warn), 401 + return render_template("login.html", login_form=form, warn=warn), rc def logout(): @@ -137,13 +136,13 @@ def displayheaders(folder=""): return render_template("displayheaders.html", **vals) -def readmail(msgid): +def readmail(msgid, folder=""): try: - mail = get_read_mails_logged_in().show("", msgid) + mail = get_read_mails_logged_in().show(folder, msgid) except QMAuthError: return render_template("not_found.html"), 404 - return render_template("readmail.html", msg=mail) + return render_template("readmail.html", msg=mail, folder=folder) def writemail(): @@ -166,10 +165,10 @@ def move(folder): return redirect(url_for("displayheaders"), 303) -def rawmail(msgid): +def rawmail(msgid, folder=""): path = request.args.get("path", "") - content = get_read_mails_logged_in().raw("", msgid, path) + content = get_read_mails_logged_in().raw(folder, msgid, path) headers = [] @@ -213,109 +212,3 @@ def sendmail(): flash(gettext("succ_send")) return redirect(url_for("displayheaders"), 303) - - -""" -sub remove { - my $self = shift; - - my $v = $self->validation; - $v->csrf_protect; - $v->required('mail'); - - if ($v->has_error) { - $self->reply->exception('errors in ' . join('', $v->failed->@*)); - return; - } - - my $auth = $self->stash(STS_AUTH); - - my $mm = $self->every_param('mail'); - my $folder = $self->stash('folder'); - - $self->users->remove($auth, $folder, $_) for @$mm; - - $self->res->code(303); - $self->redirect_to('displayheaders'); -} - - -### session password handling - -use constant { S_PASSWD => 'pw', S_OTP_S3D_PW => 'otp_s3d_pw' }; - -sub _rand_data { - my $len = shift; - - if (TRUE_RANDOM) { - #return makerandom_octet(Length => $len, Strength => 0); # was used for Crypt::Random - return urandom($len); - } - else { - my $res = ''; - for (0..$len-1) { - vec($res, $_, 8) = int rand 256; - } - - return $res; - } -} - -sub _session_passwd { - my ($self, $passwd, $challenge) = @_; - my $secAlg = LOGIN_SCHEME; - - $self->_warn_crypt; - - if (defined $passwd) { # set - if ($secAlg eq fc 'cram_md5') { - $self->session(S_PASSWD() => $passwd, challenge => $challenge); - } - elsif ($secAlg eq fc 'plain') { - unless ($passwd) { - $self->s3d(S_PASSWD, ''); - delete $self->session->{S_OTP_S3D_PW()}; - return; - } - die "'$passwd' contains invalid character \\n" if $passwd =~ /\n/; - if (length $passwd < 20) { - $passwd .= "\n" . ' ' x (20 - length($passwd) - 1); - } - my $passwd_utf8 = encode('UTF-8', $passwd); - my $rand_bytes = _rand_data(length $passwd_utf8); - $self->s3d(S_PASSWD, b64_encode($passwd_utf8 ^ $rand_bytes, '')); - $self->session(S_OTP_S3D_PW, b64_encode($rand_bytes, '')); - } - else { - die - } - } - else { # get - if ($secAlg eq fc 'cram_md5') { - wantarray or carp "you forgot the challenge"; - return ($self->session(S_PASSWD), $self->session('challenge')); - } - elsif ($secAlg eq fc 'plain') { - my $pw = b64_decode($self->s3d(S_PASSWD) || ''); - my $otp = b64_decode($self->session(S_OTP_S3D_PW) || ''); - my ($res) = split "\n", decode('UTF-8', $pw ^ $otp), 2; - return $res; - } - else { - die - } - } -} - -sub _warn_crypt { - my $self = shift; - - state $once = 0; - - if ( !TRUE_RANDOM && !$once && LOGIN_SCHEME eq fc 'plain' ) { - $self->log->warn("Falling back to pseudo random generation. Please install Crypt::URandom"); - $once = 1; - } -} - -""" |