Skip to content

Commit

Permalink
Add GitHub Basic Authentication login system.
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperKael committed Feb 27, 2021
1 parent 20a19e9 commit 68b9131
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 9 deletions.
62 changes: 62 additions & 0 deletions API/GadgetConsole.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using GadgetCore.API;
using GadgetCore.Loader;
using GadgetCore.Util;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
Expand Down Expand Up @@ -629,6 +630,10 @@ static GadgetConsole()
"Toggles debug mode.",
"Toggles the game's built-in debug mode. Use with caution.\nUses the syntax: /debugmode",
"debug");
RegisterCommand("githublogin", true, CoreCommands.GitHubLogin,
"Logs into or out of GitHub, for use in the Mod Browser.",
"Logs into or out of GitHub, for use in the Mod Browser. Uses a Personal Access Token, created on this page:\nhttps://github.com/settings/tokens/new\nUses the syntax: /githublogin [auth token]",
"ghl");

Registry.registeringVanilla = wasRegisteringVanilla;
Registry.gadgetRegistering = wasModRegistering;
Expand Down Expand Up @@ -1014,6 +1019,63 @@ public static GadgetConsoleMessage DebugMode(string sender, params string[] args
GameScript.debugMode = !GameScript.debugMode;
return new GadgetConsoleMessage("Debug Mode is now " + (GameScript.debugMode ? "ON" : "OFF"));
}

/// <summary>
/// The /githublogin command.
/// </summary>
public static GadgetConsoleMessage GitHubLogin(string sender, params string[] args)
{
if (args.Length == 1)
{
if (!string.IsNullOrEmpty(PlayerPrefs.GetString("GitHubAuthToken")))
{
PlayerPrefs.DeleteKey("GitHubAuthToken");
ModBrowser.gitHubAuthToken = null;
ModBrowser.gitHubAuthHeaders.Remove("Authorization");
return new GadgetConsoleMessage("Succesfully deleted GitHub login information and logged you out.");
}
else
{
return new GadgetConsoleMessage("Cannot delete your login information as you have not logged in. " +
"If you meant to log in, use the version of this command with an argument for an auth token.", null, MessageSeverity.ERROR);
}
}
else if (args.Length == 2)
{
Console.StartCoroutine(GitHubLoginRoutine(args[1]));
return null;
}
else return CommandSyntaxError(args[0], "[auth token]");
}

private static IEnumerator GitHubLoginRoutine(string authToken)
{
Print(new GadgetConsoleMessage("Attempting GitHub login..."));
using (WWW testWWW = new WWW(ModBrowser.MODS_URL, null, new Dictionary<string, string>()
{
["User-Agent"] = ModBrowser.GITHUB_USER_AGENT,
["Authorization"] = $"token {authToken}"
}))
{
yield return new WaitUntil(() => testWWW.isDone);
if (string.IsNullOrEmpty(testWWW.error) && !string.IsNullOrEmpty(testWWW.text))
{
PlayerPrefs.SetString("GitHubAuthToken", ModBrowser.gitHubAuthToken = authToken);
if (ModBrowser.gitHubAuthToken != null)
{
ModBrowser.gitHubAuthHeaders["Authorization"] = $"token {ModBrowser.gitHubAuthToken}";
}
if (SceneInjector.ModBrowserPanel != null) SceneInjector.ModBrowserPanel.UnlimitButton.gameObject.SetActive(false);
Print(new GadgetConsoleMessage("GitHub Login Successful! This login will be remembered even for future sessions."));
Print(new GadgetConsoleMessage("If you wish to log out, use `/githublogin` with no arguments."));
}
else
{
Print(new GadgetConsoleMessage("Login failed! Your auth token must have been invalid.", null, MessageSeverity.ERROR));
}
}
yield break;
}
}

/// <summary>
Expand Down
32 changes: 23 additions & 9 deletions ModBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@ internal class ModBrowser : MonoBehaviour
public const string PASCAL_CASE_SPACING_REGEX = @"(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])";

