Fixed an issue where organization details could not be updated

This commit is contained in:
Ivan Kravets
2023-03-27 18:59:06 -06:00
parent bea5e87543
commit 0fb064eba3
6 changed files with 63 additions and 59 deletions

View File

@ -25,6 +25,7 @@ PlatformIO Core 6
* Implemented a fix for shell injection vulnerabilities when converting INO files to CPP, ensuring your code is safe and secure (`issue #4532 <https://github.com/platformio/platformio-core/issues/4532>`_) * Implemented a fix for shell injection vulnerabilities when converting INO files to CPP, ensuring your code is safe and secure (`issue #4532 <https://github.com/platformio/platformio-core/issues/4532>`_)
* Restored the project generator for the `NetBeans IDE <https://docs.platformio.org/en/latest/integration/ide/netbeans.html>`__, providing you with more flexibility and options for your development workflow * Restored the project generator for the `NetBeans IDE <https://docs.platformio.org/en/latest/integration/ide/netbeans.html>`__, providing you with more flexibility and options for your development workflow
* Resolved an issue where the `build_cache_dir <https://docs.platformio.org/en/latest/projectconf/sections/platformio/options/directory/build_cache_dir.html>`__ setting was not being recognized consistently across multiple environments (`issue #4574 <https://github.com/platformio/platformio-core/issues/4574>`_) * Resolved an issue where the `build_cache_dir <https://docs.platformio.org/en/latest/projectconf/sections/platformio/options/directory/build_cache_dir.html>`__ setting was not being recognized consistently across multiple environments (`issue #4574 <https://github.com/platformio/platformio-core/issues/4574>`_)
* Fixed an issue where organization details could not be updated using the `pio org update <https://docs.platformio.org/en/latest/core/userguide/org/cmd_update.html>`__ command, ensuring that your organization's information remains up-to-date and accurate
6.1.6 (2023-01-23) 6.1.6 (2023-01-23)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~

View File

