fix permission check logic, refactor user level code