Skip to content
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

stages/prompt: Add initial_data prompt field and ability to select a default choice for choice fields #5095

Merged
merged 11 commits into from Apr 19, 2023

Conversation

sdimovv
Copy link
Contributor

@sdimovv sdimovv commented Mar 27, 2023

Details

Changes

New Features

  • Adds ability to specify an initial value for a prompt field (separate from a placeholder). Works on all flows not only on user-settings.
  • Adds ability to select a default choice when creating a fixed choice field (radio-button-group, dropdown)

Breaking Changes

  • Strips away some of the responsibilities of the placeholder field. Namely - the responsibility of giving initial value to prompts in the user settings flow.

Additional

The breaking change should not affect the default authentik config as that will be updated from the updated default blueprints automatically. However, any custom prompt fields or blueprints will need to be manually updated so that their initial value is specified in the "initial_value" field instead of in the "placeholder" field.

@netlify
Copy link

netlify bot commented Mar 27, 2023

Deploy Preview for authentik ready!

Name Link
🔨 Latest commit 0c09f22
🔍 Latest deploy log https://app.netlify.com/sites/authentik/deploys/642201bc4aa18c0008f06aeb
😎 Deploy Preview https://deploy-preview-5095--authentik.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@sdimovv sdimovv changed the title stages/prompt: Feat initial_data prompt field and ability to select default choice value stages/prompt: Add initial_data prompt field and ability to select a default choice for choice fields Mar 27, 2023
@codecov
Copy link

codecov bot commented Mar 27, 2023

Codecov Report

Patch coverage: 90.48% and project coverage change: -0.01 ⚠️

Comparison is base (a7fc579) 92.77% compared to head (facdc71) 92.76%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5095      +/-   ##
==========================================
- Coverage   92.77%   92.76%   -0.01%     
==========================================
  Files         506      506              
  Lines       25779    25837      +58     
==========================================
+ Hits        23913    23964      +51     
- Misses       1866     1873       +7     
Flag Coverage Δ
e2e 52.61% <19.05%> (-0.08%) ⬇️
integration 26.29% <7.94%> (-0.09%) ⬇️
unit 89.58% <90.48%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
authentik/policies/password/tests/test_flows.py 100.00% <ø> (ø)
authentik/stages/prompt/api.py 100.00% <ø> (ø)
authentik/stages/prompt/models.py 94.18% <77.78%> (-2.87%) ⬇️
authentik/stages/prompt/stage.py 99.21% <100.00%> (+0.02%) ⬆️
authentik/stages/prompt/tests.py 100.00% <100.00%> (ø)

... and 8 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@sdimovv
Copy link
Contributor Author

sdimovv commented Mar 29, 2023

@BeryJu, would it be possible to merge this before 2023.4 is out?

Copy link
Member

@BeryJu BeryJu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

looking back at this retroactively I think it would've made more sense to have an option to select some sort of "Prompt mapping" in prompts instead of specifying expressions directly, but I'm also not all too sure if that would actually be better.

Also one other thing that might be worth adding is a bit better migration, basically changing the fields in the same way as the blueprints were

authentik/stages/prompt/tests.py Show resolved Hide resolved
@sdimovv
Copy link
Contributor Author

sdimovv commented Mar 30, 2023

Hi, thanks for taking a look at this!

looking back at this retroactively I think it would've made more sense to have an option to select some sort of "Prompt mapping" in prompts instead of specifying expressions directly, but I'm also not all too sure if that would actually be better.

Not sure I understand this correctly. Do you mean to add some extra fields in the model which do not apply to all prompt types? Until now I have been extremely careful not to add "prompt type specific" fields to the model, which is why this weird mapping to the placeholder was necessary for fixed choice prompts.

Otherwise the way I imagine this to work is for every prompt type to be a different model (if needed) in the DB with different properties. For example, fixed choice prompts will not have an a placeholder field but will instead have all_choices or something similar. Then the prompt creation endpoint will have a oneOf type API where you will be able to submit a request with the data needed by the specific prompt type you are creating.

However, I am not sure of the extent of (potentially breaking) changes this will introduce and did not want to submit such a PR without your approval and go-ahead first.

Also one other thing that might be worth adding is a bit better migration, basically changing the fields in the same way as the blueprints were

Do you mean to create a new migration that migrates placeholder fields to an initial value fields or? I haven't created a manual migration before so if this is required I might need to look up the Django docs on how to do that.

@BeryJu
Copy link
Member

BeryJu commented Mar 30, 2023

I meant instead of having the expression specified directly in the prompt, adding a ForeginKey to the mapping object, to make expressions re-usable (but again that's just random thoughts so don't worry about that too much)

For the migration I meant something like

def set_generated_name(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
Prompt = apps.get_model("authentik_stages_prompt", "prompt")
for prompt in Prompt.objects.using(db_alias).all():
name = prompt.field_key
stage = prompt.promptstage_set.order_by("name").first()
if stage:
name += "_" + stage.name
else:
name += "_" + str(uuid4())
prompt.name = name
prompt.save()
(and
migrations.RunPython(code=set_generated_name),
) and add it to the migration in the PR to migrate data to the new fields

@sdimovv
Copy link
Contributor Author

sdimovv commented Mar 30, 2023

For the migration I meant something like

Ah, so basically for every prompt in the DB that has "evaluate as expression" set (except fixed choice fields):

prompt.initial_value = prompt.placeholder
prompt.initial_value_expression = True
promp.placeholder = ""
prompt.placeholder_expression = False

Is that correct?

@sdimovv
Copy link
Contributor Author

sdimovv commented Mar 30, 2023

I think that should do it?

@sdimovv
Copy link
Contributor Author

sdimovv commented Apr 7, 2023

Hi @BeryJu ,

does this need anything else?

@tanberry
Copy link
Contributor

Hi @sdimovv quick question... you mention the "breaking change" of needing to manually update the any custom prompt fields or blueprints. Do you mention this in your docs in index.md? I didn't see it, but might have missed it. If it is not there, can you add a Note or some such to call it out? Thanks!

@sdimovv
Copy link
Contributor Author

sdimovv commented Apr 17, 2023

Hi @sdimovv quick question... you mention the "breaking change" of needing to manually update the any custom prompt fields or blueprints. Do you mention this in your docs in index.md? I didn't see it, but might have missed it. If it is not there, can you add a Note or some such to call it out? Thanks!

Hi @tanberry ,

Yes I don't think it is in the docs. However, since I wrote this, @BeryJu requested to add a manual migration step. You can see this here:

def migrate_placeholder_expressions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
from authentik.stages.prompt.models import CHOICE_FIELDS
db_alias = schema_editor.connection.alias
Prompt = apps.get_model("authentik_stages_prompt", "prompt")
for prompt in Prompt.objects.using(db_alias).all():
if not prompt.placeholder_expression or prompt.type in CHOICE_FIELDS:
continue
prompt.initial_value = prompt.placeholder
prompt.initial_value_expression = True
prompt.placeholder = ""
prompt.placeholder_expression = False
prompt.save()

This should automatically migrate all prompts (except the new choice prompts) that interpret the placeholder as expression to the new initial_value field. So the breaking change should be handled automatically. I tested this to be the case on a test instance but I will be happy for you to try it out as well.

@BeryJu BeryJu merged commit ee6edec into goauthentik:main Apr 19, 2023
51 of 53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants