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

Need help making my multi-user login script easier to add users

Started by Grey_M62, 12 July 2012 - 03:00 AM
Grey_M62 #1
Posted 12 July 2012 - 05:00 AM
so i have been working on making a multiple account login script, but i need a simple way to add users. The best option for me would be to have a seperate program, Users.txt, that looks like this:

User1:Password1
User2:Password2
User3:Password3

Here is a simplified version of my script:

write "Username: "
user = read()
if user == "User1" then
	  write "Password: "
	  p1 = read("*")
	  if p1 == "Password1" then
			print "User Verified."
	  else
			print "Incorrect Password."
			sleep(1)
			os.shutdown()
	  end
elseif user == "User2" then
	  write "Password: "
	  p2 = read("*")
	  if p2 == "Password2" then
			print "User Verified."
	  else
			print "Incorrect Password."
			sleep(1)
			os.shutdown()
	  end
elseif user == "User3" then
	  write "Password: "
	  p3 = read("*")
	  if p3 == "Password3" then
			print "User Verified."
	  else
			print "Incorrect Password."
			sleep(1)
			os.shutdown()
	  end
else
	  print "User not found."
	  sleep(1)
	  os.shutdown()
end
This is only a simplified version. My code has a lot more printed messages, witch makes it harder to add new users. I want it to look similar, but make it so for the user it reads the part before the ':' above, and reads the part after for the password, but also, each individual user has its own password.

I also have a line were it prints "Welcome, (username)." after the "User Verified." but i removed it to simplify. could i also make it so that it prints that user's username in that spot?

To sum it up, i want a simplified version of my above script for my startup program, but another program 'Users.txt' to add/delete/edit users.
Jazza #2
Posted 12 July 2012 - 07:04 AM


password = {Jazza = "Fruit", Grey = "Hello"} --Make sure they are in the respective order.

write("Username:")
user = read()
write("Password:")
pass = read("*")

if password[user] == pass then
		print("Welcome " .. user)
else
		print("Sorry, Wrong Username and/or Password")
end

Basically it uses the Username to check the password in the table, and if it's right, it tells you.
You could easily use a file, so that the passwords are more secure.

Also, if you wanted to, you could

pcall(read,"*")
To stop the code from terminating.
Grey_M62 #3
Posted 12 July 2012 - 07:51 AM


password = {Jazza = "Fruit", Grey = "Hello"} --Make sure they are in the respective order.

write("Username:")
user = read()
write("Password:")
pass = read("*")

if password[user] == pass then
		print("Welcome " .. user)
else
		print("Sorry, Wrong Username and/or Password")
end

Basically it uses the Username to check the password in the table, and if it's right, it tells you.
You could easily use a file, so that the passwords are more secure.

Also, if you wanted to, you could

pcall(read,"*")
To stop the code from terminating.
You, sir, have made my life so much easier. do you know if there is a simple way to make each user have their own programs?
Grey_M62 #4
Posted 12 July 2012 - 07:58 AM
Grey_M62 #5
Posted 12 July 2012 - 08:00 AM


password = {Jazza = "Fruit", Grey = "Hello"} --Make sure they are in the respective order.

write("Username:")
user = read()
write("Password:")
pass = read("*")

if password[user] == pass then
		print("Welcome " .. user)
else
		print("Sorry, Wrong Username and/or Password")
end

Basically it uses the Username to check the password in the table, and if it's right, it tells you.
You could easily use a file, so that the passwords are more secure.

Also, if you wanted to, you could

pcall(read,"*")
To stop the code from terminating.
how do you make a different file for users/passwords? If you could tell me, could you make it have the 'user = password' on seperate lines?
Jazza #6
Posted 12 July 2012 - 09:07 AM
Alright, first question first.
To make each person have there own program? What do you mean. If you mean execute a function upon login, you would have to change…


if password[user] == pass then
print("Welcome " .. user)
else
print("Sorry, Wrong Username and/or Password")
end
…To…


if password[user] == pass then
		print("Welcome " .. user)

		if user == "Jazza" then
				jazza()
		elseif user == "Grey" then
				grey()
		end
else
		print("Sorry, Wrong Username and/or Password")
end

To answer the second question, Yes you can have them on each line…

password = {
Jazza = "Fruit"
Grey = "Hello"
}

