aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Kuzminski <marcin@python-works.com>2013-01-23 23:51:57 +0100
committerMarcin Kuzminski <marcin@python-works.com>2013-01-23 23:51:57 +0100
commit92748a388db07e240dbb8b1dc252f4da42ab598e (patch)
tree47e6ddbb82c91dec58f6b624179a66eff0c98cbd
parent957e944fc632b724d34f10ebd9a15a7cc5471b7b (diff)
IP restrictions now also enabled for IPv6
--HG-- extra : source : 6c28533d122c4ca94538f16c8852a83bc3d38952
-rw-r--r--rhodecode/lib/auth.py21
-rwxr-xr-xrhodecode/model/db.py2
-rw-r--r--rhodecode/model/validators.py41
3 files changed, 37 insertions, 27 deletions
diff --git a/rhodecode/lib/auth.py b/rhodecode/lib/auth.py
index 151a720e..6e4c1ba9 100644
--- a/rhodecode/lib/auth.py
+++ b/rhodecode/lib/auth.py
@@ -34,6 +34,7 @@ from decorator import decorator
from pylons import config, url, request
from pylons.controllers.util import abort, redirect
from pylons.i18n.translation import _
+from sqlalchemy.orm.exc import ObjectDeletedError
from rhodecode import __platform__, is_windows, is_unix
from rhodecode.model.meta import Session
@@ -447,8 +448,13 @@ class AuthUser(object):
user_ips = user_ips.options(FromCache("sql_cache_short",
"get_user_ips_%s" % user_id))
for ip in user_ips:
- _set.add(ip.ip_addr)
- return _set or set(['0.0.0.0/0'])
+ try:
+ _set.add(ip.ip_addr)
+ except ObjectDeletedError:
+ # since we use heavy caching sometimes it happens that we get
+ # deleted objects here, we just skip them
+ pass
+ return _set or set(['0.0.0.0/0', '::/0'])
def set_available_permissions(config):
@@ -990,6 +996,13 @@ def check_ip_access(source_ip, allowed_ips=None):
log.debug('checking if ip:%s is subnet of %s' % (source_ip, allowed_ips))
if isinstance(allowed_ips, (tuple, list, set)):
for ip in allowed_ips:
- if ipaddr.IPAddress(source_ip) in ipaddr.IPNetwork(ip):
- return True
+ try:
+ if ipaddr.IPAddress(source_ip) in ipaddr.IPNetwork(ip):
+ return True
+ # for any case we cannot determine the IP, don't crash just
+ # skip it and log as error, we want to say forbidden still when
+ # sending bad IP
+ except Exception:
+ log.error(traceback.format_exc())
+ continue
return False
diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py
index 7a188f8f..4e00f835 100755
--- a/rhodecode/model/db.py
+++ b/rhodecode/model/db.py
@@ -562,7 +562,7 @@ class UserIpMap(Base, BaseModel):
@classmethod
def _get_ip_range(cls, ip_addr):
from rhodecode.lib import ipaddr
- net = ipaddr.IPv4Network(ip_addr)
+ net = ipaddr.IPNetwork(address=ip_addr)
return [str(net.network), str(net.broadcast)]
def __json__(self):
diff --git a/rhodecode/model/validators.py b/rhodecode/model/validators.py
index 61ed0583..b1b7cafb 100644
--- a/rhodecode/model/validators.py
+++ b/rhodecode/model/validators.py
@@ -14,6 +14,7 @@ from formencode.validators import (
NotEmpty, IPAddress, CIDR
)
from rhodecode.lib.compat import OrderedSet
+from rhodecode.lib import ipaddr
from rhodecode.lib.utils import repo_name_slug
from rhodecode.model.db import RepoGroup, Repository, UsersGroup, User,\
ChangesetStatus
@@ -711,35 +712,31 @@ def NotReviewedRevisions(repo_id):
def ValidIp():
class _validator(CIDR):
messages = dict(
- badFormat=_('Please enter a valid IP address (a.b.c.d)'),
- illegalOctets=_('The octets must be within the range of 0-255'
- ' (not %(octet)r)'),
+ badFormat=_('Please enter a valid IPv4 or IpV6 address'),
illegalBits=_('The network size (bits) must be within the range'
' of 0-32 (not %(bits)r)'))
+ def to_python(self, value, state):
+ v = super(_validator, self).to_python(value, state)
+ v = v.strip()
+ net = ipaddr.IPNetwork(address=v)
+ if isinstance(net, ipaddr.IPv4Network):
+ #if IPv4 doesn't end with a mask, add /32
+ if '/' not in value:
+ v += '/32'
+ if isinstance(net, ipaddr.IPv6Network):
+ #if IPv6 doesn't end with a mask, add /128
+ if '/' not in value:
+ v += '/128'
+ return v
+
def validate_python(self, value, state):
try:
- # Split into octets and bits
- if '/' in value: # a.b.c.d/e
- addr, bits = value.split('/')
- else: # a.b.c.d
- addr, bits = value, 32
- # Use IPAddress validator to validate the IP part
- IPAddress.validate_python(self, addr, state)
- # Bits (netmask) correct?
- if not 0 <= int(bits) <= 32:
- raise formencode.Invalid(
- self.message('illegalBits', state, bits=bits),
- value, state)
- # Splitting faild: wrong syntax
+ addr = value.strip()
+ #this raises an ValueError if address is not IpV4 or IpV6
+ ipaddr.IPNetwork(address=addr)
except ValueError:
raise formencode.Invalid(self.message('badFormat', state),
value, state)
- def to_python(self, value, state):
- v = super(_validator, self).to_python(value, state)
- #if IP doesn't end with a mask, add /32
- if '/' not in value:
- v += '/32'
- return v
return _validator