Authorization Model
This document explains how access control works in the Wippidu Kita App.
Role hierarchy
The system defines six roles, seeded in internal/model/db.go:
| Role | Description | Inherits from |
|---|---|---|
| Anonymous | Unauthenticated users | — |
| Parent | Parents/guardians of enrolled children | — |
| Employee | Staff members assigned to locations | — |
| GroupLead | Group leader (Gruppenleiter) | Employee |
| LocationLead | Location leader (Standortleiter) | Employee |
| Admin | System administrator | Full access |
Users can hold multiple roles simultaneously (many-to-many via user_roles table). All GroupLead and LocationLead users automatically have the Employee role as well.
Role convenience methods
The User model provides helpers in internal/model/user.go:
user.HasRole("Admin") // general check
user.IsParent() // shorthand
user.IsEmployee()
user.IsGroupLead()
user.IsLocationLead()
user.IsAdmin()
Location-scoped access
Access for staff is location-scoped, not group-scoped. All staff at a location can see all children at that location, regardless of their specific group assignment.
Why: In daycare facilities, staff regularly help across groups within the same physical location. Location isolation provides security between separate facilities.
How it works
- Staff are assigned to groups via the
group_teachersjoin table - Groups belong to locations
CanUserAccessChild()ininternal/model/user.gochecks:- If user is a parent: must have a
UserChildrelationship with the child - If user is staff (Employee/GroupLead/LocationLead): must be assigned to a group at the same location as the child
- If user is Admin: access granted
- If user is a parent: must have a
Example
Location Alpha
├── The Bees ← teacher.bees (GroupLead), employee.bees1, employee.bees2
├── The Butterflies ← teacher.butterflies (GroupLead)
└── The Ladybugs ← teacher.ladybugs (GroupLead)
teacher.alpha (LocationLead) — assigned to all Alpha groups
Location Beta
├── The Dolphins ← teacher.dolphins (GroupLead)
└── The Turtles ← teacher.turtles (GroupLead)
teacher.beta (LocationLead) — assigned to all Beta groups
teacher.beescan access all 30 children at Location Alpha (not just The Bees)employee.bees1can also access all 30 children at Location Alpha- Neither can access any children at Location Beta
Employee location access levels
The EmployeeLocationAccess model controls which staff members employees can see at each location. Three levels:
| Level | Value | Who is visible |
|---|---|---|
| Location leads only | location_leads |
Only location leaders |
| Group leads and above | group_leads |
Location leads + group leads |
| All employees | all_employees |
All staff at the location |
This controls the staff directory visibility, not child access.
Delegation
GroupLeads and LocationLeads can delegate specific capabilities to other employees:
- Letter writing delegation — A GroupLead can authorize a regular Employee to create parental letters for their group
- Delegation is tracked per action and per group/location scope
- Delegated permissions can be revoked at any time
The delegation system is managed via internal/controller/admin_delegation.go.
Parent access periods
Parent-child relationships have optional validity periods:
type UserChild struct {
UserID uint
ChildID uint
ValidFrom *time.Time
ValidUntil *time.Time
RelationshipRole RelationshipRole // mother, father, guardian, etc.
}
LocationLeads manage these periods via the access times UI (/admin/access-times). When ValidUntil is set and in the past, the parent loses access to the child.
Account approval
New accounts can require admin approval before gaining access. The require_approval middleware blocks unapproved users from accessing protected routes, redirecting them to a "pending approval" page.
Relationship roles
Each parent-child relationship has a role describing the guardian type:
mother,fatherstepmother,stepfathergrandmother,grandfatherguardian(legal guardian)foster(foster parent)other
These are stored as the RelationshipRole type in internal/model/db.go and are primarily informational.