When loading permissions and the user does not exist, add records to the UserGroupAssignmentWaiting table that can be picked up later.
Request "profile" scope over OpenID so we can get a few more bits of information when avilable. Add a "clear_perissions" script Add an "add_permissions" script Add an "add_permissions" script When logging in for the first time, check for any awaiting permissions and assign them. Add "enumerate" as a whitelisted function to React Schema Add a "display_name" to the user table Add a test for adding a new permission Add a test for adding a user to group Adding a test for deleting all permissions. Adding a display name for the user table
This commit is contained in:
parent
6de91d2230
commit
160e19bb8c
|
@ -7,7 +7,8 @@ def main() -> None:
|
||||||
"""Main."""
|
"""Main."""
|
||||||
app = get_hacked_up_app_for_script()
|
app = get_hacked_up_app_for_script()
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
AuthorizationService.delete_all_permissions_and_recreate()
|
AuthorizationService.delete_all_permissions()
|
||||||
|
AuthorizationService.import_permissions_from_yaml_file()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import with_statement
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from logging.config import fileConfig
|
from logging.config import fileConfig
|
||||||
|
|
||||||
|
|
|
@ -1,331 +0,0 @@
|
||||||
"""empty message
|
|
||||||
|
|
||||||
Revision ID: e1d0d593c621
|
|
||||||
Revises:
|
|
||||||
Create Date: 2022-12-12 14:23:44.643766
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'e1d0d593c621'
|
|
||||||
down_revision = None
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.create_table('group',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('name', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('identifier', sa.String(length=255), nullable=True),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
op.create_table('message_model',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('identifier', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('name', sa.String(length=50), nullable=True),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_message_model_identifier'), 'message_model', ['identifier'], unique=True)
|
|
||||||
op.create_index(op.f('ix_message_model_name'), 'message_model', ['name'], unique=True)
|
|
||||||
op.create_table('permission_target',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('uri', sa.String(length=255), nullable=False),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('uri')
|
|
||||||
)
|
|
||||||
op.create_table('spec_reference_cache',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('identifier', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('display_name', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('process_model_id', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('type', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('file_name', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('relative_path', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('has_lanes', sa.Boolean(), nullable=True),
|
|
||||||
sa.Column('is_executable', sa.Boolean(), nullable=True),
|
|
||||||
sa.Column('is_primary', sa.Boolean(), nullable=True),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('identifier', 'type', name='_identifier_type_unique')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_spec_reference_cache_display_name'), 'spec_reference_cache', ['display_name'], unique=False)
|
|
||||||
op.create_index(op.f('ix_spec_reference_cache_identifier'), 'spec_reference_cache', ['identifier'], unique=False)
|
|
||||||
op.create_index(op.f('ix_spec_reference_cache_type'), 'spec_reference_cache', ['type'], unique=False)
|
|
||||||
op.create_table('spiff_logging',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('bpmn_process_identifier', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('bpmn_task_identifier', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('bpmn_task_name', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('bpmn_task_type', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('spiff_task_guid', sa.String(length=50), nullable=False),
|
|
||||||
sa.Column('timestamp', sa.DECIMAL(precision=17, scale=6), nullable=False),
|
|
||||||
sa.Column('message', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('current_user_id', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('spiff_step', sa.Integer(), nullable=False),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
op.create_table('user',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('username', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('service', sa.String(length=50), nullable=False),
|
|
||||||
sa.Column('service_id', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('email', sa.String(length=255), nullable=True),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('service', 'service_id', name='service_key'),
|
|
||||||
sa.UniqueConstraint('username')
|
|
||||||
)
|
|
||||||
op.create_table('message_correlation_property',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('identifier', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('message_model_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['message_model_id'], ['message_model.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('identifier', 'message_model_id', name='message_correlation_property_unique')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_message_correlation_property_identifier'), 'message_correlation_property', ['identifier'], unique=False)
|
|
||||||
op.create_table('message_triggerable_process_model',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('message_model_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_model_identifier', sa.String(length=50), nullable=False),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['message_model_id'], ['message_model.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('message_model_id')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_message_triggerable_process_model_process_model_identifier'), 'message_triggerable_process_model', ['process_model_identifier'], unique=False)
|
|
||||||
op.create_table('principal',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('user_id', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('group_id', sa.Integer(), nullable=True),
|
|
||||||
sa.CheckConstraint('NOT(user_id IS NULL AND group_id IS NULL)'),
|
|
||||||
sa.ForeignKeyConstraint(['group_id'], ['group.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('group_id'),
|
|
||||||
sa.UniqueConstraint('user_id')
|
|
||||||
)
|
|
||||||
op.create_table('process_instance',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_model_identifier', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('process_model_display_name', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('process_initiator_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('bpmn_json', sa.JSON(), nullable=True),
|
|
||||||
sa.Column('start_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('end_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('status', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('bpmn_version_control_type', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('bpmn_version_control_identifier', sa.String(length=255), nullable=True),
|
|
||||||
sa.Column('spiff_step', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['process_initiator_id'], ['user.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_process_instance_process_model_display_name'), 'process_instance', ['process_model_display_name'], unique=False)
|
|
||||||
op.create_index(op.f('ix_process_instance_process_model_identifier'), 'process_instance', ['process_model_identifier'], unique=False)
|
|
||||||
op.create_table('process_instance_report',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('identifier', sa.String(length=50), nullable=False),
|
|
||||||
sa.Column('report_metadata', sa.JSON(), nullable=True),
|
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('created_by_id', 'identifier', name='process_instance_report_unique')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_process_instance_report_created_by_id'), 'process_instance_report', ['created_by_id'], unique=False)
|
|
||||||
op.create_index(op.f('ix_process_instance_report_identifier'), 'process_instance_report', ['identifier'], unique=False)
|
|
||||||
op.create_table('refresh_token',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('token', sa.String(length=1024), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('user_id')
|
|
||||||
)
|
|
||||||
op.create_table('secret',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('key', sa.String(length=50), nullable=False),
|
|
||||||
sa.Column('value', sa.Text(), nullable=False),
|
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('key')
|
|
||||||
)
|
|
||||||
op.create_table('user_group_assignment',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('group_id', sa.Integer(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['group_id'], ['group.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('user_id', 'group_id', name='user_group_assignment_unique')
|
|
||||||
)
|
|
||||||
op.create_table('active_task',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('actual_owner_id', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('lane_assignment_id', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('form_file_name', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('ui_form_file_name', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('task_id', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('task_name', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('task_title', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('task_type', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('task_status', sa.String(length=50), nullable=True),
|
|
||||||
sa.Column('process_model_display_name', sa.String(length=255), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['actual_owner_id'], ['user.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['lane_assignment_id'], ['group.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('task_id', 'process_instance_id', name='active_task_unique')
|
|
||||||
)
|
|
||||||
op.create_table('message_correlation',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('message_correlation_property_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('name', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('value', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['message_correlation_property_id'], ['message_correlation_property.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('process_instance_id', 'message_correlation_property_id', 'name', name='message_instance_id_name_unique')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_message_correlation_message_correlation_property_id'), 'message_correlation', ['message_correlation_property_id'], unique=False)
|
|
||||||
op.create_index(op.f('ix_message_correlation_name'), 'message_correlation', ['name'], unique=False)
|
|
||||||
op.create_index(op.f('ix_message_correlation_process_instance_id'), 'message_correlation', ['process_instance_id'], unique=False)
|
|
||||||
op.create_index(op.f('ix_message_correlation_value'), 'message_correlation', ['value'], unique=False)
|
|
||||||
op.create_table('message_instance',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('message_model_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('message_type', sa.String(length=20), nullable=False),
|
|
||||||
sa.Column('payload', sa.JSON(), nullable=True),
|
|
||||||
sa.Column('status', sa.String(length=20), nullable=False),
|
|
||||||
sa.Column('failure_cause', sa.Text(), nullable=True),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['message_model_id'], ['message_model.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
op.create_table('permission_assignment',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('principal_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('permission_target_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('grant_type', sa.String(length=50), nullable=False),
|
|
||||||
sa.Column('permission', sa.String(length=50), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['permission_target_id'], ['permission_target.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['principal_id'], ['principal.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('principal_id', 'permission_target_id', 'permission', name='permission_assignment_uniq')
|
|
||||||
)
|
|
||||||
op.create_table('process_instance_metadata',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('key', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('value', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('process_instance_id', 'key', name='process_instance_metadata_unique')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_process_instance_metadata_key'), 'process_instance_metadata', ['key'], unique=False)
|
|
||||||
op.create_table('spiff_step_details',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('spiff_step', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('task_json', sa.JSON(), nullable=False),
|
|
||||||
sa.Column('timestamp', sa.DECIMAL(precision=17, scale=6), nullable=False),
|
|
||||||
sa.Column('completed_by_user_id', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('lane_assignment_id', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['lane_assignment_id'], ['group.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
op.create_table('active_task_user',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('active_task_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['active_task_id'], ['active_task.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('active_task_id', 'user_id', name='active_task_user_unique')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_active_task_user_active_task_id'), 'active_task_user', ['active_task_id'], unique=False)
|
|
||||||
op.create_index(op.f('ix_active_task_user_user_id'), 'active_task_user', ['user_id'], unique=False)
|
|
||||||
op.create_table('message_correlation_message_instance',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('message_instance_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('message_correlation_id', sa.Integer(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['message_correlation_id'], ['message_correlation.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['message_instance_id'], ['message_instance.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('message_instance_id', 'message_correlation_id', name='message_correlation_message_instance_unique')
|
|
||||||
)
|
|
||||||
op.create_index(op.f('ix_message_correlation_message_instance_message_correlation_id'), 'message_correlation_message_instance', ['message_correlation_id'], unique=False)
|
|
||||||
op.create_index(op.f('ix_message_correlation_message_instance_message_instance_id'), 'message_correlation_message_instance', ['message_instance_id'], unique=False)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_index(op.f('ix_message_correlation_message_instance_message_instance_id'), table_name='message_correlation_message_instance')
|
|
||||||
op.drop_index(op.f('ix_message_correlation_message_instance_message_correlation_id'), table_name='message_correlation_message_instance')
|
|
||||||
op.drop_table('message_correlation_message_instance')
|
|
||||||
op.drop_index(op.f('ix_active_task_user_user_id'), table_name='active_task_user')
|
|
||||||
op.drop_index(op.f('ix_active_task_user_active_task_id'), table_name='active_task_user')
|
|
||||||
op.drop_table('active_task_user')
|
|
||||||
op.drop_table('spiff_step_details')
|
|
||||||
op.drop_index(op.f('ix_process_instance_metadata_key'), table_name='process_instance_metadata')
|
|
||||||
op.drop_table('process_instance_metadata')
|
|
||||||
op.drop_table('permission_assignment')
|
|
||||||
op.drop_table('message_instance')
|
|
||||||
op.drop_index(op.f('ix_message_correlation_value'), table_name='message_correlation')
|
|
||||||
op.drop_index(op.f('ix_message_correlation_process_instance_id'), table_name='message_correlation')
|
|
||||||
op.drop_index(op.f('ix_message_correlation_name'), table_name='message_correlation')
|
|
||||||
op.drop_index(op.f('ix_message_correlation_message_correlation_property_id'), table_name='message_correlation')
|
|
||||||
op.drop_table('message_correlation')
|
|
||||||
op.drop_table('active_task')
|
|
||||||
op.drop_table('user_group_assignment')
|
|
||||||
op.drop_table('secret')
|
|
||||||
op.drop_table('refresh_token')
|
|
||||||
op.drop_index(op.f('ix_process_instance_report_identifier'), table_name='process_instance_report')
|
|
||||||
op.drop_index(op.f('ix_process_instance_report_created_by_id'), table_name='process_instance_report')
|
|
||||||
op.drop_table('process_instance_report')
|
|
||||||
op.drop_index(op.f('ix_process_instance_process_model_identifier'), table_name='process_instance')
|
|
||||||
op.drop_index(op.f('ix_process_instance_process_model_display_name'), table_name='process_instance')
|
|
||||||
op.drop_table('process_instance')
|
|
||||||
op.drop_table('principal')
|
|
||||||
op.drop_index(op.f('ix_message_triggerable_process_model_process_model_identifier'), table_name='message_triggerable_process_model')
|
|
||||||
op.drop_table('message_triggerable_process_model')
|
|
||||||
op.drop_index(op.f('ix_message_correlation_property_identifier'), table_name='message_correlation_property')
|
|
||||||
op.drop_table('message_correlation_property')
|
|
||||||
op.drop_table('user')
|
|
||||||
op.drop_table('spiff_logging')
|
|
||||||
op.drop_index(op.f('ix_spec_reference_cache_type'), table_name='spec_reference_cache')
|
|
||||||
op.drop_index(op.f('ix_spec_reference_cache_identifier'), table_name='spec_reference_cache')
|
|
||||||
op.drop_index(op.f('ix_spec_reference_cache_display_name'), table_name='spec_reference_cache')
|
|
||||||
op.drop_table('spec_reference_cache')
|
|
||||||
op.drop_table('permission_target')
|
|
||||||
op.drop_index(op.f('ix_message_model_name'), table_name='message_model')
|
|
||||||
op.drop_index(op.f('ix_message_model_identifier'), table_name='message_model')
|
|
||||||
op.drop_table('message_model')
|
|
||||||
op.drop_table('group')
|
|
||||||
# ### end Alembic commands ###
|
|
|
@ -21,17 +21,17 @@ groups:
|
||||||
admin:
|
admin:
|
||||||
users:
|
users:
|
||||||
[
|
[
|
||||||
admin,
|
admin@spiffworkflow.org,
|
||||||
]
|
]
|
||||||
Education:
|
Education:
|
||||||
users:
|
users:
|
||||||
[
|
[
|
||||||
malala
|
malala@spiffworkflow.org
|
||||||
]
|
]
|
||||||
President:
|
President:
|
||||||
users:
|
users:
|
||||||
[
|
[
|
||||||
nelson
|
nelson@spiffworkflow.org
|
||||||
]
|
]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
|
|
|
@ -27,6 +27,7 @@ class GroupModel(FlaskBpmnGroupModel):
|
||||||
identifier = db.Column(db.String(255))
|
identifier = db.Column(db.String(255))
|
||||||
|
|
||||||
user_group_assignments = relationship("UserGroupAssignmentModel", cascade="delete")
|
user_group_assignments = relationship("UserGroupAssignmentModel", cascade="delete")
|
||||||
|
user_group_assignments_waiting = relationship("UserGroupAssignmentWaitingModel", cascade="delete")
|
||||||
users = relationship( # type: ignore
|
users = relationship( # type: ignore
|
||||||
"UserModel",
|
"UserModel",
|
||||||
viewonly=True,
|
viewonly=True,
|
||||||
|
|
|
@ -29,9 +29,10 @@ class UserModel(SpiffworkflowBaseDBModel):
|
||||||
__tablename__ = "user"
|
__tablename__ = "user"
|
||||||
__table_args__ = (db.UniqueConstraint("service", "service_id", name="service_key"),)
|
__table_args__ = (db.UniqueConstraint("service", "service_id", name="service_key"),)
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
username = db.Column(db.String(255), nullable=False, unique=True) # should always be an email address.
|
username = db.Column(db.String(255), nullable=False, unique=True) # should always be a unique value
|
||||||
service = db.Column(db.String(50), nullable=False, unique=False) # not 'openid' -- google, aws
|
service = db.Column(db.String(50), nullable=False, unique=False) # not 'openid' -- google, aws
|
||||||
service_id = db.Column(db.String(255), nullable=False, unique=False)
|
service_id = db.Column(db.String(255), nullable=False, unique=False)
|
||||||
|
display_name = db.Column(db.String(255))
|
||||||
email = db.Column(db.String(255))
|
email = db.Column(db.String(255))
|
||||||
|
|
||||||
user_group_assignments = relationship("UserGroupAssignmentModel", cascade="delete") # type: ignore
|
user_group_assignments = relationship("UserGroupAssignmentModel", cascade="delete") # type: ignore
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
"""UserGroupAssignment."""
|
||||||
|
from flask_bpmn.models.db import db
|
||||||
|
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||||
|
from sqlalchemy import ForeignKey
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.group import GroupModel
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
|
||||||
|
|
||||||
|
class UserGroupAssignmentWaitingModel(SpiffworkflowBaseDBModel):
|
||||||
|
"""UserGroupAssignmentsWaitingModel - When a user is assinged to a group, but that user has not yet logged into
|
||||||
|
the system, this caches that assignment, so it can be applied at the time the user logs in."""
|
||||||
|
|
||||||
|
__tablename__ = "user_group_assignment_waiting"
|
||||||
|
__table_args__ = (
|
||||||
|
db.UniqueConstraint("username", "group_id", name="user_group_assignment_staged_unique"),
|
||||||
|
)
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
username = db.Column(db.String(255), nullable=False)
|
||||||
|
group_id = db.Column(ForeignKey(GroupModel.id), nullable=False)
|
||||||
|
|
||||||
|
group = relationship("GroupModel", overlaps="groups,user_group_assignment_waiting,users") # type: ignore
|
|
@ -141,7 +141,7 @@ def process_model_save(process_model_id: str, file_name: str) -> Union[str, Resp
|
||||||
@admin_blueprint.route("/process-models/<process_model_id>/run", methods=["GET"])
|
@admin_blueprint.route("/process-models/<process_model_id>/run", methods=["GET"])
|
||||||
def process_model_run(process_model_id: str) -> Union[str, Response]:
|
def process_model_run(process_model_id: str) -> Union[str, Response]:
|
||||||
"""Process_model_run."""
|
"""Process_model_run."""
|
||||||
user = UserService.create_user("internal", "Mr. Test", username="Mr. Test")
|
user = UserService.create_user("Mr. Test", "internal", "Mr. Test")
|
||||||
process_instance = (
|
process_instance = (
|
||||||
ProcessInstanceService.create_process_instance_from_process_model_identifier(
|
ProcessInstanceService.create_process_instance_from_process_model_identifier(
|
||||||
process_model_id, user
|
process_model_id, user
|
||||||
|
|
|
@ -341,5 +341,5 @@ def get_user_from_decoded_internal_token(decoded_token: dict) -> Optional[UserMo
|
||||||
)
|
)
|
||||||
if user:
|
if user:
|
||||||
return user
|
return user
|
||||||
user = UserService.create_user(service, service_id, username=service_id)
|
user = UserService.create_user(service_id, service, service_id)
|
||||||
return user
|
return user
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
"""Get_env."""
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.group import GroupModel
|
||||||
|
from spiffworkflow_backend.models.group import GroupNotFoundError
|
||||||
|
from spiffworkflow_backend.models.script_attributes_context import (
|
||||||
|
ScriptAttributesContext,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
from spiffworkflow_backend.models.user import UserNotFoundError
|
||||||
|
from spiffworkflow_backend.scripts.script import Script
|
||||||
|
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||||
|
from spiffworkflow_backend.services.group_service import GroupService
|
||||||
|
from spiffworkflow_backend.services.user_service import UserService
|
||||||
|
|
||||||
|
# add_permission("read", "test/*", "Editors")
|
||||||
|
class AddPermission(Script):
|
||||||
|
"""AddUserToGroup."""
|
||||||
|
|
||||||
|
def get_description(self) -> str:
|
||||||
|
"""Get_description."""
|
||||||
|
return """Add a permission to a group. ex: add_permission("read", "test/*", "Editors") """
|
||||||
|
|
||||||
|
def run(
|
||||||
|
self,
|
||||||
|
script_attributes_context: ScriptAttributesContext,
|
||||||
|
*args: Any,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Any:
|
||||||
|
"""Run."""
|
||||||
|
allowed_permission = args[0]
|
||||||
|
uri = args[1]
|
||||||
|
group_identifier = args[2]
|
||||||
|
group = GroupService.find_or_create_group(group_identifier)
|
||||||
|
target = AuthorizationService.find_or_create_permission_target(uri)
|
||||||
|
AuthorizationService.create_permission_for_principal(
|
||||||
|
group.principal, target, allowed_permission
|
||||||
|
)
|
|
@ -9,6 +9,7 @@ from spiffworkflow_backend.models.script_attributes_context import (
|
||||||
from spiffworkflow_backend.models.user import UserModel
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
from spiffworkflow_backend.models.user import UserNotFoundError
|
from spiffworkflow_backend.models.user import UserNotFoundError
|
||||||
from spiffworkflow_backend.scripts.script import Script
|
from spiffworkflow_backend.scripts.script import Script
|
||||||
|
from spiffworkflow_backend.services.group_service import GroupService
|
||||||
from spiffworkflow_backend.services.user_service import UserService
|
from spiffworkflow_backend.services.user_service import UserService
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ class AddUserToGroup(Script):
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
"""Get_description."""
|
"""Get_description."""
|
||||||
return """Add a given user to a given group."""
|
return """Add a given user to a given group. Ex. add_user_to_group(group='Education', service_id='1234123')"""
|
||||||
|
|
||||||
def run(
|
def run(
|
||||||
self,
|
self,
|
||||||
|
@ -28,16 +29,10 @@ class AddUserToGroup(Script):
|
||||||
"""Run."""
|
"""Run."""
|
||||||
username = args[0]
|
username = args[0]
|
||||||
group_identifier = args[1]
|
group_identifier = args[1]
|
||||||
|
|
||||||
|
group = GroupService.find_or_create_group(group_identifier)
|
||||||
user = UserModel.query.filter_by(username=username).first()
|
user = UserModel.query.filter_by(username=username).first()
|
||||||
if user is None:
|
if user:
|
||||||
raise UserNotFoundError(
|
|
||||||
f"Script 'add_user_to_group' could not find a user with username: {username}"
|
|
||||||
)
|
|
||||||
|
|
||||||
group = GroupModel.query.filter_by(identifier=group_identifier).first()
|
|
||||||
if group is None:
|
|
||||||
raise GroupNotFoundError(
|
|
||||||
f"Script 'add_user_to_group' could not find group with identifier '{group_identifier}'."
|
|
||||||
)
|
|
||||||
|
|
||||||
UserService.add_user_to_group(user, group)
|
UserService.add_user_to_group(user, group)
|
||||||
|
else:
|
||||||
|
UserService.add_waiting_group_assignment(username, group)
|
|
@ -0,0 +1,30 @@
|
||||||
|
"""Get_env."""
|
||||||
|
from typing import Any
|
||||||
|
from flask_bpmn.models.db import db
|
||||||
|
from spiffworkflow_backend.models.group import GroupModel
|
||||||
|
from spiffworkflow_backend.models.group import GroupNotFoundError
|
||||||
|
from spiffworkflow_backend.models.script_attributes_context import (
|
||||||
|
ScriptAttributesContext,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
from spiffworkflow_backend.models.user import UserNotFoundError
|
||||||
|
from spiffworkflow_backend.scripts.script import Script
|
||||||
|
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||||
|
from spiffworkflow_backend.services.user_service import UserService
|
||||||
|
|
||||||
|
|
||||||
|
class ClearPermissions(Script):
|
||||||
|
"""Clear all permissions across the system ."""
|
||||||
|
|
||||||
|
def get_description(self) -> str:
|
||||||
|
"""Get_description."""
|
||||||
|
return """Remove all groups and permissions from the database."""
|
||||||
|
|
||||||
|
def run(
|
||||||
|
self,
|
||||||
|
script_attributes_context: ScriptAttributesContext,
|
||||||
|
*args: Any,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Any:
|
||||||
|
"""Run."""
|
||||||
|
AuthorizationService.delete_all_permissions()
|
|
@ -93,7 +93,7 @@ class AuthenticationService:
|
||||||
+ f"?state={state}&"
|
+ f"?state={state}&"
|
||||||
+ "response_type=code&"
|
+ "response_type=code&"
|
||||||
+ f"client_id={self.client_id()}&"
|
+ f"client_id={self.client_id()}&"
|
||||||
+ "scope=openid email&"
|
+ "scope=openid profile email&"
|
||||||
+ f"redirect_uri={return_redirect_url}"
|
+ f"redirect_uri={return_redirect_url}"
|
||||||
)
|
)
|
||||||
return login_redirect_url
|
return login_redirect_url
|
||||||
|
|
|
@ -127,17 +127,15 @@ class AuthorizationService:
|
||||||
return cls.has_permission(principals, permission, target_uri)
|
return cls.has_permission(principals, permission, target_uri)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete_all_permissions_and_recreate(cls) -> None:
|
def delete_all_permissions(cls) -> None:
|
||||||
"""Delete_all_permissions_and_recreate."""
|
"""Delete_all_permissions_and_recreate. EXCEPT For permissions for the current user?"""
|
||||||
for model in [PermissionAssignmentModel, PermissionTargetModel]:
|
for model in [PermissionAssignmentModel, PermissionTargetModel]:
|
||||||
db.session.query(model).delete()
|
db.session.query(model).delete()
|
||||||
|
|
||||||
# cascading to principals doesn't seem to work when attempting to delete all so do it like this instead
|
# cascading to principals doesn't seem to work when attempting to delete all so do it like this instead
|
||||||
for group in GroupModel.query.all():
|
for group in GroupModel.query.all():
|
||||||
db.session.delete(group)
|
db.session.delete(group)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
cls.import_permissions_from_yaml_file()
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def associate_user_with_group(cls, user: UserModel, group: GroupModel) -> None:
|
def associate_user_with_group(cls, user: UserModel, group: GroupModel) -> None:
|
||||||
|
@ -193,14 +191,7 @@ class AuthorizationService:
|
||||||
"permissions"
|
"permissions"
|
||||||
].items():
|
].items():
|
||||||
uri = permission_config["uri"]
|
uri = permission_config["uri"]
|
||||||
uri_with_percent = re.sub(r"\*", "%", uri)
|
permission_target = cls.find_or_create_permission_target(uri)
|
||||||
permission_target = PermissionTargetModel.query.filter_by(
|
|
||||||
uri=uri_with_percent
|
|
||||||
).first()
|
|
||||||
if permission_target is None:
|
|
||||||
permission_target = PermissionTargetModel(uri=uri_with_percent)
|
|
||||||
db.session.add(permission_target)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
for allowed_permission in permission_config["allowed_permissions"]:
|
for allowed_permission in permission_config["allowed_permissions"]:
|
||||||
if "groups" in permission_config:
|
if "groups" in permission_config:
|
||||||
|
@ -226,6 +217,18 @@ class AuthorizationService:
|
||||||
for user in UserModel.query.all():
|
for user in UserModel.query.all():
|
||||||
cls.associate_user_with_group(user, default_group)
|
cls.associate_user_with_group(user, default_group)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_or_create_permission_target(cls, uri):
|
||||||
|
uri_with_percent = re.sub(r"\*", "%", uri)
|
||||||
|
permission_target = PermissionTargetModel.query.filter_by(
|
||||||
|
uri=uri_with_percent
|
||||||
|
).first()
|
||||||
|
if permission_target is None:
|
||||||
|
permission_target = PermissionTargetModel(uri=uri_with_percent)
|
||||||
|
db.session.add(permission_target)
|
||||||
|
db.session.commit()
|
||||||
|
return permission_target
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_permission_for_principal(
|
def create_permission_for_principal(
|
||||||
cls,
|
cls,
|
||||||
|
@ -449,40 +452,46 @@ class AuthorizationService:
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_user_from_sign_in(cls, user_info: dict) -> UserModel:
|
def create_user_from_sign_in(cls, user_info: dict) -> UserModel:
|
||||||
"""Create_user_from_sign_in."""
|
"""Create_user_from_sign_in."""
|
||||||
|
"""name, family_name, given_name, middle_name, nickname, preferred_username,"""
|
||||||
|
"""profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at. """
|
||||||
|
"""email"""
|
||||||
is_new_user = False
|
is_new_user = False
|
||||||
if user_info.get('email', None) is not None:
|
|
||||||
user_model = (
|
|
||||||
UserModel.query.filter(UserModel.email == user_info["email"]).first()
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
user_model = (
|
user_model = (
|
||||||
UserModel.query.filter(UserModel.service == user_info["iss"])
|
UserModel.query.filter(UserModel.service == user_info["iss"])
|
||||||
.filter(UserModel.service_id == user_info["sub"])
|
.filter(UserModel.service_id == user_info["sub"])
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
username = email = ""
|
email = display_name = username = ""
|
||||||
if "name" in user_info:
|
|
||||||
username = user_info["name"]
|
|
||||||
if "username" in user_info:
|
|
||||||
username = user_info["username"]
|
|
||||||
elif "preferred_username" in user_info:
|
|
||||||
username = user_info["preferred_username"]
|
|
||||||
if "email" in user_info:
|
if "email" in user_info:
|
||||||
|
username = user_info["email"]
|
||||||
email = user_info["email"]
|
email = user_info["email"]
|
||||||
|
else: # we fall back to the sub, which may be very ugly.
|
||||||
|
username = user_info["sub"] + "@" + user_info["iss"]
|
||||||
|
|
||||||
|
if "preferred_username" in user_info:
|
||||||
|
display_name = user_info["preferred_username"]
|
||||||
|
elif "nickname" in user_info:
|
||||||
|
display_name = user_info["nickname"]
|
||||||
|
elif "name" in user_info:
|
||||||
|
display_name = user_info["name"]
|
||||||
|
|
||||||
if user_model is None:
|
if user_model is None:
|
||||||
current_app.logger.debug("create_user in login_return")
|
current_app.logger.debug("create_user in login_return")
|
||||||
is_new_user = True
|
is_new_user = True
|
||||||
user_model = UserService().create_user(
|
user_model = UserService().create_user(
|
||||||
|
username=username,
|
||||||
service=user_info["iss"],
|
service=user_info["iss"],
|
||||||
service_id=user_info["sub"],
|
service_id=user_info["sub"],
|
||||||
username=username,
|
|
||||||
email=email,
|
email=email,
|
||||||
|
display_name = display_name
|
||||||
)
|
)
|
||||||
|
UserService().apply_waiting_group_assignments(user_model)
|
||||||
|
|
||||||
else :
|
else :
|
||||||
# Update with the latest information
|
# Update with the latest information
|
||||||
user_model.username = username
|
user_model.username = username
|
||||||
user_model.email = email
|
user_model.email = email
|
||||||
|
user_model.display_name = display_name
|
||||||
user_model.service = user_info["iss"]
|
user_model.service = user_info["iss"]
|
||||||
user_model.service_id = user_info["sub"]
|
user_model.service_id = user_info["sub"]
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,7 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
|
||||||
"time": time,
|
"time": time,
|
||||||
"decimal": decimal,
|
"decimal": decimal,
|
||||||
"_strptime": _strptime,
|
"_strptime": _strptime,
|
||||||
|
"enumerate": enumerate,
|
||||||
}
|
}
|
||||||
|
|
||||||
# This will overwrite the standard builtins
|
# This will overwrite the standard builtins
|
||||||
|
|
|
@ -13,6 +13,7 @@ from spiffworkflow_backend.models.group import GroupModel
|
||||||
from spiffworkflow_backend.models.principal import PrincipalModel
|
from spiffworkflow_backend.models.principal import PrincipalModel
|
||||||
from spiffworkflow_backend.models.user import UserModel
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
from spiffworkflow_backend.models.user_group_assignment import UserGroupAssignmentModel
|
from spiffworkflow_backend.models.user_group_assignment import UserGroupAssignmentModel
|
||||||
|
from spiffworkflow_backend.models.user_group_assignment_waiting import UserGroupAssignmentWaitingModel
|
||||||
|
|
||||||
|
|
||||||
class UserService:
|
class UserService:
|
||||||
|
@ -21,10 +22,11 @@ class UserService:
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_user(
|
def create_user(
|
||||||
cls,
|
cls,
|
||||||
|
username: str,
|
||||||
service: str,
|
service: str,
|
||||||
service_id: str,
|
service_id: str,
|
||||||
username: Optional[str] = "",
|
|
||||||
email: Optional[str] = "",
|
email: Optional[str] = "",
|
||||||
|
display_name: Optional[str] = ""
|
||||||
) -> UserModel:
|
) -> UserModel:
|
||||||
"""Create_user."""
|
"""Create_user."""
|
||||||
user_model: Optional[UserModel] = (
|
user_model: Optional[UserModel] = (
|
||||||
|
@ -41,6 +43,7 @@ class UserService:
|
||||||
service=service,
|
service=service,
|
||||||
service_id=service_id,
|
service_id=service_id,
|
||||||
email=email,
|
email=email,
|
||||||
|
display_name=display_name
|
||||||
)
|
)
|
||||||
db.session.add(user_model)
|
db.session.add(user_model)
|
||||||
|
|
||||||
|
@ -124,10 +127,28 @@ class UserService:
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_user_to_group(cls, user: UserModel, group: GroupModel) -> None:
|
def add_user_to_group(cls, user: UserModel, group: GroupModel) -> None:
|
||||||
"""Add_user_to_group."""
|
"""Add_user_to_group."""
|
||||||
|
exists = UserGroupAssignmentModel().query.filter_by(user_id=user.id).filter_by(group_id=group.id).count()
|
||||||
|
if not exists:
|
||||||
ugam = UserGroupAssignmentModel(user_id=user.id, group_id=group.id)
|
ugam = UserGroupAssignmentModel(user_id=user.id, group_id=group.id)
|
||||||
db.session.add(ugam)
|
db.session.add(ugam)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_waiting_group_assignment(cls, username: str, group: GroupModel) -> None:
|
||||||
|
exists = UserGroupAssignmentWaitingModel().query.filter_by(username=username).filter_by(group_id=group.id).count()
|
||||||
|
if not exists:
|
||||||
|
wugam = UserGroupAssignmentWaitingModel(username=username, group_id=group.id)
|
||||||
|
db.session.add(wugam)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def apply_waiting_group_assignments(cls, user: UserModel) -> None:
|
||||||
|
waiting = UserGroupAssignmentWaitingModel().query.filter(UserGroupAssignmentWaitingModel.username == user.username).all()
|
||||||
|
for assignment in waiting:
|
||||||
|
cls.add_user_to_group(user, assignment.group)
|
||||||
|
db.session.delete(assignment)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user_by_service_and_service_id(
|
def get_user_by_service_and_service_id(
|
||||||
service: str, service_id: str
|
service: str, service_id: str
|
||||||
|
|
|
@ -41,7 +41,7 @@ class BaseTest:
|
||||||
if isinstance(user, UserModel):
|
if isinstance(user, UserModel):
|
||||||
return user
|
return user
|
||||||
|
|
||||||
user = UserService.create_user("internal", username, username=username)
|
user = UserService.create_user(username, "internal", username)
|
||||||
if isinstance(user, UserModel):
|
if isinstance(user, UserModel):
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
"""Test_get_localtime."""
|
||||||
|
from flask.app import Flask
|
||||||
|
from flask.testing import FlaskClient
|
||||||
|
from flask_bpmn.models.db import db
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.permission_assignment import PermissionAssignmentModel
|
||||||
|
from spiffworkflow_backend.models.permission_target import PermissionTargetModel
|
||||||
|
from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
|
||||||
|
from spiffworkflow_backend.scripts.add_permission import AddPermission
|
||||||
|
from spiffworkflow_backend.scripts.clear_permissions import ClearPermissions
|
||||||
|
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||||
|
from spiffworkflow_backend.services.group_service import GroupService
|
||||||
|
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||||
|
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.group import GroupModel
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
from spiffworkflow_backend.services.process_instance_processor import (
|
||||||
|
ProcessInstanceProcessor,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.services.user_service import UserService
|
||||||
|
|
||||||
|
|
||||||
|
class TestAddPermission(BaseTest):
|
||||||
|
"""TestAddPermission."""
|
||||||
|
|
||||||
|
def test_can_add_permission (
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Test_can_get_members_of_a_group."""
|
||||||
|
test_user = self.find_or_create_user("test_user")
|
||||||
|
|
||||||
|
# now that we have everything, try to clear it out...
|
||||||
|
script_attributes_context = ScriptAttributesContext(
|
||||||
|
task=None,
|
||||||
|
environment_identifier="testing",
|
||||||
|
process_instance_id=1,
|
||||||
|
process_model_identifier="my_test_user",
|
||||||
|
)
|
||||||
|
|
||||||
|
group = GroupModel.query.filter(GroupModel.identifier == 'my_test_group').first()
|
||||||
|
permission_target = PermissionTargetModel.query.filter(PermissionTargetModel.uri == '/test_add_permission/%').first()
|
||||||
|
assert(group is None)
|
||||||
|
assert(permission_target is None)
|
||||||
|
|
||||||
|
result = AddPermission().run(
|
||||||
|
script_attributes_context,
|
||||||
|
"read",
|
||||||
|
"/test_add_permission/*",
|
||||||
|
"my_test_group"
|
||||||
|
)
|
||||||
|
group = GroupModel.query.filter(GroupModel.identifier == 'my_test_group').first()
|
||||||
|
permission_target = PermissionTargetModel.query.filter(PermissionTargetModel.uri == '/test_add_permission/%').first()
|
||||||
|
permission_assignments = PermissionAssignmentModel.query.filter(PermissionAssignmentModel.principal_id == group.principal.id).all()
|
||||||
|
assert(group is not None)
|
||||||
|
assert(permission_target is not None)
|
||||||
|
assert(len(permission_assignments) == 1)
|
|
@ -0,0 +1,68 @@
|
||||||
|
"""Test_get_localtime."""
|
||||||
|
from flask.app import Flask
|
||||||
|
from flask.testing import FlaskClient
|
||||||
|
from flask_bpmn.models.db import db
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
|
||||||
|
from spiffworkflow_backend.models.user_group_assignment_waiting import UserGroupAssignmentWaitingModel
|
||||||
|
from spiffworkflow_backend.scripts.add_user_to_group import AddUserToGroup
|
||||||
|
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||||
|
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.group import GroupModel
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
from spiffworkflow_backend.services.process_instance_processor import (
|
||||||
|
ProcessInstanceProcessor,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.services.user_service import UserService
|
||||||
|
|
||||||
|
|
||||||
|
class TestAddUserToGroup(BaseTest):
|
||||||
|
"""TestGetGroupMembers."""
|
||||||
|
|
||||||
|
def test_can_add_existing_user_to_existing_group(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Test_can_get_members_of_a_group."""
|
||||||
|
my_user = self.find_or_create_user("my_user")
|
||||||
|
my_group = GroupModel(identifier="my_group")
|
||||||
|
db.session.add(my_group)
|
||||||
|
script_attributes_context = ScriptAttributesContext(
|
||||||
|
task=None,
|
||||||
|
environment_identifier="testing",
|
||||||
|
process_instance_id=1,
|
||||||
|
process_model_identifier="my_test_user",
|
||||||
|
)
|
||||||
|
result = AddUserToGroup().run(
|
||||||
|
script_attributes_context,
|
||||||
|
my_user.username,
|
||||||
|
my_group.identifier
|
||||||
|
)
|
||||||
|
assert(my_user in my_group.users)
|
||||||
|
|
||||||
|
def test_can_add_non_existent_user_to_non_existent_group(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
script_attributes_context = ScriptAttributesContext(
|
||||||
|
task=None,
|
||||||
|
environment_identifier="testing",
|
||||||
|
process_instance_id=1,
|
||||||
|
process_model_identifier="my_test_user",
|
||||||
|
)
|
||||||
|
result = AddUserToGroup().run(
|
||||||
|
script_attributes_context,
|
||||||
|
"dan@sartography.com",
|
||||||
|
"competent-joes"
|
||||||
|
)
|
||||||
|
my_group = GroupModel.query.filter(GroupModel.identifier == "competent-joes").first()
|
||||||
|
assert (my_group is not None)
|
||||||
|
waiting_assignments = UserGroupAssignmentWaitingModel().query.filter_by(username="dan@sartography.com").first()
|
||||||
|
assert (waiting_assignments is not None)
|
|
@ -0,0 +1,64 @@
|
||||||
|
"""Test_get_localtime."""
|
||||||
|
from flask.app import Flask
|
||||||
|
from flask.testing import FlaskClient
|
||||||
|
from flask_bpmn.models.db import db
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.permission_target import PermissionTargetModel
|
||||||
|
from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
|
||||||
|
from spiffworkflow_backend.scripts.clear_permissions import ClearPermissions
|
||||||
|
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||||
|
from spiffworkflow_backend.services.group_service import GroupService
|
||||||
|
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||||
|
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.group import GroupModel
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
from spiffworkflow_backend.services.process_instance_processor import (
|
||||||
|
ProcessInstanceProcessor,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.services.user_service import UserService
|
||||||
|
|
||||||
|
|
||||||
|
class TestDeletePermissions(BaseTest):
|
||||||
|
"""TestGetGroupMembers."""
|
||||||
|
|
||||||
|
def test_can_delete_members (
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Test_can_get_members_of_a_group."""
|
||||||
|
initiator_user = self.find_or_create_user("initiator_user")
|
||||||
|
testuser1 = self.find_or_create_user("testuser1")
|
||||||
|
testuser2 = self.find_or_create_user("testuser2")
|
||||||
|
testuser3 = self.find_or_create_user("testuser3")
|
||||||
|
group_a = GroupService.find_or_create_group('groupA')
|
||||||
|
group_b = GroupService.find_or_create_group('groupB')
|
||||||
|
db.session.add(group_a)
|
||||||
|
db.session.add(group_b)
|
||||||
|
db.session.commit()
|
||||||
|
UserService.add_user_to_group(testuser1, group_a)
|
||||||
|
UserService.add_user_to_group(testuser2, group_a)
|
||||||
|
UserService.add_user_to_group(testuser3, group_b)
|
||||||
|
|
||||||
|
target = PermissionTargetModel('test/*')
|
||||||
|
db.session.add(target)
|
||||||
|
db.session.commit()
|
||||||
|
AuthorizationService.create_permission_for_principal(group_a.principal,
|
||||||
|
target,
|
||||||
|
"read")
|
||||||
|
# now that we have everything, try to clear it out...
|
||||||
|
script_attributes_context = ScriptAttributesContext(
|
||||||
|
task=None,
|
||||||
|
environment_identifier="testing",
|
||||||
|
process_instance_id=1,
|
||||||
|
process_model_identifier="my_test_user",
|
||||||
|
)
|
||||||
|
result = ClearPermissions().run(
|
||||||
|
script_attributes_context
|
||||||
|
)
|
||||||
|
|
||||||
|
groups = GroupModel.query.all()
|
||||||
|
assert(0 == len(groups))
|
|
@ -134,7 +134,7 @@ class TestAuthorizationService(BaseTest):
|
||||||
active_task.task_name, processor.bpmn_process_instance
|
active_task.task_name, processor.bpmn_process_instance
|
||||||
)
|
)
|
||||||
finance_user = AuthorizationService.create_user_from_sign_in(
|
finance_user = AuthorizationService.create_user_from_sign_in(
|
||||||
{"username": "testuser2", "sub": "open_id", "iss": "https://test.stuff"}
|
{"username": "testuser2", "sub": "testuser2", "iss": "https://test.stuff", "email": "testuser2"}
|
||||||
)
|
)
|
||||||
ProcessInstanceService.complete_form_task(
|
ProcessInstanceService.complete_form_task(
|
||||||
processor, spiff_task, {}, finance_user, active_task
|
processor, spiff_task, {}, finance_user, active_task
|
||||||
|
|
Loading…
Reference in New Issue