Files
mediacms/lti/migrations/0001_initial.py
Markos Gogoulos 06bc64b2c4 all
2025-12-29 18:21:44 +02:00

191 lines
10 KiB
Python

# Generated by Django 5.2.6 on 2025-12-29 16:15
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('files', '0015_category_is_lms_course_category_lti_context_id'),
('rbac', '0003_alter_rbacgroup_members'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='LTIToolKeys',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key_id', models.CharField(default='mediacms-lti-key', help_text='Key identifier', max_length=255, unique=True)),
('private_key_jwk', models.JSONField(help_text='Private key in JWK format (for signing)')),
('public_key_jwk', models.JSONField(help_text='Public key in JWK format (for JWKS endpoint)')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'LTI Tool Keys',
'verbose_name_plural': 'LTI Tool Keys',
},
),
migrations.CreateModel(
name='LTIPlatform',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text="Platform name (e.g., 'Moodle Production')", max_length=255, unique=True)),
('platform_id', models.URLField(help_text="Platform's issuer URL (iss claim, e.g., https://moodle.example.com)")),
('client_id', models.CharField(help_text='Client ID provided by the platform', max_length=255)),
('auth_login_url', models.URLField(help_text='OIDC authentication endpoint URL')),
('auth_token_url', models.URLField(help_text='OAuth2 token endpoint URL')),
('auth_audience', models.URLField(blank=True, help_text='OAuth2 audience (optional)', null=True)),
('key_set_url', models.URLField(help_text="Platform's public JWK Set URL")),
('deployment_ids', models.JSONField(default=list, help_text='List of deployment IDs for this platform')),
('enable_nrps', models.BooleanField(default=True, help_text='Enable Names and Role Provisioning Service')),
('enable_deep_linking', models.BooleanField(default=True, help_text='Enable Deep Linking 2.0')),
('remove_from_groups_on_unenroll', models.BooleanField(default=False, help_text="Remove users from RBAC groups when they're no longer in the course")),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'LTI Platform',
'verbose_name_plural': 'LTI Platforms',
'unique_together': {('platform_id', 'client_id')},
},
),
migrations.CreateModel(
name='LTIResourceLink',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('context_id', models.CharField(db_index=True, help_text='LTI context ID (typically course ID)', max_length=255)),
('context_title', models.CharField(blank=True, help_text='Course title', max_length=255)),
('context_label', models.CharField(blank=True, help_text='Course short name/code', max_length=100)),
('resource_link_id', models.CharField(db_index=True, help_text='LTI resource link ID', max_length=255)),
('resource_link_title', models.CharField(blank=True, help_text='Resource link title', max_length=255)),
(
'category',
models.ForeignKey(
blank=True, help_text='Mapped MediaCMS category', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='lti_resource_links', to='files.category'
),
),
('platform', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resource_links', to='lti.ltiplatform')),
(
'rbac_group',
models.ForeignKey(
blank=True, help_text='RBAC group for course members', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='lti_resource_links', to='rbac.rbacgroup'
),
),
],
options={
'verbose_name': 'LTI Resource Link',
'verbose_name_plural': 'LTI Resource Links',
},
),
migrations.CreateModel(
name='LTILaunchLog',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('launch_type', models.CharField(choices=[('resource_link', 'Resource Link Launch'), ('deep_linking', 'Deep Linking')], default='resource_link', max_length=50)),
('success', models.BooleanField(db_index=True, default=True, help_text='Whether the launch was successful')),
('error_message', models.TextField(blank=True, help_text='Error message if launch failed')),
('claims', models.JSONField(help_text='Sanitized LTI claims from the launch')),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
(
'user',
models.ForeignKey(
blank=True,
help_text='MediaCMS user (null if launch failed before user creation)',
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name='lti_launch_logs',
to=settings.AUTH_USER_MODEL,
),
),
('platform', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='launch_logs', to='lti.ltiplatform')),
('resource_link', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='launch_logs', to='lti.ltiresourcelink')),
],
options={
'verbose_name': 'LTI Launch Log',
'verbose_name_plural': 'LTI Launch Logs',
'ordering': ['-created_at'],
},
),
migrations.CreateModel(
name='LTIRoleMapping',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lti_role', models.CharField(help_text="LTI role URI or short name (e.g., 'Instructor', 'Learner')", max_length=255)),
(
'global_role',
models.CharField(
blank=True,
choices=[('advancedUser', 'Advanced User'), ('editor', 'MediaCMS Editor'), ('manager', 'MediaCMS Manager'), ('admin', 'MediaCMS Administrator')],
help_text='MediaCMS global role to assign',
max_length=20,
),
),
(
'group_role',
models.CharField(blank=True, choices=[('member', 'Member'), ('contributor', 'Contributor'), ('manager', 'Manager')], help_text='RBAC group role to assign', max_length=20),
),
('platform', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='role_mappings', to='lti.ltiplatform')),
],
options={
'verbose_name': 'LTI Role Mapping',
'verbose_name_plural': 'LTI Role Mappings',
},
),
migrations.CreateModel(
name='LTIUserMapping',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lti_user_id', models.CharField(db_index=True, help_text="LTI 'sub' claim (unique user identifier from platform)", max_length=255)),
('created_at', models.DateTimeField(auto_now_add=True)),
('last_login', models.DateTimeField(auto_now=True)),
('platform', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_mappings', to='lti.ltiplatform')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lti_mappings', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'LTI User Mapping',
'verbose_name_plural': 'LTI User Mappings',
},
),
migrations.AddIndex(
model_name='ltiresourcelink',
index=models.Index(fields=['platform', 'context_id'], name='lti_ltireso_platfor_4a3f27_idx'),
),
migrations.AddIndex(
model_name='ltiresourcelink',
index=models.Index(fields=['context_id'], name='lti_ltireso_context_c6f9e2_idx'),
),
migrations.AlterUniqueTogether(
name='ltiresourcelink',
unique_together={('platform', 'context_id', 'resource_link_id')},
),
migrations.AddIndex(
model_name='ltilaunchlog',
index=models.Index(fields=['-created_at'], name='lti_ltilaun_created_94c574_idx'),
),
migrations.AddIndex(
model_name='ltilaunchlog',
index=models.Index(fields=['platform', 'user'], name='lti_ltilaun_platfor_5240bf_idx'),
),
migrations.AlterUniqueTogether(
name='ltirolemapping',
unique_together={('platform', 'lti_role')},
),
migrations.AddIndex(
model_name='ltiusermapping',
index=models.Index(fields=['platform', 'lti_user_id'], name='lti_ltiuser_platfor_9c70bb_idx'),
),
migrations.AddIndex(
model_name='ltiusermapping',
index=models.Index(fields=['user'], name='lti_ltiuser_user_id_b06d01_idx'),
),
migrations.AlterUniqueTogether(
name='ltiusermapping',
unique_together={('platform', 'lti_user_id')},
),
]