public const string GITHUB_USER_AGENT = @"SuperKael-GadgetCore-ModBrowser";
public const string GITHUB_AUTH_TOKEN = @"R2FkZ2V0Q29yZTphY2ZjMzU0YWFjYWU0MTA0NmQ1Njk3NGEzNzA2MzJiNzcxMGU4NTQ3";
public const string REPO_URL = @"https://github.com/SuperKael/Roguelands-Mods";
public const string GIT_RAW_URL = @"https://raw.githubusercontent.com/SuperKael/Roguelands-Mods/master";
public const string GIT_API_URL = @"https://api.github.com/repos/{0}/{1}/releases";
public const string MODS_URL = GIT_RAW_URL + @"/Mods.ini";

private static Dictionary<string, string> gitHubAuthHeaders = new Dictionary<string, string>()
internal static string gitHubAuthToken = PlayerPrefs.GetString("GitHubAuthToken", null);
internal static Dictionary<string, string> gitHubAuthHeaders = new Dictionary<string, string>()
{
["User-Agent"] = GITHUB_USER_AGENT,
["Authorization"] = $"Basic {GITHUB_AUTH_TOKEN}"
["User-Agent"] = GITHUB_USER_AGENT
};

private static ModBrowser Singleton;
Expand All @@ -49,6 +48,7 @@ internal class ModBrowser : MonoBehaviour
internal Button InstallButton;
internal Button ActivateButton;
internal Button VersionsButton;
internal Button UnlimitButton;

internal static bool RestartNeeded { get; private set; } = false;

Expand Down Expand Up @@ -98,7 +98,11 @@ public static void OpenModBrowser()
SceneInjector.ModMenuPanel.gameObject.SetActive(false);
Array.ForEach(SceneInjector.ModConfigMenuText.GetComponentsInChildren<TextMesh>(), x => { x.text = "MOD BROWSER"; x.anchor = TextAnchor.UpperCenter; });
Singleton.BrowserButtonText.text = "Mod Menu";
SceneInjector.ModBrowserPanel.gameObject.SetActive(true);
Singleton.gameObject.SetActive(true);
if (gitHubAuthToken != null)
{
gitHubAuthHeaders["Authorization"] = $"token {gitHubAuthToken}";
}
Singleton.StartCoroutine(Singleton.LoadModList());
}
}
Expand All @@ -119,7 +123,8 @@ public static void CloseModBrowser()
GadgetCoreAPI.Quit();
return;
}
SceneInjector.ModBrowserPanel.gameObject.SetActive(false);
Singleton.gameObject.SetActive(false);
Singleton.UnlimitButton.gameObject.SetActive(false);
Array.ForEach(SceneInjector.ModConfigMenuText.GetComponentsInChildren<TextMesh>(), x => { x.text = "MOD CONFIG MENU"; x.anchor = TextAnchor.UpperCenter; });
Singleton.BrowserButtonText.text = "Mod Browser";
SceneInjector.ModMenuPanel.Rebuild();
Expand All @@ -139,7 +144,7 @@ private IEnumerator DownloadModFile(ModBrowserEntry entry)
if (!entry.Info.ContainsKey("File")) yield break;
downloading = true;
GadgetCore.CoreLogger.LogConsole("Initiating download for " + entry.Info["Name"] + "!");
using (WWW modFileWWW = new WWW(entry.Info["File"], null, gitHubAuthHeaders))
using (WWW modFileWWW = new WWW(entry.Info["File"]))
{
yield return new WaitUntil(() => modFileWWW.isDone);
if (modFileWWW.text == "404: Not Found")
Expand Down Expand Up @@ -362,6 +367,13 @@ private IEnumerator SelectVersion(ModBrowserEntry modEntry, string version)
yield break;
}

internal void OnUnlimitButton()
{
GadgetCoreAPI.DisplayYesNoDialog("In order to login to GitHub to remove the rate limit, you must use the command:\n\n/githublogin [auth token]\n\n" +
"Would you like to open GitHub in your web browser to generate an auth token?\n" +
"You do not have to check any of the boxes, simply set a note such as \"GadgetCore Mod Browser\", and select \"Generate token\" at the bottom. Then copy the generated token and use it with the /githublogin command.", () => System.Diagnostics.Process.Start(@"https://github.com/settings/tokens/new"));
}

