Show More
@@ -43,7 +43,7 b' from webob.exc import HTTPNotFound, HTTP' | |||
|
43 | 43 | HTTPBadRequest, HTTPError |
|
44 | 44 | |
|
45 | 45 | from rhodecode.model.db import User |
|
46 |
from rhodecode.lib.auth import AuthUser |
|
|
46 | from rhodecode.lib.auth import AuthUser | |
|
47 | 47 | from rhodecode.lib.base import _get_ip_addr, _get_access_path |
|
48 | 48 | from rhodecode.lib.utils2 import safe_unicode |
|
49 | 49 | |
@@ -148,17 +148,15 b' class JSONRPCController(WSGIController):' | |||
|
148 | 148 | if u is None: |
|
149 | 149 | return jsonrpc_error(retid=self._req_id, |
|
150 | 150 | message='Invalid API KEY') |
|
151 | ||
|
151 | 152 | #check if we are allowed to use this IP |
|
152 | allowed_ips = AuthUser.get_allowed_ips(u.user_id) | |
|
153 | if check_ip_access(source_ip=ip_addr, allowed_ips=allowed_ips) is False: | |
|
154 | log.info('Access for IP:%s forbidden, ' | |
|
155 | 'not in %s' % (ip_addr, allowed_ips)) | |
|
153 | auth_u = AuthUser(u.user_id, self._req_api_key, ip_addr=ip_addr) | |
|
154 | if not auth_u.ip_allowed: | |
|
156 | 155 | return jsonrpc_error(retid=self._req_id, |
|
157 | 156 | message='request from IP:%s not allowed' % (ip_addr)) |
|
158 | 157 | else: |
|
159 | 158 | log.info('Access for IP:%s allowed' % (ip_addr)) |
|
160 | 159 | |
|
161 | auth_u = AuthUser(u.user_id, self._req_api_key, ip_addr=ip_addr) | |
|
162 | 160 | except Exception, e: |
|
163 | 161 | return jsonrpc_error(retid=self._req_id, |
|
164 | 162 | message='Invalid API KEY') |
@@ -54,10 +54,9 b' class LoginController(BaseController):' | |||
|
54 | 54 | def index(self): |
|
55 | 55 | # redirect if already logged in |
|
56 | 56 | c.came_from = request.GET.get('came_from') |
|
57 | ||
|
58 |
i |
|
|
59 | and self.rhodecode_user.username != 'default': | |
|
60 | ||
|
57 | not_default = self.rhodecode_user.username != 'default' | |
|
58 | ip_allowed = self.rhodecode_user.ip_allowed | |
|
59 | if self.rhodecode_user.is_authenticated and not_default and ip_allowed: | |
|
61 | 60 | return redirect(url('home')) |
|
62 | 61 | |
|
63 | 62 | if request.POST: |
@@ -46,6 +46,7 b' from rhodecode.lib.auth_ldap import Auth' | |||
|
46 | 46 | from rhodecode.model import meta |
|
47 | 47 | from rhodecode.model.user import UserModel |
|
48 | 48 | from rhodecode.model.db import Permission, RhodeCodeSetting, User, UserIpMap |
|
49 | from rhodecode.lib.caching_query import FromCache | |
|
49 | 50 | |
|
50 | 51 | log = logging.getLogger(__name__) |
|
51 | 52 | |
@@ -327,7 +328,6 b' class AuthUser(object):' | |||
|
327 | 328 | self.admin = False |
|
328 | 329 | self.inherit_default_permissions = False |
|
329 | 330 | self.permissions = {} |
|
330 | self.allowed_ips = set() | |
|
331 | 331 | self._api_key = api_key |
|
332 | 332 | self.propagate_data() |
|
333 | 333 | self._instance = None |
@@ -377,13 +377,29 b' class AuthUser(object):' | |||
|
377 | 377 | |
|
378 | 378 | log.debug('Auth User is now %s' % self) |
|
379 | 379 | user_model.fill_perms(self) |
|
380 | log.debug('Filling Allowed IPs') | |
|
381 | self.allowed_ips = AuthUser.get_allowed_ips(self.user_id) | |
|
382 | 380 | |
|
383 | 381 | @property |
|
384 | 382 | def is_admin(self): |
|
385 | 383 | return self.admin |
|
386 | 384 | |
|
385 | @property | |
|
386 | def ip_allowed(self): | |
|
387 | """ | |
|
388 | Checks if ip_addr used in constructor is allowed from defined list of | |
|
389 | allowed ip_addresses for user | |
|
390 | ||
|
391 | :returns: boolean, True if ip is in allowed ip range | |
|
392 | """ | |
|
393 | #check IP | |
|
394 | allowed_ips = AuthUser.get_allowed_ips(self.user_id, cache=True) | |
|
395 | if check_ip_access(source_ip=self.ip_addr, allowed_ips=allowed_ips): | |
|
396 | log.debug('IP:%s is in range of %s' % (self.ip_addr, allowed_ips)) | |
|
397 | return True | |
|
398 | else: | |
|
399 | log.info('Access for IP:%s forbidden, ' | |
|
400 | 'not in %s' % (self.ip_addr, allowed_ips)) | |
|
401 | return False | |
|
402 | ||
|
387 | 403 | def __repr__(self): |
|
388 | 404 | return "<AuthUser('id:%s:%s|%s')>" % (self.user_id, self.username, |
|
389 | 405 | self.is_authenticated) |
@@ -411,9 +427,12 b' class AuthUser(object):' | |||
|
411 | 427 | return AuthUser(user_id, api_key, username) |
|
412 | 428 | |
|
413 | 429 | @classmethod |
|
414 | def get_allowed_ips(cls, user_id): | |
|
430 | def get_allowed_ips(cls, user_id, cache=False): | |
|
415 | 431 | _set = set() |
|
416 |
user_ips = UserIpMap.query().filter(UserIpMap.user_id == user_id) |
|
|
432 | user_ips = UserIpMap.query().filter(UserIpMap.user_id == user_id) | |
|
433 | if cache: | |
|
434 | user_ips = user_ips.options(FromCache("sql_cache_short", | |
|
435 | "get_user_ips_%s" % user_id)) | |
|
417 | 436 | for ip in user_ips: |
|
418 | 437 | _set.add(ip.ip_addr) |
|
419 | 438 | return _set or set(['0.0.0.0/0']) |
@@ -462,6 +481,15 b' class LoginRequired(object):' | |||
|
462 | 481 | def __wrapper(self, func, *fargs, **fkwargs): |
|
463 | 482 | cls = fargs[0] |
|
464 | 483 | user = cls.rhodecode_user |
|
484 | loc = "%s:%s" % (cls.__class__.__name__, func.__name__) | |
|
485 | ||
|
486 | #check IP | |
|
487 | ip_access_ok = True | |
|
488 | if not user.ip_allowed: | |
|
489 | from rhodecode.lib import helpers as h | |
|
490 | h.flash(h.literal(_('IP %s not allowed' % (user.ip_addr))), | |
|
491 | category='warning') | |
|
492 | ip_access_ok = False | |
|
465 | 493 | |
|
466 | 494 | api_access_ok = False |
|
467 | 495 | if self.api_access: |
@@ -470,9 +498,9 b' class LoginRequired(object):' | |||
|
470 | 498 | api_access_ok = True |
|
471 | 499 | else: |
|
472 | 500 | log.debug("API KEY token not valid") |
|
473 | loc = "%s:%s" % (cls.__class__.__name__, func.__name__) | |
|
501 | ||
|
474 | 502 | log.debug('Checking if %s is authenticated @ %s' % (user.username, loc)) |
|
475 | if user.is_authenticated or api_access_ok: | |
|
503 | if (user.is_authenticated or api_access_ok) and ip_access_ok: | |
|
476 | 504 | reason = 'RegularAuth' if user.is_authenticated else 'APIAuth' |
|
477 | 505 | log.info('user %s is authenticated and granted access to %s ' |
|
478 | 506 | 'using %s' % (user.username, loc, reason) |
@@ -20,7 +20,7 b' from rhodecode import __version__, BACKE' | |||
|
20 | 20 | from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\ |
|
21 | 21 | safe_str, safe_int |
|
22 | 22 | from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\ |
|
23 |
HasPermissionAnyMiddleware, CookieStoreWrapper |
|
|
23 | HasPermissionAnyMiddleware, CookieStoreWrapper | |
|
24 | 24 | from rhodecode.lib.utils import get_repo_slug, invalidate_cache |
|
25 | 25 | from rhodecode.model import meta |
|
26 | 26 | |
@@ -146,10 +146,8 b' class BaseVCSController(object):' | |||
|
146 | 146 | :param repo_name: repository name |
|
147 | 147 | """ |
|
148 | 148 | #check IP |
|
149 | allowed_ips = AuthUser.get_allowed_ips(user.user_id) | |
|
150 | if check_ip_access(source_ip=ip_addr, allowed_ips=allowed_ips) is False: | |
|
151 | log.info('Access for IP:%s forbidden, ' | |
|
152 | 'not in %s' % (ip_addr, allowed_ips)) | |
|
149 | authuser = AuthUser(user_id=user.user_id, ip_addr=ip_addr) | |
|
150 | if not authuser.ip_allowed: | |
|
153 | 151 | return False |
|
154 | 152 | else: |
|
155 | 153 | log.info('Access for IP:%s allowed' % (ip_addr)) |
@@ -536,6 +536,7 b' class UserIpMap(Base, BaseModel):' | |||
|
536 | 536 | ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) |
|
537 | 537 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) |
|
538 | 538 | ip_addr = Column("ip_addr", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None) |
|
539 | active = Column("active", Boolean(), nullable=True, unique=None, default=True) | |
|
539 | 540 | user = relationship('User', lazy='joined') |
|
540 | 541 | |
|
541 | 542 | @classmethod |
@@ -27,7 +27,6 b' import logging' | |||
|
27 | 27 | import traceback |
|
28 | 28 | import itertools |
|
29 | 29 | import collections |
|
30 | import functools | |
|
31 | 30 | from pylons import url |
|
32 | 31 | from pylons.i18n.translation import _ |
|
33 | 32 |
@@ -2002,7 +2002,6 b' a.metatag[tag="license"]:hover {' | |||
|
2002 | 2002 | } |
|
2003 | 2003 | |
|
2004 | 2004 | #login div.title { |
|
2005 | width: 420px; | |
|
2006 | 2005 | clear: both; |
|
2007 | 2006 | overflow: hidden; |
|
2008 | 2007 | position: relative; |
@@ -2021,7 +2020,6 b' a.metatag[tag="license"]:hover {' | |||
|
2021 | 2020 | } |
|
2022 | 2021 | |
|
2023 | 2022 | #login div.inner { |
|
2024 | width: 380px; | |
|
2025 | 2023 | background: #FFF url("../images/login.png") no-repeat top left; |
|
2026 | 2024 | border-top: none; |
|
2027 | 2025 | border-bottom: none; |
@@ -2038,7 +2036,6 b' a.metatag[tag="license"]:hover {' | |||
|
2038 | 2036 | } |
|
2039 | 2037 | |
|
2040 | 2038 | #login div.form div.fields div.field div.input input { |
|
2041 | width: 176px; | |
|
2042 | 2039 | background: #FFF; |
|
2043 | 2040 | border-top: 1px solid #b3b3b3; |
|
2044 | 2041 | border-left: 1px solid #b3b3b3; |
General Comments 0
You need to be logged in to leave comments.
Login now