-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
CRUD for EnvironmentVariables from Project's admin #4899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 15 commits
1884e62
ac572ba
f01bbbe
9a20328
74274cf
63b208d
26eba5a
67d29a4
88d70b5
74216af
b427496
3381e85
bd0b9fa
dec39ba
e7a2ea9
663f383
ca5cf05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
"""Project forms.""" | ||
|
||
from __future__ import ( | ||
|
@@ -8,6 +9,18 @@ | |
unicode_literals, | ||
) | ||
|
||
try: | ||
# TODO: remove this when we deprecate Python2 | ||
# re.fullmatch is >= Py3.4 only | ||
from re import fullmatch | ||
except ImportError: | ||
# https://stackoverflow.com/questions/30212413/backport-python-3-4s-regular-expression-fullmatch-to-python-2 | ||
import re | ||
|
||
def fullmatch(regex, string, flags=0): | ||
"""Emulate python-3.4 re.fullmatch().""" # noqa | ||
return re.match("(?:" + regex + r")\Z", string, flags=flags) | ||
|
||
from random import choice | ||
|
||
from builtins import object | ||
|
@@ -27,11 +40,11 @@ | |
from readthedocs.integrations.models import Integration | ||
from readthedocs.oauth.models import RemoteRepository | ||
from readthedocs.projects import constants | ||
from readthedocs.projects.constants import PUBLIC | ||
from readthedocs.projects.exceptions import ProjectSpamError | ||
from readthedocs.projects.models import ( | ||
Domain, | ||
EmailHook, | ||
EnvironmentVariable, | ||
Feature, | ||
Project, | ||
ProjectRelationship, | ||
|
@@ -758,3 +771,49 @@ class Meta(object): | |
def __init__(self, *args, **kwargs): | ||
super(FeatureForm, self).__init__(*args, **kwargs) | ||
self.fields['feature_id'].choices = Feature.FEATURES | ||
|
||
|
||
class EnvironmentVariableForm(forms.ModelForm): | ||
|
||
""" | ||
Form to add an EnvironmentVariable to a Project. | ||
|
||
This limits the name of the variable. | ||
""" | ||
|
||
project = forms.CharField(widget=forms.HiddenInput(), required=False) | ||
|
||
class Meta(object): | ||
model = EnvironmentVariable | ||
fields = ('name', 'value', 'project') | ||
|
||
def __init__(self, *args, **kwargs): | ||
self.project = kwargs.pop('project', None) | ||
super(EnvironmentVariableForm, self).__init__(*args, **kwargs) | ||
|
||
def clean_project(self): | ||
return self.project | ||
|
||
def clean_name(self): | ||
name = self.cleaned_data['name'] | ||
if name.startswith('__'): | ||
raise forms.ValidationError( | ||
_("Variable name can't start with __ (double underscore)"), | ||
) | ||
elif name.startswith('READTHEDOCS'): | ||
raise forms.ValidationError( | ||
_("Variable name can't start with READTHEDOCS"), | ||
) | ||
elif self.project.environmentvariable_set.filter(name=name).exists(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could add this as a constraint in the model There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. I suppose that we still need the validation in the form otherwise I think it will explode when trying to save it and the user will have a 500. |
||
raise forms.ValidationError( | ||
_('There is already a variable with this name for this project'), | ||
) | ||
elif ' ' in name: | ||
raise forms.ValidationError( | ||
_("Variable name can't contain spaces"), | ||
) | ||
elif not fullmatch('[a-zA-Z0-9_]+', name): | ||
raise forms.ValidationError( | ||
_('Only letters, numbers and underscore are allowed'), | ||
) | ||
return name |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need more docs than this. We should have a guide in
guides/
, something along the lines of "I need secrets or environment variables in my build" that mentions the use case of keeping secrets.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed a guide for this.
It mention only one example for now (using the secret to access to a user/pass protected URL). I'm not sure if we want to mention other cases or something else.