You've already forked Mailu
							
							
				mirror of
				https://github.com/Mailu/Mailu.git
				synced 2025-10-30 23:37:43 +02:00 
			
		
		
		
	Rename the generic 'address' to 'email'
This commit is contained in:
		| @@ -64,12 +64,12 @@ class AliasForm(Form): | ||||
|  | ||||
|  | ||||
| class AdminForm(Form): | ||||
|     admin = fields.StringField('Admin address', [validators.Email()]) | ||||
|     admin = fields.StringField('Admin email', [validators.Email()]) | ||||
|     submit = fields.SubmitField('Submit') | ||||
|  | ||||
|  | ||||
| class ManagerForm(Form): | ||||
|     manager = fields.StringField('Manager address', [validators.Email()]) | ||||
|     manager = fields.StringField('Manager email', [validators.Email()]) | ||||
|     submit = fields.SubmitField('Submit') | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ import re | ||||
| # Many-to-many association table for domain managers | ||||
| managers = db.Table('manager', | ||||
|     db.Column('domain_name', db.String(80), db.ForeignKey('domain.name')), | ||||
|     db.Column('user_address', db.String(255), db.ForeignKey('user.address')) | ||||
|     db.Column('user_email', db.String(255), db.ForeignKey('user.email')) | ||||
| ) | ||||
|  | ||||
|  | ||||
| @@ -34,9 +34,9 @@ class Domain(Base): | ||||
|     max_users = db.Column(db.Integer, nullable=False, default=0) | ||||
|     max_aliases = db.Column(db.Integer, nullable=False, default=0) | ||||
|  | ||||
|     def has_address(self, localpart): | ||||
|         for address in self.users + self.aliases: | ||||
|             if address.localpart == localpart: | ||||
|     def has_email(self, localpart): | ||||
|         for email in self.users + self.aliases: | ||||
|             if email.localpart == localpart: | ||||
|                 return True | ||||
|         else: | ||||
|             return False | ||||
| @@ -45,8 +45,8 @@ class Domain(Base): | ||||
|         return self.name | ||||
|  | ||||
|  | ||||
| class Address(Base): | ||||
|     """ Abstraction for a mail address (localpart and domain). | ||||
| class Email(Base): | ||||
|     """ Abstraction for an email address (localpart and domain). | ||||
|     """ | ||||
|     __abstract__ = True | ||||
|  | ||||
| @@ -61,7 +61,7 @@ class Address(Base): | ||||
|     # It is however very useful for quick lookups without joining tables, | ||||
|     # especially when the mail server il reading the database. | ||||
|     @declarative.declared_attr | ||||
|     def address(cls): | ||||
|     def email(cls): | ||||
|         updater = lambda context: "{0}@{1}".format( | ||||
|             context.current_parameters["localpart"], | ||||
|             context.current_parameters["domain_name"], | ||||
| @@ -72,14 +72,14 @@ class Address(Base): | ||||
|  | ||||
|     @classmethod | ||||
|     def get_by_email(cls, email): | ||||
|         return cls.query.filter_by(address=email).first() | ||||
|         return cls.query.filter_by(email=email).first() | ||||
|  | ||||
|     def __str__(self): | ||||
|         return self.address | ||||
|         return self.email | ||||
|  | ||||
|  | ||||
| class User(Address): | ||||
|     """ A user is a mail address that has a password to access a mailbox. | ||||
| class User(Email): | ||||
|     """ A user is an email address that has a password to access a mailbox. | ||||
|     """ | ||||
|     domain = db.relationship(Domain, backref='users') | ||||
|     password = db.Column(db.String(255), nullable=False) | ||||
| @@ -106,7 +106,7 @@ class User(Address): | ||||
|     is_anonymous = False | ||||
|  | ||||
|     def get_id(self): | ||||
|         return self.address | ||||
|         return self.email | ||||
|  | ||||
|     pw_context = context.CryptContext( | ||||
|         ["sha512_crypt", "sha256_crypt", "md5_crypt"] | ||||
| @@ -125,12 +125,12 @@ class User(Address): | ||||
|         else: | ||||
|             return self.manager_of | ||||
|  | ||||
|     def get_managed_addresses(self): | ||||
|         addresses = [] | ||||
|     def get_managed_emails(self): | ||||
|         emails = [] | ||||
|         for domain in self.get_managed_domains(): | ||||
|             addresses.extend(domain.users) | ||||
|             addresses.extend(domain.aliases) | ||||
|         return addresses | ||||
|             emails.extend(domain.users) | ||||
|             emails.extend(domain.aliases) | ||||
|         return emails | ||||
|  | ||||
|     @classmethod | ||||
|     def login(cls, email, password): | ||||
| @@ -138,8 +138,8 @@ class User(Address): | ||||
|         return user if (user and user.check_password(password)) else None | ||||
|  | ||||
|  | ||||
| class Alias(Address): | ||||
|     """ An alias is a mail address that redirects to some other addresses. | ||||
| class Alias(Email): | ||||
|     """ An alias is an email address that redirects to some destination. | ||||
|     """ | ||||
|     domain = db.relationship(Domain, backref='aliases') | ||||
|     destination = db.Column(db.String(), nullable=False) | ||||
| @@ -150,7 +150,7 @@ class Fetch(Base): | ||||
|     account. | ||||
|     """ | ||||
|     id = db.Column(db.Integer(), primary_key=True) | ||||
|     user_address = db.Column(db.String(255), db.ForeignKey(User.address), | ||||
|     user_email = db.Column(db.String(255), db.ForeignKey(User.email), | ||||
|         nullable=False) | ||||
|     user = db.relationship(User, backref='fetches') | ||||
|     protocol = db.Column(db.Enum('imap', 'pop3'), nullable=False) | ||||
|   | ||||
| @@ -15,7 +15,7 @@ Add a global administrator | ||||
|       tagClass: 'label label-primary large', | ||||
|       typeahead: { | ||||
|         afterSelect: function(val) { this.$element.val(""); }, | ||||
|         source: {{ current_user.get_managed_addresses()|map('string')|list|tojson }} | ||||
|         source: {{ current_user.get_managed_emails()|map('string')|list|tojson }} | ||||
|       } | ||||
|     }); | ||||
|   </script> | ||||
|   | ||||
| @@ -13,14 +13,14 @@ Global administrators | ||||
|   <tbody> | ||||
|     <tr> | ||||
|       <th>Actions</th> | ||||
|       <th>Address</th> | ||||
|       <th>Email</th> | ||||
|       <th>Created</th> | ||||
|       <th>Last edit</th> | ||||
|     </tr> | ||||
|     {% for admin in admins %} | ||||
|     <tr> | ||||
|       <td> | ||||
|         <a href="{{ url_for('.admin_delete', admin=admin.address) }}" onclick="return confirm('Are you sure?')" title="Delete"><i class="fa fa-trash"></i></a> | ||||
|         <a href="{{ url_for('.admin_delete', admin=admin.email) }}" onclick="return confirm('Are you sure?')" title="Delete"><i class="fa fa-trash"></i></a> | ||||
|       </td> | ||||
|       <td>{{ admin }}</td> | ||||
|       <td>{{ admin.created_at }}</td> | ||||
|   | ||||
| @@ -21,7 +21,7 @@ Create alias | ||||
|       tagClass: 'label label-primary large', | ||||
|       typeahead: { | ||||
|         afterSelect: function(val) { this.$element.val(""); }, | ||||
|         source: {{ current_user.get_managed_addresses()|map('string')|list|tojson }} | ||||
|         source: {{ current_user.get_managed_emails()|map('string')|list|tojson }} | ||||
|       } | ||||
|     }); | ||||
|   </script> | ||||
|   | ||||
| @@ -17,7 +17,7 @@ Alias list | ||||
|   <tbody> | ||||
|     <tr> | ||||
|       <th>Actions</th> | ||||
|       <th>Address</th> | ||||
|       <th>Email</th> | ||||
|       <th>Destination</th> | ||||
|       <th>Comment</th> | ||||
|       <th>Created</th> | ||||
| @@ -26,8 +26,8 @@ Alias list | ||||
|     {% for alias in domain.aliases %} | ||||
|     <tr> | ||||
|       <td> | ||||
|         <a href="{{ url_for('.alias_edit', alias=alias.address) }}" title="Edit"><i class="fa fa-pencil"></i></a>  | ||||
|         <a href="{{ url_for('.alias_delete', alias=alias.address) }}" onclick="return confirm('Are you sure?')" title="Delete"><i class="fa fa-trash"></i></a> | ||||
|         <a href="{{ url_for('.alias_edit', alias=alias.email) }}" title="Edit"><i class="fa fa-pencil"></i></a>  | ||||
|         <a href="{{ url_for('.alias_delete', alias=alias.email) }}" onclick="return confirm('Are you sure?')" title="Delete"><i class="fa fa-trash"></i></a> | ||||
|       </td> | ||||
|       <td>{{ alias }}</td> | ||||
|       <td>{{ alias.destination or '-' }}</td> | ||||
|   | ||||
| @@ -9,7 +9,7 @@ Fetched accounts | ||||
| {% endblock %} | ||||
|  | ||||
| {% block main_action %} | ||||
| <a class="btn btn-primary" href="{{ url_for('.fetch_create', user_address=user.address) }}">Add an account</a> | ||||
| <a class="btn btn-primary" href="{{ url_for('.fetch_create', user_email=user.email) }}">Add an account</a> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block box %} | ||||
|   | ||||
| @@ -19,7 +19,7 @@ Add a manager | ||||
|       tagClass: 'label label-primary large', | ||||
|       typeahead: { | ||||
|         afterSelect: function(val) { this.$element.val(""); }, | ||||
|         source: {{ current_user.get_managed_addresses()|map('string')|list|tojson }} | ||||
|         source: {{ current_user.get_managed_emails()|map('string')|list|tojson }} | ||||
|       } | ||||
|     }); | ||||
|   </script> | ||||
|   | ||||
| @@ -17,14 +17,14 @@ Manager list | ||||
|   <tbody> | ||||
|     <tr> | ||||
|       <th>Actions</th> | ||||
|       <th>Address</th> | ||||
|       <th>Email</th> | ||||
|       <th>Created</th> | ||||
|       <th>Last edit</th> | ||||
|     </tr> | ||||
|     {% for manager in domain.managers %} | ||||
|     <tr> | ||||
|       <td> | ||||
|         <a href="{{ url_for('.manager_delete', manager=manager.address) }}" onclick="return confirm('Are you sure?')" title="Delete"><i class="fa fa-trash"></i></a> | ||||
|         <a href="{{ url_for('.manager_delete', manager=manager.email) }}" onclick="return confirm('Are you sure?')" title="Delete"><i class="fa fa-trash"></i></a> | ||||
|       </td> | ||||
|       <td>{{ manager }}</td> | ||||
|       <td>{{ manager.created_at }}</td> | ||||
|   | ||||
| @@ -18,7 +18,7 @@ User list | ||||
|     <tr> | ||||
|       <th>Actions</th> | ||||
|       <th>User settings</th> | ||||
|       <th>Address</th> | ||||
|       <th>Email</th> | ||||
|       <th>Features</th> | ||||
|       <th>Quota</th> | ||||
|       <th>Comment</th> | ||||
| @@ -28,14 +28,14 @@ User list | ||||
|     {% for user in domain.users %} | ||||
|     <tr> | ||||
|       <td> | ||||
|         <a href="{{ url_for('.user_edit', user_email=user.address) }}" title="Edit"><i class="fa fa-pencil"></i></a>  | ||||
|         <a href="{{ url_for('.user_delete', user_email=user.address) }}" onclick="return confirm('Are you sure?')" title="Delete"><i class="fa fa-trash"></i></a> | ||||
|         <a href="{{ url_for('.user_edit', user_email=user.email) }}" title="Edit"><i class="fa fa-pencil"></i></a>  | ||||
|         <a href="{{ url_for('.user_delete', user_email=user.email) }}" onclick="return confirm('Are you sure?')" title="Delete"><i class="fa fa-trash"></i></a> | ||||
|       </td> | ||||
|       <td> | ||||
|         <a href="{{ url_for('.user_settings', user_email=user.address) }}" title="Settings"><i class="fa fa-wrench"></i></a>  | ||||
|         <a href="{{ url_for('.user_forward', user_email=user.address) }}" title="Auto-forward"><i class="fa fa-share"></i></a>  | ||||
|         <a href="{{ url_for('.user_reply', user_email=user.address) }}" title="Auto-reply"><i class="fa fa-plane"></i></a>  | ||||
|         <a href="{{ url_for('.fetch_list', user_address=user.address) }}" title="Fetched accounts"><i class="fa fa-download"></i></a>  | ||||
|         <a href="{{ url_for('.user_settings', user_email=user.email) }}" title="Settings"><i class="fa fa-wrench"></i></a>  | ||||
|         <a href="{{ url_for('.user_forward', user_email=user.email) }}" title="Auto-forward"><i class="fa fa-share"></i></a>  | ||||
|         <a href="{{ url_for('.user_reply', user_email=user.email) }}" title="Auto-reply"><i class="fa fa-plane"></i></a>  | ||||
|         <a href="{{ url_for('.fetch_list', user_email=user.email) }}" title="Fetched accounts"><i class="fa fa-download"></i></a>  | ||||
|       </td> | ||||
|       <td>{{ user }}</td> | ||||
|       <td> | ||||
|   | ||||
| @@ -19,7 +19,7 @@ def admin_list(): | ||||
| def admin_create(): | ||||
|     form = forms.AdminForm() | ||||
|     if form.validate_on_submit(): | ||||
|         user = models.User.query.filter_by(address=form.admin.data).first() | ||||
|         user = models.User.query.filter_by(email=form.admin.data).first() | ||||
|         if user: | ||||
|             user.global_admin = True | ||||
|             db.session.add(user) | ||||
| @@ -34,7 +34,7 @@ def admin_create(): | ||||
| @app.route('/admin/delete/<admin>', methods=['GET']) | ||||
| @flask_login.login_required | ||||
| def admin_delete(admin): | ||||
|     user = models.User.query.filter_by(address=admin).first() | ||||
|     user = models.User.query.filter_by(email=admin).first() | ||||
|     if user: | ||||
|         user.global_admin  = False | ||||
|         db.session.add(user) | ||||
|   | ||||
| @@ -23,8 +23,9 @@ def alias_create(domain_name): | ||||
|             flask.url_for('.alias_list', domain_name=domain.name)) | ||||
|     form = forms.AliasForm() | ||||
|     if form.validate_on_submit(): | ||||
|         if domain.has_address(form.localpart.data): | ||||
|             flask.flash('Address %s is already used' % address, 'error') | ||||
|         if domain.has_email(form.localpart.data): | ||||
|             # TODO email is not declared | ||||
|             flask.flash('Email %s is already used' % email, 'error') | ||||
|         else: | ||||
|             alias = models.Alias(localpart=form.localpart.data, domain=domain) | ||||
|             alias.destination = form.destination.data | ||||
|   | ||||
| @@ -21,7 +21,7 @@ def login(): | ||||
|             flask_login.login_user(user) | ||||
|             return flask.redirect(flask.url_for('.index')) | ||||
|         else: | ||||
|             flask.flash('Wrong e-mail address or password', 'error') | ||||
|             flask.flash('Wrong e-mail or password', 'error') | ||||
|     return flask.render_template('login.html', form=form) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -6,19 +6,19 @@ import flask | ||||
| import wtforms_components | ||||
|  | ||||
|  | ||||
| @app.route('/fetch/list', methods=['GET', 'POST'], defaults={'user_address': None}) | ||||
| @app.route('/fetch/list/<user_address>', methods=['GET']) | ||||
| @app.route('/fetch/list', methods=['GET', 'POST'], defaults={'user_email': None}) | ||||
| @app.route('/fetch/list/<user_email>', methods=['GET']) | ||||
| @flask_login.login_required | ||||
| def fetch_list(user_address): | ||||
|     user = utils.get_user(user_address, True) | ||||
| def fetch_list(user_email): | ||||
|     user = utils.get_user(user_email, True) | ||||
|     return flask.render_template('fetch/list.html', user=user) | ||||
|  | ||||
|  | ||||
| @app.route('/fetch/list', methods=['GET', 'POST'], defaults={'user_address': None}) | ||||
| @app.route('/fetch/create/<user_address>', methods=['GET', 'POST']) | ||||
| @app.route('/fetch/list', methods=['GET', 'POST'], defaults={'user_email': None}) | ||||
| @app.route('/fetch/create/<user_email>', methods=['GET', 'POST']) | ||||
| @flask_login.login_required | ||||
| def fetch_create(user_address): | ||||
|     user = utils.get_user(user_address) | ||||
| def fetch_create(user_email): | ||||
|     user = utils.get_user(user_email) | ||||
|     form = forms.FetchForm() | ||||
|     if form.validate_on_submit(): | ||||
|         fetch = models.Fetch(user=user) | ||||
| @@ -32,7 +32,7 @@ def fetch_create(user_address): | ||||
|         db.session.commit() | ||||
|         flask.flash('Fetch configuration created') | ||||
|         return flask.redirect( | ||||
|             flask.url_for('.fetch_list', user_address=user.address)) | ||||
|             flask.url_for('.fetch_list', user_email=user.email)) | ||||
|     return flask.render_template('fetch/create.html', form=form) | ||||
|  | ||||
|  | ||||
| @@ -52,7 +52,7 @@ def fetch_edit(fetch_id): | ||||
|         db.session.commit() | ||||
|         flask.flash('Fetch configuration updated') | ||||
|         return flask.redirect( | ||||
|             flask.url_for('.fetch_list', user_address=fetch.user.address)) | ||||
|             flask.url_for('.fetch_list', user_email=fetch.user.email)) | ||||
|     return flask.render_template('fetch/edit.html', | ||||
|         form=form, fetch=fetch) | ||||
|  | ||||
| @@ -65,4 +65,4 @@ def fetch_delete(fetch_id): | ||||
|     db.session.commit() | ||||
|     flask.flash('Fetch configuration delete') | ||||
|     return flask.redirect( | ||||
|         flask.url_for('.fetch_list', user_address=fetch.user.address)) | ||||
|         flask.url_for('.fetch_list', user_email=fetch.user.email)) | ||||
|   | ||||
| @@ -23,8 +23,9 @@ def user_create(domain_name): | ||||
|             flask.url_for('.user_list', domain_name=domain.name)) | ||||
|     form = forms.UserForm() | ||||
|     if form.validate_on_submit(): | ||||
|         if domain.has_address(form.localpart.data): | ||||
|             flask.flash('Address %s is already used' % address, 'error') | ||||
|         if domain.has_email(form.localpart.data): | ||||
|             # TODO: email is not declared | ||||
|             flask.flash('Email %s is already used' % email, 'error') | ||||
|         else: | ||||
|             user = models.User(localpart=form.localpart.data, domain=domain) | ||||
|             user.comment = form.comment.data | ||||
|   | ||||
| @@ -5,10 +5,10 @@ connect = /data/freeposte.db | ||||
| password_query = \ | ||||
|  SELECT password \ | ||||
|    FROM user \ | ||||
|   WHERE user.address = '%u' | ||||
|   WHERE user.email = '%u' | ||||
|  | ||||
| # Mostly get the user quota | ||||
| user_query = \ | ||||
|  SELECT '*:bytes=' || user.quota_bytes AS quota_rule \ | ||||
|    FROM user \ | ||||
|   WHERE user.address = '%u' | ||||
|   WHERE user.email = '%u' | ||||
|   | ||||
| @@ -3,20 +3,20 @@ connect = /data/freeposte.db | ||||
| map { | ||||
|   pattern = priv/reply_subject | ||||
|   table = user | ||||
|   username_field = address | ||||
|   username_field = email | ||||
|   value_field = reply_subject | ||||
| } | ||||
|  | ||||
| map { | ||||
|   pattern = priv/reply_body | ||||
|   table = user | ||||
|   username_field = address | ||||
|   username_field = email | ||||
|   value_field = reply_body | ||||
| } | ||||
|  | ||||
| map { | ||||
|   pattern = priv/forward | ||||
|   table = user | ||||
|   username_field = address | ||||
|   username_field = email | ||||
|   value_field = forward | ||||
| } | ||||
|   | ||||
| @@ -10,7 +10,7 @@ RC_LINE = """ | ||||
| poll {host} proto {protocol} port {port} | ||||
|     user "{username}" password "{password}" | ||||
|     smtphost "smtp" | ||||
|     smtpname {user_address} | ||||
|     smtpname {user_email} | ||||
|     {options} | ||||
| """ | ||||
|  | ||||
| @@ -25,15 +25,15 @@ def fetchmail(fetchmailrc): | ||||
|  | ||||
| def run(cursor): | ||||
|     cursor.execute(""" | ||||
|         SELECT user_address, protocol, host, port, tls, username, password | ||||
|         SELECT user_email, protocol, host, port, tls, username, password | ||||
|         FROM fetch | ||||
|     """) | ||||
|     fetchmailrc = "" | ||||
|     for line in cursor.fetchall(): | ||||
|         user_address, protocol, host, port, tls, username, password = line | ||||
|         user_email, protocol, host, port, tls, username, password = line | ||||
|         options = "options ssl" if tls else "" | ||||
|         fetchmailrc += RC_LINE.format( | ||||
|             user_address=user_address, | ||||
|             user_email=user_email, | ||||
|             protocol=protocol, | ||||
|             host=host, | ||||
|             port=port, | ||||
|   | ||||
| @@ -2,4 +2,4 @@ dbpath = /data/freeposte.db | ||||
| query = | ||||
|  SELECT destination | ||||
|    FROM alias | ||||
|   WHERE alias.address = '%s' | ||||
|   WHERE alias.email = '%s' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user