Skip to content
Snippets Groups Projects
Commit a6381135 authored by kaiyou's avatar kaiyou
Browse files

Apply transition functions before and after

parent 3c3af169
No related branches found
No related tags found
No related merge requests found
...@@ -51,6 +51,11 @@ class BaseApplication(object): ...@@ -51,6 +51,11 @@ class BaseApplication(object):
""" """
return True return True
def notify(self, profile):
""" Default notifying behavior is doing nothing
"""
return True
def delete(self, profile): def delete(self, profile):
""" Deleting an account generally requires application """ Deleting an account generally requires application
implementation, so this needs to be overridden implementation, so this needs to be overridden
......
...@@ -5,6 +5,7 @@ blueprint = flask.Blueprint("profile", __name__, template_folder="templates") ...@@ -5,6 +5,7 @@ blueprint = flask.Blueprint("profile", __name__, template_folder="templates")
import flask_login import flask_login
from hiboo import models, utils, application from hiboo import models, utils, application
from hiboo.profile import forms
def get_profile(service, **redirect_args): def get_profile(service, **redirect_args):
...@@ -21,30 +22,47 @@ def get_profile(service, **redirect_args): ...@@ -21,30 +22,47 @@ def get_profile(service, **redirect_args):
utils.force_redirect(utils.url_for("profile.create_quick", **redirect_args)) utils.force_redirect(utils.url_for("profile.create_quick", **redirect_args))
def transition(profile): def transition(profile, current, target, done=False):
""" Handle profile transitions as single-step workflows """ Handle profile transitions as single-step workflows
""" """
# These are coded as (current, target), None being a wildcard. # These are coded as (current, target), None being a wildcard.
# All matches apply, including wildcards. # All matches apply, including wildcards.
# Values are pairs of lists, first actions being applied before,
# then actions being applied after the transition.
TRANSITIONS = { TRANSITIONS = {
(None, models.Profile.BLOCKED): ["block"], (None, models.Profile.BLOCKED): (
(None, models.Profile.DELETED): ["delete"], ["block"],
(None, models.Profile.ACTIVE): ["activate"], ["notify"]
(models.Profile.REQUEST, models.Profile.ACTIVE): ["welcome"], ),
(None, models.Profile.DELETED): (
["delete"],
["notify"]
),
(None, models.Profile.ACTIVE): (
["activate"],
["notify"]
),
(models.Profile.REQUEST, models.Profile.ACTIVE): (
["welcome"],
[]
),
} }
app = application.registry.get(profile.service.application_id) app = application.registry.get(profile.service.application_id)
index = 1 if done else 0
empty = ([], [])
functions = ( functions = (
TRANSITIONS.get((profile.status, profile.transition), []) + TRANSITIONS.get((current, target), empty)[index] +
TRANSITIONS.get((None, profile.transition), []) + TRANSITIONS.get((None, target), empty)[index] +
TRANSITIONS.get((profile.status, None), []) TRANSITIONS.get((current, None), empty)[index]
) )
valid = any([ valid = any([
hasattr(app, function) and getattr(app, function)(profile) hasattr(app, function) and getattr(app, function)(profile)
for function in functions for function in functions
]) ])
if valid: if valid and not done:
profile.status = profile.transition profile.status = profile.transition
profile.transition = None profile.transition = None
transition(profile, current, target, True)
from hiboo.profile import login, admin, cli from hiboo.profile import login, admin, cli
\ No newline at end of file
...@@ -53,7 +53,7 @@ def set_status(profile_uuid, status): ...@@ -53,7 +53,7 @@ def set_status(profile_uuid, status):
actor=flask_login.current_user, actor=flask_login.current_user,
public=True public=True
) )
transition(profile) transition(profile, profile.status, profile.transition)
models.db.session.commit() models.db.session.commit()
flask.flash(_("Profile status change was requested"), "success") flask.flash(_("Profile status change was requested"), "success")
return flask.redirect(flask.url_for(".details", profile_uuid=profile_uuid)) return flask.redirect(flask.url_for(".details", profile_uuid=profile_uuid))
...@@ -63,8 +63,9 @@ def set_status(profile_uuid, status): ...@@ -63,8 +63,9 @@ def set_status(profile_uuid, status):
@security.admin_required() @security.admin_required()
def complete_transition(profile_uuid): def complete_transition(profile_uuid):
profile = models.Profile.query.get(profile_uuid) or flask.abort(404) profile = models.Profile.query.get(profile_uuid) or flask.abort(404)
profile.status = profile.transition current, target = profile.status, profile.transition
profile.transition = None profile.status, profile.transition = target, None
transition(profile, current, target, True)
models.db.session.commit() models.db.session.commit()
flask.flash(_("Profile status change was completed"), "success") flask.flash(_("Profile status change was completed"), "success")
return flask.redirect(flask.url_for(".details", profile_uuid=profile_uuid)) return flask.redirect(flask.url_for(".details", profile_uuid=profile_uuid))
......
...@@ -25,7 +25,7 @@ def create(service_uuid, create_for=False, quick=False): ...@@ -25,7 +25,7 @@ def create(service_uuid, create_for=False, quick=False):
service = models.Service.query.get(service_uuid) or flask.abort(404) service = models.Service.query.get(service_uuid) or flask.abort(404)
status = models.Profile.ACTIVE status = models.Profile.ACTIVE
is_admin = flask_login.current_user.is_admin is_admin = flask_login.current_user.is_admin
format = format.ProfileFormat.registry[service.profile_format] formatter = format.ProfileFormat.registry[service.profile_format]
# If the admin passed a user uuid, use that one, otherwise ignore it # If the admin passed a user uuid, use that one, otherwise ignore it
user = hiboo_user.get_user(intent="profile.create_for", create_for=None) if (create_for and is_admin) else flask_login.current_user user = hiboo_user.get_user(intent="profile.create_for", create_for=None) if (create_for and is_admin) else flask_login.current_user
# Check that profile creation is allowed # Check that profile creation is allowed
...@@ -45,11 +45,11 @@ def create(service_uuid, create_for=False, quick=False): ...@@ -45,11 +45,11 @@ def create(service_uuid, create_for=False, quick=False):
status = models.Profile.REQUEST status = models.Profile.REQUEST
# Initialize and validate the form before applying overrides # Initialize and validate the form before applying overrides
form = forms.ProfileForm() form = forms.ProfileForm()
form.username.validators = format.validators() form.username.validators = formatter.validators()
submit = form.validate_on_submit() submit = form.validate_on_submit()
# If this is a quick creation or the service prevents custom profile creation, force the username # If this is a quick creation or the service prevents custom profile creation, force the username
if quick or service.single_profile: if quick or service.single_profile:
for username in format.alternatives(format.coalesce(user.username)): for username in formatter.alternatives(formatter.coalesce(user.username)):
if not service.check_username(username): if not service.check_username(username):
form.force_username(username) form.force_username(username)
break break
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment