This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
EmberAnimus's profile picture

Auth Bug

Started by EmberAnimus, 10 October 2016 - 02:11 AM
EmberAnimus #1
Posted 10 October 2016 - 04:11 AM
When using the fs.open files and re-writing the seralized table with users outside of the code, the user login works fine. However, using a 'System Admin Account' with its 'Add User' command from the UI will break the Authenticator/Verifier portion before the UI's.
(Authenticator:

for username,password in pairs(UserCredentials) do
  if user == username and pass == password then
  success = true
  for username,user_rank in pairs(UserRanks) do
	rank = user_rank
  end
  else
  success = false
  end
end
)
(The Admin Add User command:

elseif key == keys.numPad2 then
	  write("What is their username: ")
	  NewUser = read()
	  write("What is their password: ")
	  NewPass = read()
	  GetUsers = fs.open("UserData.config","r")
	  UserFileData = GetUsers.readAll()
	  AllUsers = textutils.unserialize(UserFileData)
	  GetUsers.close()
	  Addusers = fs.open("UserData.config","w")
	  AllUsers[NewUser] = NewPass
	  Addusers.write(textutils.serialize(AllUsers))
	  Addusers.close()
)
The Following is a link to the whole code for perspective, should you need it:
http://pastebin.com/9ivJ7e6w
Dog #2
Posted 10 October 2016 - 10:21 PM
I've only glanced over your full code, but there are some issues in your authenticator that should be addressed. Your second loop (the one that sets user rank) goes through every username and keeps setting the rank over and over because you aren't doing any comparison. Additionally you should add a break keyword to your first loop's success state so the loop doesn't continue after you find a match and end up setting success to false again. Also, you should definitely use local variables/functions since this is security related - not only are they faster, but they are more secure. Global variables can be seen and manipulated by any program running on the machine.

--# Example of how to make a variable local
local success = false --# declare success as a local variable and set it to false
local rank --# declare rank as a local variable

for username, password in pairs(UserCredentials) do
  if user == username and pass == password then
    success = true
    rank = UserRanks[username] --# skip the second loop and address the entry in the ranks table directly
    break --# stop and exit the loop
  end
end

I would also recommend having the Admin Add User command automatically set each new users's rank to 1 (or whatever the lowest rank is) - that way if you forget to set it with option 4 then their rank when they login will at least be 1 instead of nil.
EmberAnimus #3
Posted 11 October 2016 - 03:57 AM
I updated my code to include the local portions and the auth tweak/fix.
I noticed what you meant about :
I would also recommend having the Admin Add User command automatically set each new users's rank to 1 (or whatever the lowest rank is) - that way if you forget to set it with option 4 then their rank when they login will at least be 1 instead of nil.
As when i ran it without that, after adding a user, it returned an 'attempt to concatenate string and nil." error.
I hot-fixed this with a comparison check to set rank equal to the pre-defined default rank (plan to add a data tree with key'd values later).
The reason for this is i want to make my code more efficient, i want to make a function for the open and close sequences, to trim repetitiveness and to boost readability/reduce code space.
Say i declare the function:

function FileRead(ReadPath)
file = fs.open(ReadPath,'r')
filedata = textutils.unserialize(file.readAll())
file.close()
return filedata
end
with the sample file in question containing:

{
  Key = "Value",
  Foo = "Bar",
}
And then i want to declare a write function, such that: It opens the file stated in the WritePath, and retrieves the data using the FileRead function, and then writes the new data to the file.
Would i just do this? :

function FileWrite(WritePath,DataKey,DataValue)
FileContents = FileRead(WritePath)
file = fs.open(WritePath,'w')
FileContents[DataKey] = DataValue
NewFileData = textutils.serialize(FileContents)
file.write(NewFileData)
file.close()
end
Or am i wrong?
Dog #4
Posted 11 October 2016 - 05:26 AM
Your FileRead function looks OK, except I would localize the function and the file and filedata variables.

For your FileWrite function, I would localize the function and the FileContents, file, and NewFileData variables. I would do something like this…

local function FileWrite(WritePath, DataKey, DataValue)
  local FileContents = FileRead(WritePath)
  local file = fs.open(WritePath, 'w')
  FileContents[DataKey] = DataValue
  file.write(textutils.serialize(FileContents)) --# do both of these together and save a line and a variable
  file.close()
end
EmberAnimus #5
Posted 11 October 2016 - 04:46 PM
Ah, i see. Thank you very much for your help Dog!