def Environment_get_known_users(self, cnx=None): project_id = self.config.get('por-dashboard', 'project-id') project = None if project_id: db = DBSession() project = db.query(Project).get(project_id) for user in db.query(User).all(): if user.roles_in_context(project): yield user.login, user.fullname, user.email
def render(self): result = {} result['main_template'] = get_renderer( 'penelope.core:skins/main_template.pt').implementation() result['main'] = get_renderer( 'penelope.core.forms:templates/master.pt').implementation() schema = WizardSchema().clone() wizard_fanstatic.need() form = WizardForm(schema, action=self.request.current_route_url(), formid='wizard', method='POST', buttons=[ SubmitButton(title=u'Submit'), ResetButton(title=u'Reset'), ]) form['new_users'].widget = SequenceWidget() form['users'].widget = SequenceWidget(min_len=1) users = DBSession.query(User).order_by(User.fullname) form['users']['user']['usernames'].widget.values = [('', '')] + \ [(str(u.id), u.fullname) for u in users] roles = DBSession.query(Role).order_by(Role.name) form['users']['user']['role'].widget.values = [('', '')] + \ [(str(role.id), role.name) for role in roles] form['new_users']['new_user']['role'].widget.values = [('', '')] + \ [(str(role.id), role.name) for role in roles] form['milestones'].widget = SequenceWidget(min_len=1) form['contracts'].title = '' form['contracts']['customer_requests'].widget = SequenceWidget(min_len=3) controls = self.request.POST.items() if controls != []: try: appstruct = form.validate(controls) self.handle_save(form, appstruct) except ValidationFailure as e: result['form'] = e.render() return result appstruct = {} appstruct['contracts'] ={'customer_requests': []} appstruct['contracts']['customer_requests'].append({'ticket': True, 'title': u'Project management'}) appstruct['contracts']['customer_requests'].append({'ticket': True, 'title': u'Analisi'}) appstruct['contracts']['customer_requests'].append({'ticket': True, 'title': u'Supporto'}) result['form'] = form.render(appstruct=appstruct) return result
def test_password_set(self): email = u'*****@*****.**' self.add_user(email) session = DBSession() self.assertEqual(session.query(User).filter_by(email=email).one().password, None) token = self.generate_token(email)['token'] from penelope.core.security.views import change_password request = Request(method='POST', params={'token': token, 'password': '******', 'password_repeat': 'topsecret'}) response = change_password(request) self.assertEqual(response.headers.get('Location'),'/login_form') self.assertNotEqual(session.query(User).filter_by(email=email).one().password, None)
def test_token_store_cleanup(self): email = u'*****@*****.**' self.add_user(email) self.generate_token(email)['token'] token2 = self.generate_token(email)['token'] session = DBSession() self.assertEqual(len(session.query(PasswordResetToken).join(User).filter(User.email == email).all()),1) from penelope.core.security.views import change_password request = Request(method='POST', params={'token': token2, 'password': '******', 'password_repeat': 'topsecret'}) response = change_password(request) self.assertEqual(response.headers.get('Location'),'/login_form') self.assertEqual(len(session.query(PasswordResetToken).join(User).filter(User.email == email).all()),0)
def report_index(context, request): users = DBSession.query(User).order_by(User.fullname) users = filter_users_with_timeentries(users) projects = sorted(request.filter_viewables(qry_active_projects()), key=unicodelower) customers = sorted(set(p.customer for p in projects), key=unicodelower) current_uid = request.authenticated_user.id saved_queries = DBSession.query(SavedQuery).filter(SavedQuery.author_id==current_uid) return { 'users': users, 'customers': customers, 'projects': projects, 'saved_queries': saved_queries.all() }
def timeentry_crstate_validation_errors(project_id, tickets, request): # XXX this check is deactivated for now (see #312) return [] project = DBSession.query(Project).get(project_id) customer_requests = ticket_store.get_requests_from_tickets(project, tickets) for ticket_id, cr_id in customer_requests: cr = DBSession.query(CustomerRequest).get(cr_id) if cr.workflow_state != 'estimated': return ['Customer Request is not estimated'] return []
def __call__(self): te_ids = set(int(s[3:]) for s, checkbox_state in self.request.POST.iteritems() if s.startswith('te_') and checkbox_state=='on') tes = DBSession.query(TimeEntry).filter(TimeEntry.id.in_(te_ids)) new_state = self.request.POST.get('new_state', None) new_cr = self.request.POST.get('new_cr', None) if new_cr: new_cr = DBSession.query(CustomerRequest).get(new_cr) return {'back_url': '%s/reports/report_state_change?%s' % (self.request.application_url, self.request.query_string), 'post': self.request.POST.items(), 'tes': tes, 'new_state': new_state, 'new_cr': new_cr}
def state_cr_change(self): new_state = self.request.POST['new_state'] new_cr = self.request.POST['new_cr'] invoice_number = self.request.POST['invoice_number'] te_ids = set(int(s[3:]) for s, checkbox_state in self.request.POST.iteritems() if s.startswith('te_') and checkbox_state=='on') qry = DBSession.query(TimeEntry).filter(TimeEntry.id.in_(te_ids)) done_state = set() done_cr = set() errors = {} for te in qry: if new_state: try: workflow = get_workflow(te, te.__class__.__name__) workflow.transition_to_state(te, self.request, new_state, skip_same=True) done_state.add(te.id) if new_state == 'invoiced' and invoice_number: te.invoice_number = invoice_number except WorkflowError as msg: errors[te.id] = msg if new_cr: done_cr.add(te.id) te.customer_request_id = new_cr return done_state, done_cr, errors
def search(self, limit, author_id, project_id, date_from, date_to, searchtext): qry = DBSession.query(TimeEntry) qry = qry.filter(TimeEntry.author_id==author_id) if project_id is not colander.null: qry = qry.filter(TimeEntry.project_id==project_id) if date_from is not colander.null: qry = qry.filter(TimeEntry.date>=date_from) if date_to is not colander.null: qry = qry.filter(TimeEntry.date<=date_to) if searchtext is not colander.null: qry = qry.filter(TimeEntry.description.ilike(u'%{0}%'.format(searchtext))) qry = qry.order_by(sa.desc(TimeEntry.date), sa.desc(TimeEntry.start), sa.desc(TimeEntry.creation_date)) if limit: qry = qry.limit(limit) qry = self.request.filter_viewables(qry) entries_by_date = [] entries_count = 0 for k, g in itertools.groupby(qry, operator.attrgetter('date')): g = list(g) entries_by_date.append((k, g)) entries_count += len(g) return entries_by_date, entries_count
def activate_iteration(context, request): docid = request.params.get('docid') if not docid: return view_iterations(context, request, validation_error=u'Missing document_id') #query = gdata.spreadsheet.service.CellQuery() #first take project names #query['min-col'] = '3' #query['max-col'] = '3' #query['min-row'] = '5' #cr_raw = get_cell_values(request, query) session = DBSession() #deactivate all CR #for cr in session.query(CustomerRequest): # cr.active = False #activate selected CR #cr_ids = set([item for sublist in [a.split(',') for a in cr_raw] for item in sublist]) #crs = session.query(CustomerRequest).filter(CustomerRequest.id.in_(cr_ids)) #for cr in crs: # cr.active = True gc = session.query(GlobalConfig).get(1) gc.active_iteration_url = docid return manage_iterations(context,request)
def get_customer_by_name(request, customer_name): """ This method search for customer by name """ session = DBSession() if not isinstance(customer_name, basestring): return { 'status:': False, 'message': u'Customer name parameter must be a string!', } try: customer = session.query(Customer).filter_by(name=customer_name).one() except orm_exc.NoResultFound: return { 'status': False, 'message': u'No customer found in db for %s name' % customer_name, } return { 'status': True, 'message': u'Customer found.', 'name': customer.name, 'projects': [x.name for x in customer.projects], }
def view_home(request): """ Default home view """ fanstatic_resources.dashboard_home.need() session = DBSession() user = request.authenticated_user projects = session.query(Project) my_projects = projects\ .filter(Project.users_favorite(user))\ .order_by(Project.customer_id).all() my_projects = request.filter_viewables(my_projects) active_projects = set(projects.filter(Project.active)) active_projects = sorted(request.filter_viewables(active_projects.difference(my_projects)), key=unicodelower) listings = [] listing_columns = 4 listings.append({'title': 'Active projects', 'projgroups': tuple(chunks(tuple(active_projects), listing_columns)),}) kanbanboards = user.kanban_boards return { 'my_projects': my_projects, 'kanbanboards': kanbanboards, 'listings': listings, 'can_see_kanbanboards': request.has_permission('listing', KanbanBoard), 'get_application_link': get_application_link, }
def notify_feedly(self, ticket, comment, author): from penelope.core.activity_stream import add_activity users_to_notify = set() users_to_notify.add(ticket.values.get('reporter')) users_to_notify.add(ticket.values.get('owner')) try: users_to_notify.remove(author) except KeyError: pass absolute_path = '/trac/{trac_id}/ticket/{ticket_id}'.format(ticket_id=ticket.id, trac_id=self.env.config['por-dashboard'].get('project-id')) message = "Ticket #{ticket} has been {comment} in {trac_name}.".format(ticket=ticket.id, comment=comment, trac_name=self.config['project'].get('name')) created_by = author user_ids = [] for email in users_to_notify: try: user_ids.append(DBSession.query(User.id).filter(User.email==email).one().id) except sqlalchemy.orm.exc.NoResultFound: pass try: add_activity(user_ids, message, absolute_path, created_by) except ConnectionError: pass
def create_initial_application_acl(mapper, connection, target): if target.application_type == SVN: acl_rules = [ ('internal_developer', 'edit'), ('internal_developer', 'view'), ('external_developer', 'edit'), ('external_developer', 'view'), ] else: acl_rules = [ ('internal_developer', 'view'), ('external_developer', 'view'), ('secretary', 'view'), ('secretary', 'edit'), ] if target.application_type == 'trac': acl_rules.append(('customer', 'view')) for role_id, permission_name in acl_rules: acl = DBSession.query(ApplicationACL).get((target.id, role_id, permission_name)) if not acl: acl = ApplicationACL(application_id=target.id, role_id=role_id, permission_name=permission_name) DBSession.add(acl) else: # XXX this should not happen. pass
def unusedEmail(value): user = DBSession.query(User.id).filter(User.email == value).first() if user: return "email '%s' is already associated to another user" % \ value else: return True
def get_user_by_email(request, email): """ This method search for user using his email address """ session = DBSession() if not isinstance(email, basestring): return { 'status:': False, 'message': u'Email parameter must be a string!', } try: user = session.query(User).filter_by(email=email).one() except orm_exc.NoResultFound: return { 'status': False, 'message': u'No user found in db for %s mail address' % email, } return { 'status': True, 'message': u'User found.', 'email': user.email, 'login': user.login, 'openids': [x.openid for x in user.openids] }
def get_user_by_openid(request, openid): """ This method search for user using one of the possible user openids """ session = DBSession() if not isinstance(openid, basestring): return { 'status:': False, 'message': u'Openid parameter must be a string!', } try: user = session.query(User).join('openids').filter_by(openid=openid).one() except orm_exc.NoResultFound: return { 'status': False, 'message': u'No user found in db for %s openid' % openid, } return { 'status': True, 'message': u'User found.', 'email': user.email, 'login': user.login, 'openids': [x.openid for x in user.openids], }
def add_tickets(self, project, customerrequest, tickets, reporter, notify=False): from trac.ticket.notification import TicketNotifyEmail from trac.util.text import exception_to_unicode from penelope.core.models.dashboard import User settings = get_current_registry().settings tracenvs = settings.get('penelope.trac.envs') request = get_current_request() for trac in project.tracs: for t in tickets: owner = DBSession.query(User).get(t['owner']) ticket = {'summary': t['summary'], 'description': t['description'], 'customerrequest': customerrequest.id, 'reporter': reporter.email, 'type': 'task', 'priority': 'major', 'milestone': 'Backlog', 'owner': owner.email, 'status': 'new'} tracenv = Environment('%s/%s' % (tracenvs, trac.trac_name)) tracenv.abs_href.base = trac.api_uri t = Ticket(tracenv) t.populate(ticket) t.insert() if notify: try: tn = TicketNotifyEmail(tracenv) tn.notify(t, newticket=True) except Exception, e: request.add_message('Failure sending notification on creation ' 'of a ticket #%s: %s' % (t.id, exception_to_unicode(e)), 'error')
def get_project_by_name(request, project_name): """ This method search for project by name """ session = DBSession() if not isinstance(project_name, basestring): return { 'status:': False, 'message': u'Project name parameter must be a string!', } try: project = session.query(Project).filter_by(name=project_name).one() except orm_exc.NoResultFound: return { 'status': False, 'message': u'No project found in db for %s name' % project_name, } return { 'status': True, 'message': u'Project found.', 'name': project.name, 'id': project.id, 'customer': project.customer.name, 'applications': [x.name for x in project.applications], 'customer_requests': [(x.id, x.name,) for x in project.customer_requests], }
def search(request): schema = SearchSchema().bind(request=request) form = PorInlineForm( schema, action=request.current_route_url(), formid='search', method='GET', buttons=[SearchButton(title=u'Search'),] ) tracs = searchable_tracs(request) form['tracs'].widget.values = [('', '')] \ + [(t.trac_name, t.project_name) for t in tracs] users = DBSession.query(User).order_by(User.fullname) form['authors'].widget.values = [('', '')] \ + [(a.email, a.fullname) for a in users] controls = request.GET.items() if not controls: return {'form': form.render(), 'results':[]} try: appstruct = form.validate(controls) except deform.ValidationFailure as e: return {'form': e.render(), 'results':[]} params = appstruct.copy() if not params['tracs']: params['tracs'] = [t.trac_name for t in tracs] fs = FullTextSearch(request=request, **params) results = fs.get_search_results() next_url = None previous_url = None docs = [] if results: docs = [FullTextSearchObject(**doc) for doc in results] records_len = results.result.numFound if not fs.page_start + fs.page_size >= records_len: # end of set next_query = add_param(request, 'page_start', fs.page_start + fs.page_size) next_url = current_route_url(request, _query=next_query) if not fs.page_start == 0: previous_page = fs.page_start - fs.page_size if previous_page < 0: previous_page = 0 previous_query = add_param(request, 'page_start', previous_page) previous_url = current_route_url(request, _query=previous_query) return {'docs': docs, 'next': next_url, 'form': form.render(appstruct=appstruct), 'previous': previous_url, 'add_params': add_params, 'results': results}
def save_query(context, request): current_uid = request.authenticated_user.id query_meta = cgi.parse_qs(request.POST['query_meta']) if not 'query_name' in query_meta: return Response(u"Please specify a query name.", status=409) query_name = query_meta['query_name'][0] taken = DBSession.query(SavedQuery).filter(SavedQuery.author_id==current_uid).filter(SavedQuery.query_name==query_name).count() submit_type = request.POST['submit_type'] if submit_type == 'submit_edit': if taken: return Response(u"Name already in use: '%s'." % query_name, status=409) sq_id = query_meta['sq_id'][0] qry = DBSession.query(SavedQuery) qry = qry.filter(SavedQuery.author_id==current_uid) qry = qry.filter(SavedQuery.id==sq_id) sq = qry.one() sq.query_name = query_name return Response(u"The query has been renamed as '%s'." % query_name) elif submit_type == 'submit_delete': sq_id = query_meta['sq_id'][0] qry = DBSession.query(SavedQuery) qry = qry.filter(SavedQuery.author_id==current_uid) qry = qry.filter(SavedQuery.id==sq_id) sq = qry.one() DBSession.delete(sq) return Response(u"The saved query has been deleted.") elif submit_type == 'submit_add': if taken: return Response(u"Name already in use: '%s'." % query_name, status=409) # add sq = SavedQuery(query_name=query_name, report_name=query_meta['report_name'][0], query_string=request.POST['query_string'], author_id = current_uid) DBSession.add(sq) return Response(u"The query has been saved as '%s'." % query_name)
def report_te_detail(context, request): ids = map(int, request.params['ids'].split(',')) qry = DBSession.query(TimeEntry).filter(TimeEntry.id.in_(ids)).order_by(TimeEntry.id) projects = set(te.project for te in qry) for project in projects: if not request.has_permission('reports_all_entries_for_project', project): return HTTPForbidden() return { 'time_entries': qry.all(), 'ticket_url': ticket_url, }
def login(context, request): headers={} emails = context.profile.get('emails') if emails: try: user = DBSession.query(User).filter(User.email.in_(emails)).one() except NoResultFound: #we are in a proper domain - we don't have a user user = autoregister(context.profile) if not user.active: raise HTTPForbidden() headers = remember(request, str(user.login)) return login_success(context, request, headers=headers)
def password_reset(request): email = request.params.get('email') try: session = DBSession() user = DBSession.query(User).filter_by(email=email).one() ptoken = DBSession.query(PasswordResetToken).get(user.id) if not ptoken: ptoken = PasswordResetToken(user_id=user.id) token = str(uuid4()) ptoken.token = token session.add(ptoken) except NoResultFound: token = None if token: settings = request.registry.settings if not settings: return {'request': request, 'token': token} notify_with_password_reset(email, token) return {'request': request, 'token': token}
def generate_authz(settings): """ [groups] @admin = haren ### ### deny all but admins to the tree ### [/] * = @admin = rw ### ### allow more specific people on a per-repo basis below ### [repo1:/] ldap-user1 = rw file-user1 = rw [repo2:/] ldap-user2 = rw file-user2 = rw """ svnauth_init = settings.get('por.svn.authz_init') db = DBSession() authz = ConfigParser() authz.read(svnauth_init) users = db.query(User).all() for repo in db.query(Subversion).all(): repo_authz(repo, authz, users) authz_file = settings.get('por.svn.authz') with open(authz_file, 'wb') as configfile: authz.write(configfile) return authz
def _security_result(self): context = self.context.get_instance() result = super(ApplicationModelView, self).show() renderer = getMultiAdapter((context, self.context, self.request), IApplicationView) result.update(renderer.render()) roles = sorted(DBSession.query(Role).filter(Role.id!='administrator'), key=unicodelower) result['roles'] = roles result['permission_names'] = self.acl_permission_names result['acl'] = dict(self.acl_disabled) for acl in context.acl: result['acl'][(acl.role.id, acl.permission_name)] = (True, False) return result
def view_iterations(context, request, **params): session = DBSession() gc = session.query(GlobalConfig).get(1) docid = gc.active_iteration_url folder_iteration = get_iteration_folder(request) params.update({'context':context, 'doc_url': None, 'request':request}) if folder_iteration and docid: log.info("Iteration folder found: %s" % folder_iteration.resource_id.text) document = request.gclient['DocsClient'].get_doc(docid) params.update({'doc_url': '%s&rm=minimal' % document.get_html_link().href}) return SkinObject('view_iterations')(**params)
def check_password(environ, login, password): hash = hashlib.md5('%s:%s' % (login, password)).hexdigest() if int(time()) - cache.get(hash, 0) < TIMEOUT: return True db = DBSession() try: try: user = db.query(User).filter_by(svn_login=login).one() except NoResultFound: return None if user.check_password(password): cache[hash] = int(time()) return True else: return False finally: transaction.commit()
def search(self, customer_id, project_id, date_from, date_to): qry = DBSession.query(CustomerRequest)\ .join(Contract)\ .join(Project)\ .join(Customer)\ .filter(Project.activated == True) # noqa groupby = ['customer', 'project', 'contract', 'request'] if customer_id is not colander.null: qry = qry.filter(Project.customer_id == customer_id) if project_id is not colander.null: qry = qry.filter(Project.id == project_id) if date_from is not colander.null: qry = qry.filter(Contract.end_date >= date_from) if date_to is not colander.null: qry = qry.filter(Contract.start_date <= date_to) rows = [] id_tree = IDTree() for cr in qry: entry = { 'customer': cr.project.customer.name.strip(), 'project': cr.project.name.strip(), 'request': cr.name.strip(), 'contract': cr.contract.name.strip(), 'estimated_days_label': 'Estimated days', 'estimated_days': cr.estimation_days, 'worked_days_label': 'Worked days', 'worked_days': cr.timeentries_days } rows.append(entry) id_tree.insert_entry(groupby, cr.id, **entry) return { 'groupby': groupby, 'rows': rows, 'id_tree': id_tree, }
def time_entry_total_duration(request, date): try: date = datetime.datetime.strptime(date, '%Y-%m-%d') except ValueError: return { 'status': False, 'message': 'bad date format', } qry = DBSession.query(TimeEntry).filter(TimeEntry.date==date) qry = qry.filter(TimeEntry.author_id==request.authenticated_user.id) duration = sum((te.hours for te in qry), datetime.timedelta(0)) # we can return past timeentry descriptions here return { 'status': True, 'duration': timedelta_as_human_str(duration), }