@ -22,29 +22,27 @@ from platformio.account.validate import validate_email, validate_orgname
@click.argument("cur_orgname") @click.argument("cur_orgname")
@click.option( @click.option(
"--orgname", "--orgname",
callback=lambda _, __, value: validate_orgname(value), callback=lambda _, __, value: validate_orgname(value) if value else value,
help="A new orgname", help="A new orgname",
) )
@click.option("--email") @click.option(
"--email",
callback=lambda _, __, value: validate_email(value) if value else value,
)
@click.option("--displayname") @click.option("--displayname")
def org_update_cmd(cur_orgname, **kwargs): def org_update_cmd(cur_orgname, **kwargs):
client = AccountClient() client = AccountClient()
org = client.get_org(cur_orgname) org = client.get_org(cur_orgname)
del org["owners"] new_org = {
new_org = org.copy() key: value if value is not None else org[key] for key, value in kwargs.items()
}
if not any(kwargs.values()): if not any(kwargs.values()):
for field in org: for key in kwargs:
new_org[field] = click.prompt( new_org[key] = click.prompt(key.capitalize(), default=org[key])
field.replace("_", " ").capitalize(), default=org[field] if key == "email":
) validate_email(new_org[key])
if field == "email": if key == "orgname":
validate_email(new_org[field]) validate_orgname(new_org[key])
if field == "orgname":
validate_orgname(new_org[field])
else:
new_org.update(
{key.replace("new_", ""): value for key, value in kwargs.items() if value}
)
client.update_org(cur_orgname, new_org) client.update_org(cur_orgname, new_org)
return click.secho( return click.secho(
"The organization `%s` has been successfully updated." % cur_orgname, "The organization `%s` has been successfully updated." % cur_orgname,

View File

@ -22,9 +22,7 @@ from platformio.account.validate import validate_orgname_teamname
@click.argument( @click.argument(
"orgname_teamname", "orgname_teamname",
metavar="ORGNAME:TEAMNAME", metavar="ORGNAME:TEAMNAME",
callback=lambda _, __, value: validate_orgname_teamname( callback=lambda _, __, value: validate_orgname_teamname(value),
value, teamname_validate=True
),
) )
@click.option( @click.option(
"--description", "--description",

View File

@ -26,7 +26,7 @@ from platformio.account.validate import validate_orgname_teamname, validate_team
) )
@click.option( @click.option(
"--name", "--name",
callback=lambda _, __, value: validate_teamname(value), callback=lambda _, __, value: validate_teamname(value) if value else value,
help="A new team name", help="A new team name",
) )
@click.option( @click.option(
@ -36,18 +36,14 @@ def team_update_cmd(orgname_teamname, **kwargs):
orgname, teamname = orgname_teamname.split(":", 1) orgname, teamname = orgname_teamname.split(":", 1)
client = AccountClient() client = AccountClient()
team = client.get_team(orgname, teamname) team = client.get_team(orgname, teamname)
del team["id"] new_team = {
del team["members"] key: value if value is not None else team[key] for key, value in kwargs.items()
new_team = team.copy() }
if not any(kwargs.values()): if not any(kwargs.values()):
for field in team: for key in kwargs:
new_team[field] = click.prompt( new_team[key] = click.prompt(key.capitalize(), default=team[key])
field.replace("_", " ").capitalize(), default=team[field] if key == "name":
) validate_teamname(new_team[key])
if field == "name":
validate_teamname(new_team[field])
else:
new_team.update({key: value for key, value in kwargs.items() if value})
client.update_team(orgname, teamname, new_team) client.update_team(orgname, teamname, new_team)
return click.secho( return click.secho(
"The team %s has been successfully updated." % teamname, "The team %s has been successfully updated." % teamname,

View File

@ -18,8 +18,10 @@ import click
def validate_username(value, field="username"): def validate_username(value, field="username"):
value = str(value).strip() value = str(value).strip() if value else None
if not re.match(r"^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,37}$", value, flags=re.I): if not value or not re.match(
r"^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,37}$", value, flags=re.I
):
raise click.BadParameter( raise click.BadParameter(
"Invalid %s format. " "Invalid %s format. "
"%s must contain only alphanumeric characters " "%s must contain only alphanumeric characters "
@ -30,16 +32,22 @@ def validate_username(value, field="username"):
return value return value
def validate_orgname(value):
return validate_username(value, "Organization name")
def validate_email(value): def validate_email(value):
value = str(value).strip() value = str(value).strip() if value else None
if not re.match(r"^[a-z\d_\.\+\-]+@[a-z\d\-]+\.[a-z\d\-\.]+$", value, flags=re.I): if not value or not re.match(
r"^[a-z\d_\.\+\-]+@[a-z\d\-]+\.[a-z\d\-\.]+$", value, flags=re.I
):
raise click.BadParameter("Invalid email address") raise click.BadParameter("Invalid email address")
return value return value
def validate_password(value): def validate_password(value):
value = str(value).strip() value = str(value).strip() if value else None
if not re.match(r"^(?=.*[a-z])(?=.*\d).{8,}$", value): if not value or not re.match(r"^(?=.*[a-z])(?=.*\d).{8,}$", value):
raise click.BadParameter( raise click.BadParameter(
"Invalid password format. " "Invalid password format. "
"Password must contain at least 8 characters" "Password must contain at least 8 characters"
@ -48,27 +56,11 @@ def validate_password(value):
return value return value
def validate_orgname(value):
return validate_username(value, "Organization name")
def validate_orgname_teamname(value, teamname_validate=False):
if ":" not in value:
raise click.BadParameter(
"Please specify organization and team name in the next"
" format - orgname:teamname. For example, mycompany:DreamTeam"
)
teamname = str(value.strip().split(":", 1)[1])
if teamname_validate:
validate_teamname(teamname)
return value
def validate_teamname(value): def validate_teamname(value):
if not value: value = str(value).strip() if value else None
return value if not value or not re.match(
value = str(value).strip() r"^[a-z\d](?:[a-z\d]|[\-_ ](?=[a-z\d])){0,19}$", value, flags=re.I
if not re.match(r"^[a-z\d](?:[a-z\d]|[\-_ ](?=[a-z\d])){0,19}$", value, flags=re.I): ):
raise click.BadParameter( raise click.BadParameter(
"Invalid team name format. " "Invalid team name format. "
"Team name must only contain alphanumeric characters, " "Team name must only contain alphanumeric characters, "
@ -77,3 +69,16 @@ def validate_teamname(value):
" not be longer than 20 characters." " not be longer than 20 characters."
) )
return value return value
def validate_orgname_teamname(value):
value = str(value).strip() if value else None
if not value or ":" not in value:
raise click.BadParameter(
"Please specify organization and team name using the following"
" format - orgname:teamname. For example, mycompany:DreamTeam"
)
orgname, teamname = value.split(":", 1)
validate_orgname(orgname)
validate_teamname(teamname)
return value

View File

@ -22,6 +22,7 @@ from platformio import fs, proc
from platformio.package.manager.platform import PlatformPackageManager from platformio.package.manager.platform import PlatformPackageManager
from platformio.platform.factory import PlatformFactory from platformio.platform.factory import PlatformFactory
from platformio.project.config import ProjectConfig from platformio.project.config import ProjectConfig
from platformio.project.exception import ProjectError
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
@ -64,13 +65,18 @@ def pytest_generate_tests(metafunc):
def test_run(pioproject_dir): def test_run(pioproject_dir):
with fs.cd(pioproject_dir): with fs.cd(pioproject_dir):
config = ProjectConfig() config = ProjectConfig()
# temporary fix for unreleased dev-platforms with broken env name
try:
config.validate()
except ProjectError as exc:
pytest.skip(str(exc))
build_dir = config.get("platformio", "build_dir") build_dir = config.get("platformio", "build_dir")
if os.path.isdir(build_dir): if os.path.isdir(build_dir):
fs.rmtree(build_dir) fs.rmtree(build_dir)
env_names = config.envs() env_names = config.envs()
# temporary fix for unreleased dev-platforms with broken env name
env_names = [name for name in env_names if " " not in name]
result = proc.exec_command( result = proc.exec_command(
["platformio", "run", "-e", random.choice(env_names)] ["platformio", "run", "-e", random.choice(env_names)]
) )