COMpatible+ Google+ Integrations+ Scoping+
In COM_GetLoginStatus,
you can get rid of the if (scopes == "") by incorporating it in case "all" in the switch:

        case "":
        case "all":
            googlePermissionScopes |= GooglePermissionScopes.All;
            break;




This is probably good to move to a constant declared at the top of the file where it's easy to see:


string endpoint = "https://accounts.google.com/o/oauth2/auth?";





If the values in GooglePermissionScopes have distinct bits,
then instead of this:


    if ((googlePermissionScopes &amp; GooglePermissionScopes.OpenID) == GooglePermissionScopes.OpenID)



You could write simpler like this:

    if ((googlePermissionScopes &amp; GooglePermissionScopes.OpenID) &gt; 0)


But then again, I'm not familiar with GooglePermissionScopes so I don't know if this is correct, or acceptable.



It's not clear what magic number 6 is about here:


        if (endpoint.Length &gt; 6)
        {
            endpoint += "%20";
        }



It would be good to make that clear somehow, at the minimum with a comment.

As @Heslacher pointed out, endpoint is initialized to a string longer (much longer) than 6 characters, so this condition is completely pointless.



This can be written simpler using +=:


    endpoint = endpoint + "&amp;state=" + state;



This can be similarly simplified,
and "&amp;response_type=code" + "&amp;client_id=" can be joined:

endpoint = endpoint + "&amp;redirect_uri=" + CallbackUrl + "&amp;response_type=code" + "&amp;client_id=" + ClientId + "&amp;access_type=offline";




As for your question:


  I'm not sure if I should be using a StringBuilder here or not, since it's not a looped string concatenation.


Since it's not in a loop, I doubt the performance difference would be measurable. I think it doesn't matter. It's fine to keep it simple.



You wrote URL-encoded strings at multiple places, for example %20 and https%3A%2F%2F.
Writing this by hand is error prone, and a PITA.
It would be better to write in human-readable format,
and call a url-encoder method at the end.
Granted, the current approach is better in terms of "performance",
but again, it's probably not measurable and not worth it.