And I will look into loading from a file, I'm guessing it would be the same file for each username/password combination, or individual?
–After re-reading the first paragraph, I realised you meant one. Looking into it now.
Grey_M62 #7
Posted 12 July 2012 - 10:21 AM
What I meant by 'each user has their own programs' was that each individual user would have their own separate list of programs. For example, if you made a program called 'fruit', no one else could see or use it. I could make one called 'fruit' if I wanted, and it would be separate. I'm guessing this isn't possible.
Grey_M62 #8
Posted 12 July 2012 - 10:29 AM
Looking into it now.
^ forgot to quote.
Jazza #9
Posted 12 July 2012 - 10:45 AM
Hmm, you could just create a folder and load the programs from thar? Or, you could do something like…

save(user .. fname, path)
save does not work that way, unless you make a custom function, but that's how I would do it.
Also, I'm not great at this stuff, I just know the basics and how to optimise stuff, at least how I think it should be.
Grey_M62 #10
Posted 12 July 2012 - 11:20 AM
Hmm, you could just create a folder and load the programs from thar? Or, you could do something like…

save(user .. fname, path)
save does not work that way, unless you make a custom function, but that's how I would do it.
Also, I'm not great at this stuff, I just know the basics and how to optimise stuff, at least how I think it should be.
Ok. Have you found anything on saving users/passwords to a separate file?
Jazza #11
Posted 12 July 2012 - 11:37 AM
I have, but I haven't found one that works.. =(
Grey_M62 #12
Posted 12 July 2012 - 09:05 PM
I have, but I haven't found one that works.. =(
ok. Tell me when you do.
Grim Reaper #13
Posted 12 July 2012 - 10:20 PM
Here is some sample code:


--[[ Multi user login example by PaymentOption ]]--
tUsers = {};
-- Format = tUsers[n] = {name = "name", password = "password"};
local file = nil;
if not fs.exists("Information") and not fs.isDir("Information") then
shell.run("mkdir", "Information");
end
-- File format: EACH FILE IS A SINGLE USER
-- username
-- password
function loadUsers() -- This is how we'll load all of the proper information into the tUsers table.'
tFiles = fs.list("Information");

for i=1, #tFiles do
  file = fs.open("Information/"..tFiles[i], "r");
  tUsers[i] = {name = file.readLine(), password = file.readLine()};
  file.close();
end
end
function printUsers()
for i,n in pairs(tUsers) do
  print(n.name);
end
end
function clear() term.clear(); term.setCursorPos(1, 1); end
function getLogin()
clear();

local userName = "";
local userPass = "";

term.write("Username: ");
print("");
term.write("Password: ");

term.setCursorPos(10, 1);
userName = read();

term.setCursorPos(10, 2);
userPass = read();

for i=1, #tUsers do
  if userName == tUsers[i].name then
   if userPass == tUsers[i].password then
    return true;
   end
  end
end

return false;
end
loadUsers();
if getLogin() then
clear();
print("Success!");
sleep(2);
clear();
print(os.version());
else
clear();
print("Failure!");
sleep(2);
clear();
os.shutdown();
end

Hope I helped! :)/>/>
Grey_M62 #14
Posted 12 July 2012 - 10:43 PM
Here is some sample code:


--[[ Multi user login example by PaymentOption ]]--
tUsers = {};
-- Format = tUsers[n] = {name = "name", password = "password"};
local file = nil;
if not fs.exists("Information") and not fs.isDir("Information") then
shell.run("mkdir", "Information");
end
-- File format: EACH FILE IS A SINGLE USER
-- username
-- password
function loadUsers() -- This is how we'll load all of the proper information into the tUsers table.'
tFiles = fs.list("Information");

for i=1, #tFiles do
  file = fs.open("Information/"..tFiles[i], "r");
  tUsers[i] = {name = file.readLine(), password = file.readLine()};
  file.close();
end
end
function printUsers()
for i,n in pairs(tUsers) do
  print(n.name);
end
end
function clear() term.clear(); term.setCursorPos(1, 1); end
function getLogin()
clear();

local userName = "";
local userPass = "";

term.write("Username: ");
print("");
term.write("Password: ");

term.setCursorPos(10, 1);
userName = read();

term.setCursorPos(10, 2);
userPass = read();

