##// END OF EJS Templates
Pull request !2622 Created on Thu, 24 Oct 2024 19:40:11, by
  • travis changes
  • manifest: include version file
  • testing: stubs for travis and tox configs
  • tasks: when CELERY_EAGER_PROPAGATES_EXCEPTIONS is true do not retry tasks
  • requirements: bump ziggurat_foundations to 0.8.3
1 version available for this pull request, show versions.
v1
ver Time Author Commit Description
latest r140:38e51247f8ce
travis changes
latest r139:f1c3213bc48c
manifest: include version file
latest r137:7b4089435f79
testing: stubs for travis and tox configs
latest r136:605a8dbaa29c
tasks: when CELERY_EAGER_PROPAGATES_EXCEPTIONS is true do not retry tasks
latest r135:81277de43ee2
requirements: bump ziggurat_foundations to 0.8.3
@@ -0,0 +1,43 b''
1 language: python
2
3 dist: xenial
4
5 notifications:
6 on_success: change
7 on_failure: always
8
9 matrix:
10 include:
11 - python: 3.5
12 env: TOXENV=py35
13 - python: 3.6
14 env: TOXENV=py36
15 addons:
16 postgresql: "9.6"
17 - python: 3.6
18 env: TOXENV=py36 PGPORT=5432
19 addons:
20 postgresql: "10"
21 apt:
22 packages:
23 - postgresql-10
24 - postgresql-client-10
25
26 install:
27 - travis_retry pip install -U setuptools pip tox
28
29 script:
30 - travis_retry tox
31
32 services:
33 - postgresql
34 - elasticsearch
35 - redis
36
37 before_script:
38 - psql -c "create user test with encrypted password 'test';" -U postgres
39 - psql -c 'create database appenlight_test owner test;' -U postgres
40
41 after_success:
42 - pip install coveralls
43 - coveralls
@@ -0,0 +1,16 b''
1 .. :changelog:
2
3 History
4 -------
5
6 0.9.1 (2016-XX-XX)
7 ++++++++++++++++++
8
9 * Added suppot for "NOT' operator in rule engine
10 * Various bugfixes
11
12
13 0.9.0 (2016-06-29)
14 ++++++++++++++++++
15
16 * first tagged public release
@@ -0,0 +1,15 b''
1 [tox]
2 envlist = py35,py36
3 setupdir = backend
4
5 [testenv]
6 extras = dev
7 passenv = DB
8 DB_STRING
9
10 commands=
11 pip install -U pip setuptools wheel
12 pip install -r backend/requirements.txt
13 pip install -e backend
14 appenlight-reindex-elasticsearch -c testing.ini -t all
15 pytest backend/src/appenlight/tests
@@ -1,7 +1,7 b''
1 [bumpversion]
1 [bumpversion]
2 current_version = 1.1.0
2 current_version = 1.1.1
3 message = release: Bump version {current_version} to {new_version}
3 message = release: Bump version {current_version} to {new_version}
4 tag_name = {new_version}
4 tag_name = {new_version}
5
5
6 [bumpversion:file:backend/src/appenlight/VERSION]
6 [bumpversion:file:backend/VERSION]
7
7
@@ -126,8 +126,8 b' dist/'
126 downloads/
126 downloads/
127 eggs/
127 eggs/
128 .eggs/
128 .eggs/
129 lib/
129 /lib/
130 lib64/
130 /lib64/
131 parts/
131 parts/
132 sdist/
132 sdist/
133 var/
133 var/
@@ -1,2 +1,2 b''
1 include *.txt *.ini *.cfg *.rst *.md
1 include *.txt *.ini *.cfg *.rst *.md VERSION
2 recursive-include appenlight *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 *.rst *.otf *.ttf *.svg *.woff *.eot
2 recursive-include appenlight *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 *.rst *.otf *.ttf *.svg *.woff *.eot
1 NO CONTENT: file renamed from backend/src/appenlight/VERSION to backend/VERSION
NO CONTENT: file renamed from backend/src/appenlight/VERSION to backend/VERSION
@@ -17,7 +17,7 b' wtforms==2.1'
17 celery==3.1.23
17 celery==3.1.23
18 formencode==1.3.0
18 formencode==1.3.0
19 psutil==2.1.2
19 psutil==2.1.2
20 ziggurat_foundations==0.6.8
20 ziggurat_foundations==0.8.3
note
author

zigg

21 bcrypt==3.1.6
21 bcrypt==3.1.6
22 appenlight_client
22 appenlight_client
23 markdown==2.5
23 markdown==2.5
@@ -1,11 +1,10 b''
1 import os
1 import os
2 import sys
3 import re
2 import re
4
3
5 from setuptools import setup, find_packages
4 from setuptools import setup, find_packages
6
5
7 here = os.path.abspath(os.path.dirname(__file__))
6 here = os.path.abspath(os.path.dirname(__file__))
8 README = open(os.path.join(here, '..', 'README.md')).read()
7 README = open(os.path.join(here, 'README.rst')).read()
9 CHANGES = open(os.path.join(here, 'CHANGELOG.rst')).read()
8 CHANGES = open(os.path.join(here, 'CHANGELOG.rst')).read()
10
9
11 REQUIREMENTS = open(os.path.join(here, 'requirements.txt')).readlines()
10 REQUIREMENTS = open(os.path.join(here, 'requirements.txt')).readlines()
@@ -29,10 +28,11 b' def _get_meta_var(name, data, callback_handler=None):'
29
28
30 return callback_handler(eval(matches.groups()[0]))
29 return callback_handler(eval(matches.groups()[0]))
31
30
31
32 with open(os.path.join(here, 'src', 'appenlight', '__init__.py'), 'r') as _meta:
32 with open(os.path.join(here, 'src', 'appenlight', '__init__.py'), 'r') as _meta:
33 _metadata = _meta.read()
33 _metadata = _meta.read()
34
34
35 with open(os.path.join('src', 'appenlight', 'VERSION')) as _meta_version:
35 with open(os.path.join(here, 'VERSION'), 'r') as _meta_version:
36 __version__ = _meta_version.read().strip()
36 __version__ = _meta_version.read().strip()
37
37
38 __license__ = _get_meta_var('__license__', _metadata)
38 __license__ = _get_meta_var('__license__', _metadata)
@@ -25,6 +25,8 b' import pyelasticsearch'
25 from celery.utils.log import get_task_logger
25 from celery.utils.log import get_task_logger
26 from zope.sqlalchemy import mark_changed
26 from zope.sqlalchemy import mark_changed
27 from pyramid.threadlocal import get_current_request, get_current_registry
27 from pyramid.threadlocal import get_current_request, get_current_registry
28 from ziggurat_foundations.models.services.resource import ResourceService
29
28 from appenlight.celery import celery
30 from appenlight.celery import celery
29 from appenlight.models.report_group import ReportGroup
31 from appenlight.models.report_group import ReportGroup
30 from appenlight.models import DBSession, Datastores
32 from appenlight.models import DBSession, Datastores
@@ -82,6 +84,8 b' def test_retry_exception_task():'
82 log.warning('test retry celery log', extra={'location': 'celery'})
84 log.warning('test retry celery log', extra={'location': 'celery'})
83 raise Exception('Celery exception test')
85 raise Exception('Celery exception test')
84 except Exception as exc:
86 except Exception as exc:
87 if celery.conf["CELERY_EAGER_PROPAGATES_EXCEPTIONS"]:
88 raise
85 test_retry_exception_task.retry(exc=exc)
89 test_retry_exception_task.retry(exc=exc)
86
90
87
91
@@ -214,6 +218,8 b' def add_reports(resource_id, request_params, dataset, **kwargs):'
214 return True
218 return True
215 except Exception as exc:
219 except Exception as exc:
216 print_traceback(log)
220 print_traceback(log)
221 if celery.conf["CELERY_EAGER_PROPAGATES_EXCEPTIONS"]:
222 raise
217 add_reports.retry(exc=exc)
223 add_reports.retry(exc=exc)
218
224
219
225
@@ -335,6 +341,8 b' def add_logs(resource_id, request_params, dataset, **kwargs):'
335 return True
341 return True
336 except Exception as exc:
342 except Exception as exc:
337 print_traceback(log)
343 print_traceback(log)
344 if celery.conf["CELERY_EAGER_PROPAGATES_EXCEPTIONS"]:
345 raise
338 add_logs.retry(exc=exc)
346 add_logs.retry(exc=exc)
339
347
340
348
@@ -397,6 +405,8 b' def add_metrics(resource_id, request_params, dataset, proto_version):'
397 return True
405 return True
398 except Exception as exc:
406 except Exception as exc:
399 print_traceback(log)
407 print_traceback(log)
408 if celery.conf["CELERY_EAGER_PROPAGATES_EXCEPTIONS"]:
409 raise
400 add_metrics.retry(exc=exc)
410 add_metrics.retry(exc=exc)
401
411
402
412
@@ -442,7 +452,7 b' def check_user_report_notifications(resource_id):'
442 ApplicationService.check_for_groups_alert(
452 ApplicationService.check_for_groups_alert(
443 application, 'alert', report_groups=report_groups,
453 application, 'alert', report_groups=report_groups,
444 occurence_dict=occurence_dict)
454 occurence_dict=occurence_dict)
445 users = set([p.user for p in application.users_for_perm('view')])
455 users = set([p.user for p in ResourceService.users_for_perm(application, 'view')])
446 report_groups = report_groups.all()
456 report_groups = report_groups.all()
447 for user in users:
457 for user in users:
448 UserService.report_notify(user, request, application,
458 UserService.report_notify(user, request, application,
@@ -536,6 +546,8 b' def update_tag_counter(tag_name, tag_value, count):'
536 return True
546 return True
537 except Exception as exc:
547 except Exception as exc:
538 print_traceback(log)
548 print_traceback(log)
549 if celery.conf["CELERY_EAGER_PROPAGATES_EXCEPTIONS"]:
550 raise
539 update_tag_counter.retry(exc=exc)
551 update_tag_counter.retry(exc=exc)
540
552
541
553
@@ -576,7 +588,7 b' def daily_digest():'
576
588
577 application = ApplicationService.by_id(resource_id)
589 application = ApplicationService.by_id(resource_id)
578 if application:
590 if application:
579 users = set([p.user for p in application.users_for_perm('view')])
591 users = set([p.user for p in ResourceService.users_for_perm(application, 'view')])
580 for user in users:
592 for user in users:
581 user.send_digest(request, application, reports=reports,
593 user.send_digest(request, application, reports=reports,
582 since_when=since_when)
594 since_when=since_when)
@@ -21,8 +21,8 b' import pyramid.threadlocal'
21 import datetime
21 import datetime
22 import appenlight.lib.helpers as h
22 import appenlight.lib.helpers as h
23
23
24 from appenlight.models.user import User
24 from ziggurat_foundations.models.services.user import UserService
25 from appenlight.models.group import Group
25 from ziggurat_foundations.models.services.group import GroupService
26 from appenlight.models import DBSession
26 from appenlight.models import DBSession
27 from appenlight.models.alert_channel import AlertChannel
27 from appenlight.models.alert_channel import AlertChannel
28 from appenlight.models.integrations import IntegrationException
28 from appenlight.models.integrations import IntegrationException
@@ -153,7 +153,7 b' def clean_whitespace(value):'
153
153
154
154
155 def found_username_validator(form, field):
155 def found_username_validator(form, field):
156 user = User.by_user_name(field.data)
156 user = UserService.by_user_name(field.data)
157 # sets user to recover in email validator
157 # sets user to recover in email validator
158 form.field_user = user
158 form.field_user = user
159 if not user:
159 if not user:
@@ -161,19 +161,19 b' def found_username_validator(form, field):'
161
161
162
162
163 def found_username_email_validator(form, field):
163 def found_username_email_validator(form, field):
164 user = User.by_email(field.data)
164 user = UserService.by_email(field.data)
165 if not user:
165 if not user:
166 raise wtforms.ValidationError('Email is incorrect')
166 raise wtforms.ValidationError('Email is incorrect')
167
167
168
168
169 def unique_username_validator(form, field):
169 def unique_username_validator(form, field):
170 user = User.by_user_name(field.data)
170 user = UserService.by_user_name(field.data)
171 if user:
171 if user:
172 raise wtforms.ValidationError('This username already exists in system')
172 raise wtforms.ValidationError('This username already exists in system')
173
173
174
174
175 def unique_groupname_validator(form, field):
175 def unique_groupname_validator(form, field):
176 group = Group.by_group_name(field.data)
176 group = GroupService.by_group_name(field.data)
177 mod_group = getattr(form, '_modified_group', None)
177 mod_group = getattr(form, '_modified_group', None)
178 if group and (not mod_group or mod_group.id != group.id):
178 if group and (not mod_group or mod_group.id != group.id):
179 raise wtforms.ValidationError(
179 raise wtforms.ValidationError(
@@ -181,7 +181,7 b' def unique_groupname_validator(form, field):'
181
181
182
182
183 def unique_email_validator(form, field):
183 def unique_email_validator(form, field):
184 user = User.by_email(field.data)
184 user = UserService.by_email(field.data)
185 if user:
185 if user:
186 raise wtforms.ValidationError('This email already exists in system')
186 raise wtforms.ValidationError('This email already exists in system')
187
187
@@ -219,7 +219,7 b' def blocked_email_validator(form, field):'
219
219
220
220
221 def old_password_validator(form, field):
221 def old_password_validator(form, field):
222 if not field.user.check_password(field.data or ''):
222 if not UserService.check_password(field.user, field.data or ''):
223 raise wtforms.ValidationError('You need to enter correct password')
223 raise wtforms.ValidationError('You need to enter correct password')
224
224
225
225
@@ -22,7 +22,7 b' import appenlight.lib.helpers as helpers'
22
22
23 from authomatic.providers import oauth2, oauth1
23 from authomatic.providers import oauth2, oauth1
24 from authomatic import Authomatic
24 from authomatic import Authomatic
25 from appenlight.models.user import User
25 from ziggurat_foundations.models.services.user import UserService
26
26
27
27
28 class CSRFException(Exception):
28 class CSRFException(Exception):
@@ -66,7 +66,7 b' def get_user(request):'
66 return None
66 return None
67
67
68 if user_id:
68 if user_id:
69 user = User.by_id(user_id)
69 user = UserService.by_id(user_id)
70 if user:
70 if user:
71 request.environ['appenlight.username'] = '%d:%s' % (
71 request.environ['appenlight.username'] = '%d:%s' % (
72 user_id, user.user_name)
72 user_id, user.user_name)
@@ -33,6 +33,7 b' from appenlight.validators import (LogSearchSchema,'
33 accepted_search_params)
33 accepted_search_params)
34 from itsdangerous import TimestampSigner
34 from itsdangerous import TimestampSigner
35 from ziggurat_foundations.permissions import ALL_PERMISSIONS
35 from ziggurat_foundations.permissions import ALL_PERMISSIONS
36 from ziggurat_foundations.models.services.user import UserService
36 from dateutil.relativedelta import relativedelta
37 from dateutil.relativedelta import relativedelta
37 from dateutil.rrule import rrule, MONTHLY, DAILY
38 from dateutil.rrule import rrule, MONTHLY, DAILY
38
39
@@ -251,8 +252,8 b' def build_filter_settings_from_query_dict('
251 resource_permissions = ['view']
252 resource_permissions = ['view']
252
253
253 if request.user:
254 if request.user:
254 applications = request.user.resources_with_perms(
255 applications = UserService.resources_with_perms(
255 resource_permissions, resource_types=['application'])
256 request.user, resource_permissions, resource_types=['application'])
256
257
257 # CRITICAL - this ensures our resultset is limited to only the ones
258 # CRITICAL - this ensures our resultset is limited to only the ones
258 # user has view permissions
259 # user has view permissions
@@ -16,7 +16,7 b''
16
16
17 import sqlalchemy as sa
17 import sqlalchemy as sa
18
18
19 from appenlight.models.resource import Resource
19 from ziggurat_foundations.models.services.resource import ResourceService
todo
author

huhu

20 from appenlight.models import Base, get_db_session
20 from appenlight.models import Base, get_db_session
21 from sqlalchemy.orm import validates
21 from sqlalchemy.orm import validates
22 from ziggurat_foundations.models.base import BaseModel
22 from ziggurat_foundations.models.base import BaseModel
@@ -53,8 +53,8 b' class AlertChannelAction(Base, BaseModel):'
53 def resource_name(self, db_session=None):
53 def resource_name(self, db_session=None):
54 db_session = get_db_session(db_session)
54 db_session = get_db_session(db_session)
55 if self.resource_id:
55 if self.resource_id:
56 return Resource.by_resource_id(self.resource_id,
56 return ResourceService.by_resource_id(
57 db_session=db_session).resource_name
57 self.resource_id, db_session=db_session).resource_name
58 else:
58 else:
59 return 'any resource'
59 return 'any resource'
60
60
@@ -20,11 +20,11 b' import logging'
20 from datetime import datetime
20 from datetime import datetime
21 from appenlight.models import Base, get_db_session
21 from appenlight.models import Base, get_db_session
22 from appenlight.models.services.report_stat import ReportStatService
22 from appenlight.models.services.report_stat import ReportStatService
23 from appenlight.models.resource import Resource
24 from appenlight.models.integrations import IntegrationException
23 from appenlight.models.integrations import IntegrationException
25 from pyramid.threadlocal import get_current_request
24 from pyramid.threadlocal import get_current_request
26 from sqlalchemy.dialects.postgresql import JSON
25 from sqlalchemy.dialects.postgresql import JSON
27 from ziggurat_foundations.models.base import BaseModel
26 from ziggurat_foundations.models.base import BaseModel
27 from ziggurat_foundations.models.services.resource import ResourceService
28
28
29 log = logging.getLogger(__name__)
29 log = logging.getLogger(__name__)
30
30
@@ -84,12 +84,12 b' class Event(Base, BaseModel):'
84 db_session = get_db_session(db_session)
84 db_session = get_db_session(db_session)
85 db_session.flush()
85 db_session.flush()
86 if not resource:
86 if not resource:
87 resource = Resource.by_resource_id(self.resource_id)
87 resource = ResourceService.by_resource_id(self.resource_id)
88 if not request:
88 if not request:
89 request = get_current_request()
89 request = get_current_request()
90 if not resource:
90 if not resource:
91 return
91 return
92 users = set([p.user for p in resource.users_for_perm('view')])
92 users = set([p.user for p in ResourceService.users_for_perm(resource, 'view')])
93 for user in users:
93 for user in users:
94 for channel in user.alert_channels:
94 for channel in user.alert_channels:
95 matches_resource = not channel.resources or resource in [r.resource_id for r in channel.resources]
95 matches_resource = not channel.resources or resource in [r.resource_id for r in channel.resources]
@@ -113,7 +113,7 b' class Event(Base, BaseModel):'
113 Generates close alert event if alerts get closed """
113 Generates close alert event if alerts get closed """
114 event_types = [Event.types['error_report_alert'],
114 event_types = [Event.types['error_report_alert'],
115 Event.types['slow_report_alert']]
115 Event.types['slow_report_alert']]
116 app = Resource.by_resource_id(self.resource_id)
116 app = ResourceService.by_resource_id(self.resource_id)
117 # if app was deleted close instantly
117 # if app was deleted close instantly
118 if not app:
118 if not app:
119 self.close()
119 self.close()
@@ -19,6 +19,7 b' from appenlight.models import Base'
19 from appenlight.lib.utils import permission_tuple_to_dict
19 from appenlight.lib.utils import permission_tuple_to_dict
20 from pyramid.security import Allow, ALL_PERMISSIONS
20 from pyramid.security import Allow, ALL_PERMISSIONS
21 from ziggurat_foundations.models.resource import ResourceMixin
21 from ziggurat_foundations.models.resource import ResourceMixin
22 from ziggurat_foundations.models.services.resource import ResourceService
22
23
23
24
24 class Resource(ResourceMixin, Base):
25 class Resource(ResourceMixin, Base):
@@ -67,8 +68,8 b' class Resource(ResourceMixin, Base):'
67 @property
68 @property
68 def user_permissions_list(self):
69 def user_permissions_list(self):
69 return [permission_tuple_to_dict(perm) for perm in
70 return [permission_tuple_to_dict(perm) for perm in
70 self.users_for_perm('__any_permission__',
71 ResourceService.users_for_perm(
71 limit_group_permissions=True)]
72 self, '__any_permission__', limit_group_permissions=True)]
72
73
73 @property
74 @property
74 def __acl__(self):
75 def __acl__(self):
@@ -17,6 +17,8 b''
17 import sqlalchemy as sa
17 import sqlalchemy as sa
18 from pyramid.threadlocal import get_current_registry
18 from pyramid.threadlocal import get_current_registry
19 from paginate_sqlalchemy import SqlalchemyOrmPage
19 from paginate_sqlalchemy import SqlalchemyOrmPage
20 from ziggurat_foundations.models.services.user import UserService
21
20 from appenlight.models import get_db_session
22 from appenlight.models import get_db_session
21 from appenlight.models.event import Event
23 from appenlight.models.event import Event
22 from appenlight.models.services.base import BaseService
24 from appenlight.models.services.base import BaseService
@@ -82,8 +84,7 b' class EventService(BaseService):'
82 @classmethod
84 @classmethod
83 def latest_for_user(cls, user, db_session=None):
85 def latest_for_user(cls, user, db_session=None):
84 registry = get_current_registry()
86 registry = get_current_registry()
85 resources = user.resources_with_perms(
87 resources = UserService.resources_with_perms(user, ['view'], resource_types=registry.resource_types)
86 ['view'], resource_types=registry.resource_types)
87 resource_ids = [r.resource_id for r in resources]
88 resource_ids = [r.resource_id for r in resources]
88 db_session = get_db_session(db_session)
89 db_session = get_db_session(db_session)
89 return EventService.for_resource(
90 return EventService.for_resource(
@@ -96,8 +97,7 b' class EventService(BaseService):'
96 if not filter_settings:
97 if not filter_settings:
97 filter_settings = {}
98 filter_settings = {}
98 registry = get_current_registry()
99 registry = get_current_registry()
99 resources = user.resources_with_perms(
100 resources = UserService.resources_with_perms(user, ['view'], resource_types=registry.resource_types)
100 ['view'], resource_types=registry.resource_types)
101 resource_ids = [r.resource_id for r in resources]
101 resource_ids = [r.resource_id for r in resources]
102 query = EventService.for_resource(
102 query = EventService.for_resource(
103 resource_ids, or_target_user_id=user.id, limit=100,
103 resource_ids, or_target_user_id=user.id, limit=100,
@@ -16,10 +16,10 b''
16
16
17 from appenlight.models import get_db_session
17 from appenlight.models import get_db_session
18 from appenlight.models.group import Group
18 from appenlight.models.group import Group
19 from appenlight.models.services.base import BaseService
19 from ziggurat_foundations.models.services.group import GroupService
20
20
21
21
22 class GroupService(BaseService):
22 class GroupService(GroupService):
23 @classmethod
23 @classmethod
24 def by_id(cls, group_id, db_session=None):
24 def by_id(cls, group_id, db_session=None):
25 db_session = get_db_session(db_session)
25 db_session = get_db_session(db_session)
@@ -16,10 +16,10 b''
16
16
17 from appenlight.models.group_resource_permission import GroupResourcePermission
17 from appenlight.models.group_resource_permission import GroupResourcePermission
18 from appenlight.models import get_db_session
18 from appenlight.models import get_db_session
19 from appenlight.models.services.base import BaseService
19 from ziggurat_foundations.models.services.group_resource_permission import GroupResourcePermissionService
20
20
21
21
22 class GroupResourcePermissionService(BaseService):
22 class GroupResourcePermissionService(GroupResourcePermissionService):
23 @classmethod
23 @classmethod
24 def by_resource_group_and_perm(cls, group_id, perm_name, resource_id,
24 def by_resource_group_and_perm(cls, group_id, perm_name, resource_id,
25 db_session=None):
25 db_session=None):
@@ -22,12 +22,13 b' import sqlalchemy as sa'
22 from collections import namedtuple
22 from collections import namedtuple
23 from datetime import datetime
23 from datetime import datetime
24
24
25 from ziggurat_foundations.models.services.user import UserService
26
25 from appenlight.lib.rule import Rule
27 from appenlight.lib.rule import Rule
26 from appenlight.models import get_db_session
28 from appenlight.models import get_db_session
27 from appenlight.models.integrations import IntegrationException
29 from appenlight.models.integrations import IntegrationException
28 from appenlight.models.report import REPORT_TYPE_MATRIX
30 from appenlight.models.report import REPORT_TYPE_MATRIX
29 from appenlight.models.user import User
31 from appenlight.models.user import User
30 from appenlight.models.services.base import BaseService
31 from paginate_sqlalchemy import SqlalchemyOrmPage
32 from paginate_sqlalchemy import SqlalchemyOrmPage
32 from pyramid.threadlocal import get_current_registry
33 from pyramid.threadlocal import get_current_registry
33
34
@@ -36,7 +37,7 b' log = logging.getLogger(__name__)'
36 GroupOccurence = namedtuple('GroupOccurence', ['occurences', 'group'])
37 GroupOccurence = namedtuple('GroupOccurence', ['occurences', 'group'])
37
38
38
39
39 class UserService(BaseService):
40 class UserService(UserService):
40 @classmethod
41 @classmethod
41 def all(cls, db_session=None):
42 def all(cls, db_session=None):
42 return get_db_session(db_session).query(User).order_by(User.user_name)
43 return get_db_session(db_session).query(User).order_by(User.user_name)
@@ -22,6 +22,7 b' from appenlight.models.services.event import EventService'
22 from appenlight.models.integrations import IntegrationException
22 from appenlight.models.integrations import IntegrationException
23 from pyramid.threadlocal import get_current_request
23 from pyramid.threadlocal import get_current_request
24 from ziggurat_foundations.models.user import UserMixin
24 from ziggurat_foundations.models.user import UserMixin
25 from ziggurat_foundations.models.services.user import UserService
25
26
26 log = logging.getLogger(__name__)
27 log = logging.getLogger(__name__)
27
28
@@ -66,9 +67,9 b' class User(UserMixin, Base):'
66 result = super(User, self).get_dict(exclude_keys, include_keys)
67 result = super(User, self).get_dict(exclude_keys, include_keys)
67 if extended_info:
68 if extended_info:
68 result['groups'] = [g.group_name for g in self.groups]
69 result['groups'] = [g.group_name for g in self.groups]
69 result['permissions'] = [p.perm_name for p in self.permissions]
70 result['permissions'] = [p.perm_name for p in UserService.permissions(self)]
70 request = get_current_request()
71 request = get_current_request()
71 apps = self.resources_with_perms(
72 apps = UserService.resources_with_perms(self,
72 ['view'], resource_types=['application'])
73 ['view'], resource_types=['application'])
73 result['applications'] = sorted(
74 result['applications'] = sorted(
74 [{'resource_id': a.resource_id,
75 [{'resource_id': a.resource_id,
@@ -96,8 +97,7 b' class User(UserMixin, Base):'
96 def assigned_report_groups(self):
97 def assigned_report_groups(self):
97 from appenlight.models.report_group import ReportGroup
98 from appenlight.models.report_group import ReportGroup
98
99
99 resources = self.resources_with_perms(
100 resources = UserService.resources_with_perms(self, ['view'], resource_types=['application'])
100 ['view'], resource_types=['application'])
101 query = self.assigned_reports_relation
101 query = self.assigned_reports_relation
102 rid_list = [r.resource_id for r in resources]
102 rid_list = [r.resource_id for r in resources]
103 query = query.filter(ReportGroup.resource_id.in_(rid_list))
103 query = query.filter(ReportGroup.resource_id.in_(rid_list))
@@ -20,6 +20,8 b' import logging'
20
20
21 from pyramid.paster import setup_logging, bootstrap
21 from pyramid.paster import setup_logging, bootstrap
22 from pyramid.threadlocal import get_current_request
22 from pyramid.threadlocal import get_current_request
23 from ziggurat_foundations.models.services.user import UserService
24
23
25
24 from appenlight.forms import UserRegisterForm
26 from appenlight.forms import UserRegisterForm
25 from appenlight.lib.ext_json import json
27 from appenlight.lib.ext_json import json
@@ -138,8 +140,8 b' def main():'
138 if create_user:
140 if create_user:
139 group = GroupService.by_id(1)
141 group = GroupService.by_id(1)
140 user = User(user_name=user_name, email=email, status=1)
142 user = User(user_name=user_name, email=email, status=1)
141 user.regenerate_security_code()
143 UserService.regenerate_security_code(user)
142 user.set_password(user_password)
144 UserService.set_password(user, user_password)
143 DBSession.add(user)
145 DBSession.add(user)
144 token = AuthToken(description="Uptime monitoring token")
146 token = AuthToken(description="Uptime monitoring token")
145 if args.auth_token:
147 if args.auth_token:
@@ -24,6 +24,8 b' from appenlight.models.services.plugin_config import PluginConfigService'
24 from appenlight.lib import to_integer_safe
24 from appenlight.lib import to_integer_safe
25 from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest
25 from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest
26 from ziggurat_foundations.permissions import permission_to_04_acls
26 from ziggurat_foundations.permissions import permission_to_04_acls
27 from ziggurat_foundations.models.services.user import UserService
28 from ziggurat_foundations.models.services.resource import ResourceService
27 import defusedxml.ElementTree as ElementTree
29 import defusedxml.ElementTree as ElementTree
28 import urllib.request, urllib.error, urllib.parse
30 import urllib.request, urllib.error, urllib.parse
29 import logging
31 import logging
@@ -82,7 +84,7 b' def add_root_superperm(request, context):'
82 non-resource permission
84 non-resource permission
83 """
85 """
84 if hasattr(request, 'user') and request.user:
86 if hasattr(request, 'user') and request.user:
85 acls = permission_to_04_acls(request.user.permissions)
87 acls = permission_to_04_acls(UserService.permissions(request.user))
86 for perm_user, perm_name in acls:
88 for perm_user, perm_name in acls:
87 if perm_name == 'root_administration':
89 if perm_name == 'root_administration':
88 context.__acl__.append(rewrite_root_perm(perm_user, perm_name))
90 context.__acl__.append(rewrite_root_perm(perm_user, perm_name))
@@ -98,7 +100,7 b' class RootFactory(object):'
98 (Allow, Authenticated, 'create_resources')]
100 (Allow, Authenticated, 'create_resources')]
99 # general page factory - append custom non resource permissions
101 # general page factory - append custom non resource permissions
100 if hasattr(request, 'user') and request.user:
102 if hasattr(request, 'user') and request.user:
101 acls = permission_to_04_acls(request.user.permissions)
103 acls = permission_to_04_acls(UserService.permissions(request.user))
102 for perm_user, perm_name in acls:
104 for perm_user, perm_name in acls:
103 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
105 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
104
106
@@ -115,11 +117,11 b' class ResourceFactory(object):'
115 resource_id = request.matchdict.get("resource_id",
117 resource_id = request.matchdict.get("resource_id",
116 request.GET.get("resource_id"))
118 request.GET.get("resource_id"))
117 resource_id = to_integer_safe(resource_id)
119 resource_id = to_integer_safe(resource_id)
118 self.resource = Resource.by_resource_id(resource_id) \
120 self.resource = ResourceService.by_resource_id(resource_id) \
119 if resource_id else None
121 if resource_id else None
120 if self.resource and request.user:
122 if self.resource and request.user:
121 self.__acl__ = self.resource.__acl__
123 self.__acl__ = self.resource.__acl__
122 permissions = self.resource.perms_for_user(request.user)
124 permissions = ResourceService.perms_for_user(self.resource, request.user)
123 for perm_user, perm_name in permission_to_04_acls(permissions):
125 for perm_user, perm_name in permission_to_04_acls(permissions):
124 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
126 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
125 add_root_superperm(request, self)
127 add_root_superperm(request, self)
@@ -145,13 +147,13 b' class ResourceReportFactory(object):'
145 raise HTTPNotFound()
147 raise HTTPNotFound()
146
148
147 self.public = self.report_group.public
149 self.public = self.report_group.public
148 self.resource = Resource.by_resource_id(self.report_group.resource_id) \
150 self.resource = ResourceService.by_resource_id(self.report_group.resource_id) \
149 if self.report_group else None
151 if self.report_group else None
150
152
151 if self.resource:
153 if self.resource:
152 self.__acl__ = self.resource.__acl__
154 self.__acl__ = self.resource.__acl__
153 if request.user:
155 if request.user:
154 permissions = self.resource.perms_for_user(request.user)
156 permissions = ResourceService.perms_for_user(self.resource, request.user)
155 for perm_user, perm_name in permission_to_04_acls(permissions):
157 for perm_user, perm_name in permission_to_04_acls(permissions):
156 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
158 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
157 if self.public:
159 if self.public:
@@ -293,11 +295,11 b' class ResourcePluginConfigFactory(object):'
293 if not self.plugin:
295 if not self.plugin:
294 raise HTTPNotFound()
296 raise HTTPNotFound()
295 if self.plugin.resource_id:
297 if self.plugin.resource_id:
296 self.resource = Resource.by_resource_id(self.plugin.resource_id)
298 self.resource = ResourceService.by_resource_id(self.plugin.resource_id)
297 if self.resource:
299 if self.resource:
298 self.__acl__ = self.resource.__acl__
300 self.__acl__ = self.resource.__acl__
299 if request.user and self.resource:
301 if request.user and self.resource:
300 permissions = self.resource.perms_for_user(request.user)
302 permissions = ResourceService.perms_for_user(self.resource, request.user)
301 for perm_user, perm_name in permission_to_04_acls(permissions):
303 for perm_user, perm_name in permission_to_04_acls(permissions):
302 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
304 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
303
305
@@ -316,10 +318,10 b' class ResourceJSONBodyFactory(object):'
316 self.__acl__ = []
318 self.__acl__ = []
317 resource_id = request.unsafe_json_body().get('resource_id')
319 resource_id = request.unsafe_json_body().get('resource_id')
318 resource_id = to_integer_safe(resource_id)
320 resource_id = to_integer_safe(resource_id)
319 self.resource = Resource.by_resource_id(resource_id)
321 self.resource = ResourceService.by_resource_id(resource_id)
320 if self.resource and request.user:
322 if self.resource and request.user:
321 self.__acl__ = self.resource.__acl__
323 self.__acl__ = self.resource.__acl__
322 permissions = self.resource.perms_for_user(request.user)
324 permissions = ResourceService.perms_for_user(self.resource, request.user)
323 for perm_user, perm_name in permission_to_04_acls(permissions):
325 for perm_user, perm_name in permission_to_04_acls(permissions):
324 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
326 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
325 add_root_superperm(request, self)
327 add_root_superperm(request, self)
@@ -337,10 +339,10 b' class ResourcePluginMixedFactory(object):'
337 resource_id = request.GET.get('resource_id')
339 resource_id = request.GET.get('resource_id')
338 if resource_id:
340 if resource_id:
339 resource_id = to_integer_safe(resource_id)
341 resource_id = to_integer_safe(resource_id)
340 self.resource = Resource.by_resource_id(resource_id)
342 self.resource = ResourceService.by_resource_id(resource_id)
341 if self.resource and request.user:
343 if self.resource and request.user:
342 self.__acl__ = self.resource.__acl__
344 self.__acl__ = self.resource.__acl__
343 permissions = self.resource.perms_for_user(request.user)
345 permissions = ResourceService.perms_for_user(self.resource, request.user)
344 for perm_user, perm_name in permission_to_04_acls(permissions):
346 for perm_user, perm_name in permission_to_04_acls(permissions):
345 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
347 self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
346 add_root_superperm(request, self)
348 add_root_superperm(request, self)
@@ -1419,7 +1419,7 b' class TestRegistration(object):'
1419 register(request)
1419 register(request)
1420 user = UserService.by_user_name('foo')
1420 user = UserService.by_user_name('foo')
1421 assert user.user_name == 'foo'
1421 assert user.user_name == 'foo'
1422 assert len(user.user_password) == 60
1422 assert len(user.user_password) >= 60
1423
1423
1424
1424
1425 @pytest.mark.usefixtures('base_app', 'with_migrations', 'clean_tables',
1425 @pytest.mark.usefixtures('base_app', 'with_migrations', 'clean_tables',
@@ -17,7 +17,7 b''
17 from pyramid.view import view_config
17 from pyramid.view import view_config
18 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
18 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
19 from pyramid import security
19 from pyramid import security
20 from appenlight.models.user import User
20 from ziggurat_foundations.models.services.user import UserService
21
21
22 import logging
22 import logging
23
23
@@ -28,7 +28,7 b' log = logging.getLogger(__name__)'
28 match_param=['section=admin_section', 'view=relogin_user'],
28 match_param=['section=admin_section', 'view=relogin_user'],
29 renderer='json', request_method='GET')
29 renderer='json', request_method='GET')
30 def relogin_to_user(request):
30 def relogin_to_user(request):
31 user = User.by_id(request.GET.get('user_id'))
31 user = UserService.by_id(request.GET.get('user_id'))
32 if not user:
32 if not user:
33 return HTTPNotFound()
33 return HTTPNotFound()
34 headers = security.remember(request, user.id)
34 headers = security.remember(request, user.id)
@@ -34,7 +34,9 b' from appenlight.models.resource import Resource'
34 from appenlight.models.application import Application
34 from appenlight.models.application import Application
35 from appenlight.models.application_postprocess_conf import \
35 from appenlight.models.application_postprocess_conf import \
36 ApplicationPostprocessConf
36 ApplicationPostprocessConf
37 from appenlight.models.user import User
37 from ziggurat_foundations.models.services.user import UserService
38 from ziggurat_foundations.models.services.resource import ResourceService
39 from ziggurat_foundations.models.services.user_resource_permission import UserResourcePermissionService
38 from appenlight.models.user_resource_permission import UserResourcePermission
40 from appenlight.models.user_resource_permission import UserResourcePermission
39 from appenlight.models.group_resource_permission import GroupResourcePermission
41 from appenlight.models.group_resource_permission import GroupResourcePermission
40 from appenlight.models.services.application import ApplicationService
42 from appenlight.models.services.application import ApplicationService
@@ -92,7 +94,8 b' def applications_list(request):'
92 else:
94 else:
93 permissions = request.params.getall('permission')
95 permissions = request.params.getall('permission')
94 if permissions:
96 if permissions:
95 resources = request.user.resources_with_perms(
97 resources = UserService.resources_with_perms(
98 request.user,
96 permissions,
99 permissions,
97 resource_types=[request.GET.get('resource_type',
100 resource_types=[request.GET.get('resource_type',
98 'application')])
101 'application')])
@@ -242,7 +245,7 b' def application_ownership_transfer(request):'
242 MultiDict(request.safe_json_body or {}), csrf_context=request)
245 MultiDict(request.safe_json_body or {}), csrf_context=request)
243 form.password.user = request.user
246 form.password.user = request.user
244 if form.validate():
247 if form.validate():
245 user = User.by_user_name(form.user_name.data)
248 user = UserService.by_user_name(form.user_name.data)
246 user.resources.append(resource)
249 user.resources.append(resource)
247 # remove integrations to not leak security data of external applications
250 # remove integrations to not leak security data of external applications
248 for integration in resource.integrations[:]:
251 for integration in resource.integrations[:]:
@@ -650,21 +653,21 b' def user_resource_permission_create(request):'
650 """
653 """
651 resource = request.context.resource
654 resource = request.context.resource
652 user_name = request.unsafe_json_body.get('user_name')
655 user_name = request.unsafe_json_body.get('user_name')
653 user = User.by_user_name(user_name)
656 user = UserService.by_user_name(user_name)
654 if not user:
657 if not user:
655 user = User.by_email(user_name)
658 user = UserService.by_email(user_name)
656 if not user:
659 if not user:
657 return False
660 return False
658
661
659 for perm_name in request.unsafe_json_body.get('permissions', []):
662 for perm_name in request.unsafe_json_body.get('permissions', []):
660 permission = UserResourcePermission.by_resource_user_and_perm(
663 permission = UserResourcePermissionService.by_resource_user_and_perm(
661 user.id, perm_name, resource.resource_id)
664 user.id, perm_name, resource.resource_id)
662 if not permission:
665 if not permission:
663 permission = UserResourcePermission(perm_name=perm_name,
666 permission = UserResourcePermission(perm_name=perm_name,
664 user_id=user.id)
667 user_id=user.id)
665 resource.user_permissions.append(permission)
668 resource.user_permissions.append(permission)
666 DBSession.flush()
669 DBSession.flush()
667 perms = [p.perm_name for p in resource.perms_for_user(user)
670 perms = [p.perm_name for p in ResourceService.perms_for_user(resource, user)
668 if p.type == 'user']
671 if p.type == 'user']
669 result = {'user_name': user.user_name,
672 result = {'user_name': user.user_name,
670 'permissions': list(set(perms))}
673 'permissions': list(set(perms))}
@@ -680,16 +683,16 b' def user_resource_permission_delete(request):'
680 """
683 """
681 resource = request.context.resource
684 resource = request.context.resource
682
685
683 user = User.by_user_name(request.GET.get('user_name'))
686 user = UserService.by_user_name(request.GET.get('user_name'))
684 if not user:
687 if not user:
685 return False
688 return False
686
689
687 for perm_name in request.GET.getall('permissions'):
690 for perm_name in request.GET.getall('permissions'):
688 permission = UserResourcePermission.by_resource_user_and_perm(
691 permission = UserResourcePermissionService.by_resource_user_and_perm(
689 user.id, perm_name, resource.resource_id)
692 user.id, perm_name, resource.resource_id)
690 resource.user_permissions.remove(permission)
693 resource.user_permissions.remove(permission)
691 DBSession.flush()
694 DBSession.flush()
692 perms = [p.perm_name for p in resource.perms_for_user(user)
695 perms = [p.perm_name for p in ResourceService.perms_for_user(resource, user)
693 if p.type == 'user']
696 if p.type == 'user']
694 result = {'user_name': user.user_name,
697 result = {'user_name': user.user_name,
695 'permissions': list(set(perms))}
698 'permissions': list(set(perms))}
@@ -716,7 +719,8 b' def group_resource_permission_create(request):'
716 group_id=group.id)
719 group_id=group.id)
717 resource.group_permissions.append(permission)
720 resource.group_permissions.append(permission)
718 DBSession.flush()
721 DBSession.flush()
719 perm_tuples = resource.groups_for_perm(
722 perm_tuples = ResourceService.groups_for_perm(
723 resource,
720 ANY_PERMISSION,
724 ANY_PERMISSION,
721 limit_group_permissions=True,
725 limit_group_permissions=True,
722 group_ids=[group.id])
726 group_ids=[group.id])
@@ -745,7 +749,8 b' def group_resource_permission_delete(request):'
745 group.id, perm_name, resource.resource_id)
749 group.id, perm_name, resource.resource_id)
746 resource.group_permissions.remove(permission)
750 resource.group_permissions.remove(permission)
747 DBSession.flush()
751 DBSession.flush()
748 perm_tuples = resource.groups_for_perm(
752 perm_tuples = ResourceService.groups_for_perm(
753 resource,
749 ANY_PERMISSION,
754 ANY_PERMISSION,
750 limit_group_permissions=True,
755 limit_group_permissions=True,
751 group_ids=[group.id])
756 group_ids=[group.id])
@@ -18,6 +18,7 b' from appenlight.lib.helpers import gen_pagination_headers'
18 from appenlight.models.services.event import EventService
18 from appenlight.models.services.event import EventService
19 from pyramid.view import view_config
19 from pyramid.view import view_config
20 from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound
20 from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound
21 from ziggurat_foundations.models.services.user import UserService
21
22
22
23
23 @view_config(route_name='events_no_id',
24 @view_config(route_name='events_no_id',
@@ -40,8 +41,8 b' def fetch_events(request):'
40 @view_config(route_name='events', renderer='json', request_method='PATCH',
41 @view_config(route_name='events', renderer='json', request_method='PATCH',
41 permission='authenticated')
42 permission='authenticated')
42 def event_PATCH(request):
43 def event_PATCH(request):
43 resources = request.user.resources_with_perms(
44 resources = UserService.resources_with_perms(
44 ['view'], resource_types=request.registry.resource_types)
45 request.user, ['view'], resource_types=request.registry.resource_types)
45 event = EventService.for_resource(
46 event = EventService.for_resource(
46 [r.resource_id for r in resources],
47 [r.resource_id for r in resources],
47 event_id=request.matchdict['event_id']).first()
48 event_id=request.matchdict['event_id']).first()
@@ -19,6 +19,7 b' import logging'
19 from pyramid.view import view_config
19 from pyramid.view import view_config
20 from pyramid.httpexceptions import HTTPUnprocessableEntity, HTTPNotFound
20 from pyramid.httpexceptions import HTTPUnprocessableEntity, HTTPNotFound
21
21
22 from ziggurat_foundations.models.services.user import UserService
22 from appenlight.lib.utils import permission_tuple_to_dict
23 from appenlight.lib.utils import permission_tuple_to_dict
23 from appenlight.models.services.config import ConfigService
24 from appenlight.models.services.config import ConfigService
24 from appenlight.models.group import Group
25 from appenlight.models.group import Group
@@ -122,7 +123,7 b' def groups_resource_permissions_list(request):'
122 if not group:
123 if not group:
123 return HTTPNotFound()
124 return HTTPNotFound()
124 return [permission_tuple_to_dict(perm) for perm in
125 return [permission_tuple_to_dict(perm) for perm in
125 group.resources_with_possible_perms()]
126 GroupService.resources_with_possible_perms(group)]
126
127
127
128
128 @view_config(route_name='groups_property',
129 @view_config(route_name='groups_property',
@@ -140,7 +141,7 b' def groups_users_list(request):'
140 users_dicts = []
141 users_dicts = []
141 for user in group.users:
142 for user in group.users:
142 u_dict = user.get_dict(include_keys=props)
143 u_dict = user.get_dict(include_keys=props)
143 u_dict['gravatar_url'] = user.gravatar_url(s=20)
144 u_dict['gravatar_url'] = UserService.gravatar_url(user, s=20)
144 users_dicts.append(u_dict)
145 users_dicts.append(u_dict)
145 return users_dicts
146 return users_dicts
146
147
@@ -153,7 +154,7 b' def groups_users_remove(request):'
153 Get list of permissions assigned to specific resources
154 Get list of permissions assigned to specific resources
154 """
155 """
155 group = GroupService.by_id(request.matchdict.get('group_id'))
156 group = GroupService.by_id(request.matchdict.get('group_id'))
156 user = User.by_user_name(request.GET.get('user_name'))
157 user = UserService.by_user_name(request.GET.get('user_name'))
157 if not group or not user:
158 if not group or not user:
158 return HTTPNotFound()
159 return HTTPNotFound()
159 if len(group.users) > 1:
160 if len(group.users) > 1:
@@ -175,9 +176,9 b' def groups_users_add(request):'
175 Get list of permissions assigned to specific resources
176 Get list of permissions assigned to specific resources
176 """
177 """
177 group = GroupService.by_id(request.matchdict.get('group_id'))
178 group = GroupService.by_id(request.matchdict.get('group_id'))
178 user = User.by_user_name(request.unsafe_json_body.get('user_name'))
179 user = UserService.by_user_name(request.unsafe_json_body.get('user_name'))
179 if not user:
180 if not user:
180 user = User.by_email(request.unsafe_json_body.get('user_name'))
181 user = UserService.by_email(request.unsafe_json_body.get('user_name'))
181
182
182 if not group or not user:
183 if not group or not user:
183 return HTTPNotFound()
184 return HTTPNotFound()
@@ -187,5 +188,5 b' def groups_users_add(request):'
187 props = ['user_name', 'id', 'first_name', 'last_name', 'email',
188 props = ['user_name', 'id', 'first_name', 'last_name', 'email',
188 'last_login_date', 'status']
189 'last_login_date', 'status']
189 u_dict = user.get_dict(include_keys=props)
190 u_dict = user.get_dict(include_keys=props)
190 u_dict['gravatar_url'] = user.gravatar_url(s=20)
191 u_dict['gravatar_url'] = UserService.gravatar_url(user, s=20)
191 return u_dict
192 return u_dict
@@ -27,6 +27,7 b' from pyramid.security import NO_PERMISSION_REQUIRED'
27 from ziggurat_foundations.ext.pyramid.sign_in import ZigguratSignInSuccess
27 from ziggurat_foundations.ext.pyramid.sign_in import ZigguratSignInSuccess
28 from ziggurat_foundations.ext.pyramid.sign_in import ZigguratSignInBadAuth
28 from ziggurat_foundations.ext.pyramid.sign_in import ZigguratSignInBadAuth
29 from ziggurat_foundations.ext.pyramid.sign_in import ZigguratSignOut
29 from ziggurat_foundations.ext.pyramid.sign_in import ZigguratSignOut
30 from ziggurat_foundations.models.services.user import UserService
30
31
31 from appenlight.lib.social import handle_social_data
32 from appenlight.lib.social import handle_social_data
32 from appenlight.models import DBSession
33 from appenlight.models import DBSession
@@ -93,9 +94,9 b' def lost_password(request):'
93 """
94 """
94 form = forms.LostPasswordForm(request.POST, csrf_context=request)
95 form = forms.LostPasswordForm(request.POST, csrf_context=request)
95 if request.method == 'POST' and form.validate():
96 if request.method == 'POST' and form.validate():
96 user = User.by_email(form.email.data)
97 user = UserService.by_email(form.email.data)
97 if user:
98 if user:
98 user.regenerate_security_code()
99 UserService.regenerate_security_code(user)
99 user.security_code_date = datetime.datetime.utcnow()
100 user.security_code_date = datetime.datetime.utcnow()
100 email_vars = {
101 email_vars = {
101 'user': user,
102 'user': user,
@@ -120,7 +121,7 b' def lost_password_generate(request):'
120 """
121 """
121 Shows new password form - perform time check and set new password for user
122 Shows new password form - perform time check and set new password for user
122 """
123 """
123 user = User.by_user_name_and_security_code(
124 user = UserService.by_user_name_and_security_code(
124 request.GET.get('user_name'), request.GET.get('security_code'))
125 request.GET.get('user_name'), request.GET.get('security_code'))
125 if user:
126 if user:
126 delta = datetime.datetime.utcnow() - user.security_code_date
127 delta = datetime.datetime.utcnow() - user.security_code_date
@@ -128,7 +129,7 b' def lost_password_generate(request):'
128 if user and delta.total_seconds() < 600:
129 if user and delta.total_seconds() < 600:
129 form = forms.NewPasswordForm(request.POST, csrf_context=request)
130 form = forms.NewPasswordForm(request.POST, csrf_context=request)
130 if request.method == "POST" and form.validate():
131 if request.method == "POST" and form.validate():
131 user.set_password(form.new_password.data)
132 UserService.set_password(user, form.new_password.data)
132 request.session.flash(_('You can sign in with your new password.'))
133 request.session.flash(_('You can sign in with your new password.'))
133 return HTTPFound(location=request.route_url('register'))
134 return HTTPFound(location=request.route_url('register'))
134 else:
135 else:
@@ -183,9 +184,9 b' def register(request):'
183 new_user = User()
184 new_user = User()
184 DBSession.add(new_user)
185 DBSession.add(new_user)
185 form.populate_obj(new_user)
186 form.populate_obj(new_user)
186 new_user.regenerate_security_code()
187 UserService.regenerate_security_code(new_user)
187 new_user.status = 1
188 new_user.status = 1
188 new_user.set_password(new_user.user_password)
189 UserService.set_password(new_user, new_user.user_password)
189 new_user.registration_ip = request.environ.get('REMOTE_ADDR')
190 new_user.registration_ip = request.environ.get('REMOTE_ADDR')
190
191
191 if social_data:
192 if social_data:
@@ -20,6 +20,9 b' from datetime import datetime, timedelta'
20 from pyramid.view import view_config
20 from pyramid.view import view_config
21 from pyramid.httpexceptions import HTTPUnprocessableEntity
21 from pyramid.httpexceptions import HTTPUnprocessableEntity
22
22
23 from ziggurat_foundations.models.services.resource import ResourceService
24 from ziggurat_foundations.models.services.user import UserService
25
23 from appenlight.models import DBSession
26 from appenlight.models import DBSession
24 from appenlight.models.user import User
27 from appenlight.models.user import User
25 from appenlight.models.report_comment import ReportComment
28 from appenlight.models.report_comment import ReportComment
@@ -51,8 +54,8 b' def index(request):'
51 if request.user:
54 if request.user:
52 request.user.last_login_date = datetime.utcnow()
55 request.user.last_login_date = datetime.utcnow()
53
56
54 applications = request.user.resources_with_perms(
57 applications = UserService.resources_with_perms(
55 ['view'], resource_types=['application'])
58 request.user, ['view'], resource_types=['application'])
56
59
57 search_params = request.GET.mixed()
60 search_params = request.GET.mixed()
58
61
@@ -134,7 +137,7 b' def comment_create(request):'
134 report_time=report_group.first_timestamp)
137 report_time=report_group.first_timestamp)
135 form.populate_obj(comment)
138 form.populate_obj(comment)
136 report_group.comments.append(comment)
139 report_group.comments.append(comment)
137 perm_list = application.users_for_perm('view')
140 perm_list = ResourceService.users_for_perm(application, 'view')
138 uids_to_notify = []
141 uids_to_notify = []
139 users_to_notify = []
142 users_to_notify = []
140 for perm in perm_list:
143 for perm in perm_list:
@@ -179,13 +182,13 b' def assigned_users(request):'
179 """
182 """
180 report_group = request.context.report_group
183 report_group = request.context.report_group
181 application = request.context.resource
184 application = request.context.resource
182 users = set([p.user for p in application.users_for_perm('view')])
185 users = set([p.user for p in ResourceService.users_for_perm(application, 'view')])
183 currently_assigned = [u.user_name for u in report_group.assigned_users]
186 currently_assigned = [u.user_name for u in report_group.assigned_users]
184 user_status = {'assigned': [], 'unassigned': []}
187 user_status = {'assigned': [], 'unassigned': []}
185 # handle users
188 # handle users
186 for user in users:
189 for user in users:
187 user_dict = {'user_name': user.user_name,
190 user_dict = {'user_name': user.user_name,
188 'gravatar_url': user.gravatar_url(),
191 'gravatar_url': UserService.gravatar_url(user),
189 'name': '%s %s' % (user.first_name, user.last_name,)}
192 'name': '%s %s' % (user.first_name, user.last_name,)}
190 if user.user_name in currently_assigned:
193 if user.user_name in currently_assigned:
191 user_status['assigned'].append(user_dict)
194 user_status['assigned'].append(user_dict)
@@ -209,7 +212,7 b' def assign_users(request):'
209 # first unassign old users
212 # first unassign old users
210 for user_name in new_assigns['unassigned']:
213 for user_name in new_assigns['unassigned']:
211 if user_name in currently_assigned:
214 if user_name in currently_assigned:
212 user = User.by_user_name(user_name)
215 user = UserService.by_user_name(user_name)
213 report_group.assigned_users.remove(user)
216 report_group.assigned_users.remove(user)
214 comment = ReportComment(owner_id=request.user.id,
217 comment = ReportComment(owner_id=request.user.id,
215 report_time=report_group.first_timestamp)
218 report_time=report_group.first_timestamp)
@@ -219,7 +222,7 b' def assign_users(request):'
219 # assign new users
222 # assign new users
220 for user_name in new_assigns['assigned']:
223 for user_name in new_assigns['assigned']:
221 if user_name not in currently_assigned:
224 if user_name not in currently_assigned:
222 user = User.by_user_name(user_name)
225 user = UserService.by_user_name(user_name)
223 if user in report_group.assigned_users:
226 if user in report_group.assigned_users:
224 report_group.assigned_users.remove(user)
227 report_group.assigned_users.remove(user)
225 DBSession.flush()
228 DBSession.flush()
@@ -23,6 +23,9 b' import redis'
23 import six
23 import six
24 import pyramid.renderers
24 import pyramid.renderers
25 import requests
25 import requests
26
27 from ziggurat_foundations.models.services.user import UserService
28
26 import appenlight.celery.tasks
29 import appenlight.celery.tasks
27 from pyramid.view import view_config
30 from pyramid.view import view_config
28 from pyramid_mailer.message import Message
31 from pyramid_mailer.message import Message
@@ -72,8 +75,7 b' def alerting_test(request):'
72 """
75 """
73 Allows to test send data on various registered alerting channels
76 Allows to test send data on various registered alerting channels
74 """
77 """
75 applications = request.user.resources_with_perms(
78 applications = UserService.resources_with_perms(request.user, ['view'], resource_types=['application'])
76 ['view'], resource_types=['application'])
77 # what we can select in total
79 # what we can select in total
78 all_possible_app_ids = [app.resource_id for app in applications]
80 all_possible_app_ids = [app.resource_id for app in applications]
79 resource = applications[0]
81 resource = applications[0]
@@ -29,6 +29,7 b' from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest'
29 from pyramid.security import NO_PERMISSION_REQUIRED
29 from pyramid.security import NO_PERMISSION_REQUIRED
30 from ziggurat_foundations.models.services.external_identity import \
30 from ziggurat_foundations.models.services.external_identity import \
31 ExternalIdentityService
31 ExternalIdentityService
32 from ziggurat_foundations.models.services.user import UserService
32
33
33 from appenlight.lib import generate_random_string
34 from appenlight.lib import generate_random_string
34 from appenlight.lib.social import handle_social_data
35 from appenlight.lib.social import handle_social_data
@@ -64,7 +65,7 b' def users_list(request):'
64 users_dicts = []
65 users_dicts = []
65 for user in users:
66 for user in users:
66 u_dict = user.get_dict(include_keys=props)
67 u_dict = user.get_dict(include_keys=props)
67 u_dict['gravatar_url'] = user.gravatar_url(s=20)
68 u_dict['gravatar_url'] = UserService.gravatar_url(user, s=20)
68 users_dicts.append(u_dict)
69 users_dicts.append(u_dict)
69 return users_dicts
70 return users_dicts
70
71
@@ -87,8 +88,8 b' def users_create(request):'
87 # insert new user here
88 # insert new user here
88 DBSession.add(user)
89 DBSession.add(user)
89 form.populate_obj(user)
90 form.populate_obj(user)
90 user.regenerate_security_code()
91 UserService.regenerate_security_code(user)
91 user.set_password(user.user_password)
92 UserService.set_password(user, user.user_password)
92 user.status = 1 if form.status.data else 0
93 user.status = 1 if form.status.data else 0
93 request.session.flash(_('User created'))
94 request.session.flash(_('User created'))
94 DBSession.flush()
95 DBSession.flush()
@@ -106,7 +107,7 b' def users_update(request):'
106 """
107 """
107 Updates user object
108 Updates user object
108 """
109 """
109 user = User.by_id(request.matchdict.get('user_id'))
110 user = UserService.by_id(request.matchdict.get('user_id'))
110 if not user:
111 if not user:
111 return HTTPNotFound()
112 return HTTPNotFound()
112 post_data = request.safe_json_body or {}
113 post_data = request.safe_json_body or {}
@@ -116,7 +117,7 b' def users_update(request):'
116 if form.validate():
117 if form.validate():
117 form.populate_obj(user, ignore_none=True)
118 form.populate_obj(user, ignore_none=True)
118 if form.user_password.data:
119 if form.user_password.data:
119 user.set_password(user.user_password)
120 UserService.set_password(user, user.user_password)
120 if form.status.data:
121 if form.status.data:
121 user.status = 1
122 user.status = 1
122 else:
123 else:
@@ -134,11 +135,11 b' def users_resource_permissions_list(request):'
134 """
135 """
135 Get list of permissions assigned to specific resources
136 Get list of permissions assigned to specific resources
136 """
137 """
137 user = User.by_id(request.matchdict.get('user_id'))
138 user = UserService.by_id(request.matchdict.get('user_id'))
138 if not user:
139 if not user:
139 return HTTPNotFound()
140 return HTTPNotFound()
140 return [permission_tuple_to_dict(perm) for perm in
141 return [permission_tuple_to_dict(perm) for perm in
141 user.resources_with_possible_perms()]
142 UserService.resources_with_possible_perms(user)]
142
143
143
144
144 @view_config(route_name='users', renderer='json',
145 @view_config(route_name='users', renderer='json',
@@ -149,9 +150,9 b' def users_DELETE(request):'
149 operation there will be at least one admin left
150 operation there will be at least one admin left
150 """
151 """
151 msg = _('There needs to be at least one administrator in the system')
152 msg = _('There needs to be at least one administrator in the system')
152 user = User.by_id(request.matchdict.get('user_id'))
153 user = UserService.by_id(request.matchdict.get('user_id'))
153 if user:
154 if user:
154 users = User.users_for_perms(['root_administration']).all()
155 users = UserService.users_for_perms(['root_administration']).all()
155 if len(users) < 2 and user.id == users[0].id:
156 if len(users) < 2 and user.id == users[0].id:
156 request.session.flash(msg, 'warning')
157 request.session.flash(msg, 'warning')
157 else:
158 else:
@@ -227,8 +228,8 b' def users_password(request):'
227 csrf_context=request)
228 csrf_context=request)
228 form.old_password.user = user
229 form.old_password.user = user
229 if form.validate():
230 if form.validate():
230 user.regenerate_security_code()
231 UserService.regenerate_security_code(user)
231 user.set_password(form.new_password.data)
232 UserService.set_password(user, form.new_password.data)
232 msg = 'Your password got updated. ' \
233 msg = 'Your password got updated. ' \
233 'Next time log in with your new credentials.'
234 'Next time log in with your new credentials.'
234 request.session.flash(_(msg))
235 request.session.flash(_(msg))
@@ -250,8 +251,7 b' def users_websocket(request):'
250 res = request.response.body('OK')
251 res = request.response.body('OK')
251 add_cors_headers(res)
252 add_cors_headers(res)
252 return res
253 return res
253 applications = user.resources_with_perms(
254 applications = UserService.resources_with_perms(user, ['view'], resource_types=['application'])
254 ['view'], resource_types=['application'])
255 channels = ['app_%s' % app.resource_id for app in applications]
255 channels = ['app_%s' % app.resource_id for app in applications]
256 payload = {"username": user.user_name,
256 payload = {"username": user.user_name,
257 "conn_id": str(uuid.uuid4()),
257 "conn_id": str(uuid.uuid4()),
@@ -594,11 +594,11 b' def search_users(request):'
594 items_returned = []
594 items_returned = []
595 like_condition = request.params.get('user_name', '') + '%'
595 like_condition = request.params.get('user_name', '') + '%'
596 # first append used if email is passed
596 # first append used if email is passed
597 found_user = User.by_email(request.params.get('user_name', ''))
597 found_user = UserService.by_email(request.params.get('user_name', ''))
598 if found_user:
598 if found_user:
599 name = '{} {}'.format(found_user.first_name, found_user.last_name)
599 name = '{} {}'.format(found_user.first_name, found_user.last_name)
600 items_returned.append({'user': found_user.user_name, 'name': name})
600 items_returned.append({'user': found_user.user_name, 'name': name})
601 for found_user in User.user_names_like(like_condition).limit(20):
601 for found_user in UserService.user_names_like(like_condition).limit(20):
602 name = '{} {}'.format(found_user.first_name, found_user.last_name)
602 name = '{} {}'.format(found_user.first_name, found_user.last_name)
603 items_returned.append({'user': found_user.user_name, 'name': name})
603 items_returned.append({'user': found_user.user_name, 'name': name})
604 return items_returned
604 return items_returned
@@ -615,7 +615,7 b' def auth_tokens_list(request):'
615 if request.matched_route.name == 'users_self_property':
615 if request.matched_route.name == 'users_self_property':
616 user = request.user
616 user = request.user
617 else:
617 else:
618 user = User.by_id(request.matchdict.get('user_id'))
618 user = UserService.by_id(request.matchdict.get('user_id'))
619 if not user:
619 if not user:
620 return HTTPNotFound()
620 return HTTPNotFound()
621 return [c.get_dict() for c in user.auth_tokens]
621 return [c.get_dict() for c in user.auth_tokens]
@@ -634,7 +634,7 b' def auth_tokens_POST(request):'
634 if request.matched_route.name == 'users_self_property':
634 if request.matched_route.name == 'users_self_property':
635 user = request.user
635 user = request.user
636 else:
636 else:
637 user = User.by_id(request.matchdict.get('user_id'))
637 user = UserService.by_id(request.matchdict.get('user_id'))
638 if not user:
638 if not user:
639 return HTTPNotFound()
639 return HTTPNotFound()
640
640
@@ -667,7 +667,7 b' def auth_tokens_DELETE(request):'
667 if request.matched_route.name == 'users_self_property':
667 if request.matched_route.name == 'users_self_property':
668 user = request.user
668 user = request.user
669 else:
669 else:
670 user = User.by_id(request.matchdict.get('user_id'))
670 user = UserService.by_id(request.matchdict.get('user_id'))
671 if not user:
671 if not user:
672 return HTTPNotFound()
672 return HTTPNotFound()
673
673
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (1082 lines changed) Show them Hide them
General Comments 1
Under Review
author

Auto status change to "Under Review"

You need to be logged in to leave comments. Login now

Merge is not currently possible because of below failed checks.

  • - User `default` not allowed to perform merge.
  • - Pull request reviewer approval is pending.
  • - Cannot merge, 1 TODO still not resolved.