[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Unity Message")]
private void Awake()
{
Expand Down Expand Up @@ -439,7 +451,7 @@ private IEnumerator LoadModList()
if (listLoading) yield break;
listLoading = true;
Singleton.Clean();
using (WWW modsWWW = new WWW(MODS_URL, null, gitHubAuthHeaders))
using (WWW modsWWW = new WWW(MODS_URL))
{
yield return new WaitUntil(() => modsWWW.isDone);
IniData modsIni;
Expand Down Expand Up @@ -496,7 +508,7 @@ private IEnumerator LoadModList()

private IEnumerator ProcessMetadataURL(string ID, string URL, ModBrowserEntry modEntry)
{
using (WWW modWWW = new WWW(URL, null, gitHubAuthHeaders))
using (WWW modWWW = new WWW(URL))
{
yield return new WaitUntil(() => modWWW.isDone);
modEntry.Info.Remove("URL");
Expand Down Expand Up @@ -625,6 +637,7 @@ private IEnumerator ProcessGitVersions(string gitURL, ModBrowserEntry modEntry)
{
GadgetCore.CoreLogger.LogWarning("GitHub API Rate limit exceeded! Please wait one hour before for it to reset.");
modEntry.Info["Error"] = "GitHub Rate Limit Exceeded!";
Singleton.UnlimitButton.gameObject.SetActive(string.IsNullOrEmpty(gitHubAuthToken));
}
}
}
Expand Down Expand Up @@ -660,6 +673,7 @@ private IEnumerator ProcessGitVersion(string ID, string gitID, ModBrowserEntry m
{
GadgetCore.CoreLogger.LogWarning("GitHub API Rate limit exceeded! Please wait one hour before for it to reset.");
modEntry.Info["Error"] = "GitHub Rate Limit Exceeded!";
Singleton.UnlimitButton.gameObject.SetActive(string.IsNullOrEmpty(gitHubAuthToken));
}
else
{
Expand Down
Binary file modified Release/GadgetCore.dll
Binary file not shown.
5 changes: 5 additions & 0 deletions Release/GadgetCore.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified Release/GadgetCore.zip
Binary file not shown.
24 changes: 24 additions & 0 deletions SceneInjector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,30 @@ private static void BuildModBrowser()

ModBrowserPanel.BrowserButtonText = modBrowserButtonText;

ModBrowserPanel.UnlimitButton = new GameObject("Unlimit Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent<Button>();
ModBrowserPanel.UnlimitButton.GetComponent<RectTransform>().SetParent(ModMenuCanvas.transform);
ModBrowserPanel.UnlimitButton.GetComponent<RectTransform>().anchorMin = new Vector2(0.025f, 0.05f);
ModBrowserPanel.UnlimitButton.GetComponent<RectTransform>().anchorMax = new Vector2(0.125f, 0.20f);
ModBrowserPanel.UnlimitButton.GetComponent<RectTransform>().offsetMin = new Vector2(0, 0);
ModBrowserPanel.UnlimitButton.GetComponent<RectTransform>().offsetMax = new Vector2(0, 0);
ModBrowserPanel.UnlimitButton.GetComponent<Image>().sprite = BoxSprite;
ModBrowserPanel.UnlimitButton.GetComponent<Image>().type = Image.Type.Sliced;
ModBrowserPanel.UnlimitButton.GetComponent<Image>().fillCenter = true;
ModBrowserPanel.UnlimitButton.targetGraphic = ModBrowserPanel.UnlimitButton.GetComponent<Image>();
ModBrowserPanel.UnlimitButton.onClick.AddListener(ModBrowserPanel.OnUnlimitButton);
Text unlimitButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent<Text>();
unlimitButtonText.rectTransform.SetParent(ModBrowserPanel.UnlimitButton.transform);
unlimitButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
unlimitButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
unlimitButtonText.rectTransform.offsetMin = Vector2.zero;
unlimitButtonText.rectTransform.offsetMax = Vector2.zero;
unlimitButtonText.alignment = TextAnchor.MiddleCenter;
unlimitButtonText.font = modBrowserDescText.font;
unlimitButtonText.fontSize = 12;
unlimitButtonText.text = "Login To GitHub\nTo Remove Limit";

ModBrowserPanel.UnlimitButton.gameObject.SetActive(false);

RectTransform listLoadingTextBackground = new GameObject("List Loading Panel", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent<RectTransform>();
listLoadingTextBackground.GetComponent<RectTransform>().SetParent(ModBrowserPanel.transform);
listLoadingTextBackground.GetComponent<RectTransform>().anchorMin = new Vector2(0f, 0f);
Expand Down

0 comments on commit 68b9131

Please sign in to comment.