[api] refactor the whole changestate permission check

This whole logic if a request can change state is worth an extra file, it's
almost 300 lines of code