From the architectural point of view, your question is similar to Best Design for a User/Role Management System?. There the accepted answer suggests to use the role-based access control (RBAC) pattern, which also makes sense in your case.
Basically each User knows one or more Roles (what you called user type). Each Role knows one or more Operations it can perform (what you called functionality).
If you want to add new functionality, you have to create a new class derived from Operation, which contains the new sourcecode, and link all appropiate Roles against it. If you want to add a new user or a new role, you don't have to create new sourcecode, so you create no new class but just a new object from the classes Subject or Role and link it appropriate.
For the maintenance of your app, you could easily extract the User- and Role-creation from code into a configuration outside of your app, so that you don't have to modify any code for changing them. This works well because you don't have to create or modify classes. But since that is the case to change Operations, these are more difficult to configure from outside your app and most likely the best way is just to create the new classes; but of course it's also possible, e.g. with a plugin mechanism.