for i=1, #tUsers do
  if userName == tUsers[i].name then
   if userPass == tUsers[i].password then
	return true;
   end
  end
end

return false;
end
loadUsers();
if getLogin() then
clear();
print("Success!");
sleep(2);
clear();
print(os.version());
else
clear();
print("Failure!");
sleep(2);
clear();
os.shutdown();
end

Hope I helped! :)/>/>
Seems a bit complicated to me…
Grim Reaper #15
Posted 12 July 2012 - 11:17 PM
Well, all you have to do is setup the right files and loadUsers() function in the tUsers table. You could have other users and handle the login however you would like. If you have any specific questions, message me, or reply :)/>/>
Grey_M62 #16
Posted 12 July 2012 - 11:45 PM
Well, all you have to do is setup the right files and loadUsers() function in the tUsers table. You could have other users and handle the login however you would like. If you have any specific questions, message me, or reply :)/>/>
Could you provide an example of the code from the users file?
Grim Reaper #17
Posted 13 July 2012 - 01:44 AM
Here is an example that I used:


(This is inside a file in the Information directory. Keep in mind each user needs their own file!)


PaymentOption
Payment

The first line is the username and the second line is the password.

I hope I helped! :)/>/>
Grey_M62 #18
Posted 13 July 2012 - 01:45 AM
Here is an example that I used:


(This is inside a file in the Information directory. Keep in mind each user needs their own file!)


PaymentOption
Payment

The first line is the username and the second line is the password.

I hope I helped! :)/>/>
so, is it one file per user, or something like that?
Grim Reaper #19
Posted 13 July 2012 - 01:56 AM
That's exactly right! :)/>/>
Grey_M62 #20
Posted 13 July 2012 - 03:14 AM
That's exactly right! :)/>/>
how would i add a new user? 'edit information/(newuser)' ?
Grim Reaper #21
Posted 13 July 2012 - 03:29 AM
Exactly.

Within that file you would just right on the first line the username and the password on the next line. That's all there is to it. :)/>/>
Grey_M62 #22
Posted 13 July 2012 - 03:48 AM
would the 'information/(newuser)' appear on my programs list?

Exactly.

Within that file you would just right on the first line the username and the password on the next line. That's all there is to it. :)/>/>
^ forgot to quote.
Grey_M62 #23
Posted 13 July 2012 - 04:05 AM
Exactly.

Within that file you would just right on the first line the username and the password on the next line. That's all there is to it. :)/>/>
Actually, is there a way that you could modify Jazza's code but make it have the separate files for users? I like the interface of that code better.
Grey_M62 #24
Posted 13 July 2012 - 04:32 AM
Exactly.

Within that file you would just right on the first line the username and the password on the next line. That's all there is to it. :)/>/>
So, i modified the code a bit, and i get an error. I want it to recognize the username and say 'Welcome, (username).' but it gives me an error. here is the code:

tUsers = {}
local file = nil;
if not fs.exists("Information") and not fs.isDir("Information") then
shell.run("mkdir", "Information");
end
function loadUsers()
tFiles = fs.list("Information");
for i=1, #tFiles do
  file = fs.open("Information/"..tFiles[i], "r");
  tUsers[i] = {name = file.readLine(), password = file.readLine()};
  file.close();
end
end
function printUsers()
for i,n in pairs(tUsers) do
  print(n.name);
end
end
function clear() term.clear(); term.setCursorPos(1, 1); end
function getLogin()
clear();
local userName = "";
local userPass = "";
print( "Secure PC v3.2 - Locked" )
print("")
sleep(1)
term.write("Username: ");
print("");
term.write("Password: ");
term.setCursorPos(11, 3);
userName = read();
term.setCursorPos(11, 4);
userPass = read("*");
for i=1, #tUsers do
  if userName == tUsers[i].name then
   if userPass == tUsers[i].password then
	return true;
   end
  end
end
return false;
end
loadUsers();
if getLogin() then
print("User Verified.");
sleep(1);
write("Welcome,".. userName) write(".") -- Here is where i get the error.
clear();
print("Secure PC v3.2 - Unlocked");
print("")
sleep(0.5)
else
print("Incorrect Username and/or Password.");
sleep(1);
clear();
os.shutdown();
end
Grim Reaper #25
Posted 13 July 2012 - 04:53 AM
This error is due to the fact that the variable 'userName' is defined locally within the getLogin() function. If you'd like to print the username try this:

