Security reference
Groups, access rights, record rules, field restrictions and the checks done in code, plus the security of the public schedule links.
This page is a reference for developers and security reviewers. The task-level summary for administrators is in Roles and permissions.
Groups#
| XML id | Name | Implies | Notes |
|---|---|---|---|
smarterp_planning.module_category_planning | Planning (category) | ||
smarterp_planning.group_planning_user | Planning / User | base.group_user | Comment: sees the published schedule, takes open shifts, unassigns or asks to switch. |
smarterp_planning.group_planning_manager | Planning / Administrator | group_planning_user | Users base.user_root and base.user_admin are members. |
Bridge modules add no groups. They refer to project.group_project_user, sales_team.group_sale_salesman, hr.group_hr_user, hr_attendance.group_hr_attendance_officer and hr_timesheet.group_hr_timesheet_approver.
Access rights#
ir.model.access.csv of the core module:
| Model | Internal User | Planning / User | Planning / Administrator | Other |
|---|---|---|---|---|
smarterp.planning.shift | read | read, write | read, write, create, unlink | |
smarterp.planning.role | read | all | ||
smarterp.planning.template | read | all | ||
smarterp.planning.recurrency | read | all | ||
smarterp.planning.planning | all | |||
smarterp.planning.broadcast | read | |||
smarterp.planning.capacity | read | read (through User) | read: Employees officer (hr.group_hr_user) | |
smarterp.planning.send, .period.wizard, .template.apply (wizards) | all | |||
smarterp.planning.split, .duplicate, .spread, .print (wizards) | all | The code checks the right to plan when the wizard acts (print has no such check; it reads shifts under the user's rules). |
Bridge files:
| Module | Model | Group | Rights |
|---|---|---|---|
| Project | smarterp.planning.shift, .recurrency | project.group_project_user | all |
| Project | smarterp.planning.capacity | project.group_project_user | read |
| Skills | smarterp.planning.skill.requirement | Internal User | read |
| Skills | smarterp.planning.skill.requirement | Planning / Administrator | all |
Record rules#
All rules are in noupdate data and apply to the operations shown. Rules of the same operation add up (OR) across a user's groups; global rules (no group) apply to everyone.
| Rule | Model | Domain | Applies to | Operations |
|---|---|---|---|---|
| Internal user reads own and open shifts | shift | state = published and (user_id = user or no resource) | Internal User | read |
| Planning user reads published shifts | shift | state = published | Planning / User | read |
| Planning user edits own shift | shift | user_id = user | Planning / User | write |
| Manager | shift | all | Planning / Administrator | all |
| Project managers plan their projects | shift | project_id.user_id = user | project.group_project_user | all |
| Multi-company | shift, template, recurrency, planning | company_id in company_ids | global | all |
| Multi-company | role, capacity | company_id empty or in company_ids | global | all |
| Multi-company | broadcast | company_id in company_ids | global | all |
| Own utilisation | capacity | user_id = user | Planning / User | read |
| All utilisation | capacity | all | Planning / Administrator and Employees officer | read |
| Project teams' utilisation | capacity | resource_id.planning_shift_ids.project_id.user_id = user | project.group_project_user | read |
| Project recurrences | recurrency | no shift, or slot_ids.project_id.user_id = user | project.group_project_user | all |
| Skill requirement multi-company | skill requirement | company_id empty or in company_ids | global | all |
Field restrictions#
| Field | Restriction |
|---|---|
smarterp.planning.shift.employee_id | hr.group_hr_user |
| Attendance fields on the shift | Planning / Administrator and hr_attendance.group_hr_attendance_officer |
hr.employee.planning_role_ids, default_planning_role_id, planning_token, planning_shift_count | hr.group_hr_user |
Project figures on project.project | project.group_project_user |
Order planning_shift_count; order line planning hours | Planning / User (in the view) |
cost, actual_cost on the shift | Hidden in views for non-administrators but not restricted at field level: anyone who can read a shift can read them through the API. |
hourly_cost on the role | Not restricted: every internal user can read roles. |
Checks in code#
| Check | Where | Error text |
|---|---|---|
_check_manager() | Auto Plan, Copy Previous Week, Plan with Template (apply) | "Only planning managers can do this." |
_check_can_plan() | Publish, unpublish, drag checks, undo, bulk actions, copy-to, split, duplicate, spread, unassign | "You are not allowed to plan these shifts." |
_check_self_service_write() | write | "Only planning managers can change fields on a shift. Use Assign to Me, Unassign or Ask to Switch instead." |
_check_can_approve() | Approve and reject | "Only the shift manager or a planning manager can approve changes." |
get_planning_dashboard | Dashboard | "The planning dashboard is for planners." |
Project: _check_self_service_write | Writes of project_id or task_id | "You can only plan shifts on projects you manage." |
| Digest KPI compute | Digest | "Do not have access, skip this data for user's digest email" |
_is_manager() is true for the superuser and members of group_planning_manager. _can_plan() is true for managers and, with the Project bridge, for project users who manage the project of every shift in the recordset.
Self-service methods (_planning_take, _planning_release, action_request_switch, action_cancel_switch) write with sudo() after checking eligibility, so a user with read-only rights can use them on shifts they can see. Schedule data, conflicts, capacity and workload read other users' shifts with sudo() and expose only counts, names and times.
The public schedule links#
The pages under /planning/... have auth="public" and rely on two secrets.
| Page | Secrets | Conditions |
|---|---|---|
/planning/<planning_token>/<employee_token> | The sent-schedule access_token (UUID) and the employee's planning_token (UUID) | Both match; the employee's resource is among the schedule's resources; same company; the link is not older than planning_link_validity_weeks after the schedule's end. |
/planning/shift/<shift_token>/<employee_token> | The shift's access_token and the employee's planning_token | Both match; same company; the shift is a published planning shift. No expiry. |
Every action re-checks eligibility on the server through the same model methods as the backend buttons; the pages grant nothing the backend would not. Every failure of a lookup answers 404, so a wrong code reveals nothing. POST routes require a CSRF token.
Points to know:
- The employee's
planning_tokenis created once and does not expire or rotate. There is no screen to renew it (the field is not shown in any view). To revoke leaked links, a developer clearsplanning_tokenon the employee; a new one is created the next time a schedule is sent. Sent-schedule tokens expire by the validity setting. - Anyone with a link acts as the employee. Treat the emails as confidential.
- The pages show the employee's name, shifts, roles and notes, and the shifts they may take.