env = LDAPTestEnv.new

env.validate 'User password' do
  password_change_tests = [
    # student password change permissions
    lambda { student.can_set_password_for    student                        },
    lambda { student.cannot_set_password_for student2, LDAPTestEnvException },
    lambda { student.cannot_set_password_for other_school_student,
                                             LDAPTestEnvException },
    lambda { student.cannot_set_password_for teacher,  LDAPTestEnvException },
    lambda { student.cannot_set_password_for other_school_teacher,
                                             LDAPTestEnvException },
    lambda { student.cannot_set_password_for admin, LDAPTestEnvException },
    lambda { student.cannot_set_password_for other_school_admin,
                                             LDAPTestEnvException },
    lambda { student.cannot_set_password_for owner, LDAPTestEnvException },

    # teacher with password change permissions to student accounts
    lambda { teacher.can_set_password_for    teacher },
    lambda { teacher.can_set_password_for    student },
    lambda { teacher.cannot_set_password_for other_school_student,
                                             LDAPTestEnvException },
    lambda { teacher.cannot_set_password_for teacher2, LDAPTestEnvException },
    lambda { teacher.cannot_set_password_for other_school_teacher,
                                             LDAPTestEnvException },
    lambda { teacher.cannot_set_password_for admin, LDAPTestEnvException },
    lambda { teacher.cannot_set_password_for other_school_admin,
                                             LDAPTestEnvException },
    lambda { teacher.cannot_set_password_for owner, LDAPTestEnvException },

    # teacher without password change permissions to student accounts
    lambda { teacher2.can_set_password_for teacher2 },
    lambda { teacher2.cannot_set_password_for student, LDAPTestEnvException },

    # admin password change permissions
    lambda { admin.can_set_password_for admin   },
    lambda { admin.can_set_password_for student },
    lambda { admin.can_set_password_for teacher },
    lambda { admin.cannot_set_password_for owner, LDAPTestEnvException },
    lambda { admin.cannot_set_password_for other_school_student,
                                           LDAPTestEnvException },
    lambda { admin.cannot_set_password_for other_school_teacher,
                                           LDAPTestEnvException },
    lambda { admin.cannot_set_password_for other_school_admin,
                                           LDAPTestEnvException },

    # staff password change permissions
    lambda { staff.can_set_password_for staff },
    lambda { staff.cannot_set_password_for owner, LDAPTestEnvException },
    lambda { staff.cannot_set_password_for student, LDAPTestEnvException },
    lambda { staff.cannot_set_password_for teacher, LDAPTestEnvException },
    lambda { staff.cannot_set_password_for other_school_admin,
                                           LDAPTestEnvException },
    lambda { staff.cannot_set_password_for other_school_student,
                                           LDAPTestEnvException },
    lambda { staff.cannot_set_password_for other_school_teacher,
                                           LDAPTestEnvException },

    # organisation owner password change permissions
    # (not testing for owner --> owner because that would break "everything")
    lambda { owner.can_set_password_for staff },
    lambda { owner.can_set_password_for student },
    lambda { owner.can_set_password_for teacher },
    lambda { owner.can_set_password_for other_school_admin },
    lambda { owner.can_set_password_for other_school_student },
    lambda { owner.can_set_password_for other_school_teacher },

    # password management password change permissions
    lambda { pwmgmt.can_set_password_for student },
    lambda { pwmgmt.can_set_password_for teacher },
    lambda { pwmgmt.can_set_password_for admin   },
  ]

  password_change_tests.each do |test|
    reset
    test.call()
  end
end

env.validate 'password attribute secrecy' do
  # Nobody should be able to read anybody's "userPassword"- or
  # "sambaNTPassword"-attributes (maybe add "bootserver" to this list?).
  [ admin, laptop, owner, puavo, pwmgmt, student, teacher ].each do |actor|
    [ :userPassword, :sambaNTPassword ].each do |attribute|
      actor.cannot_read actor,   [ attribute ], InsufficientAccessRights
      actor.cannot_read student, [ attribute ], InsufficientAccessRights
    end
  end
end
