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

Making Multiple Users on One Computer

Started by flaminsnowman99, 15 June 2013 - 05:33 PM
flaminsnowman99 #1
Posted 15 June 2013 - 07:33 PM
Hello! So I'm getting back into the swing of Lua and ComputerCraft and I wanted to start simplish. I made a lock for a door with a username and password but I wanted to make it a little tougher for myself. I want to make it so there can be multiple user each with their own unique username and password. However, I don't know how to do this. Help is greatly appreciated. Thanks!
brett122798 #2
Posted 15 June 2013 - 08:04 PM
I'm not sure how you're approaching this.. is it a server that holds the data or the computer itself? If it's the computer itself, you can easily have two usernames and passwords like this:


if (usernameInput == "User1" and passwordInput == "Pass1") or (usernameInput == "User2" and passwordInput == "Pass2") then
-- Unlocking the door stuffz
end

It also can be done the same way with a server but you need to deal with rednet stuff.
flaminsnowman99 #3
Posted 15 June 2013 - 11:52 PM
I'm sorry, I don't think I worded what I need correctly. It won't know how many people will be there. So I can't have individual variables. I'm not hugely familiar with Lua but in Java, I would use an ArrayList and use add() to add a member to the list. Then the list could be as long as possible and can have each individual persons password and username. Is that a little more descriptive?
theoriginalbit #4
Posted 15 June 2013 - 11:55 PM
use tables.


local users = {}

then you can put in new users


users[username] = password

then you can check if the username and password are correct


if users[enteredUser] == enteredPassword then
  -- the username and password was correct
end

EDIT: To help you understand better here is a table tutorial link. Tables can be indexed values (like ArrayList in Java) or they can be key/value pairs (like HashMaps in Java)… and in LuaJ (which is what CC runs, its Lua in Java) tables are actually implemented in HashMaps.
Edited on 15 June 2013 - 09:57 PM
flaminsnowman99 #5
Posted 16 June 2013 - 12:37 AM
Thank you! That helps a lot! I'm looking through the tutorial though and I have one problem. Checking for an already existing value in the table. So I wanna do a check like….

if users[username] == users[checkAllUsers] then
	-- choose another name
But I don't know what to put where "checkAllUsers" is.

Also, is there a way to remove values from the table?
theoriginalbit #6
Posted 16 June 2013 - 01:01 AM
to check for an existing value you can do this

if users[username] then
and if the username with that key doesn't exist it will be nil, nil in Lua resolves to false.

Yes it is possible to remove values from a table. just set it to nil.


users[username] = nil

give me a minute, I'll put together a little example.
theoriginalbit #7
Posted 16 June 2013 - 01:15 AM
Ok so in this example security has been increased by hashing the passwords and making them unreadable by humans. Also hashing, unlike encrypting, is irreversible. Assume that I've used GravityScore's SHA256 hashing algorithm and it is in a file called `hash`. Link to API. Now as well as just hashing I've added a SALT to each password to improve security as well. Salting reduces the chance of a rainbow table attack. The hash I've used is as follows

local SALT = "BpSi?*7=)6U[b~<V{k*IH7;*l7-nv3|+S=S3G$8/+y`<=xU2PTV}W|ux)Y!KeXK<"
[/code]

this is the user creation example
[code]

--# create a user
local function createUser( uname, pword )
  --# the user already exists
  if users[uname] then
	return false, "User already exists"
  end
  --# save the password into the user table
  users[uname] = hash.sha256( pword .. SALT ) --# where hash is the name of GravityScore's API on the file system
  return true
end

this is the user deletion example


--# remove a user
local function removeUser( uname, pword )
  --# the user doesn't exist
  if not users[uname] then
	return false, "No user with that username"
  end
  --# the passwords do not match
  if users[uname] ~= hash.sha256( pword .. SALT ) then
	return false, "Cannot remove account that is not your own"
  end
  --# remove the user
  users[uname] = nil
  return true
end

this is the login example


--# check if the password is correct
local function checkLogin( uname, pword )
  return users[uname] == hash.sha256( pword .. SALT )
end

this is a very basic (and not the best way) to save the users out to a file for persistence across reboots


--# save all the user information to a file
local function saveUsers()
  local h = fs.open( ".data", 'w' )
  h.write( textutils.serialize(users) )
  h.close()
end

--# load all the user information from a file
local function loadUsers()
  local h = fs.open( ".data", 'r' )
  users = textutils.unserialize( h.readAll() )
  h.close()
end

now you may notice with these functions that when there is a failure I return 2 values, a boolean and a string as to why it failed. This is why.
NOTE: all password values are in plaintext, NOT a hashed values, the functions hash, so when passing in the passwords they must just be the raw user input.



local ok, err = createUser( "TheOriginalBIT", "4hGd$f/-U" )
if not ok then
  print("Cannot create account\n"..err)
end

other functions would be as follows


local ok, err = updateUserName( "4hGd$f/-U", "TheOriginalBIT", "BIT" )
local ok, err = updateUserPass( "BIT", "4hGd$f/-U", "th1si5M0R3s3cur3.h&amp;h&amp;n0t!" )

if checkLogin( "BIT", "4hGd$f/-U", "th1si5M0R3s3cur3.h&amp;h&amp;n0t!" ) then
  print("Yay it works!")
end

local ok, err = removeUser( "BIT", "th1si5M0R3s3cur3.h&amp;h&amp;n0t!" )

I hope this helps. If you have any questions, just ask… :)/>

— BIT
flaminsnowman99 #8
Posted 16 June 2013 - 01:32 AM
Awesome example! Thank you so much! You've been a lot of help!
theoriginalbit #9
Posted 16 June 2013 - 01:33 AM
No problems :)/> glad I can help :)/>