Skip to content

Commit 60d3cd1

Browse files
authored
Implement DatePGPPublicKeyField and DateTimePGPPublicKeyField (#57) (#58)
* Fixes #57: Implemented DatePGPPublicKeyField and DateTimePGPPublicKeyField
1 parent 3fde329 commit 60d3cd1

File tree

11 files changed

+526
-40
lines changed

11 files changed

+526
-40
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Updated out-dated requirements (latest versions of Flake8 and pycodestyle
66
are incompatible with each other)
77
* Updated README with better explanations of the fields
8+
* Implemented DatePGPPublicKeyField and DateTimePGPPublicKeyField
89

910
## 2.1.1
1011

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,25 @@ Supported PGP public key fields are:
4343
- `EmailPGPPublicKeyField`
4444
- `IntegerPGPPublicKeyField`
4545
- `TextPGPPublicKeyField`
46+
- `DatePGPPublicKeyField`
47+
- `DateTimePGPPublicKeyField`
4648

4749
Public key encryption creates a token generated with a public key to
4850
encrypt the data and a private key to decrypt it.
4951

5052
Public and private keys can be set in settings with `PUBLIC_PGP_KEY` and
5153
`PRIVATE_PGP_KEY`.
5254

55+
N.B. `DatePGPPublicKeyField` and `DateTimePGPPublicKeyField` only support the following lookups:
56+
57+
- `__exact`
58+
- `__gt`
59+
- `__gte`
60+
- `__lt`
61+
- `__lte`
62+
63+
There is no support for `__range` yet (SQL `BETWEEN`). Pull requests are welcome.
64+
5365
##### Generate GPG keys.
5466

5567
The public key is going to encrypt the message and the private key will be
@@ -93,7 +105,7 @@ N.B. `DatePGPSymmetricKeyField` and `DateTimePGPSymmetricKeyField` only support
93105
- `__lt`
94106
- `__lte`
95107

96-
There is no support for `__range` yet (SQL `BETWEEN`).
108+
There is no support for `__range` yet (SQL `BETWEEN`). Pull requests are welcome.
97109

98110
### Django settings
99111

@@ -141,8 +153,13 @@ class MyModel(models.Model):
141153
hmac_field = fields.TextHMACField()
142154
hmac_with_original_field = fields.TextHMACField(original='pgp_sym_field')
143155

156+
email_pgp_pub_field = fields.EmailPGPPublicKeyField()
144157
integer_pgp_pub_field = fields.IntegerPGPPublicKeyField()
145158
pgp_pub_field = fields.TextPGPPublicKeyField()
159+
date_pgp_pub_field = fields.DatePGPPublicKeyField()
160+
datetime_pgp_pub_field = fields.DateTimePGPPublicKeyField()
161+
162+
email_pgp_sym_field = fields.EmailPGPSymmetricKeyField()
146163
integer_pgp_sym_field = fields.IntegerPGPSymmetricKeyField()
147164
pgp_sym_field = fields.TextPGPSymmetricKeyField()
148165
date_pgp_sym_field = fields.DatePGPSymmetricKeyField()

pgcrypto/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
class PGPAdmin(object):
1+
class PGPAdmin(object): # pragma: no cover
22

33
def get_queryset(self, request):
44
"""Skip any auto decryption when ORM calls are from the admin."""

pgcrypto/aggregates.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class EncryptionBase(Aggregate):
5050
"""Base class to add a custom aggregate method to a query."""
5151

5252
def add_to_query(self, query, alias, col, source, is_summary):
53-
"""Add the aggregate to the query.
53+
"""Add the aggregate to the query. This method will be removed in Django 1.10.
5454
5555
`alias` is `{self.lookup}__decrypt` where 'decrypt' is `self.name.lower()`.
5656
@@ -83,6 +83,20 @@ class PGPSymmetricKeyAggregate(PGPSymmetricKeySQL, EncryptionBase):
8383
name = 'decrypted'
8484

8585

86+
class DatePGPPublicKeyAggregate(EncryptionBase):
87+
"""PGP public key based aggregation.
88+
89+
`pgp_sym_encrypt` is a pgcrypto functions, encrypts the field's value
90+
with a key.
91+
"""
92+
name = 'decrypted'
93+
sql = PGPPublicKeySQL
94+
function = 'pgp_pub_decrypt'
95+
template = "cast(%(function)s(%(field)s, dearmor('{}')) AS DATE)".format(
96+
settings.PRIVATE_PGP_KEY,
97+
)
98+
99+
86100
class DatePGPSymmetricKeyAggregate(EncryptionBase):
87101
"""PGP symmetric key based aggregation.
88102
@@ -97,6 +111,20 @@ class DatePGPSymmetricKeyAggregate(EncryptionBase):
97111
)
98112

99113

114+
class DateTimePGPPublicKeyAggregate(EncryptionBase):
115+
"""PGP public key based aggregation.
116+
117+
`pgp_sym_encrypt` is a pgcrypto functions, encrypts the field's value
118+
with a key.
119+
"""
120+
name = 'decrypted'
121+
sql = PGPPublicKeySQL
122+
function = 'pgp_pub_decrypt'
123+
template = "cast(%(function)s(%(field)s, dearmor('{}')) AS TIMESTAMP)".format(
124+
settings.PRIVATE_PGP_KEY,
125+
)
126+
127+
100128
class DateTimePGPSymmetricKeyAggregate(EncryptionBase):
101129
"""PGP symmetric key based aggregation.
102130

pgcrypto/fields.py

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,33 @@
99
PGP_SYM_ENCRYPT_SQL,
1010
)
1111
from pgcrypto.lookups import (
12-
DateEXACT,
13-
DateGT,
14-
DateGTE,
15-
DateLT,
16-
DateLTE,
17-
DateTimeEXACT,
18-
DateTimeGT,
19-
DateTimeGTE,
20-
DateTimeLT,
21-
DateTimeLTE,
12+
DatePGPPublicKeyEXACT,
13+
DatePGPPublicKeyGT,
14+
DatePGPPublicKeyGTE,
15+
DatePGPPublicKeyLT,
16+
DatePGPPublicKeyLTE,
17+
DatePGPSymmetricKeyEXACT,
18+
DatePGPSymmetricKeyGT,
19+
DatePGPSymmetricKeyGTE,
20+
DatePGPSymmetricKeyLT,
21+
DatePGPSymmetricKeyLTE,
22+
DateTimePGPPublicKeyEXACT,
23+
DateTimePGPPublicKeyGT,
24+
DateTimePGPPublicKeyGTE,
25+
DateTimePGPPublicKeyLT,
26+
DateTimePGPPublicKeyLTE,
27+
DateTimePGPSymmetricKeyEXACT,
28+
DateTimePGPSymmetricKeyGT,
29+
DateTimePGPSymmetricKeyGTE,
30+
DateTimePGPSymmetricKeyLT,
31+
DateTimePGPSymmetricKeyLTE,
2232
DigestLookup,
2333
HMACLookup,
2434
)
2535
from pgcrypto.mixins import (
36+
DatePGPPublicKeyFieldMixin,
2637
DatePGPSymmetricKeyFieldMixin,
38+
DateTimePGPPublicKeyFieldMixin,
2739
DateTimePGPSymmetricKeyFieldMixin,
2840
EmailPGPPublicKeyFieldMixin,
2941
EmailPGPSymmetricKeyFieldMixin,
@@ -64,6 +76,32 @@ class TextPGPPublicKeyField(PGPPublicKeyFieldMixin, models.TextField):
6476
encrypt_sql = PGP_PUB_ENCRYPT_SQL
6577

6678

79+
class DatePGPPublicKeyField(DatePGPPublicKeyFieldMixin, models.TextField):
80+
"""Date PGP public key encrypted field for postgres."""
81+
encrypt_sql = PGP_PUB_ENCRYPT_SQL
82+
cast_sql = 'cast(%s as DATE)'
83+
84+
85+
DatePGPPublicKeyField.register_lookup(DatePGPPublicKeyEXACT)
86+
DatePGPPublicKeyField.register_lookup(DatePGPPublicKeyGT)
87+
DatePGPPublicKeyField.register_lookup(DatePGPPublicKeyGTE)
88+
DatePGPPublicKeyField.register_lookup(DatePGPPublicKeyLT)
89+
DatePGPPublicKeyField.register_lookup(DatePGPPublicKeyLTE)
90+
91+
92+
class DateTimePGPPublicKeyField(DateTimePGPPublicKeyFieldMixin, models.TextField):
93+
"""DateTime PGP public key encrypted field for postgres."""
94+
encrypt_sql = PGP_PUB_ENCRYPT_SQL
95+
cast_sql = 'cast(%s as TIMESTAMP)'
96+
97+
98+
DateTimePGPPublicKeyField.register_lookup(DateTimePGPPublicKeyEXACT)
99+
DateTimePGPPublicKeyField.register_lookup(DateTimePGPPublicKeyGT)
100+
DateTimePGPPublicKeyField.register_lookup(DateTimePGPPublicKeyGTE)
101+
DateTimePGPPublicKeyField.register_lookup(DateTimePGPPublicKeyLT)
102+
DateTimePGPPublicKeyField.register_lookup(DateTimePGPPublicKeyLTE)
103+
104+
67105
class EmailPGPSymmetricKeyField(EmailPGPSymmetricKeyFieldMixin, models.EmailField):
68106
"""Email PGP symmetric key encrypted field."""
69107
encrypt_sql = PGP_SYM_ENCRYPT_SQL
@@ -85,11 +123,11 @@ class DatePGPSymmetricKeyField(DatePGPSymmetricKeyFieldMixin, models.TextField):
85123
cast_sql = 'cast(%s as DATE)'
86124

87125

88-
DatePGPSymmetricKeyField.register_lookup(DateEXACT)
89-
DatePGPSymmetricKeyField.register_lookup(DateGT)
90-
DatePGPSymmetricKeyField.register_lookup(DateGTE)
91-
DatePGPSymmetricKeyField.register_lookup(DateLT)
92-
DatePGPSymmetricKeyField.register_lookup(DateLTE)
126+
DatePGPSymmetricKeyField.register_lookup(DatePGPSymmetricKeyEXACT)
127+
DatePGPSymmetricKeyField.register_lookup(DatePGPSymmetricKeyGT)
128+
DatePGPSymmetricKeyField.register_lookup(DatePGPSymmetricKeyGTE)
129+
DatePGPSymmetricKeyField.register_lookup(DatePGPSymmetricKeyLT)
130+
DatePGPSymmetricKeyField.register_lookup(DatePGPSymmetricKeyLTE)
93131

94132

95133
class DateTimePGPSymmetricKeyField(DateTimePGPSymmetricKeyFieldMixin, models.TextField):
@@ -98,8 +136,8 @@ class DateTimePGPSymmetricKeyField(DateTimePGPSymmetricKeyFieldMixin, models.Tex
98136
cast_sql = 'cast(%s as TIMESTAMP)'
99137

100138

101-
DateTimePGPSymmetricKeyField.register_lookup(DateTimeEXACT)
102-
DateTimePGPSymmetricKeyField.register_lookup(DateTimeGT)
103-
DateTimePGPSymmetricKeyField.register_lookup(DateTimeGTE)
104-
DateTimePGPSymmetricKeyField.register_lookup(DateTimeLT)
105-
DateTimePGPSymmetricKeyField.register_lookup(DateTimeLTE)
139+
DateTimePGPSymmetricKeyField.register_lookup(DateTimePGPSymmetricKeyEXACT)
140+
DateTimePGPSymmetricKeyField.register_lookup(DateTimePGPSymmetricKeyGT)
141+
DateTimePGPSymmetricKeyField.register_lookup(DateTimePGPSymmetricKeyGTE)
142+
DateTimePGPSymmetricKeyField.register_lookup(DateTimePGPSymmetricKeyLT)
143+
DateTimePGPSymmetricKeyField.register_lookup(DateTimePGPSymmetricKeyLTE)

0 commit comments

Comments
 (0)