Spoiler


tUsers = {}
local file = nil;
local userName = "";
if not fs.exists("Information") and not fs.isDir("Information") then
shell.run("mkdir", "Information");
end
function loadUsers()
tFiles = fs.list("Information");
for i=1, #tFiles do
  file = fs.open("Information/"..tFiles[i], "r");
  tUsers[i] = {name = file.readLine(), password = file.readLine()};
  file.close();
end
end
function printUsers()
for i,n in pairs(tUsers) do
  print(n.name);
end
end
function clear() term.clear(); term.setCursorPos(1, 1); end
function getLogin()
clear();
userName = ""; -- This will reference the global variable 'userName'
local userPass = "";
print( "Secure PC v3.2 - Locked" )
print("")
sleep(1)
print("Username: ");
print("Password: ");
term.setCursorPos(11, 3);
userName = read();
term.setCursorPos(11, 4);
userPass = read("*");
for i=1, #tUsers do
  if userName == tUsers[i].name then
   if userPass == tUsers[i].password then
		return true;
   end
  end
end
return false;
end
loadUsers();
if getLogin() then
print("User Verified.");
sleep(1);
write("Welcome,".. userName..".") -- Here is where i get the error.
sleep(1);
clear();
print("Secure PC v3.2 - Unlocked");
print("")
sleep(0.5)
else
print("Incorrect Username and/or Password.");
sleep(1);
clear();
os.shutdown();
end

All I have done is created a global instance of the 'userName' variable. Meaning that all functions and statements may use it. Before, it was locally defined within a function, meaning that you couldn't use it unless your statement was within getLogin(). This would mean that if you tried to use it outside the function that Lua would create the variable, but it would be set to nil because it has not been initialized, or set to a value that is not 'nil'.
Jazza #26
Posted 13 July 2012 - 02:27 PM
I'm confused, why do you do this…

term.write("Username: ");
print("");
term.write("Password: ");
term.setCursorPos(11, 3);
userName = read();
term.setCursorPos(11, 4);

When you could have done…


print("Username: ");
userName = read();
print("Password: ");
userPass = read();

I'm guessing it's because the code is not optimised.
Grim Reaper #27
Posted 13 July 2012 - 05:47 PM
It's just a preference. I'm not much for going back and cleaning up solutions for efficiency, I am more concerned that it works. :)/>/> However, you are right, that works, and in less code.

Also, if you call read after the first print statement, the second print won't execute until the first read is complete. Printing both items first just makes it look cleaner and a little more professional.
Grey_M62 #28
Posted 13 July 2012 - 09:05 PM
It's just a preference. I'm not much for going back and cleaning up solutions for efficiency, I am more concerned that it works. :P/>/> However, you are right, that works, and in less code.

Also, if you call read after the first print statement, the second print won't execute until the first read is complete. Printing both items first just makes it look cleaner and a little more professional.
In this situation, i agree with you. in my opinion, it does look nicer.
Laserman34170 #29
Posted 26 July 2012 - 05:18 PM
All the information about a user should be stored in folders that the users can't backtrack out of (custom file manager?). This way they only see THEIR data.
Here's some sample code.

-- This is the "users" file for storage of passwords
steve=ilovemc
admin=iamboss
guest=default
-- Usernames on the left, passwords on the right
-- Encrypt the file for better security


-- This is the actual login code
function getUserInfo(user)-- Get the password for a user
  local file = io.open("/users")
  if not file then
	print("No users file found :)/>/>")
	return "nil"
  end
  local password = file:read()
  if not string.find(password, user) then
	return "notfound"
  end
  password = string.gsub(password, user.."=","")
  return password
end
write("Enter username: ")
user = read()
write("Enter password: ")
userpass = read("*")
pass = getUserInfo(user)
if pass == "nil" then
  print("Users file not found")
  return
elseif pass == "notfound" then
  print("User doesn't exist")
  return
else
  if pass == userpass then
	print("Yeah! You got the password right!
  else
	print("No! You got the password wrong!")
  end
end

Then you can have a custom boot or an admin account to change users.
Hope I helped!
Note: All this was on the fly. I cannot guarantee that it will work.