diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py
index 98cdcc7104271ed1ee9d5e8a8313cd87cee57bc8..6ebcb2ae2ecae7f796c67a00c36dd6e0aafcceba 100644
--- a/aleksis/apps/alsijil/preferences.py
+++ b/aleksis/apps/alsijil/preferences.py
@@ -34,6 +34,14 @@ class RegisterAbsenceAsPrimaryGroupOwner(BooleanPreference):
     )
 
 
+@site_preferences_registry.register
+class EditLessonDocumentationAsOriginalTeacher(BooleanPreference):
+    section = alsijil
+    name = "edit_lesson_documentation_as_original_teacher"
+    default = True
+    verbose_name = _("Allow original teachers to edit their lessons although they are substituted")
+
+
 @site_preferences_registry.register
 class CarryOverDataToNextPeriods(BooleanPreference):
     section = alsijil
diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py
index 7358a9d4a0f556a86886e14583bb17b0639f40d7..75b39b8c1e16c68ef52e8f2e8e4ae1b199723834 100644
--- a/aleksis/apps/alsijil/rules.py
+++ b/aleksis/apps/alsijil/rules.py
@@ -17,6 +17,7 @@ from .util.predicates import (
     is_group_member,
     is_group_owner,
     is_group_role_assignment_group_owner,
+    is_lesson_original_teacher,
     is_lesson_parent_group_owner,
     is_lesson_participant,
     is_lesson_teacher,
@@ -25,6 +26,7 @@ from .util.predicates import (
     is_owner_of_any_group,
     is_person_group_owner,
     is_person_primary_group_owner,
+    is_personal_note_lesson_original_teacher,
     is_personal_note_lesson_parent_group_owner,
     is_personal_note_lesson_teacher,
     is_teacher,
@@ -34,6 +36,7 @@ from .util.predicates import (
 view_register_object_predicate = has_person & (
     is_none  # View is opened as "Current lesson"
     | is_lesson_teacher
+    | is_lesson_original_teacher
     | is_lesson_participant
     | is_lesson_parent_group_owner
     | has_global_perm("alsijil.view_lesson")
@@ -48,6 +51,7 @@ add_perm("alsijil.view_lesson_menu", has_person)
 view_lesson_personal_notes_predicate = view_register_object_predicate & (
     ~is_lesson_participant
     | is_lesson_teacher
+    | is_lesson_original_teacher
     | has_global_perm("alsijil.view_personalnote")
     | has_lesson_group_object_perm("core.view_personalnote_group")
 )
@@ -56,6 +60,10 @@ add_perm("alsijil.view_register_object_personalnote", view_lesson_personal_notes
 # Edit personal note
 edit_lesson_personal_note_predicate = view_lesson_personal_notes_predicate & (
     is_lesson_teacher
+    | (
+        is_lesson_original_teacher
+        & is_site_preference_set("alsijil", "edit_lesson_documentation_as_original_teacher")
+    )
     | has_global_perm("alsijil.change_personalnote")
     | has_lesson_group_object_perm("core.edit_personalnote_group")
 )
@@ -65,6 +73,7 @@ add_perm("alsijil.edit_register_object_personalnote", edit_lesson_personal_note_
 view_personal_note_predicate = has_person & (
     (is_own_personal_note & is_site_preference_set("alsijil", "view_own_personal_notes"))
     | is_personal_note_lesson_teacher
+    | is_personal_note_lesson_original_teacher
     | is_personal_note_lesson_parent_group_owner
     | has_global_perm("alsijil.view_personalnote")
     | has_personal_note_group_perm("core.view_personalnote_group")
@@ -74,6 +83,10 @@ add_perm("alsijil.view_personalnote", view_personal_note_predicate)
 # Edit personal note
 edit_personal_note_predicate = view_personal_note_predicate & (
     ~is_own_personal_note
+    & ~(
+        is_personal_note_lesson_original_teacher
+        or not is_site_preference_set("alsijil", "edit_lesson_documentation_as_original_teacher")
+    )
     | has_global_perm("alsijil.view_personalnote")
     | has_personal_note_group_perm("core.edit_personalnote_group")
 )
@@ -86,6 +99,10 @@ add_perm("alsijil.view_lessondocumentation", view_lesson_documentation_predicate
 # Edit lesson documentation
 edit_lesson_documentation_predicate = view_register_object_predicate & (
     is_lesson_teacher
+    | (
+        is_lesson_original_teacher
+        & is_site_preference_set("alsijil", "edit_lesson_documentation_as_original_teacher")
+    )
     | has_global_perm("alsijil.change_lessondocumentation")
     | has_lesson_group_object_perm("core.edit_lessondocumentation_group")
 )
@@ -243,13 +260,22 @@ add_perm("alsijil.delete_grouprole", delete_group_role_predicate)
 
 view_assigned_group_roles_predicate = (
     is_group_owner
-    | is_lesson_teacher
-    | is_lesson_parent_group_owner
     | has_global_perm("alsjil.assign_grouprole")
-    | has_object_perm("alsijil.assign_grouprole")
+    | has_object_perm("core.assign_grouprole")
 )
 add_perm("alsijil.view_assigned_grouproles", view_assigned_group_roles_predicate)
 
+view_assigned_group_roles_register_object_predicate = (
+    is_lesson_teacher
+    | is_lesson_original_teacher
+    | is_lesson_parent_group_owner
+    | has_global_perm("alsjil.assign_grouprole")
+)
+add_perm(
+    "alsijil.view_assigned_grouproles_for_register_object",
+    view_assigned_group_roles_register_object_predicate,
+)
+
 assign_group_role_person_predicate = is_person_group_owner | has_global_perm(
     "alsjil.assign_grouprole"
 )
diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py
index 5d87d14da98148d62202e181ceb1189519cbe869..8ef58e204d474227c281a5b15ef4a2faba2b2eb1 100644
--- a/aleksis/apps/alsijil/util/predicates.py
+++ b/aleksis/apps/alsijil/util/predicates.py
@@ -22,12 +22,25 @@ def is_none(user: User, obj: Any) -> bool:
 def is_lesson_teacher(user: User, obj: Union[LessonPeriod, Event, ExtraLesson]) -> bool:
     """Predicate for teachers of a lesson.
 
-    Checks whether the person linked to the user is a teacher
-    in the lesson or the substitution linked to the given LessonPeriod.
+    Checks whether the person linked to the user is a teacher in the register object.
+    If the register object is a lesson period and has a substitution linked,
+    this will **only** check if the person is one of the substitution teachers.
+    """
+    if obj:
+        return user.person in obj.get_teachers().all()
+    return False
+
+
+@predicate
+def is_lesson_original_teacher(user: User, obj: Union[LessonPeriod, Event, ExtraLesson]) -> bool:
+    """Predicate for teachers of a lesson.
+
+    Checks whether the person linked to the user is a teacher in the register object.
+    If the register object is a lesson period and has a substitution linked,
+    this will **also** check if the person is one of the substitution teachers.
     """
     if obj:
-        sub = obj.get_substitution() if isinstance(obj, LessonPeriod) else None
-        if sub and sub in user.person.lesson_substitutions.all():
+        if isinstance(obj, LessonPeriod) and user.person in obj.lesson.teachers.all():
             return True
         return user.person in obj.get_teachers().all()
     return False
@@ -206,22 +219,35 @@ def is_own_personal_note(user: User, obj: PersonalNote) -> bool:
 
 @predicate
 def is_personal_note_lesson_teacher(user: User, obj: PersonalNote) -> bool:
-    """Predicate for teachers of a lesson referred to in the lesson period of a personal note.
+    """Predicate for teachers of a register object linked to a personal note.
 
     Checks whether the person linked to the user is a teacher
-    in the lesson or the substitution linked to the LessonPeriod of the given PersonalNote.
+    in the register object linked to the personal note.
+    If the register object is a lesson period and has a substitution linked,
+    this will **only** check if the person is one of the substitution teachers.
     """
     if hasattr(obj, "register_object"):
-        if getattr(obj, "lesson_period", None):
-            sub = obj.lesson_period.get_substitution()
-            if sub and user.person in Person.objects.filter(
-                lesson_substitutions=obj.lesson_period.get_substitution()
-            ):
-                return True
-
         return user.person in obj.register_object.get_teachers().all()
+    return False
 
-        return False
+
+@predicate
+def is_personal_note_lesson_original_teacher(user: User, obj: PersonalNote) -> bool:
+    """Predicate for teachers of a register object linked to a personal note.
+
+    Checks whether the person linked to the user is a teacher
+    in the register object linked to the personal note.
+    If the register object is a lesson period and has a substitution linked,
+    this will **also** check if the person is one of the substitution teachers.
+    """
+    if hasattr(obj, "register_object"):
+        if (
+            isinstance(obj.register_object, LessonPeriod)
+            and user.person in obj.lesson_period.lesson.teachers.all()
+        ):
+            return True
+
+        return user.person in obj.register_object.get_teachers().all()
     return False
 
 
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index 1f400054e242fb21197bd454f01d71bc358fbfb1..a3b9f4e59d65041d23649b1eeb4485c0ab9b5ac4 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -179,7 +179,9 @@ def register_object(
         # Group roles
         show_group_roles = request.user.person.preferences[
             "alsijil__group_roles_in_lesson_view"
-        ] and request.user.has_perm("alsijil.view_assigned_grouproles", register_object)
+        ] and request.user.has_perm(
+            "alsijil.view_assigned_grouproles_for_register_object", register_object
+        )
         if show_group_roles:
             groups = register_object.get_groups().all()
             group_roles = GroupRole.objects.with_assignments(date_of_lesson, groups)