def submitbug(request): if request.method == 'POST': form = SubmitBugForm(request.POST) if form.is_valid(): c = connection.cursor() c.execute("SELECT nextval('bug_id_seq')") bugid = c.fetchall()[0][0] send_template_mail( settings.BUGREPORT_NOREPLY_EMAIL, settings.BUGREPORT_EMAIL, 'BUG #%s: %s' % (bugid, form.cleaned_data['shortdesc']), 'misc/bugmail.txt', { 'bugid': bugid, 'bug': form.cleaned_data, }, usergenerated=True, cc=form.cleaned_data['email'], replyto='%s, %s' % (form.cleaned_data['email'], settings.BUGREPORT_EMAIL), sendername="PG Bug reporting form", ) return render_pgweb(request, 'support', 'misc/bug_completed.html', { 'bugid': bugid, }) else: form = SubmitBugForm( initial={ 'name': '%s %s' % (request.user.first_name, request.user.last_name), 'email': request.user.email, }) versions = Version.objects.filter(supported=True) return render_pgweb( request, 'support', 'base/form.html', { 'form': form, 'formitemtype': 'bug report', 'formtitle': 'Submit Bug Report <i class="fas fa-bug"></i>', 'operation': 'Submit', 'form_intro': template_to_string('misc/bug_header.html', { 'supportedversions': versions, }), 'savebutton': 'Submit and Send Email', })
def commentform(request, itemid, version, filename): v = get_object_or_404(Version, tree=version) if not v.supported: # No docs comments on unsupported versions return HttpResponseRedirect("/docs/{0}/static/{1}".format( version, filename)) if request.method == 'POST': form = DocCommentForm(request.POST) if form.is_valid(): if version == '0.0': version = 'devel' send_template_mail( settings.DOCSREPORT_NOREPLY_EMAIL, settings.DOCSREPORT_EMAIL, '%s' % form.cleaned_data['shortdesc'], 'docs/docsbugmail.txt', { 'version': version, 'filename': filename, 'details': form.cleaned_data['details'], }, usergenerated=True, cc=form.cleaned_data['email'], replyto='%s, %s' % (form.cleaned_data['email'], settings.DOCSREPORT_EMAIL), sendername='PG Doc comments form') return render_pgweb(request, 'docs', 'docs/docsbug_completed.html', {}) else: form = DocCommentForm( initial={ 'name': '%s %s' % (request.user.first_name, request.user.last_name), 'email': request.user.email, }) return render_pgweb( request, 'docs', 'base/form.html', { 'form': form, 'formitemtype': 'documentation comment', 'operation': 'Submit', 'form_intro': template_to_string('docs/docsbug.html', { 'user': request.user, }), 'savebutton': 'Send Email', })
def item(request, itemid, throwaway=None): event = get_object_or_404(Event, pk=itemid) if not event.approved: raise Http404 return render_pgweb(request, 'about', 'events/item.html', { 'obj': event, })
def details(request, cve_prefix, cve): """Provides additional details about a specific CVE""" # First determine if the entrypoint of the URL is a lowercase "cve". If it # is, redirect to the uppercase if cve_prefix != "CVE": return redirect('/support/security/CVE-{}/'.format(cve), permanent=True) # Get the CVE number from the CVE ID string so we can look it up # against the database. This shouldn't fail due to an ill-formatted CVE, # as both use the same validation check, but we will wrap it just in case. # # However, we do need to ensure that the CVE does both exist and # is published. try: security_patch = get_object_or_404( SecurityPatch, cvenumber=make_cvenumber(cve), public=True, ) except ValidationError: raise Http404() return render_pgweb( request, 'support', 'security/details.html', { 'security_patch': security_patch, 'versions': security_patch.securitypatchversion_set.select_related( 'version').order_by('-version__tree').all(), })
def _submitted_item_submit(request, objtype, model, obj): if obj.modstate != ModerationState.CREATED: # Can only submit if state is created return HttpResponseRedirect("/account/edit/{}/".format(objtype)) if request.method == 'POST': form = ConfirmSubmitForm(obj._meta.verbose_name, data=request.POST) if form.is_valid(): with transaction.atomic(): obj.modstate = ModerationState.PENDING obj.send_notification = False obj.save() send_simple_mail(settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "{} '{}' submitted for moderation".format(obj._meta.verbose_name.capitalize(), obj.title), "{} {} with title '{}' submitted for moderation by {}\n\nModerate at: {}\n".format( obj._meta.verbose_name.capitalize(), obj.id, obj.title, request.user.username, '{}/admin/_moderate/{}/{}/'.format(settings.SITE_ROOT, obj._meta.model_name, obj.pk), ), ) return HttpResponseRedirect("/account/edit/{}/".format(objtype)) else: form = ConfirmSubmitForm(obj._meta.verbose_name) return render_pgweb(request, 'account', 'account/submit_preview.html', { 'obj': obj, 'form': form, 'objtype': obj._meta.verbose_name, 'preview': obj.get_preview_fields(), })
def orglist(request): orgs = Organisation.objects.prefetch_related('managers').filter( approved=True) return render_pgweb(request, 'account', 'account/orglist.html', { 'orgs': orgs, })
def listobjects(request, objtype): if objtype not in objtypes: raise Http404("Object type not found") o = objtypes[objtype] if o.get('tristate', False): objects = { 'approved': o['objects']( request.user).filter(modstate=ModerationState.APPROVED), 'unapproved': o['objects']( request.user).filter(modstate=ModerationState.PENDING), 'inprogress': o['objects']( request.user).filter(modstate=ModerationState.CREATED), } else: objects = { 'approved': o['objects'](request.user).filter(approved=True), 'unapproved': o['objects'](request.user).filter(approved=False), } return render_pgweb( request, 'account', 'account/objectlist.html', { 'objects': objects, 'title': o['title'], 'editapproved': o['editapproved'], 'submit_header': o.get('submit_header', None), 'suburl': objtype, 'tristate': o.get('tristate', False), })
def signup(request): if request.user.is_authenticated: return HttpSimpleResponse( request, "Account error", "You must log out before you can sign up for a new account") if request.method == 'POST': # Attempt to create user then, eh? form = SignupForm(get_client_ip(request), data=request.POST) if form.is_valid(): # Attempt to create the user here # XXX: Do we need to validate something else? log.info("Creating user for {0} from {1}".format( form.cleaned_data['username'], get_client_ip(request))) user = User.objects.create_user( form.cleaned_data['username'].lower(), form.cleaned_data['email'].lower(), last_login=datetime.now()) user.first_name = form.cleaned_data['first_name'] user.last_name = form.cleaned_data['last_name'] # generate a random value for password. It won't be possible to log in with it, but # it creates more entropy for the token generator (I think). user.password = generate_random_token() user.save() # Now generate a token token = default_token_generator.make_token(user) log.info("Generated token {0} for user {1} from {2}".format( token, form.cleaned_data['username'], get_client_ip(request))) # Generate an outgoing email send_template_mail( settings.ACCOUNTS_NOREPLY_FROM, form.cleaned_data['email'], 'Your new postgresql.org community account', 'account/new_account_email.txt', { 'uid': urlsafe_base64_encode(force_bytes(user.id)), 'token': token, 'user': user }) return HttpResponseRedirect('/account/signup/complete/') else: form = SignupForm(get_client_ip(request)) return render_pgweb( request, 'account', 'base/form.html', { 'form': form, 'formitemtype': 'Account', 'form_intro': """ To sign up for a free community account, enter your preferred userid and email address. Note that a community account is only needed if you want to submit information - all content is available for reading without an account. A confirmation email will be sent to the specified address, and once confirmed a password for the new account can be specified. """, 'savebutton': 'Sign up', 'operation': 'New', 'recaptcha': True, })
def resetpwd(request): # Basic django password reset feature is completely broken. For example, it does not support # resetting passwords for users with "old hashes", which means they have no way to ever # recover. So implement our own, since it's quite the trivial feature. if request.method == "POST": try: u = User.objects.get(email__iexact=request.POST['email']) if u.password == OAUTH_PASSWORD_STORE: return HttpServerError(request, "This account cannot change password as it's connected to a third party login site.") except User.DoesNotExist: log.info("Attempting to reset password of {0}, user not found".format(request.POST['email'])) return HttpResponseRedirect('/account/reset/done/') form = PgwebPasswordResetForm(data=request.POST) if form.is_valid(): log.info("Initiating password set from {0} for {1}".format(get_client_ip(request), form.cleaned_data['email'])) token = default_token_generator.make_token(u) send_template_mail( settings.ACCOUNTS_NOREPLY_FROM, form.cleaned_data['email'], 'Password reset for your postgresql.org account', 'account/password_reset_email.txt', { 'user': u, 'uid': urlsafe_base64_encode(force_bytes(u.pk)), 'token': token, }, ) return HttpResponseRedirect('/account/reset/done/') else: form = PgwebPasswordResetForm() return render_pgweb(request, 'account', 'account/password_reset.html', { 'form': form, })
def communityauth_consent(request, siteid): org = get_object_or_404(CommunityAuthSite, id=siteid).org if request.method == 'POST': form = CommunityAuthConsentForm(org.orgname, data=request.POST) if form.is_valid(): CommunityAuthConsent.objects.get_or_create( user=request.user, org=org, defaults={'consentgiven': datetime.now()}, ) return HttpResponseRedirect(form.cleaned_data['next']) else: form = CommunityAuthConsentForm( org.orgname, initial={'next': request.GET.get('next', '')}) return render_pgweb( request, 'account', 'base/form.html', { 'form': form, 'operation': 'Authentication', 'form_intro': 'The site you are about to log into is run by {0}. If you choose to proceed with this authentication, your name and email address will be shared with <em>{1}</em>.</p><p>Please confirm that you consent to this sharing.' .format(org.orgname, org.orgname), 'savebutton': 'Proceed with login', })
def region(request, servtype, regionname): regname = [n for r, n in regions if r == regionname] if not regname: raise Http404 regname = regname[0] what = servtype == 'support' and 'support' or 'hosting' whatname = servtype == 'support' and 'Professional Services' or 'Hosting Providers' title = "%s - %s" % (whatname, regname) support = servtype == 'support' # DB model is a bit funky here, so use the extra-where functionality to filter properly. # Field names are cleaned up earlier, so it's safe against injections. services = ProfessionalService.objects.select_related('org').filter( approved=True).extra(where=[ "region_%s AND provides_%s" % (regionname, what), ]) return render_pgweb( request, 'support', 'profserv/list.html', { 'title': title, 'support': support, 'what': what, 'whatname': whatname, 'regionname': regname, 'services': services, })
def resetpwd(request): # Basic django password reset feature is completely broken. For example, it does not support # resetting passwords for users with "old hashes", which means they have no way to ever # recover. So implement our own, since it's quite the trivial feature. if request.method == "POST": try: u = User.objects.get(email__iexact=request.POST['email']) if u.password == OAUTH_PASSWORD_STORE: return HttpServerError(request, "This account cannot change password as it's connected to a third party login site.") except User.DoesNotExist: log.info("Attempting to reset password of {0}, user not found".format(request.POST['email'])) return HttpResponseRedirect('/account/reset/done/') form = PgwebPasswordResetForm(data=request.POST) if form.is_valid(): log.info("Initiating password set from {0} for {1}".format(get_client_ip(request), form.cleaned_data['email'])) token = default_token_generator.make_token(u) send_template_mail(settings.ACCOUNTS_NOREPLY_FROM, form.cleaned_data['email'], 'Password reset for your postgresql.org account', 'account/password_reset_email.txt', { 'user': u, 'uid': urlsafe_base64_encode(force_bytes(u.pk)), 'token': token, }, ) return HttpResponseRedirect('/account/reset/done/') else: form = PgwebPasswordResetForm() return render_pgweb(request, 'account', 'account/password_reset.html', { 'form': form, })
def results(request, surveyid, junk=None): survey = get_object_or_404(Survey, pk=surveyid) surveylist = Survey.objects.all().order_by('-posted') return render_pgweb(request, 'community', 'survey/results.html', { 'survey': survey, 'surveylist': surveylist, })
def root(request): versions = Version.objects.filter( Q(supported=True) | Q(testing__gt=0, tree__gt=0)).order_by('-tree') r = render_pgweb(request, 'docs', 'docs/index.html', { 'versions': [_VersionPdfWrapper(v) for v in versions], }) r['xkey'] = 'pgdocs_all pgdocs_pdf' return r
def item(request, itemid, throwaway=None): news = get_object_or_404(NewsArticle, pk=itemid) if not news.approved: raise Http404 return render_pgweb(request, 'about', 'news/item.html', { 'obj': news, 'newstags': NewsTag.objects.all(), })
def manualarchive(request): versions = Version.objects.filter(testing=0, supported=False, tree__gt=0).order_by('-tree') r = render_pgweb(request, 'docs', 'docs/archive.html', { 'versions': [_VersionPdfWrapper(v) for v in versions], }) r['xkey'] = 'pgdocs_all pgdocs_pdf' return r
def productlist(request, catid, junk=None): category = get_object_or_404(Category, pk=catid) products = Product.objects.select_related('org','licencetype').filter(category=category, approved=True) return render_pgweb(request, 'download', 'downloads/productlist.html', { 'category': category, 'products': products, 'productcount': len(products), })
def productlist(request, catid, junk=None): category = get_object_or_404(Category, pk=catid) products = Product.objects.select_related('org', 'licencetype').filter(category=category, approved=True) return render_pgweb(request, 'download', 'downloads/productlist.html', { 'category': category, 'products': products, 'productcount': len(products), })
def root(request, servtype): title = servtype == 'support' and 'Professional Services' or 'Hosting Providers' what = servtype == 'support' and 'support' or 'hosting' support = servtype == 'support' return render_pgweb(request, 'support', 'profserv/root.html', { 'title': title, 'support': support, 'regions': regions, 'what': what, })
def main(request): community_events = Event.objects.select_related('country').filter(approved=True, badged=True).filter(enddate__gt=date.today()).order_by('enddate', 'startdate',) other_events = Event.objects.select_related('country').filter(approved=True, badged=False).filter(enddate__gt=date.today()).order_by('enddate', 'startdate',) return render_pgweb(request, 'about', 'events/archive.html', { 'title': 'Upcoming Events', 'eventblocks': ( {'name': 'Community Events', 'events': community_events, 'link': '', }, {'name': 'Other Events', 'events': other_events, 'link': '', }, ), })
def main(request): return render_pgweb( request, 'about', 'events/archive.html', { 'title': 'Upcoming Events', 'events': Event.objects.select_related('country').filter( approved=True, enddate__gt=date.today()).order_by( 'enddate', 'startdate'), })
def item(request, itemid, slug=None): news = get_object_or_404(NewsArticle, pk=itemid) if news.modstate != ModerationState.APPROVED: raise Http404 if slug != slugify(news.title): return HttpResponsePermanentRedirect('/about/news/{}-{}/'.format(slugify(news.title), news.id)) return render_pgweb(request, 'about', 'news/item.html', { 'obj': news, 'newstags': NewsTag.objects.all(), })
def _list_patches(request, filt): patches = GetPatchesList(filt) return render_pgweb(request, 'support', 'security/security.html', { 'patches': patches, 'supported': Version.objects.filter(supported=True), 'unsupported': Version.objects.filter(supported=False, tree__gt=0).extra( where=["EXISTS (SELECT 1 FROM security_securitypatchversion pv WHERE pv.version_id=core_version.id)"], ), })
def _eventarchive(request, title): # Hardcode to the latest 100 events. Do we need paging too? events = Event.objects.select_related('country').filter(approved=True).filter(enddate__lte=date.today()).order_by('-enddate', '-startdate',)[:100] return render_pgweb(request, 'about', 'events/archive.html', { 'title': '%s Archive' % title, 'archive': True, 'eventblocks': ( {'name': title, 'events': events, }, ), })
def listobjects(request, objtype): if not objtypes.has_key(objtype): raise Http404("Object type not found") o = objtypes[objtype] return render_pgweb(request, 'account', 'account/objectlist.html', { 'objects': o['objects'](request.user), 'title': o['title'], 'submit_header': o.has_key('submit_header') and o['submit_header'] or None, 'suburl': objtype, })
def community(request): s = Survey.objects.filter(current=True) try: s = s[0] except: s = None planet = ImportedRSSItem.objects.filter(feed__internalname="planet").order_by("-posttime")[:7] return render_pgweb(request, 'community', 'core/community.html', { 'survey': s, 'planet': planet, })
def archive(request, tag=None, paging=None): if tag: tag = get_object_or_404(NewsTag, urlname=tag.strip('/')) news = NewsArticle.objects.filter(approved=True, tags=tag) else: tag = None news = NewsArticle.objects.filter(approved=True) return render_pgweb(request, 'about', 'news/newsarchive.html', { 'news': news, 'tag': tag, 'newstags': NewsTag.objects.all(), })
def item(request, itemid, slug=None): event = get_object_or_404(Event, pk=itemid) if not event.approved: raise Http404 if slug != slugify(event.title): return HttpResponsePermanentRedirect('/about/event/{}-{}/'.format( slugify(event.title), event.id)) return render_pgweb(request, 'about', 'events/item.html', { 'obj': event, })
def home(request): myarticles = NewsArticle.objects.filter(org__managers=request.user, approved=False) myevents = Event.objects.filter(org__managers=request.user, approved=False) myorgs = Organisation.objects.filter(managers=request.user, approved=False) myproducts = Product.objects.filter(org__managers=request.user, approved=False) myprofservs = ProfessionalService.objects.filter(org__managers=request.user, approved=False) return render_pgweb(request, 'account', 'account/index.html', { 'newsarticles': myarticles, 'events': myevents, 'organisations': myorgs, 'products': myproducts, 'profservs': myprofservs, })
def signup(request): if request.user.is_authenticated(): return HttpServerError(request, "You must log out before you can sign up for a new account") if request.method == 'POST': # Attempt to create user then, eh? form = SignupForm(get_client_ip(request), data=request.POST) if form.is_valid(): # Attempt to create the user here # XXX: Do we need to validate something else? log.info("Creating user for {0} from {1}".format(form.cleaned_data['username'], get_client_ip(request))) user = User.objects.create_user(form.cleaned_data['username'].lower(), form.cleaned_data['email'].lower(), last_login=datetime.now()) user.first_name = form.cleaned_data['first_name'] user.last_name = form.cleaned_data['last_name'] # generate a random value for password. It won't be possible to log in with it, but # it creates more entropy for the token generator (I think). user.password = generate_random_token() user.save() # Now generate a token token = default_token_generator.make_token(user) log.info("Generated token {0} for user {1} from {2}".format(token, form.cleaned_data['username'], get_client_ip(request))) # Generate an outgoing email send_template_mail(settings.ACCOUNTS_NOREPLY_FROM, form.cleaned_data['email'], 'Your new postgresql.org community account', 'account/new_account_email.txt', {'uid': urlsafe_base64_encode(force_bytes(user.id)), 'token': token, 'user': user} ) return HttpResponseRedirect('/account/signup/complete/') else: form = SignupForm(get_client_ip(request)) return render_pgweb(request, 'account', 'base/form.html', { 'form': form, 'formitemtype': 'Account', 'form_intro': """ To sign up for a free community account, enter your preferred userid and email address. Note that a community account is only needed if you want to submit information - all content is available for reading without an account. A confirmation email will be sent to the specified address, and once confirmed a password for the new account can be specified. """, 'savebutton': 'Sign up', 'operation': 'New', 'recaptcha': True, })
def listobjects(request, objtype): if objtype not in objtypes: raise Http404("Object type not found") o = objtypes[objtype] return render_pgweb(request, 'account', 'account/objectlist.html', { 'objects': { 'approved': o['objects'](request.user).filter(approved=True), 'unapproved': o['objects'](request.user).filter(approved=False), }, 'title': o['title'], 'submit_header': o.get('submit_header', None), 'suburl': objtype, })
def index(request): """ contains list of PUGs, in country/locale alphabetical order """ pug_list = [] for pug in PUG.objects.filter(approved=True).order_by( 'country__name', 'locale').all(): if pug_list and pug_list[-1].get('country') == pug.country.name: pug_list[-1]['pugs'].append(pug) else: pug_list.append({'country': pug.country.name, 'pugs': [pug]}) return render_pgweb(request, 'community', 'pugs/index.html', { 'pug_list': pug_list, })
def submitbug(request): if request.method == 'POST': form = SubmitBugForm(request.POST) if form.is_valid(): with transaction.atomic(): c = connection.cursor() c.execute("SELECT nextval('bug_id_seq')") bugid = c.fetchall()[0][0] messageid = _make_bugs_messageid(bugid) BugIdMap(id=bugid, messageid=messageid.strip('<>')).save() send_template_mail( settings.BUGREPORT_NOREPLY_EMAIL, settings.BUGREPORT_EMAIL, 'BUG #%s: %s' % (bugid, form.cleaned_data['shortdesc']), 'misc/bugmail.txt', { 'bugid': bugid, 'bug': form.cleaned_data, }, usergenerated=True, cc=form.cleaned_data['email'], replyto='%s, %s' % (form.cleaned_data['email'], settings.BUGREPORT_EMAIL), sendername="PG Bug reporting form", messageid=messageid, ) return HttpResponseRedirect("/account/submitbug/{0}/".format(bugid)) else: form = SubmitBugForm(initial={ 'name': '%s %s' % (request.user.first_name, request.user.last_name), 'email': request.user.email, }) versions = Version.objects.filter(supported=True) return render_pgweb(request, 'support', 'base/form.html', { 'form': form, 'formitemtype': 'bug report', 'formtitle': 'Submit Bug Report <i class="fas fa-bug"></i>', 'operation': 'Submit', 'form_intro': template_to_string('misc/bug_header.html', { 'supportedversions': versions, }), 'savebutton': 'Submit and Send Email', })
def profile(request): # We always have the user, but not always the profile. And we need a bit # of a hack around the normal forms code since we have two different # models on a single form. (profile, created) = UserProfile.objects.get_or_create(pk=request.user.pk) # Don't allow users whose accounts were created via oauth to change # their email, since that would kill the connection between the # accounts. can_change_email = (request.user.password != OAUTH_PASSWORD_STORE) # We may have a contributor record - and we only show that part of the # form if we have it for this user. try: contrib = Contributor.objects.get(user=request.user.pk) except Contributor.DoesNotExist: contrib = None contribform = None if request.method == 'POST': # Process this form userform = UserForm(data=request.POST, instance=request.user) profileform = UserProfileForm(data=request.POST, instance=profile) if contrib: contribform = ContributorForm(data=request.POST, instance=contrib) if userform.is_valid() and profileform.is_valid() and ( not contrib or contribform.is_valid()): userform.save() profileform.save() if contrib: contribform.save() return HttpResponseRedirect("/account/") else: # Generate form userform = UserForm(instance=request.user) profileform = UserProfileForm(instance=profile) if contrib: contribform = ContributorForm(instance=contrib) return render_pgweb( request, 'account', 'account/userprofileform.html', { 'userform': userform, 'profileform': profileform, 'contribform': contribform, 'can_change_email': can_change_email, })
def index(request): """ contains list of PUGs, in country/locale alphabetical order """ pug_list = [] for pug in PUG.objects.filter(approved=True).order_by('country__name', 'locale').all(): if pug_list and pug_list[-1].get('country') == pug.country.name: pug_list[-1]['pugs'].append(pug) else: pug_list.append({ 'country': pug.country.name, 'pugs': [pug] }) return render_pgweb(request, 'community', 'pugs/index.html', { 'pug_list': pug_list, })
def listobjects(request, objtype): if objtype not in objtypes: raise Http404("Object type not found") o = objtypes[objtype] return render_pgweb( request, 'account', 'account/objectlist.html', { 'objects': { 'approved': o['objects'](request.user).filter(approved=True), 'unapproved': o['objects']( request.user).filter(approved=False), }, 'title': o['title'], 'submit_header': o.get('submit_header', None), 'suburl': objtype, })
def profile(request): # We always have the user, but not always the profile. And we need a bit # of a hack around the normal forms code since we have two different # models on a single form. (profile, created) = UserProfile.objects.get_or_create(pk=request.user.pk) # Don't allow users whose accounts were created via oauth to change # their email, since that would kill the connection between the # accounts. can_change_email = (request.user.password != OAUTH_PASSWORD_STORE) # We may have a contributor record - and we only show that part of the # form if we have it for this user. try: contrib = Contributor.objects.get(user=request.user.pk) except Contributor.DoesNotExist: contrib = None contribform = None if request.method == 'POST': # Process this form userform = UserForm(data=request.POST, instance=request.user) profileform = UserProfileForm(data=request.POST, instance=profile) if contrib: contribform = ContributorForm(data=request.POST, instance=contrib) if userform.is_valid() and profileform.is_valid() and (not contrib or contribform.is_valid()): userform.save() profileform.save() if contrib: contribform.save() return HttpResponseRedirect("/account/") else: # Generate form userform = UserForm(instance=request.user) profileform = UserProfileForm(instance=profile) if contrib: contribform = ContributorForm(instance=contrib) return render_pgweb(request, 'account', 'account/userprofileform.html', { 'userform': userform, 'profileform': profileform, 'contribform': contribform, 'can_change_email': can_change_email, })
def commentform(request, itemid, version, filename): if version == 'current': v = Version.objects.get(current=True) else: v = get_object_or_404(Version, tree=version) if not v.supported: # No docs comments on unsupported versions return HttpResponseRedirect("/docs/{0}/{1}".format(version, filename)) if request.method == 'POST': form = DocCommentForm(request.POST) if form.is_valid(): if version == '0.0': version = 'devel' send_template_mail( settings.DOCSREPORT_NOREPLY_EMAIL, settings.DOCSREPORT_EMAIL, '%s' % form.cleaned_data['shortdesc'], 'docs/docsbugmail.txt', { 'version': version, 'filename': filename, 'details': form.cleaned_data['details'], }, usergenerated=True, cc=form.cleaned_data['email'], replyto='%s, %s' % (form.cleaned_data['email'], settings.DOCSREPORT_EMAIL), sendername='PG Doc comments form' ) return HttpResponseRedirect("done/") else: form = DocCommentForm(initial={ 'name': '%s %s' % (request.user.first_name, request.user.last_name), 'email': request.user.email, }) return render_pgweb(request, 'docs', 'base/form.html', { 'form': form, 'formitemtype': 'documentation comment', 'operation': 'Submit', 'form_intro': template_to_string('docs/docsbug.html', { 'user': request.user, }), 'savebutton': 'Send Email', })
def communityauth_consent(request, siteid): org = get_object_or_404(CommunityAuthSite, id=siteid).org if request.method == 'POST': form = CommunityAuthConsentForm(org.orgname, data=request.POST) if form.is_valid(): CommunityAuthConsent.objects.get_or_create(user=request.user, org=org, defaults={'consentgiven': datetime.now()}, ) return HttpResponseRedirect(form.cleaned_data['next']) else: form = CommunityAuthConsentForm(org.orgname, initial={'next': request.GET.get('next', '')}) return render_pgweb(request, 'account', 'base/form.html', { 'form': form, 'operation': 'Authentication', 'form_intro': 'The site you are about to log into is run by {0}. If you choose to proceed with this authentication, your name and email address will be shared with <em>{1}</em>.</p><p>Please confirm that you consent to this sharing.'.format(org.orgname, org.orgname), 'savebutton': 'Proceed with login', })
def confirm_change_email(request, tokenhash): tokens = EmailChangeToken.objects.filter(user=request.user, token=tokenhash) token = len(tokens) and tokens[0] or None if request.user.password == OAUTH_PASSWORD_STORE: # Link shouldn't exist in this case, so just throw an unfriendly # error message. return HttpServerError(request, "This account cannot change email address as it's connected to a third party login site.") if token: # Valid token find, so change the email address request.user.email = token.email.lower() request.user.save() token.delete() return render_pgweb(request, 'account', 'account/emailchangecompleted.html', { 'token': tokenhash, 'success': token and True or False, })
def region(request, servtype, regionname): regname = [n for r, n in regions if r == regionname] if not regname: raise Http404 regname = regname[0] what = servtype == 'support' and 'support' or 'hosting' whatname = servtype == 'support' and 'Professional Services' or 'Hosting Providers' title = "%s - %s" % (whatname, regname) support = servtype == 'support' # DB model is a bit funky here, so use the extra-where functionality to filter properly. # Field names are cleaned up earlier, so it's safe against injections. services = ProfessionalService.objects.select_related('org').filter(approved=True).extra(where=["region_%s AND provides_%s" % (regionname, what), ]) return render_pgweb(request, 'support', 'profserv/list.html', { 'title': title, 'support': support, 'what': what, 'whatname': whatname, 'regionname': regname, 'services': services, })
def change_email(request): tokens = EmailChangeToken.objects.filter(user=request.user) token = len(tokens) and tokens[0] or None if request.user.password == OAUTH_PASSWORD_STORE: # Link shouldn't exist in this case, so just throw an unfriendly # error message. return HttpServerError(request, "This account cannot change email address as it's connected to a third party login site.") if request.method == 'POST': form = ChangeEmailForm(request.user, data=request.POST) if form.is_valid(): # If there is an existing token, delete it if token: token.delete() # Create a new token token = EmailChangeToken(user=request.user, email=form.cleaned_data['email'].lower(), token=generate_random_token()) token.save() send_template_mail( settings.ACCOUNTS_NOREPLY_FROM, form.cleaned_data['email'], 'Your postgresql.org community account', 'account/email_change_email.txt', {'token': token, 'user': request.user, } ) return HttpResponseRedirect('done/') else: form = ChangeEmailForm(request.user) return render_pgweb(request, 'account', 'account/emailchangeform.html', { 'form': form, 'token': token, })
def submitbug_done(request, bugid): return render_pgweb(request, 'support', 'misc/bug_completed.html', { 'bugid': bugid, })
def completelist(request): contributortypes = list(ContributorType.objects.all()) return render_pgweb(request, 'community', 'contributors/list.html', { 'contributortypes': contributortypes, })
def sponsors(request): sponsors = Sponsor.objects.select_related().filter(sponsortype__sortkey__gt=0).order_by('sponsortype__sortkey', '?') return render_pgweb(request, 'about', 'sponsors/sponsors.html', { 'sponsors': sponsors, })
def about(request): # get 5 random quotes quotes = Quote.objects.filter(approved=True).order_by('?').all()[:5] return render_pgweb(request, 'about', 'core/about.html', { 'quotes': quotes, })
def versions(request): return render_pgweb(request, 'support', 'support/versioning.html', { 'versions': Version.objects.filter(tree__gt=0).filter(testing=0), })
def simple_form(instancetype, itemid, request, formclass, formtemplate='base/form.html', redirect='/account/', navsection='account', fixedfields=None, createifempty=False): if itemid == 'new': instance = instancetype() is_new = True else: is_new = False # Regular form item, attempt to edit it try: int(itemid) except ValueError: raise Http404("Invalid URL") if createifempty: (instance, wascreated) = instancetype.objects.get_or_create(pk=itemid) else: instance = get_object_or_404(instancetype, pk=itemid) if hasattr(instance, 'submitter'): if not instance.submitter == request.user: raise Exception("You are not the owner of this item!") elif hasattr(instance, 'verify_submitter'): if not instance.verify_submitter(request.user): raise Exception("You are not the owner of this item!") if request.method == 'POST': # Process this form form = formclass(data=request.POST, instance=instance) # Save away the old value from the instance before it's saved if not is_new: old_values = {fn: str(getattr(instance, fn)) for fn in form.changed_data if hasattr(instance, fn)} if form.is_valid(): # We are handling notifications, so disable the ones we'd otherwise send do_notify = getattr(instance, 'send_notification', False) instance.send_notification = False if not getattr(instance, 'approved', True) and not is_new: # If the object has an "approved" field and it's set to false, we don't # bother notifying about the changes. But if it lacks this field, we notify # about everything, as well as if the field exists and the item has already # been approved. # Newly added objects are always notified. do_notify = False notify = io.StringIO() r = form.save(commit=False) r.submitter = request.user # Set fixed fields. Note that this will not work if the fixed fields are ManyToMany, # but we'll fix that sometime in the future if fixedfields: for k, v in list(fixedfields.items()): setattr(r, k, v) r.save() # If we have a callback with the current user if hasattr(form, 'apply_submitter'): form.apply_submitter(r, request.user) r.save() if is_new: subj = 'A new {0} has been added'.format(instance._meta.verbose_name) for f in form.fields: notify.write("{}:\n".format(f)) if instance._meta.get_field(f) in instance._meta.many_to_many: notify.write("{}\n".format("\n".join([str(x) for x in form.cleaned_data[f]]))) else: notify.write("{}\n".format(str(form.cleaned_data[f]))) notify.write("\n") else: subj = '{0} id {1} has been modified'.format(instance._meta.verbose_name, instance.id) for fn in form.changed_data: if not hasattr(instance, fn): continue f = instance._meta.get_field(fn) if f in instance._meta.many_to_many: # m2m field have separate config of notificatgions if getattr(instance, 'send_m2m_notification', False): for f in instance._meta.many_to_many: if f.name in form.cleaned_data: old = set([str(x) for x in getattr(instance, f.name).all()]) new = set([str(x) for x in form.cleaned_data[f.name]]) added = new.difference(old) removed = old.difference(new) if added or removed: notify.write("--- {}\n+++ {}\n{}\n{}\n".format( f.verbose_name, f.verbose_name, "\n".join(["+ %s" % a for a in added]), "\n".join(["- %s" % r for r in removed]), )) else: # Regular field! # Sometimes it shows up as changed even if it hasn't changed, so do # a second check on if the diff is non-empty. diffrows = [x for x in difflib.unified_diff( old_values[f.name].splitlines(), str(form.cleaned_data[f.name]).splitlines(), n=1, lineterm='', fromfile=f.verbose_name, tofile=f.verbose_name, ) if not x.startswith("@@")] if diffrows: notify.write("\n".join(diffrows)) notify.write("\n\n") if do_notify and notify.tell(): send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "%s by %s" % (subj, request.user.username), "Title: {0}\n\n{1}".format( str(instance), notify.getvalue(), ), ) form.save_m2m() return HttpResponseRedirect(redirect) else: # Generate form form = formclass(instance=instance) if hasattr(form, 'filter_by_user'): form.filter_by_user(request.user) for fn in form.fields: if fn in getattr(instancetype, 'markdown_fields', []): form.fields[fn].widget.attrs.update({'class': 'markdown-content'}) for togg in getattr(form, 'toggle_fields', []): form.fields[togg['name']].widget.attrs.update({ 'data-toggles': ','.join(togg['fields']), 'data-toggle-invert': togg['invert'] and 'true' or 'false', 'class': 'toggle-checkbox', }) return render_pgweb(request, navsection, formtemplate, { 'form': form, 'formitemtype': instance._meta.verbose_name, 'form_intro': hasattr(form, 'form_intro') and form.form_intro or None, 'described_checkboxes': getattr(form, 'described_checkboxes', {}), 'savebutton': (itemid == "new") and "Submit New" or "Save", 'operation': (itemid == "new") and "New" or "Edit", })
def categorylist(request): categories = Category.objects.all() return render_pgweb(request, 'download', 'downloads/categorylist.html', { 'categories': categories, })
def ftpbrowser(request, subpath): if subpath: # An actual path has been selected. Fancy! if subpath.find('..') > -1: # Just claim it doesn't exist if the user tries to do this # type of bad thing raise Http404 subpath = subpath.strip('/') else: subpath = "" # Pickle up the list of things we need try: f = open(settings.FTP_PICKLE, "rb") allnodes = pickle.load(f) f.close() except Exception as e: return HttpServerError(request, "Failed to load ftp site information: %s" % e) # An incoming subpath may either be canonical, or have one or more elements # present that are actually symlinks. For each element of the path, test to # see if it is present in the pickle. If not, look for a symlink entry with # and if present, replace the original entry with the symlink target. canonpath = '' if subpath != '': parent = '' for d in subpath.split('/'): # Check if allnodes contains a node matching the path if d in allnodes[parent]: if allnodes[parent][d]['t'] == 'd': canonpath = os.path.join(canonpath, d) elif allnodes[parent][d]['t'] == 'l': canonpath = os.path.join(canonpath, allnodes[parent][d]['d']).strip('/') else: # There's a matching node, but it's not a link or a directory raise Http404 parent = canonpath else: # There's no matching node raise Http404 # If we wound up with a canonical path that doesn't match the original request, # redirect the user canonpath = canonpath.strip('/') if subpath != canonpath: return HttpResponseRedirect('/ftp/' + canonpath) node = allnodes[subpath] del allnodes # Add all directories directories = [{'link': k, 'url': k, 'type': 'd'} for k, v in list(node.items()) if v['t'] == 'd'] # Add all symlinks (only directories supported) directories.extend([{'link': k, 'url': v['d'], 'type': 'l'} for k, v in list(node.items()) if v['t'] == 'l']) # A ittle early sorting wouldn't go amiss, so .. ends up at the top directories.sort(key=version_sort, reverse=True) # Add a link to the parent directory if subpath: directories.insert(0, {'link': '[Parent Directory]', 'url': '..'}) # Fetch files files = [{'name': k, 'mtime': v['d'], 'size': v['s']} for k, v in list(node.items()) if v['t'] == 'f'] breadcrumbs = [] if subpath: breadroot = "" for pathpiece in subpath.split('/'): if not pathpiece: # Trailing slash will give out an empty pathpiece continue if breadroot: breadroot = "%s/%s" % (breadroot, pathpiece) else: breadroot = pathpiece breadcrumbs.append({'name': pathpiece, 'path': breadroot}) # Check if there are any "content files" we should render directly on the webpage file_readme = ('README' in node and node['README']['t'] == 'f') and node['README']['c'] or None file_message = ('.message' in node and node['.message']['t'] == 'f') and node['.message']['c'] or None file_maintainer = ('CURRENT_MAINTAINER' in node and node['CURRENT_MAINTAINER']['t'] == 'f') and node['CURRENT_MAINTAINER']['c'] or None del node return render_pgweb(request, 'download', 'downloads/ftpbrowser.html', { 'basepath': subpath.rstrip('/'), 'directories': directories, 'files': sorted(files, key=lambda f: f['name']), 'breadcrumbs': breadcrumbs, 'readme': file_readme, 'messagefile': file_message, 'maintainer': file_maintainer, })