diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index e4b0dca..db1602e 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -74,6 +74,10 @@ In chronological order: * Lucas Cimon @Lucas-C * Added the possibility to define CORS origins through ISSO_CORS_ORIGIN environment variable * Fix a bug with in + * Fixing likes counter of replies not being displayed + * Adding contrib/dump_comments.py + * Adding a [server] proxy-fix-enable-x-prefix configuration option + * Using .access_route instead of .remote_addr to take into account HTTP_X_FORWARDED_FOR header * Yuchen Pei @ycpei * Fix link in moderation emails when isso is installed in a sub URL diff --git a/docs/docs/configuration/server.rst b/docs/docs/configuration/server.rst index 5013013..46c2ede 100644 --- a/docs/docs/configuration/server.rst +++ b/docs/docs/configuration/server.rst @@ -190,6 +190,13 @@ profile show 10 most time consuming function in Isso after each request. Do not use in production. +trusted-proxies + an optional list of reverse proxies IPs behind which you have deployed + your Isso web service (e.g. `127.0.0.1`). + This allow for proper remote address resolution based on a + `X-Forwarded-For` HTTP header, which is important for the mechanism + forbiding several comment votes coming from the same subnet. + .. _configure-smtp: SMTP diff --git a/isso/views/comments.py b/isso/views/comments.py index 5ac0fd4..5610a37 100644 --- a/isso/views/comments.py +++ b/isso/views/comments.py @@ -140,6 +140,7 @@ class API(object): self.moderated = isso.conf.getboolean("moderation", "enabled") # this is similar to the wordpress setting "Comment author must have a previously approved comment" self.approve_if_email_previously_approved = isso.conf.getboolean("moderation", "approve-if-email-previously-approved") + self.trusted_proxies = list(isso.conf.getiter("server", "trusted-proxies")) self.guard = isso.db.guard self.threads = isso.db.threads @@ -275,7 +276,7 @@ class API(object): data["website"] = normalize(data["website"]) data['mode'] = 2 if self.moderated else 1 - data['remote_addr'] = utils.anonymize(str(request.remote_addr)) + data['remote_addr'] = self._remote_addr(request) with self.isso.lock: if uri not in self.threads: @@ -336,6 +337,21 @@ class API(object): resp.headers.add("X-Set-Cookie", cookie("isso-%i" % rv["id"])) return resp + def _remote_addr(self, request): + """Return the anonymized IP address of the requester. + + Takes into consideration a potential X-Forwarded-For HTTP header + if a necessary server.trusted-proxies configuration entry is set. + + Recipe source: https://stackoverflow.com/a/22936947/636849 + """ + remote_addr = request.remote_addr + if self.trusted_proxies: + route = request.access_route + [remote_addr] + remote_addr = next((addr for addr in reversed(route) + if addr not in self.trusted_proxies), remote_addr) + return utils.anonymize(str(remote_addr)) + """ @api {get} /id/:id view @apiGroup Comment @@ -890,8 +906,7 @@ class API(object): @xhr def like(self, environ, request, id): - nv = self.comments.vote( - True, id, utils.anonymize(str(request.remote_addr))) + nv = self.comments.vote(True, id, self._remote_addr(request)) return JSON(nv, 200) """ @@ -917,8 +932,7 @@ class API(object): @xhr def dislike(self, environ, request, id): - nv = self.comments.vote( - False, id, utils.anonymize(str(request.remote_addr))) + nv = self.comments.vote(False, id, self._remote_addr(request)) return JSON(nv, 200) # TODO: remove someday (replaced by :func:`counts`) diff --git a/share/isso.conf b/share/isso.conf index ed706c8..3f66982 100644 --- a/share/isso.conf +++ b/share/isso.conf @@ -112,6 +112,13 @@ reload = off # in production. profile = off +# an optional list of reverse proxies IPs behind which you have deployed +# your Isso web service (e.g. `127.0.0.1`). +# This allow for proper remote address resolution based on a +# `X-Forwarded-For` HTTP header, which is important for the mechanism +# forbiding several comment votes coming from the same subnet. +trusted-proxies = + [smtp] # Isso can notify you on new comments via SMTP. In the email notification, you