mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-21 12:01:38 +00:00
Prevent misuse of RequestAccess
This commit is contained in:
parent
91cba1b0e9
commit
dcfdf7fabd
2 changed files with 29 additions and 6 deletions
|
|
@ -314,9 +314,16 @@ function App:releaseSyncLock()
|
||||||
Log.trace("Could not release sync lock because it is owned by {}", lock.Value)
|
Log.trace("Could not release sync lock because it is owned by {}", lock.Value)
|
||||||
end
|
end
|
||||||
|
|
||||||
function App:requestPermission(source: string, name: string, apis: {string}, initialState: {[string]: boolean?}): {[string]: boolean}
|
function App:requestPermission(plugin: Plugin, source: string, name: string, apis: {string}, initialState: {[string]: boolean?}): {[string]: boolean}
|
||||||
local responseEvent = Instance.new("BindableEvent")
|
local responseEvent = Instance.new("BindableEvent")
|
||||||
|
|
||||||
|
Log.info("The third-party plugin '{}' is requesting permission to use the API!", name)
|
||||||
|
|
||||||
|
local unloadProtection = plugin.Unloading:Connect(function()
|
||||||
|
Log.warn("Cancelling API permission request for '{}' because the third-party plugin has been removed.", name)
|
||||||
|
responseEvent:Fire(initialState)
|
||||||
|
end)
|
||||||
|
|
||||||
self:setState(function(state)
|
self:setState(function(state)
|
||||||
state.popups[source .. " Permissions"] = {
|
state.popups[source .. " Permissions"] = {
|
||||||
name = name,
|
name = name,
|
||||||
|
|
@ -338,6 +345,7 @@ function App:requestPermission(source: string, name: string, apis: {string}, ini
|
||||||
|
|
||||||
local response = responseEvent.Event:Wait()
|
local response = responseEvent.Event:Wait()
|
||||||
responseEvent:Destroy()
|
responseEvent:Destroy()
|
||||||
|
unloadProtection:Disconnect()
|
||||||
|
|
||||||
self:setState(function(state)
|
self:setState(function(state)
|
||||||
state.popups[source .. " Permissions"] = nil
|
state.popups[source .. " Permissions"] = nil
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ function API.new(app)
|
||||||
local Rojo = {}
|
local Rojo = {}
|
||||||
|
|
||||||
Rojo._rateLimit = {}
|
Rojo._rateLimit = {}
|
||||||
|
Rojo._sourceToPlugin = {}
|
||||||
Rojo._permissions = Settings:get("apiPermissions") or {}
|
Rojo._permissions = Settings:get("apiPermissions") or {}
|
||||||
|
Rojo._activePermissionRequests = {}
|
||||||
Rojo._changedEvent = Instance.new("BindableEvent")
|
Rojo._changedEvent = Instance.new("BindableEvent")
|
||||||
Rojo._apiDescriptions = {}
|
Rojo._apiDescriptions = {}
|
||||||
|
|
||||||
|
|
@ -55,7 +57,7 @@ function API.new(app)
|
||||||
local traceback = string.split(debug.traceback(), "\n")
|
local traceback = string.split(debug.traceback(), "\n")
|
||||||
local topLevel = traceback[#traceback - 1]
|
local topLevel = traceback[#traceback - 1]
|
||||||
|
|
||||||
local localPlugin = string.match(topLevel, "(user_.-)%.")
|
local localPlugin = string.match(topLevel, "user_.-%.%w+")
|
||||||
if localPlugin then
|
if localPlugin then
|
||||||
return localPlugin
|
return localPlugin
|
||||||
end
|
end
|
||||||
|
|
@ -188,15 +190,26 @@ function API.new(app)
|
||||||
end
|
end
|
||||||
|
|
||||||
Rojo._apiDescriptions.RequestAccess = "Used to gain access to Rojo API members"
|
Rojo._apiDescriptions.RequestAccess = "Used to gain access to Rojo API members"
|
||||||
function Rojo:RequestAccess(apis: {string}): {[string]: boolean}
|
function Rojo:RequestAccess(plugin: Plugin, apis: {string}): {[string]: boolean}
|
||||||
assert(type(apis) == "table", "Rojo:RequestAccess expects an array of valid API names")
|
assert(type(apis) == "table", "Rojo:RequestAccess expects an array of valid API names as the second argument")
|
||||||
|
assert(typeof(plugin) == "Instance" and plugin:IsA("Plugin"), "Rojo:RequestAccess expects a Plugin as the first argument")
|
||||||
|
|
||||||
|
local source, name = Rojo:_getCallerSource(), Rojo:_getCallerName()
|
||||||
|
Rojo._sourceToPlugin[source] = plugin
|
||||||
|
|
||||||
if Rojo:_checkRateLimit("RequestAccess") then
|
if Rojo:_checkRateLimit("RequestAccess") then
|
||||||
-- Because this opens a popup, we dont want to let users get spammed by it
|
-- Because this opens a popup, we dont want to let users get spammed by it
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local source, name = Rojo:_getCallerSource(), Rojo:_getCallerName()
|
if Rojo._activePermissionRequests[source] then
|
||||||
|
-- If a request is already active, exit
|
||||||
|
error(
|
||||||
|
"Rojo:RequestAccess cannot be called in multiple threads at once. Please call it once and wait for the response before calling it again.",
|
||||||
|
2
|
||||||
|
)
|
||||||
|
end
|
||||||
|
Rojo._activePermissionRequests[source] = true
|
||||||
|
|
||||||
if Rojo._permissions[source] == nil then
|
if Rojo._permissions[source] == nil then
|
||||||
Rojo._permissions[source] = {}
|
Rojo._permissions[source] = {}
|
||||||
|
|
@ -226,10 +239,11 @@ function API.new(app)
|
||||||
for _, api in sanitizedApis do
|
for _, api in sanitizedApis do
|
||||||
response[api] = true
|
response[api] = true
|
||||||
end
|
end
|
||||||
|
Rojo._activePermissionRequests[source] = nil
|
||||||
return response
|
return response
|
||||||
end
|
end
|
||||||
|
|
||||||
local response = app:requestPermission(source, name, sanitizedApis, Rojo._permissions[source])
|
local response = app:requestPermission(plugin, source, name, sanitizedApis, Rojo._permissions[source])
|
||||||
|
|
||||||
for api, granted in response do
|
for api, granted in response do
|
||||||
Log.warn(string.format(
|
Log.warn(string.format(
|
||||||
|
|
@ -240,6 +254,7 @@ function API.new(app)
|
||||||
end
|
end
|
||||||
Settings:set("apiPermissions", Rojo._permissions)
|
Settings:set("apiPermissions", Rojo._permissions)
|
||||||
|
|
||||||
|
Rojo._activePermissionRequests[source] = nil
|
||||||
return response
|
return response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue