Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dkim client support #154

Closed
wants to merge 1 commit into from
Closed

add dkim client support #154

wants to merge 1 commit into from

Conversation

gpatel-fr
Copy link
Contributor

Related to closed issue #21

@icgood
Copy link
Member

icgood commented Jun 18, 2019

I reopened the issue.

fix #21

Copy link
Member

@icgood icgood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall. Thanks for doing this! I had a few changes for you then it should be good to merge.

setup.py Outdated
@@ -33,6 +33,7 @@
namespace_packages=['slimta'],
install_requires=['gevent >= 1.1rc',
'pysasl >= 0.4.0',
'dkimpy >= 0.9.0',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep this dependency as optional. A few things:

Please move this to an extras_require parameter:

extras_require={'dkim': ['dkimpy >= 0.9.0']},

And then move your new policy class to its own module (maybe slimta.policy.dkimheader). The test can stay put, just add dkimpy >= 0.9.0 as a new line in test/requirements.txt.

@@ -132,4 +135,61 @@ def apply(self, envelope):
envelope.prepend_header('Received', data)


class AddDkimHeader(QueuePolicy):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename this to AddDKIMHeader.

self.logger = logging.getLogger(__name__)

def apply(self, envelope):
from dkim import dkim_sign, DKIMException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once you separate this class into its own file, this import can go up to the top.

**dict(sender=envelope.sender,domain=dom) )
return
data = hd.replace(b'\r\n',b'').decode('utf-8').split(':',1)[1]
envelope.prepend_header('DKIM-Signature', data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be:

envelope.headers['DKIM-Signature'] = data

Prepending is typically only desired for the Received header.

'signature_algorithm': 'rsa-sha1',
'include_headers': ['from','subject'] }
AddDkimHeader(dkim).apply(env)
self.assertTrue(env.headers['DKIM-Signature'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a few assertIn checks for some of the expected tag=value pairs in the header?

@gpatel-fr
Copy link
Contributor Author

2 points

  • I am baffled by the separate file for dkim header; it's a header after all. Well if you used to collect data about animals and were storing the info in a drawer labelled 'animals' with sections for dogs, cats, horses and I wanted to add a section about guinea pigs, I'd expect to add a new section for guinea pigs in the drawer animals, not create a new drawer especially for guinea pigs. I'd say well, right, it's your filing system but sure I wonder greatly why you want it this way :-). IMO looking at the policy directory it would look strange having a 'headers.py' and a 'headerDKIM.py' or something like that.

  • about the prepending of the DKIM header, it was my belief that it was the standard way of doing it:
    https://www.ietf.org/rfc/rfc6376.txt
    see 5.6, how do you understand it ?

@icgood
Copy link
Member

icgood commented Jun 19, 2019

I am baffled by the separate file for dkim header; it's a header after all. Well if you used to collect data about animals and were storing the info in a drawer labelled 'animals' with sections for dogs, cats, horses and I wanted to add a section about guinea pigs, I'd expect to add a new section for guinea pigs in the drawer animals, not create a new drawer especially for guinea pigs. I'd say well, right, it's your filing system but sure I wonder greatly why you want it this way :-). IMO looking at the policy directory it would look strange having a 'headers.py' and a 'headerDKIM.py' or something like that.

It has to do with keeping the dkimpy dependency optional. Your implementation accomplishes that by doing the import inside the apply method, but that's against PEP-8 and something I've tried to avoid thus far.

I do see your point, however, of organizing the files in a way that makes sense. How about this, move headers.py as-is to headers/__init__.py. Then, add your new policy in headers/dkim.py, with the dkimpy import at the top. Thoughts?

about the prepending of the DKIM header, it was my belief that it was the standard way of doing it:
https://www.ietf.org/rfc/rfc6376.txt
see 5.6, how do you understand it ?

Sorry about that, I hadn't looked at that yet, thanks for the link! You were correct to prepend.

@gpatel-fr
Copy link
Contributor Author

About PEP-8 I'd say it is exceedingly onerous to try to conform to it everywhere, especially for import. I have looked a bit and autopep8 do not try to fix non module level import, pep8 itself

https://pep8.readthedocs.io/en/1.4.4/_modules/pep8.html

do not even conform stricly, and python-slimta either:

https://github.com/slimta/python-slimta/blob/master/slimta/queue/__init__.py

putting the headers.py code in init.py is just hiding away the inconsistency - I will refrain to pursue my drawer metaphor here -.

I think a better compromise is to just add after the headers import something along the lines of

try:
  import dkimpy
except ImportError:
  pass # noqua

I don't know if a 'pass' instruction is subjected to the honours of code quality control (I'll check it)

And by the way, the import of dkimpy in the Apply method was a remnant of my first implementation, that was indeed setting dkimpy as an optional dependency. I just forgot to move it to the file beginning.
It's a bit of an unwieldy case, it could be a separate product python-slimta-dkim except that headers are already included in the main product. And standard is a relative idea here: dkim is not managed by the standard Python library, but at the internet level (IETF) it is no less standard than the classical headers (received, from,...). Moving headers to a separate product python-slimta-headers would be meaningless, how to manage mail without headers. There is already a third party library in python-slimta (pycares), but although dns and dkim are internet standards dns is vastly more important than dkim. All considered I still think that the except at the beginning of headers.py conforms best to the spirit of PEP8 while not changing what is IMO a clear and rational organization that don't need fixing.

@icgood
Copy link
Member

icgood commented Jun 20, 2019

I'd be happy with this pattern that I've seen often, e.g. in the Python codebase:

try:
    import dkim
except ImportError:
    dkim = None
# inside AddDKIMHeader.__init__()
if dkim is None:
    raise ImportError('dkimpy is not installed')

Raising the exception in the policy constructor should bring the error to attention during initialization rather than once an email goes through, so I'd place it there.

@gpatel-fr
Copy link
Contributor Author

Thanks, now I just have to do the rest of the job :-)

@gpatel-fr
Copy link
Contributor Author

err, hello again.
I wonder what I have done wrong with this out of date with the base branch. Oh I see. You did a change a few days ago and I forgot to check for this today. Is this a problem since it's a totally unrelated change ?
anyway, I added a very small change, a comment for the prepend header in headers.py. Other than that (I hope you will not object) I think I have done what I could, I have not found any way to keep 100% coverage for headers.py without breaking PEP-8 more in test_slimta_policy_headers.py.

@gpatel-fr gpatel-fr closed this Oct 13, 2019
@gpatel-fr gpatel-fr deleted the dkim branch October 13, 2019 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants