Exemple #1
0
def dyn_usersettings_submit(param, request):
	"""
	ExtDirect method for submitting user setting section form.
	"""

	sess = DBSession()
	s = None
	if 'auth.settings' in request.session:
		s = request.session['auth.settings']
	for (ust, us) in sess \
		.query(UserSettingType, UserSetting) \
		.outerjoin(UserSetting, and_(
			UserSettingType.id == UserSetting.type_id,
			UserSetting.user_id == request.user.id
		)) \
		.filter(UserSettingType.name.in_(param.keys())):
			if ust.name in param:
				if us:
					us.value = ust.param_to_db(param[ust.name])
				else:
					us = UserSetting()
					us.user = request.user
					us.type = ust
					us.value = ust.param_to_db(param[ust.name])
					sess.add(us)
				if s:
					s[ust.name] = ust.parse_param(param[ust.name])
	if s:
		request.session['auth.settings'] = s
	return {
		'success' : True
	}
Exemple #2
0
def xop_request(ctx, request):
	# TODO: add optional redirect-to-site?
	if not ctx.can_access(request):
		raise HTTPForbidden('Access Denied')
	gw = ctx.get_gateway()
	if (not gw) or (not hasattr(gw, 'process_request')):
		raise HTTPForbidden('Access Denied')
	if not callable(gw.process_request):
		raise HTTPForbidden('Access Denied')

	try:
		sess = DBSession()
		xoplist = gw.process_request(request, sess)
	except Exception as e:
		# TODO: cancel and log?
		raise HTTPForbidden('Access Denied')
	for xop in xoplist:
		ctx.check_operation(xop)
		sess.add(xop)

	if hasattr(gw, 'generate_response') and callable(gw.generate_response):
		return gw.generate_response(request, xoplist)

	resp = Response(body='OK', content_type='text/plain', charset='UTF-8')
	return resp
Exemple #3
0
	def dav_create(self, req, name, rtype=None, props=None, data=None):
		# TODO: externalize type resolution
		user = req.user
		sess = DBSession()
		if rtype and (dprops.COLLECTION in rtype):
			obj = FileFolder(
				user_id=user.id,
				group_id=user.group_id,
				name=name,
				parent=None,
				rights=F_DEFAULT_DIRS
			)
			sess.add(obj)
		else:
			obj = File(
				user_id=user.id,
				group_id=user.group_id,
				filename=name,
				name=name,
				folder=None,
				rights=F_DEFAULT_FILES
			)
			sess.add(obj)
			if data is not None:
				# TODO: detect type of data (fd / buffer)
				obj.set_from_file(data, user, sess)
			if props and (dprops.CONTENT_TYPE in props):
				obj.mime_type = props[dprops.CONTENT_TYPE]
		if props:
			if dprops.CREATION_DATE in props:
				obj.creation_time = props[dprops.CREATION_DATE]
			if dprops.LAST_MODIFIED in props:
				obj.modification_time = props[dprops.LAST_MODIFIED]
		return (obj, False)
Exemple #4
0
def file_ul(request):
	sess = DBSession()
	try:
		ff_id = request.POST['ffid']
	except KeyError:
		ff_id = None
	folder = None
	if ff_id:
		ff_id = int(ff_id)
		folder = sess.query(FileFolder).get(ff_id)
	if folder and not folder.can_write(request.user):
		raise ValueError('Folder access denied')
	for fo in request.POST.getall('file'):
		obj = File(
			user_id=request.user.id,
			user=request.user,
			group_id=request.user.group.id,
			group=request.user.group,
			rights=F_DEFAULT_FILES
		)
		if fo.filename:
			obj.name = obj.filename = fo.filename
		obj.folder = folder
		sess.add(obj)
		obj.set_from_file(fo.file, request.user, sess)
	res = Response(html_escape(json.dumps({
		'success' : True,
		'msg'     : 'File(s) uploaded'
	}), False))
	res.headerlist.append(('X-Frame-Options', 'SAMEORIGIN'))
	return res
Exemple #5
0
def client_upload(request):
	csrf = request.POST.get('csrf', '')
	mode = request.POST.get('mode', '')
	if not mode:
		raise HTTPForbidden('Invalid upload use')
	if csrf != request.get_csrf():
		raise HTTPForbidden('Error uploading file')
	sess = DBSession()
	# FIXME: add folder cfg
	tpldef = []
	for fo in request.POST.getall('files'):
		obj = File()
		if fo.filename:
			obj.name = obj.filename = fo.filename
		sess.add(obj)
		obj.set_from_file(fo.file, None, sess)
		signal = request.run_hook('access.cl.upload', obj, mode, request, sess, tpldef)
		if True not in signal:
			tpldef.append({
				'name'  : obj.filename,
				'size'  : obj.size,
				'error' : _('Error uploading file')
			})
			sess.delete(obj)
	tpldef = { 'files' : tpldef }
	request.run_hook('access.cl.tpldef.upload', tpldef, request)
	return tpldef
Exemple #6
0
def xop_request(ctx, request):
	# TODO: add optional redirect-to-site?
	if not ctx.can_access(request):
		raise HTTPForbidden('Access Denied')
	gw = ctx.get_gateway()
	if (not gw) or (not hasattr(gw, 'process_request')):
		raise HTTPForbidden('Access Denied')
	if not callable(gw.process_request):
		raise HTTPForbidden('Access Denied')

	try:
		sess = DBSession()
		xoplist = gw.process_request(request, sess)
	except Exception as e:
		# TODO: cancel and log?
		raise HTTPForbidden('Access Denied')
	for xop in xoplist:
		ctx.check_operation(xop)
		sess.add(xop)

	if hasattr(gw, 'generate_response') and callable(gw.generate_response):
		return gw.generate_response(request, xoplist)

	resp = Response(body='OK', content_type='text/plain', charset='UTF-8')
	return resp
Exemple #7
0
def client_upload(request):
	csrf = request.POST.get('csrf', '')
	mode = request.POST.get('mode', '')
	if not mode:
		raise HTTPForbidden('Invalid upload use')
	if csrf != request.get_csrf():
		raise HTTPForbidden('Error uploading file')
	sess = DBSession()
	# FIXME: add folder cfg
	tpldef = []
	for fo in request.POST.getall('files'):
		obj = File()
		if fo.filename:
			obj.name = obj.filename = fo.filename
		sess.add(obj)
		obj.set_from_file(fo.file, None, sess)
		signal = request.run_hook('access.cl.upload', obj, mode, request, sess, tpldef)
		if True not in signal:
			tpldef.append({
				'name'  : obj.filename,
				'size'  : obj.size,
				'error' : _('Error uploading file')
			})
			sess.delete(obj)
	tpldef = { 'files' : tpldef }
	request.run_hook('access.cl.tpldef.upload', tpldef, request)
	return tpldef
Exemple #8
0
	def _wizcb_submit_hdl(wiz, em, step, act, val, req):
		xcls = cls
		if isinstance(xcls, str):
			xcls = _name_to_class(xcls)

		sess = DBSession()
		cfg = get_current_registry().settings
	
		fieldIDs = json.loads(val['field_id'])
		fieldlist = val['field']
		templateName = val['template']
		templId = val['templ_id']

		for fid in fieldIDs:
			resvalue = {'templ_id' : templId, 
						'field_id' : fid, 
						'template' : templateName, 
						'field'    : sess.query(PDNSFieldType).filter(PDNSFieldType.id==fid).first()
						}
			em = ExtModel(xcls)
			obj = xcls()
			em.set_values(obj, resvalue, req, True)
			sess.add(obj)
			sess.flush()
			print("TROLOLO")
		return {
			'do'     : 'close',
			'reload' : True
			}
Exemple #9
0
def client_issue_append(ctx, req):
    loc = req.localizer
    cfg = req.registry.settings
    if not asbool(cfg.get('netprofile.client.ticket.enabled', True)):
        raise HTTPForbidden(detail=_('Issues view is disabled'))
    errors = {}
    if ctx.archived:
        req.session.flash({
            'class':
            'danger',
            'text':
            loc.translate(
                _('This ticket is archived. You can\'t append to it.'))
        })
        return HTTPSeeOther(location=req.route_url('tickets.cl.issues',
                                                   traverse=(ctx.id, 'view')))
    if 'submit' in req.POST:
        csrf = req.POST.get('csrf', '')
        comments = req.POST.get('comments', '')
        if csrf != req.get_csrf():
            errors['csrf'] = _a('Error submitting form')
        elif not comments:
            errors['comments'] = _a('Invalid field length')
        if len(errors) == 0:
            sess = DBSession()
            ch = TicketChange()
            ch.ticket = ctx
            ch.from_client = True
            ch.show_client = True
            ch.comments = comments
            sess.add(ch)

            req.session.flash({
                'text':
                loc.translate(
                    _('Your comment was successfully appended to the issue'))
            })
            return HTTPSeeOther(location=req.route_url(
                'tickets.cl.issues', traverse=(ctx.id, 'view')))
    tpldef = {
        'crumbs': [{
            'text': loc.translate(_('My Issues')),
            'url': req.route_url('tickets.cl.issues', traverse=())
        }, {
            'text':
            loc.translate(_('View Issue #%d')) % ctx.id,
            'url':
            req.route_url('tickets.cl.issues', traverse=(ctx.id, 'view'))
        }, {
            'text':
            loc.translate(_('Append Comment to Issue #%d')) % ctx.id
        }],
        'ticket':
        ctx,
        'errors': {err: loc.translate(errors[err])
                   for err in errors}
    }
    req.run_hook('access.cl.tpldef', tpldef, req)
    req.run_hook('access.cl.tpldef.issue.append', tpldef, req)
    return tpldef
Exemple #10
0
    def _wizcb_submit_hdl(wiz, em, step, act, val, req):
        xcls = cls
        if isinstance(xcls, str):
            xcls = _name_to_class(xcls)

        sess = DBSession()

        fieldIDs = json.loads(val['field_id'])
        templateName = val['template']
        templId = val['templ_id']

        for fid in fieldIDs:
            resvalue = {
                'templ_id':
                templId,
                'field_id':
                fid,
                'template':
                templateName,
                'field':
                sess.query(PDNSFieldType).filter(
                    PDNSFieldType.id == fid).first()
            }
            em = ExtModel(xcls)
            obj = xcls()
            em.set_values(obj, resvalue, req, True)
            sess.add(obj)
            sess.flush()
            print("TROLOLO")
        return {'do': 'close', 'reload': True}
Exemple #11
0
def client_promise(ctx, request):
	loc = get_localizer(request)
	csrf = request.POST.get('csrf', '')
	diff = request.POST.get('diff', '')

	if 'submit' in request.POST:
		sess = DBSession()
		if csrf != request.get_csrf():
			request.session.flash({
				'text' : loc.translate(_('Error submitting form')),
				'class' : 'danger'
			})
			return HTTPSeeOther(location=request.route_url('stashes.cl.accounts', traverse=()))
		fp = FuturePayment()
		fp.stash = ctx
		fp.entity = request.user.parent
		fp.origin = FuturePaymentOrigin.user
		fp.difference = diff
		sess.add(fp)
		request.session.flash({
			'text' : loc.translate(_('Successfully added new promised payment'))
		})
		return HTTPSeeOther(location=request.route_url('stashes.cl.accounts', traverse=()))

	request.session.flash({
		'text' : loc.translate(_('Error submitting form')),
		'class' : 'danger'
	})

	return HTTPSeeOther(location=request.route_url('stashes.cl.accounts', traverse=()))
Exemple #12
0
def dyn_usersettings_submit(param, request):
	"""
	ExtDirect method for submitting user settings form.
	"""

	sess = DBSession()
	mmgr = request.registry.getUtility(IModuleManager)
	cached = None
	if 'auth.settings' in request.session:
		cached = request.session['auth.settings']

	all_settings = mmgr.get_settings('user')
	values = dict(
		(s.name, s)
		for s
		in sess.query(UserSetting).filter(UserSetting.user == request.user)
	)

	for moddef, sections in all_settings.items():
		for sname, section in sections.items():
			if section.read_cap and not request.has_permission(section.read_cap):
				continue
			for setting_name, setting in section.items():
				if setting.read_cap and not request.has_permission(setting.read_cap):
					continue
				if setting.write_cap and not request.has_permission(setting.write_cap):
					continue
				fullname = '%s.%s.%s' % (moddef, sname, setting_name)
				old_value = setting.default
				if fullname in values:
					old_value = setting.parse_param(values[fullname].value)
				new_value = old_value
				if fullname in param:
					new_value = setting.parse_param(param[fullname])

				if new_value == setting.default:
					if fullname in values:
						sess.delete(values[fullname])
						del values[fullname]
					if cached:
						cached[fullname] = setting.default
					continue
				if new_value != old_value:
					if fullname in values:
						values[fullname].value = setting.format_param(new_value)
					else:
						values[fullname] = UserSetting(
							user=request.user,
							name=fullname,
							value=setting.format_param(new_value)
						)
						sess.add(values[fullname])
					if cached:
						cached[fullname] = new_value

	if cached:
		request.session['auth.settings'] = cached
	return { 'success' : True }
Exemple #13
0
	def clone(self, req, ctx, recurse=True, _flush=True):
		sess = DBSession()
		obj = ctx.dav_clone(req)
		sess.add(obj)
		if recurse:
			for ch in self.children(ctx):
				newch = self.clone(req, ch, recurse, False)
				obj.dav_append(req, newch, ch.__name__)
		return obj
Exemple #14
0
def _wizcb_future_submit(wiz, em, step, act, val, req):
	sess = DBSession()
	obj = FuturePayment()
	em.set_values(obj, val, req, True)
	sess.add(obj)
	return {
		'do'     : 'close',
		'reload' : True
	}
Exemple #15
0
 def clone(self, req, ctx, recurse=True, _flush=True):
     sess = DBSession()
     obj = ctx.dav_clone(req)
     sess.add(obj)
     if recurse:
         for ch in self.children(ctx):
             newch = self.clone(req, ch, recurse, False)
             obj.dav_append(req, newch, ch.__name__)
     return obj
Exemple #16
0
	def dav_sync_token(self):
		varname = 'DAV:SYNC:ABC:%u' % (self.user.id,)
		try:
			var = NPVariable.get_ro(varname)
		except NoResultFound:
			sess = DBSession()
			cvar = NPVariable.get_ro('DAV:SYNC:PLUG:UABOOKS')
			var = NPVariable(name=varname, integer_value=cvar.integer_value)
			sess.add(var)
		return var.integer_value
Exemple #17
0
 def _wizcb_aent_submit(wiz, em, step, act, val, req):
     sess = DBSession()
     em = ExtModel(AccessEntity)
     obj = AccessEntity()
     # Work around field name clash
     if 'state' in val:
         del val['state']
     em.set_values(obj, val, req, True)
     sess.add(obj)
     return {'do': 'close', 'reload': True}
Exemple #18
0
def _cal_events_create(params, req):
	sess = DBSession()
	ev = Event()
	ev.creation_time = dt.datetime.now()
	if not _ev_set(sess, ev, params, req):
		del ev
		return False
	ev.user = req.user
	sess.add(ev)
	return True
Exemple #19
0
def _wizcb_stashio_submit(wiz, em, step, act, val, req):
    sess = DBSession()
    obj = StashIO()
    em.set_values(obj, val, req, True)
    sess.add(obj)
    if obj.difference:
        stash = sess.query(Stash).get(obj.stash_id)
        if stash:
            stash.amount += obj.difference
    return {"do": "close", "reload": True}
Exemple #20
0
def _check_session(event):
    request = event.request
    if not isinstance(event.policy, SessionAuthenticationPolicy):
        return
    user = request.user
    route_name = None
    if request.matched_route:
        route_name = request.matched_route.name
        # TODO: unhardcode excluded routes
        if route_name in {'core.login',
                          'debugtoolbar',
                          'core.logout.direct',
                          'core.wellknown'}:
            return
    if not user:
        _goto_login(request)
    settings = request.registry.settings

    skey = settings.get('redis.sessions.cookie_name')
    if not skey:
        skey = settings.get('session.key')
    assert skey is not None, 'Session cookie name does not exist'

    sess = DBSession()
    sname = request.cookies.get(skey)
    if sname:
        now = dt.datetime.now()
        oldsess = True

        try:
            npsess = sess.query(NPSession).filter(
                    NPSession.session_name == sname).one()
        except NoResultFound:
            npsess = user.generate_session(request, sname, now)
            if npsess is None:
                _goto_login(request)
            oldsess = False
            sess.add(npsess)

        if oldsess and not npsess.check_request(request, now):
            _goto_login(request)

        pw_age = request.session.get('sess.pwage', 'ok')
        if pw_age == 'force':
            # TODO: unhardcode excluded routes
            if route_name not in {'extrouter',
                                  'extapi',
                                  'core.home',
                                  'core.js.webshell'}:
                _goto_login(request)

        npsess.update_time(now)
        request.np_session = npsess
    else:
        _goto_login(request)
Exemple #21
0
	def lock(self):
		req = self.req
		ctx = req.context
		req.dav.user_acl(req, ctx, dprops.ACL_WRITE_CONTENT)

		path = req.dav.ctx_path(ctx)
		str_path = '/'.join(path)
		locks = req.dav.get_locks(path)
		lock = None

		if req.body:
			# New lock
			oldlock = None
			for oldlock in locks:
				if oldlock.scope == DAVLock.SCOPE_EXCLUSIVE:
					raise dav.DAVConflictingLockError(lock=oldlock)
			lreq = dav.DAVLockRequest(req)
			lock = lreq.get_lock(DAVLock)
			if oldlock and (lock.scope != DAVLock.SCOPE_SHARED):
				raise dav.DAVConflictingLockError(lock=oldlock)
			lock.uri = str_path
			lock.depth = req.dav.get_http_depth(req)
			if isinstance(ctx, File):
				lock.file = ctx
		else:
			# Refreshing old lock
			ifh = self.get_if()
			if not ifh:
				raise dav.DAVBadRequestError('No If: headers supplied in LOCK refresh request.')
			try:
				for oldlock in locks:
					for ifobj in ifh:
						for token in ifobj['tokens']:
							if oldlock.test_token(token['tok']):
								lock = oldlock
								raise StopIteration
			except StopIteration:
				pass
			if lock is None:
				if len(locks):
					raise dav.DAVLockedError('Resource is locked.', lock=locks[0])
				else:
					raise dav.DAVBadRequestError('New LOCK request must be accompanied by a request body.')

		lock.refresh(req.dav.get_http_timeout(req))

		if req.body:
			sess = DBSession()
			sess.add(lock)

		resp = dav.DAVLockResponse(lock=lock, request=req, new_file=False)
		resp.make_body()
		return resp
Exemple #22
0
    def apply_async(self, entry, producer=None, advance=True, **kwargs):
        res = super(Scheduler, self).apply_async(entry, producer,
                                                 advance, **kwargs)
        model = entry.model

        if model.log_executions:
            sess = DBSession()
            log = model.new_result(res)
            sess.add(log)
            self._pending_results[log.celery_id] = res
            transaction.commit()

        return res
Exemple #23
0
 def setUp(self):
     self.config = testing.setUp()
     from sqlalchemy import create_engine
     engine = create_engine('sqlite://')
     from .models import (
         Base,
         MyModel,
         )
     DBSession.configure(bind=engine)
     Base.metadata.create_all(engine)
     with transaction.manager:
         model = MyModel(name='one', value=55)
         DBSession.add(model)
Exemple #24
0
	def _wizcb_aent_submit(wiz, em, step, act, val, req):
		sess = DBSession()
		em = ExtModel(AccessEntity)
		obj = AccessEntity()
		# Work around field name clash
		if 'state' in val:
			del val['state']
		em.set_values(obj, val, req, True)
		sess.add(obj)
		return {
			'do'     : 'close',
			'reload' : True
		}
Exemple #25
0
 def setUp(self):
     self.config = testing.setUp()
     from sqlalchemy import create_engine
     engine = create_engine('sqlite://')
     from .models import (
         Base,
         MyModel,
     )
     DBSession.configure(bind=engine)
     Base.metadata.create_all(engine)
     with transaction.manager:
         model = MyModel(name='one', value=55)
         DBSession.add(model)
Exemple #26
0
	def _wizcb_submit_hdl(wiz, em, step, act, val, req):
		xcls = cls
		if isinstance(xcls, str):
			xcls = _name_to_class(xcls)
		sess = DBSession()
		em = ExtModel(xcls)
		obj = xcls()
		em.set_values(obj, val, req, True)
		sess.add(obj)
		return {
			'do'     : 'close',
			'reload' : True
		}
Exemple #27
0
def ff_tree_create(params, request):
	recs = []
	sess = DBSession()
	user = request.user
	total = 0
	for rec in params.get('records', ()):
		ff_name = rec.get('text')
		ff_parent = rec.get('parentId')
		# TODO: support changing uid/gid and rights, maybe?
		if not ff_name:
			raise ValueError('Empty folder names are not supported')
		if ff_parent and (ff_parent != 'root'):
			ff_parent = int(ff_parent)
		else:
			ff_parent = None

		ff = FileFolder(user=user, group=user.group)
		ff.name = ff_name
		root_ff = user.group.effective_root_folder
		if root_ff and (ff_parent is None):
			raise ValueError('Folder access denied')
		if ff_parent:
			ffp = sess.query(FileFolder).get(ff_parent)
			if ffp is None:
				raise KeyError('Unknown parent folder ID %d' % ff_parent)
			if (not ffp.can_write(user)) or (not ffp.can_traverse_path(user)):
				raise ValueError('Folder access denied')
			if root_ff and (not ffp.is_inside(root_ff)):
				raise ValueError('Folder access denied')
			ff.parent = ffp
		elif not user.root_writable:
			raise ValueError('Folder access denied')

		sess.add(ff)
		sess.flush()
		recs.append({
			'id'             : str(ff.id),
			'parentId'       : str(ff.parent.id) if ff.parent else 'root',
			'text'           : ff.name,
			'xhandler'       : 'NetProfile.controller.FileBrowser',
			'allow_read'     : ff.can_read(user),
			'allow_write'    : ff.can_write(user),
			'allow_traverse' : ff.can_traverse(user),
			'parent_write'   : ff.parent.can_write(user) if ff.parent else user.root_writable
		})
		total += 1
	return {
		'success' : True,
		'records' : recs,
		'total'   : total
	}
Exemple #28
0
def _check_session(event):
    request = event.request
    if not isinstance(event.policy, SessionAuthenticationPolicy):
        return
    user = request.user
    route_name = None
    if request.matched_route:
        route_name = request.matched_route.name
        # TODO: unhardcode excluded routes
        if route_name in ('core.login', 'debugtoolbar', 'core.logout.direct',
                          'core.wellknown'):
            return
    if not user:
        _goto_login(request)
    settings = request.registry.settings

    skey = settings.get('redis.sessions.cookie_name')
    if not skey:
        skey = settings.get('session.key')
    assert skey is not None, 'Session cookie name does not exist'

    sess = DBSession()
    sname = request.cookies.get(skey)
    if sname:
        now = dt.datetime.now()
        oldsess = True

        try:
            npsess = sess.query(NPSession).filter(
                NPSession.session_name == sname).one()
        except NoResultFound:
            npsess = user.generate_session(request, sname, now)
            if npsess is None:
                _goto_login(request)
            oldsess = False
            sess.add(npsess)

        if oldsess and (not npsess.check_request(request, now)):
            _goto_login(request)

        pw_age = request.session.get('sess.pwage', 'ok')
        if pw_age == 'force':
            # TODO: unhardcode excluded routes
            if route_name not in ('extrouter', 'extapi', 'core.home',
                                  'core.js.webshell'):
                _goto_login(request)

        npsess.update_time(now)
        request.np_session = npsess
    else:
        _goto_login(request)
Exemple #29
0
def _wizcb_stashio_submit(wiz, step, act, val, req):
	sess = DBSession()
	em = ExtModel(StashIO)
	obj = StashIO()
	em.set_values(obj, val, req, True)
	sess.add(obj)
	if obj.difference:
		stash = sess.query(Stash).get(obj.stash_id)
		if stash:
			stash.amount += obj.difference
	return {
		'do'     : 'close',
		'reload' : True
	}
Exemple #30
0
def client_issue_append(ctx, req):
	loc = req.localizer
	cfg = req.registry.settings
	if not asbool(cfg.get('netprofile.client.ticket.enabled', True)):
		raise HTTPForbidden(detail=_('Issues view is disabled'))
	errors = {}
	if ctx.archived:
		req.session.flash({
			'class' : 'danger',
			'text'  : loc.translate(_('This ticket is archived. You can\'t append to it.'))
		})
		return HTTPSeeOther(location=req.route_url('tickets.cl.issues', traverse=(ctx.id, 'view')))
	if 'submit' in req.POST:
		csrf = req.POST.get('csrf', '')
		comments = req.POST.get('comments', '')
		if csrf != req.get_csrf():
			errors['csrf'] = _a('Error submitting form')
		elif not comments:
			errors['comments'] = _a('Invalid field length')
		if len(errors) == 0:
			sess = DBSession()
			ch = TicketChange()
			ch.ticket = ctx
			ch.from_client = True
			ch.show_client = True
			ch.comments = comments
			sess.add(ch)

			req.session.flash({
				'text' : loc.translate(_('Your comment was successfully appended to the issue'))
			})
			return HTTPSeeOther(location=req.route_url('tickets.cl.issues', traverse=(ctx.id, 'view')))
	tpldef = {
		'crumbs' : [{
			'text' : loc.translate(_('My Issues')),
			'url'  : req.route_url('tickets.cl.issues', traverse=())
		}, {
			'text' : loc.translate(_('View Issue #%d')) % ctx.id,
			'url'  : req.route_url('tickets.cl.issues', traverse=(ctx.id, 'view'))
		}, {
			'text' : loc.translate(_('Append Comment to Issue #%d')) % ctx.id
		}],
		'ticket' : ctx,
		'errors' : {err: loc.translate(errors[err]) for err in errors}
	}
	req.run_hook('access.cl.tpldef', tpldef, req)
	req.run_hook('access.cl.tpldef.issue.append', tpldef, req)
	return tpldef
Exemple #31
0
def dyn_globalsettings_submit(param, request):
	"""
	ExtDirect method for submitting global settings form.
	"""

	sess = DBSession()
	mmgr = request.registry.getUtility(IModuleManager)

	all_settings = mmgr.get_settings('global')
	values = dict(
		(s.name, s)
		for s
		in sess.query(GlobalSetting)
	)

	for moddef, sections in all_settings.items():
		for sname, section in sections.items():
			if section.read_cap and not request.has_permission(section.read_cap):
				continue
			for setting_name, setting in section.items():
				if setting.read_cap and not request.has_permission(setting.read_cap):
					continue
				if setting.write_cap and not request.has_permission(setting.write_cap):
					continue
				fullname = '%s.%s.%s' % (moddef, sname, setting_name)
				old_value = setting.default
				if fullname in values:
					old_value = setting.parse_param(values[fullname].value)
				new_value = old_value
				if fullname in param:
					new_value = setting.parse_param(param[fullname])

				# We don't delete global settings if their values are default
				# ones because we need the values in other places: procedures,
				# SQL events, triggers etc.
				if new_value != old_value:
					if fullname in values:
						values[fullname].value = setting.format_param(new_value)
					else:
						values[fullname] = GlobalSetting(
							name=fullname,
							value=setting.format_param(new_value)
						)
						sess.add(values[fullname])

	return { 'success' : True }
Exemple #32
0
def _wizcb_stashio_submit(wiz, em, step, act, val, req):
	sess = DBSession()
	obj = StashIO()
	em.set_values(obj, val, req, True)
	sess.add(obj)
	stash = None
	if obj.difference:
		stash = sess.query(Stash).get(obj.stash_id)
		if stash:
			stash.amount += obj.difference
	ret = {
		'do'     : 'close',
		'reload' : True
	}
	if stash is not None:
		ret['affects'] = (
			('stashes', 'StashIO'),
			('stashes', 'Stash', obj.stash_id),
		)
	return ret
Exemple #33
0
def client_promise(ctx, request):
    loc = get_localizer(request)
    csrf = request.POST.get("csrf", "")
    diff = request.POST.get("diff", "")

    if "submit" in request.POST:
        sess = DBSession()
        if csrf != request.get_csrf():
            request.session.flash({"text": loc.translate(_("Error submitting form")), "class": "danger"})
            return HTTPSeeOther(location=request.route_url("stashes.cl.accounts", traverse=()))
        fp = FuturePayment()
        fp.stash = ctx
        fp.entity = request.user.parent
        fp.origin = FuturePaymentOrigin.user
        fp.difference = diff
        sess.add(fp)
        request.session.flash({"text": loc.translate(_("Successfully added new promised payment"))})
        return HTTPSeeOther(location=request.route_url("stashes.cl.accounts", traverse=()))

    request.session.flash({"text": loc.translate(_("Error submitting form")), "class": "danger"})

    return HTTPSeeOther(location=request.route_url("stashes.cl.accounts", traverse=()))
Exemple #34
0
def client_oauth_register(request, regdict):
	nxt = request.route_url('access.cl.home')
	loc = get_localizer(request)
	headers = None
	#if authenticated_userid(request):
	#	 return HTTPSeeOther(location=nxt)

	cfg = request.registry.settings
	rate_id = int(cfg.get('netprofile.client.registration.rate_id', 1))
	state_id = int(cfg.get('netprofile.client.registration.state_id', 1))

	errors = {}
	sess = DBSession()

	login = regdict.get('username', None)
	passwd = regdict.get('password', None)
	email = regdict.get('email', None)
	name_family = regdict.get('familyname', '')
	name_given = regdict.get('givenname', '')

	### !!!!! What if user changes his password in out database?!
	if login is not None and passwd is not None:
		q = sess.query(AccessEntity).filter(AccessEntity.nick == login, AccessEntity.access_state != AccessState.block_inactive.value)
		if q is not None:
			for user in q:
				if user.password == passwd:
					headers = remember(request, login)
					return headers

	if headers is None:
		ent = PhysicalEntity()
		ent.nick = login
		ent.email = email
		ent.name_family = name_family
		ent.name_given = name_given
		ent.state_id = state_id

		stash = Stash()
		stash.entity = ent
		stash.name = loc.translate(_('Primary Account'))

		acc = AccessEntity()
		acc.nick = login
		acc.password = passwd
		acc.stash = stash
		acc.rate_id = rate_id
		acc.state_id = state_id
		ent.children.append(acc)
		
		sess.add(ent)
		sess.add(stash)
		sess.add(acc)
		sess.flush()
		headers = remember(request, login)
		return headers

	else:
		return False
Exemple #35
0
def client_promise(ctx, request):
    loc = request.localizer
    csrf = request.POST.get('csrf', '')
    diff = request.POST.get('diff', '')

    if 'submit' in request.POST:
        sess = DBSession()
        if csrf != request.get_csrf():
            request.session.flash({
                'text':
                loc.translate(_('Error submitting form')),
                'class':
                'danger'
            })
            return HTTPSeeOther(
                location=request.route_url('stashes.cl.accounts', traverse=()))
        fp = FuturePayment()
        fp.stash = ctx
        fp.entity = request.user.parent
        fp.origin = FuturePaymentOrigin.user
        fp.difference = diff
        sess.add(fp)
        request.session.flash({
            'text':
            loc.translate(_('Successfully added new promised payment'))
        })
        return HTTPSeeOther(
            location=request.route_url('stashes.cl.accounts', traverse=()))

    request.session.flash({
        'text': loc.translate(_('Error submitting form')),
        'class': 'danger'
    })

    return HTTPSeeOther(
        location=request.route_url('stashes.cl.accounts', traverse=()))
Exemple #36
0
def _auth_to_db(event):
	request = event.request

	if not request.matched_route:
		return
	rname = request.matched_route.name
	if rname[0] == '_':
		return
	if request.method == 'OPTIONS':
		return

	sess = DBSession()
	user = request.user

	if user:
		sess.execute(SetVariable('accessuid', user.id))
		sess.execute(SetVariable('accessgid', user.group_id))
		sess.execute(SetVariable('accesslogin', user.login))

		skey = request.registry.settings.get('redis.sessions.cookie_name')
		if not skey:
			skey = request.registry.settings.get('session.key')
		assert skey is not None, 'Session cookie name does not exist'
		sname = request.cookies.get(skey)
		if sname:
			try:
				npsess = sess.query(NPSession).filter(NPSession.session_name == sname).one()
				npsess.update_time()
			except NoResultFound:
				npsess = user.generate_session(request, sname)
				sess.add(npsess)
			request.np_session = npsess
	else:
		sess.execute(SetVariable('accessuid', 0))
		sess.execute(SetVariable('accessgid', 0))
		sess.execute(SetVariable('accesslogin', '[GUEST]'))
Exemple #37
0
def createMailBox(request):
	loc = get_localizer(request)
	cfg = request.registry.settings
	sess = DBSession()
	errmess = None
	csrf = request.POST.get('csrf', '')
	access_user = sess.query(AccessEntity).filter_by(nick=str(request.user)).first()
	admindomains = sess.query(PostfixDomainAdmins).filter_by(username=str(request.user))

	if csrf != request.get_csrf():
		request.session.flash({
				'text' : loc.translate(_('Error submitting form')),
				'class' : 'danger'
				})
		return HTTPSeeOther(location=request.route_url('postfix.cl.mail'))
	else:
		domain_name = request.POST.get('mbDomain', None)
		domain_descr = request.POST.get('mbDomainDescription', None)
		username = request.POST.get('mbUsername', None)
		mailbox_name = request.POST.get('mbName', None)
		mailbox_password = request.POST.get('mbPassword', None)
		if domain_name and username:
			if username == access_user.nick:
				if mailbox_name and mailbox_password:
					newmailbox = PostfixMailbox(
						username=username, 
						password=mailbox_password, 
						name=mailbox_name, 
						domain=domain_name
						)
					sess.add(newmailbox)
					sess.flush()
				else:
					if domain_name not in [ad.username for ad in admindomains]:
						newdomainadmin = PostfixDomainAdmins(username=username, domain=domain_name) 
						newdomain = PostfixDomain(domain=domain_name, description=domain_descr)
						sess.add(newdomainadmin)
						sess.add(newdomain)
						sess.flush()

	return HTTPSeeOther(location=request.route_url('postfix.cl.mail'))
Exemple #38
0
	def notfound_lock(self):
		# TODO: DRY, unify this with normal lock
		# TODO: ACL
		req = self.req

		path = req.dav.path(req.url)
		str_path = '/'.join(path)
		locks = req.dav.get_locks(path)
		lock = None

		if req.body:
			# New lock
			oldlock = None
			for oldlock in locks:
				if oldlock.scope == DAVLock.SCOPE_EXCLUSIVE:
					raise dav.DAVConflictingLockError(lock=oldlock)
			lreq = dav.DAVLockRequest(req)
			lock = lreq.get_lock(DAVLock)
			if oldlock and (lock.scope != DAVLock.SCOPE_SHARED):
				raise dav.DAVConflictingLockError(lock=oldlock)
			lock.uri = str_path
			lock.depth = req.dav.get_http_depth(req)
		else:
			# Refreshing old lock
			ifh = self.get_if()
			if not ifh:
				raise dav.DAVBadRequestError('No If: headers supplied in LOCK refresh request.')
			try:
				for oldlock in locks:
					for ifobj in ifh:
						for token in ifobj['tokens']:
							if oldlock.test_token(token['tok']):
								lock = oldlock
								raise StopIteration
			except StopIteration:
				pass
			if lock is None:
				if len(locks):
					raise dav.DAVLockedError('Resource is locked.', lock=locks[0])
				else:
					raise dav.DAVBadRequestError('New LOCK request must be accompanied by a request body.')

		if not req.view_name:
			# TODO: find proper DAV error to put here
			raise Exception('Invalid file name (empty file names are not allowed).')
		if len(req.subpath) > 0:
			# TODO: find proper DAV error to put here
			raise Exception('Invalid file name (slashes are not allowed).')
		req.dav.user_acl(req, req.context, dprops.ACL_BIND)
		creator = getattr(req.context, 'dav_create', None)
		if creator is None:
			raise dav.DAVNotImplementedError('Unable to create child node.')
		with io.BytesIO(b'') as bio:
			obj, modified = creator(req, req.view_name, None, None, bio) # TODO: handle IOErrors, handle non-seekable request body
		if isinstance(obj, File):
			lock.file = obj
		lock.refresh(req.dav.get_http_timeout(req))

		if req.body:
			sess = DBSession()
			sess.add(lock)

		resp = dav.DAVLockResponse(lock=lock, request=req, new_file=True)
		resp.make_body()
		return resp
Exemple #39
0
def client_issue_new(ctx, req):
    loc = req.localizer
    cfg = req.registry.settings
    if not asbool(cfg.get('netprofile.client.ticket.enabled', True)):
        raise HTTPForbidden(detail=_('Issues view is disabled'))
    origin_id = int(cfg.get('netprofile.client.ticket.origin_id', 0))
    user_id = int(cfg.get('netprofile.client.ticket.assign_uid', 0))
    group_id = int(cfg.get('netprofile.client.ticket.assign_gid', 0))
    errors = {}
    sess = DBSession()
    ent = req.user.parent
    states = sess.query(TicketState)\
     .filter(TicketState.is_start == True, TicketState.allow_client == True)
    if 'submit' in req.POST:
        csrf = req.POST.get('csrf', '')
        name = req.POST.get('name', '')
        descr = req.POST.get('descr', '')
        state = int(req.POST.get('state', 0))
        if csrf != req.get_csrf():
            errors['csrf'] = _a('Error submitting form')
        else:
            l = len(name)
            if (l == 0) or (l > 254):
                errors['name'] = _a('Invalid field length')
            for s in states:
                if s.id == state:
                    state = s
                    break
            else:
                errors['state'] = _('Invalid issue type')
        if len(errors) == 0:
            tkt = Ticket()
            tkt.name = name
            tkt.state = state
            tkt.entity = ent
            tkt.show_client = True
            if descr:
                tkt.description = descr
            if origin_id:
                tkt.origin_id = origin_id
            if user_id:
                tkt.assigned_user_id = user_id
            if group_id:
                tkt.assigned_group_id = group_id
            sess.add(tkt)
            sess.flush()

            req.session.flash(
                {'text': loc.translate(_('New issue successfully created'))})
            return HTTPSeeOther(location=req.route_url(
                'tickets.cl.issues', traverse=(tkt.id, 'view')))
    tpldef = {
        'states':
        states,
        'crumbs': [{
            'text': loc.translate(_('My Issues')),
            'url': req.route_url('tickets.cl.issues', traverse=())
        }, {
            'text': loc.translate(_('New Issue'))
        }],
        'errors': {err: loc.translate(errors[err])
                   for err in errors}
    }
    req.run_hook('access.cl.tpldef', tpldef, req)
    req.run_hook('access.cl.tpldef.issue.new', tpldef, req)
    return tpldef
Exemple #40
0
def create_record(request):
    loc = get_localizer(request)
    cfg = request.registry.settings
    sess = DBSession()
    csrf = request.POST.get('csrf', '')
    if csrf != request.get_csrf():
        request.session.flash({
                'text': loc.translate(_('Error submitting form')),
                'class': 'danger'
                })
        return HTTPSeeOther(location=request.route_url('pdns.cl.domains'))
    else:
        # get fields related to obtained type and create corresponding fields
        rectype = request.POST.get('type', None)
        if rectype != "record" and rectype != "newdomain":
            # so we are creating some service, domain, mailserver, etc
            currentvalues = {}
            hostname = request.POST.get('hostName', None)
            currentvalues['name'] = hostname

            # check if we already have such domain name,
            # if so, return a warning111
            # domain_clash = sess.query(func.count('*'))\
            # 		.select_from(PDNSDomain)\
            # 		.filter(PDNSDomain.name == hostname)\
            # 		.scalar()
            # if domain_clash > 0:
            # 	request.session.flash({
            # 		'text' : loc.translate(_('Domain already exists, please add corresponding records manually')),
            # 		'class' : 'danger'
            # 		})
            # 	return HTTPSeeOther(location=request.route_url('pdns.cl.domains'))
            # if no same domain name warinigs returned, we can continue processing our data
            # host record

            # domaintype = request.POST.get('hosttype', 'NATIVE')
            domainip = request.POST.get('hostValue', None)
            # if IP-address is not specified, raise a warning
            if not domainip:
                request.session.flash({
                        'text': loc.translate(
                            _('You need to specify IP address')
                         ),
                        'class': 'danger'
                        })
                return HTTPSeeOther(
                    location=request.route_url('pdns.cl.domains')
                )
            currentvalues['domainip'] = domainip

            # get the nameservers from the config
            ns1 = cfg.get('netprofile.client.pdns.ns1')
            ns2 = cfg.get('netprofile.client.pdns.ns2')

            currentvalues['nameserver1'] = ns1
            currentvalues['nameserver2'] = ns2

            currentvalues['ttl'] = 3600
            currentvalues['prefix'] = ''
            currentvalues['name'] = hostname
            # and here we create our something. 
            # as we have new service type, rectype, we can get all related fields

            newdomain = sess.query(PDNSDomain).filter(
                PDNSDomain.name == hostname
            ).first()
            service_template = sess.query(PDNSTemplateType).filter(
                PDNSTemplateType.name == rectype
            ).join(PDNSTemplate).all()

            # default values are stored as JSON in the database
            # if default value is a key of a dictionnary, lookup it's value in the currentvalues dict
            # else it is a complex value with prefix and value from currentvalues dict, as in jabber contents field
            # some examples:
            # Domain NS Record: {"ttl":"86400",  "content":"nameserver2"}
            # Mailserver CNAME Record: {"ttl":"3600",  "prefix":"mail", "content":"name"}
            # Jabber SRV Record: {"ttl":"3600",  "prefix":"_xmpp-client._tcp", "content":["5 0 5222 jabber", "name"]}
            for t in service_template:
                for f in t.template_fields:
                    defvalues = json.loads(f.defaultvalues)
                    newname = currentvalues['name']
                    if 'prefix' in defvalues.keys():
                        newname = "{0}.{1}".format(
                            defvalues['prefix'],
                            newname
                        )
                    newrtype = f.field.name

                    defcontent = defvalues.get('content', None)
                    if defcontent:
                        if not isinstance(defcontent, list):
                            newcontent = currentvalues.get(defcontent, None)
                        else:
                            def_in_cur = [
                                defcontent.index(k) for k in filter(
                                    lambda x: x in defcontent,
                                    currentvalues.keys()
                                )
                            ]
                            for i in def_in_cur:
                                defcontent[i] = currentvalues[defcontent[i]]
                            newcontent = ".".join(defcontent)
                    else:
                        newcontent = ''

                    newttl = int(defvalues.get('ttl', 3600))

                    newRecord = PDNSRecord(
                        domain=newdomain,
                        name=newname,
                        rtype=newrtype,
                        content=newcontent,
                        ttl=newttl,
                    )
                    sess.add(newRecord)
                    sess.flush()
        elif rectype == "record":
            ttl = request.POST.get('ttl', None)
            if ttl == "":
                ttl = None
            prio = request.POST.get('prio', None)
            if prio == "":
                prio = None
            newrecord = PDNSRecord(
                domain_id=int(request.POST.get('domainid', None)),
                name=request.POST.get('name', None),
                rtype=request.POST.get('rtype', None),
                content=request.POST.get('content', None),
                ttl=ttl,
                prio=prio
            )
            sess.add(newrecord)
            sess.flush()
        elif rectype == "newdomain":
            hostname = request.POST.get('hostName', '127.0.0.1')
            hosttype = request.POST.get('hostType', 'NATIVE')
            domain_clash = sess.query(func.count('*'))\
                .select_from(PDNSDomain)\
                .filter(PDNSDomain.name == hostname)\
                .scalar()
            if domain_clash > 0:
                request.session.flash({
                        'text': loc.translate(
                            _('Domain already exists,'
                                ' please add corresponding records manually')
                        ),
                        'class': 'danger'
                        })
                return HTTPSeeOther(
                    location=request.route_url('pdns.cl.domains')
                )

            newdomain = PDNSDomain(
                name=hostname,
                master='',
                dtype=hosttype,
                account=request.POST.get('user', None)
                )
            sess.add(newdomain)
            sess.flush()

    return HTTPSeeOther(location=request.route_url(
        'pdns.cl.domains',
        _query=(('created', 1),)
        ))
Exemple #41
0
def client_register(request):
	if authenticated_userid(request):
		return HTTPSeeOther(location=request.route_url('access.cl.home'))
	cur_locale = locale_neg(request)
	loc = request.localizer
	cfg = request.registry.settings
	comb_js = asbool(cfg.get('netprofile.client.combine_js', False))
	can_reg = asbool(cfg.get('netprofile.client.registration.enabled', False))
	must_verify = asbool(cfg.get('netprofile.client.registration.verify_email', True))
	must_recaptcha = asbool(cfg.get('netprofile.client.registration.recaptcha.enabled', False))
	min_pwd_len = int(cfg.get('netprofile.client.registration.min_password_length', 8))
	rate_id = int(cfg.get('netprofile.client.registration.rate_id', 1))
	state_id = int(cfg.get('netprofile.client.registration.state_id', 1))
	maillogin = asbool(cfg.get('netprofile.client.email_as_username', False))
	csrf = request.POST.get('csrf', '')
	errors = {}
	if not can_reg:
		return HTTPSeeOther(location=request.route_url('access.cl.login'))
	if must_recaptcha:
		rc_private = cfg.get('netprofile.client.recaptcha.private_key')
		rc_public = cfg.get('netprofile.client.recaptcha.public_key')
		if (not rc_private) or (not rc_public):
			# TODO: log missing reCAPTCHA keys
			must_recaptcha = False
	if 'submit' in request.POST:
		sess = DBSession()
		if csrf != request.get_csrf():
			errors['csrf'] = _('Error submitting form')
		elif must_recaptcha:
			try:
				rcresp = verify_recaptcha(rc_private, request)
			except ValueError as e:
				errors['recaptcha'] = str(e)
			else:
				if rcresp and not rcresp.valid:
					errors['recaptcha'] = rcresp.text()
		if len(errors) == 0:
			login = request.POST.get('user', '')
			passwd = request.POST.get('pass', '')
			passwd2 = request.POST.get('pass2', '')
			email = request.POST.get('email', '')
			name_family = request.POST.get('name_family', '')
			name_given = request.POST.get('name_given', '')
			name_middle = request.POST.get('name_middle', '')
			l = len(email)
			if (l == 0) or (l > 254):
				errors['email'] = _('Invalid field length')
			elif not _re_email.match(email):
				errors['email'] = _('Invalid e-mail format')
			if maillogin:
				login = email
			else:
				l = len(login)
				if (l == 0) or (l > 254):
					errors['user'] = _('Invalid field length')
				elif _re_login.match(login):
					errors['user'] = _('Invalid character used in username')
			l = len(passwd)
			if l < min_pwd_len:
				errors['pass'] = _('Password is too short')
			elif l > 254:
				errors['pass'] = _('Password is too long')
			if passwd != passwd2:
				errors['pass2'] = _('Passwords do not match')
			l = len(name_family)
			if (l == 0) or (l > 254):
				errors['name_family'] = _('Invalid field length')
			l = len(name_given)
			if (l == 0) or (l > 254):
				errors['name_given'] = _('Invalid field length')
			l = len(name_middle)
			if l > 254:
				errors['name_middle'] = _('Invalid field length')
			if 'user' not in errors:
				# XXX: currently we check across all entity types.
				login_clash = sess.query(func.count('*'))\
					.select_from(Entity)\
					.filter(Entity.nick == login)\
					.scalar()
				if login_clash > 0:
					errors['user'] = _('This username is already taken')
		if len(errors) == 0:
			ent = PhysicalEntity()
			ent.nick = login
			ent.email = email
			ent.name_family = name_family
			ent.name_given = name_given
			if name_middle:
				ent.name_middle = name_middle
			ent.state_id = state_id

			stash = Stash()
			stash.entity = ent
			stash.name = loc.translate(_('Primary Account'))

			acc = AccessEntity()
			acc.nick = login
			acc.password = passwd
			acc.stash = stash
			acc.rate_id = rate_id
			acc.state_id = state_id
			ent.children.append(acc)

			sess.add(ent)
			sess.add(stash)
			sess.add(acc)

			if must_verify:
				link_id = int(cfg.get('netprofile.client.registration.link_id', 1))
				rand_len = int(cfg.get('netprofile.client.registration.code_length', 20))
				queue_mail = asbool(cfg.get('netprofile.client.registration.mail_queue', False))
				sender = cfg.get('netprofile.client.registration.mail_sender')

				acc.access_state = AccessState.block_inactive.value
				link = AccessEntityLink()
				link.entity = acc
				link.type_id = link_id

				chars = string.ascii_uppercase + string.digits
				try:
					rng = random.SystemRandom()
				except NotImplementedError:
					rng = random
				link.value = ''.join(rng.choice(chars) for i in range(rand_len))
				link.timestamp = datetime.datetime.now()
				sess.add(link)

				mailer = get_mailer(request)

				tpldef = {
					'cur_loc' : cur_locale,
					'entity'  : ent,
					'stash'   : stash,
					'access'  : acc,
					'link'    : link
				}
				request.run_hook('access.cl.tpldef.register.mail', tpldef, request)
				msg_text = Attachment(
					data=render('netprofile_access:templates/email_register_plain.mak', tpldef, request),
					content_type='text/plain; charset=\'utf-8\'',
					disposition='inline',
					transfer_encoding='quoted-printable'
				)
				msg_html = Attachment(
					data=render('netprofile_access:templates/email_register_html.mak', tpldef, request),
					content_type='text/html; charset=\'utf-8\'',
					disposition='inline',
					transfer_encoding='quoted-printable'
				)
				msg = Message(
					subject=(loc.translate(_('Activation required for user %s')) % login),
					sender=sender,
					recipients=(email,),
					body=msg_text,
					html=msg_html
				)
				if queue_mail:
					mailer.send_to_queue(msg)
				else:
					mailer.send(msg)
			return HTTPSeeOther(location=request.route_url('access.cl.regsent'))
	tpldef = {
		'cur_loc'        : cur_locale,
		'comb_js'        : comb_js,
		'must_verify'    : must_verify,
		'must_recaptcha' : must_recaptcha,
		'min_pwd_len'    : min_pwd_len,
		'maillogin'	 : maillogin,
		'errors'         : {err: loc.translate(errors[err]) for err in errors}
	}
	if must_recaptcha:
		tpldef['rc_public'] = rc_public
	request.run_hook('access.cl.tpldef.register', tpldef, request)
	return tpldef
Exemple #42
0
def create_record(request):
	loc = get_localizer(request)
	cfg = request.registry.settings
	sess = DBSession()
	csrf = request.POST.get('csrf', '')
	if csrf != request.get_csrf():
		request.session.flash({
				'text' : loc.translate(_('Error submitting form')),
				'class' : 'danger'
				})
		return HTTPSeeOther(location=request.route_url('pdns.cl.domains'))
	else:
		#get fields related to obtained type and create corresponding fields
		rectype = request.POST.get('type', None)
		if rectype != "record" and rectype != "newdomain":
			#so we are creating some service, domain, mailserver, etc
			currentvalues = {}
			hostname = request.POST.get('hostName', None)
			currentvalues['name'] = hostname
			
			#check if we already have such domain name,
			#if so, return a warning111
			#domain_clash = sess.query(func.count('*'))\
			#		.select_from(PDNSDomain)\
			#		.filter(PDNSDomain.name == hostname)\
			#		.scalar()
			#if domain_clash > 0:
			#	request.session.flash({
			#		'text' : loc.translate(_('Domain already exists, please add corresponding records manually')),
			#		'class' : 'danger'
			#		})
			#	return HTTPSeeOther(location=request.route_url('pdns.cl.domains'))
			#if no same domain name warinigs returned, we can continue processing our data
			#host record

			#domaintype = request.POST.get('hosttype', 'NATIVE')
			domainip = request.POST.get('hostValue', None)
			#if IP-address is not specified, raise a warning
			if not domainip:
				request.session.flash({
						'text' : loc.translate(_('You need to specify IP address')),
						'class' : 'danger'
						})
				return HTTPSeeOther(location=request.route_url('pdns.cl.domains'))
			currentvalues['domainip'] = domainip
			
			#get the nameservers from the config
			ns1 = cfg.get('netprofile.client.pdns.ns1')
			ns2 = cfg.get('netprofile.client.pdns.ns2')

			currentvalues['nameserver1'] = ns1
			currentvalues['nameserver2'] = ns2

			currentvalues['ttl'] = 3600
			currentvalues['prefix'] = ''
			currentvalues['name'] = hostname
			#and here we create our something. 
			#as we have new service type, rectype, we can get all related fields

			newdomain = sess.query(PDNSDomain).filter(PDNSDomain.name==hostname).first()
			service_template = sess.query(PDNSTemplateType).filter(PDNSTemplateType.name==rectype).join(PDNSTemplate).all()
			
			#default values are stored as JSON in the database
			#if default value is a key of a dictionnary, lookup it's value in the currentvalues dict
			#else it is a complex value with prefix and value from currentvalues dict, as in jabber contents field
			#some examples:
			#Domain NS Record: {"ttl":"86400",  "content":"nameserver2"}
			#Mailserver CNAME Record: {"ttl":"3600",  "prefix":"mail", "content":"name"}
			#Jabber SRV Record: {"ttl":"3600",  "prefix":"_xmpp-client._tcp", "content":["5 0 5222 jabber", "name"]}
			for t in service_template:
				for f in t.template_fields:
					defvalues = json.loads(f.defaultvalues)
					newname = currentvalues['name']
					if 'prefix' in defvalues.keys():
						newname = "{0}.{1}".format(defvalues['prefix'], newname)
					newrtype = f.field.name
					
					defcontent = defvalues.get('content', None)
					if defcontent:
						if not isinstance(defcontent, list):
							newcontent = currentvalues.get(defcontent, None)
						else:
							def_in_cur = [defcontent.index(k) for k in filter(lambda x: x in defcontent, currentvalues.keys())]
							for i in def_in_cur:
								defcontent[i] = currentvalues[defcontent[i]]
							newcontent =".".join(defcontent)
					else:
						newcontent = ''

					newttl = int(defvalues.get('ttl', 3600))
					
					newRecord = PDNSRecord(
						domain = newdomain,
						name = newname,
						rtype = newrtype,
						content = newcontent,
						ttl = newttl,
					)
					sess.add(newRecord)
					sess.flush()
		elif rectype == "record":
			ttl = None if request.POST.get('ttl', None) == '' else request.POST.get('ttl', None);
			prio = None if request.POST.get('prio', None) == '' else request.POST.get('prio', None);
			newrecord = PDNSRecord(domain_id=int(request.POST.get('domainid', None)), name=request.POST.get('name', None), rtype=request.POST.get('rtype', None), content=request.POST.get('content', None), ttl=ttl, prio=prio)
			sess.add(newrecord)
			sess.flush()
		elif rectype == "newdomain":
			hostname = request.POST.get('hostName', '127.0.0.1')
			hosttype = request.POST.get('hostType', 'NATIVE')
			domain_clash = sess.query(func.count('*'))\
				.select_from(PDNSDomain)\
				.filter(PDNSDomain.name == hostname)\
				.scalar()
			if domain_clash > 0:
				request.session.flash({
						'text' : loc.translate(_('Domain already exists, please add corresponding records manually')),
						'class' : 'danger'
						})
				return HTTPSeeOther(location=request.route_url('pdns.cl.domains'))

			newdomain = PDNSDomain(
				name=hostname, 
				master='', 
				dtype=hosttype, 
				account=request.POST.get('user', None)
				)
			sess.add(newdomain)
			sess.flush()
			
	return HTTPSeeOther(location=request.route_url('pdns.cl.domains', _query=(('created', 1),)))
Exemple #43
0
def client_register(request):
	if authenticated_userid(request):
		return HTTPSeeOther(location=request.route_url('access.cl.home'))
	cur_locale = locale_neg(request)
	loc = get_localizer(request)
	cfg = request.registry.settings
	comb_js = asbool(cfg.get('netprofile.client.combine_js', False))
	can_reg = asbool(cfg.get('netprofile.client.registration.enabled', False))
	must_verify = asbool(cfg.get('netprofile.client.registration.verify_email', True))
	must_recaptcha = asbool(cfg.get('netprofile.client.registration.recaptcha.enabled', False))
	min_pwd_len = int(cfg.get('netprofile.client.registration.min_password_length', 8))
	rate_id = int(cfg.get('netprofile.client.registration.rate_id', 1))
	state_id = int(cfg.get('netprofile.client.registration.state_id', 1))
	maillogin = asbool(cfg.get('netprofile.client.email_as_username', False))
	csrf = request.POST.get('csrf', '')
	errors = {}
	if not can_reg:
		return HTTPSeeOther(location=request.route_url('access.cl.login'))
	if must_recaptcha:
		rc_private = cfg.get('netprofile.client.recaptcha.private_key')
		rc_public = cfg.get('netprofile.client.recaptcha.public_key')
		if (not rc_private) or (not rc_public):
			# TODO: log missing reCAPTCHA keys
			must_recaptcha = False
	if 'submit' in request.POST:
		sess = DBSession()
		if csrf != request.get_csrf():
			errors['csrf'] = _('Error submitting form')
		elif must_recaptcha:
			try:
				rcresp = verify_recaptcha(rc_private, request)
			except ValueError as e:
				errors['recaptcha'] = str(e)
			else:
				if rcresp and not rcresp.valid:
					errors['recaptcha'] = rcresp.text()
		if len(errors) == 0:
			login = request.POST.get('user', '')
			passwd = request.POST.get('pass', '')
			passwd2 = request.POST.get('pass2', '')
			email = request.POST.get('email', '')
			name_family = request.POST.get('name_family', '')
			name_given = request.POST.get('name_given', '')
			name_middle = request.POST.get('name_middle', '')
			l = len(login)
			if (l == 0) or (l > 254):
				errors['user'] = _('Invalid field length')
			elif not maillogin and not _re_login.match(login):
				errors['user'] = _('Invalid character used in username')
			l = len(passwd)
			if l < min_pwd_len:
				errors['pass'] = _('Password is too short')
			elif l > 254:
				errors['pass'] = _('Password is too long')
			if passwd != passwd2:
				errors['pass2'] = _('Passwords do not match')
			l = len(email)
			if (l == 0) or (l > 254):
				errors['email'] = _('Invalid field length')
			elif not _re_email.match(email):
				errors['email'] = _('Invalid e-mail format')
			if maillogin:
				login = email
			l = len(name_family)
			if (l == 0) or (l > 254):
				errors['name_family'] = _('Invalid field length')
			l = len(name_given)
			if (l == 0) or (l > 254):
				errors['name_given'] = _('Invalid field length')
			l = len(name_middle)
			if l > 254:
				errors['name_middle'] = _('Invalid field length')
			if 'user' not in errors:
				# XXX: currently we check across all entity types.
				login_clash = sess.query(func.count('*'))\
					.select_from(Entity)\
					.filter(Entity.nick == login)\
					.scalar()
				if login_clash > 0:
					errors['user'] = _('This username is already taken')
		if len(errors) == 0:
			ent = PhysicalEntity()
			ent.nick = login
			ent.email = email
			ent.name_family = name_family
			ent.name_given = name_given
			if name_middle:
				ent.name_middle = name_middle
			ent.state_id = state_id

			stash = Stash()
			stash.entity = ent
			stash.name = loc.translate(_('Primary Account'))

			acc = AccessEntity()
			acc.nick = login
			acc.password = passwd
			acc.stash = stash
			acc.rate_id = rate_id
			acc.state_id = state_id
			ent.children.append(acc)

			sess.add(ent)
			sess.add(stash)
			sess.add(acc)

			if must_verify:
				link_id = int(cfg.get('netprofile.client.registration.link_id', 1))
				rand_len = int(cfg.get('netprofile.client.registration.code_length', 20))
				queue_mail = asbool(cfg.get('netprofile.client.registration.mail_queue', False))
				sender = cfg.get('netprofile.client.registration.mail_sender')

				acc.access_state = AccessState.block_inactive.value
				link = AccessEntityLink()
				link.entity = acc
				link.type_id = link_id

				chars = string.ascii_uppercase + string.digits
				try:
					rng = random.SystemRandom()
				except NotImplementedError:
					rng = random
				link.value = ''.join(rng.choice(chars) for i in range(rand_len))
				link.timestamp = datetime.datetime.now()
				sess.add(link)

				mailer = get_mailer(request)

				tpldef = {
					'cur_loc' : cur_locale,
					'entity'  : ent,
					'stash'   : stash,
					'access'  : acc,
					'link'    : link
				}
				request.run_hook('access.cl.tpldef.register.mail', tpldef, request)
				msg_text = Attachment(
					data=render('netprofile_access:templates/email_register_plain.mak', tpldef, request),
					content_type='text/plain; charset=\'utf-8\'',
					disposition='inline',
					transfer_encoding='quoted-printable'
				)
				msg_html = Attachment(
					data=render('netprofile_access:templates/email_register_html.mak', tpldef, request),
					content_type='text/html; charset=\'utf-8\'',
					disposition='inline',
					transfer_encoding='quoted-printable'
				)
				msg = Message(
					subject=(loc.translate(_('Activation required for user %s')) % login),
					sender=sender,
					recipients=(email,),
					body=msg_text,
					html=msg_html
				)
				if queue_mail:
					mailer.send_to_queue(msg)
				else:
					mailer.send(msg)
			return HTTPSeeOther(location=request.route_url('access.cl.regsent'))
	tpldef = {
		'cur_loc'        : cur_locale,
		'comb_js'        : comb_js,
		'must_verify'    : must_verify,
		'must_recaptcha' : must_recaptcha,
		'min_pwd_len'    : min_pwd_len,
		'maillogin'	 : maillogin,
		'errors'         : {err: loc.translate(errors[err]) for err in errors}
	}
	if must_recaptcha:
		tpldef['rc_public'] = rc_public
	request.run_hook('access.cl.tpldef.register', tpldef, request)
	return tpldef