-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f3ce418
commit a587591
Showing
4 changed files
with
326 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
from flask import Flask, render_template, request, url_for | ||
import sys | ||
import subprocess | ||
import re | ||
import os | ||
import tempfile | ||
|
||
# Initialize the Flask application | ||
app = Flask(__name__) | ||
|
||
# Define a route for the default URL, which loads the form | ||
@app.route('/') | ||
def form(): | ||
return render_template('form_submit.html') | ||
|
||
@app.route('/user', methods=['POST']) | ||
def user(): | ||
#get the form data | ||
username=request.form['username'] | ||
shell=request.form['shell'] | ||
homedir=request.form['homedir'] | ||
passwd=request.form['password'] | ||
sudo=request.form['sudo'] | ||
action=request.form['dropdown'] | ||
|
||
# check if user is already exist or not | ||
userExist=isUserExist(request.form['username']) | ||
|
||
# take the action | ||
if action == "Create": | ||
if userExist: #if user already exist nothing to do | ||
msg1="User " + str(username) + " already exist!" | ||
else: #add requested user | ||
returnCode=addUser(username,shell,homedir,passwd) | ||
if returnCode: | ||
msg1="User " + str(username) + " added!" | ||
else: | ||
msg1="User " + str(username) + " doesn't added!" | ||
|
||
elif action == "Modify": | ||
if userExist: # modify the user if exist | ||
returnCode=modUser(username,shell,homedir,passwd) | ||
if returnCode: | ||
msg1="User " + str(username) + " modified!" | ||
else: | ||
msg1="User " + str(username) + " doesn't modified!" | ||
else: | ||
msg1="User " + str(username) + " doesn't exist!" | ||
|
||
elif action == "Delete": | ||
if userExist: # delete user if exist | ||
returnCode=delUser(username) | ||
if returnCode: | ||
msg1="User " + str(username) + " deleted!" | ||
else: | ||
msg1="User " + str(username) + " doesn't deleted!" | ||
else: | ||
msg1="User " + str(username) + " doesn't exist!" | ||
|
||
#now it's time for sudo | ||
msg2="" | ||
userExist=isUserExist(request.form['username']) # for sudo check if user exist | ||
temp=tempfile.NamedTemporaryFile() | ||
sudoersFile=temp.name | ||
os.system("sudo cp /etc/sudoers " + temp.name) # normal user doesn't have permission to read and modify so first create a temp file for sudoers | ||
sudo_entry= username + "\tALL=(ALL) ALL\n" # if sudo entry need to insert use it. | ||
sudoer = open(sudoersFile, "r") | ||
regex = re.compile(username + ".+=.+ALL") | ||
for line in sudoer: #check if a sudo entry is exist of not | ||
sudo_entryMatch = regex.findall(line) | ||
if sudo_entryMatch: # if sudo entry found exit the loop | ||
break | ||
sudoer.close | ||
if action == "Create" and sudo == "Yes" and userExist: | ||
if sudo_entryMatch: #if sudo entry found then no need to add it | ||
msg2="sudo entry Found: " + str(sudo_entryMatch) | ||
else: #else if sudo entry not found then add it | ||
msg2="Sudo entry Not Found, adding entry: " + sudo_entry | ||
add_sudo(sudo_entry,sudoersFile) | ||
os.system("sudo cp " + temp.name +" /etc/sudoers") | ||
|
||
elif action == "Modify" and userExist: | ||
if sudo_entryMatch and sudo == "No": # if sudo entry found but selected NO for sudo then delete it. | ||
msg2="sudo entry Found, deleting: " + str(sudo_entryMatch) | ||
del_sudo(regex,sudo_entryMatch,sudoersFile) | ||
os.system("sudo cp " + temp.name +" /etc/sudoers") | ||
elif not sudo_entryMatch and sudo == "Yes": | ||
msg2="Sudo entry Not Found, adding entry: " + sudo_entry | ||
add_sudo(sudo_entry,sudoersFile) | ||
os.system("sudo cp " + temp.name +" /etc/sudoers") | ||
elif sudo_entryMatch and sudo == "Yes": | ||
msg2="Sudo entry Found" | ||
elif not sudo_entryMatch and sudo == "No": | ||
msg2="Sudo not required" | ||
|
||
elif action == "Delete" and userExist: | ||
if sudo_entryMatch: # if action is user delete then delete sudo entry | ||
msg2="sudo entry Found, deleting: " + str(sudo_entryMatch) | ||
del_sudo(regex,sudo_entryMatch,sudoersFile) | ||
os.system("sudo cp " + temp.name +" /etc/sudoers") | ||
else: | ||
msg2="nothing for sudo entry" | ||
|
||
temp.close() | ||
|
||
return render_template('form_action.html', message1=msg1, message2=msg2, username=username) | ||
|
||
def command(cmd): # method to execute the system commands | ||
p = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) | ||
out,err = p.communicate() | ||
if p.returncode == 0: | ||
return True | ||
else: | ||
return False | ||
|
||
def passencrypt(cmd): # encrypt the password | ||
p = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) | ||
out,err = p.communicate() | ||
return out | ||
|
||
def isUserExist(user): # check if user is exist or not | ||
cmd = ["id", user] | ||
rcode=command(cmd) | ||
print rcode | ||
return rcode | ||
|
||
def addUser(username,shell,homedir,passwd): # add a system user using system commands | ||
passoutput=passencrypt(["/usr/bin/sudo", "/usr/bin/openssl", "passwd", "-crypt", str(passwd)]) | ||
returnCode=command(["/usr/bin/sudo", "/usr/sbin/useradd", "-m", "-d", str(homedir), "-s", str(shell), "-p", str(passoutput.strip()), username]) | ||
print username,shell,homedir,passwd | ||
return returnCode | ||
|
||
def modUser(username,shell,homedir,passwd): # modify a system user using system commands | ||
passoutput=passencrypt(["/usr/bin/sudo", "/usr/bin/openssl", "passwd", "-crypt", str(passwd)]) | ||
returnCode=command(["/usr/bin/sudo", "/usr/sbin/usermod", "-d", str(homedir), "-s", str(shell), "-p", str(passoutput.strip()), username]) | ||
print username,shell,homedir,passwd | ||
return returnCode | ||
|
||
def delUser(username): # delete user | ||
returnCode=command(["/usr/bin/sudo", "/usr/sbin/userdel", "-r", username]) | ||
return returnCode | ||
|
||
def add_sudo(sudo_entry,sudoersFile): # add sudo entry | ||
sudoer = open(sudoersFile, "a") | ||
sudoer.write(sudo_entry) | ||
sudoer.close() | ||
|
||
def del_sudo(regex,sudo_entryMatch,sudoersFile): # delete sudo entry | ||
sudoer = open(sudoersFile, "r") | ||
lines = sudoer.readlines() | ||
sudoer.close() | ||
sudoer = open(sudoersFile, "w") | ||
matchLine=sudo_entryMatch[0] + "\n" | ||
for line in lines: | ||
if line != matchLine: | ||
sudoer.write(line) | ||
sudoer.close() | ||
|
||
|
||
# Run the app :) | ||
if __name__ == '__main__': | ||
app.run | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
::selection{ background-color: #E13300; color: white; } | ||
::moz-selection{ background-color: #E13300; color: white; } | ||
::webkit-selection{ background-color: #E13300; color: white; } | ||
|
||
body { | ||
font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif; | ||
color: #888; | ||
font-style: normal; | ||
font-size: 14px; | ||
line-height: 22px; | ||
} | ||
|
||
a { | ||
color: #003399; | ||
background-color: transparent; | ||
font-weight: normal; | ||
} | ||
|
||
.title { | ||
padding: 0 20px; | ||
background: #32373a; | ||
position: relative; | ||
height: 50px; | ||
} | ||
|
||
h1 { | ||
color: #fff; | ||
margin: 0; | ||
font-size: 18px; | ||
font-weight: 400; | ||
line-height: 50px; | ||
text-transform: capitalize; | ||
} | ||
|
||
code { | ||
font-family: Consolas, Monaco, Courier New, Courier, monospace; | ||
font-size: 12px; | ||
background-color: #f9f9f9; | ||
border: 1px solid #D0D0D0; | ||
color: #002166; | ||
display: block; | ||
padding: 12px 10px 12px 10px; | ||
} | ||
|
||
#content { | ||
padding: 20px; | ||
zoom: 1; | ||
} | ||
|
||
#body{ | ||
margin: 0 15px 0 15px; | ||
} | ||
|
||
p.footer{ | ||
text-align: right; | ||
font-size: 11px; | ||
border-top: 1px solid #D0D0D0; | ||
line-height: 32px; | ||
padding: 0 10px 0 10px; | ||
margin: 20px 0 0 0; | ||
} | ||
|
||
#container{ | ||
margin: 10px; | ||
border: 1px solid #D0D0D0; | ||
-webkit-box-shadow: 0 0 8px #D0D0D0; | ||
} | ||
|
||
/* Form Styles */ | ||
form label{ | ||
/* display: block;*/ | ||
display: inline; | ||
margin-bottom: 5px; | ||
} | ||
form input[type=text]{ | ||
border: 1px solid #aaa; | ||
border-radius: 2px; | ||
box-shadow: inset 0 1px 2px rgba(0,0,0,.1); | ||
box-sizing: border-box; | ||
padding: 5px; | ||
margin-bottom: 20px; | ||
outline: 0; | ||
-webkit-border-radius: 2px; | ||
-moz-border-radius: 2px; | ||
-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); | ||
-moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); | ||
} | ||
form input[type=submit]{ | ||
background: #198ad1; | ||
color: #fff; | ||
display: inline-block; | ||
padding: 0 20px; | ||
font-size: 16px; | ||
line-height: 2.6em; | ||
font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif; | ||
font-weight: 400; | ||
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.1); | ||
-moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,.1); | ||
box-shadow: inset 0 -1px 0 rgba(0,0,0,.1); | ||
-webkit-border-radius: 2px; | ||
-moz-border-radius: 2px; | ||
border-radius: 2px; | ||
text-transform: capitalize; | ||
border: 0; | ||
cursor: pointer; | ||
text-align: center; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<html> | ||
<head> | ||
<title>Handle POST requests with Flask</title> | ||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}"> | ||
</head> | ||
<body> | ||
<div id="container"> | ||
<div class="title"> | ||
<h1>POST request with Flask</h1> | ||
</div> | ||
<div id="content"> | ||
<strong>{{message1}}</strong> | ||
<br /> | ||
<strong>{{message2}}</strong> | ||
</div> | ||
</div> | ||
</body> | ||
</html> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<html> | ||
<head> | ||
<title>Linux User Management</title> | ||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}"> | ||
</head> | ||
<body> | ||
<div id="container"> | ||
<div class="title"> | ||
<h1>Linux User Management with Flask</h1> | ||
</div> | ||
<div id="content"> | ||
<form method="post" action="{{ url_for('user') }}"> | ||
<label for="username">User Name:</label> | ||
<input type="text" name="username" /><br /> | ||
<label for="shell">Shell:</label> | ||
<input type="text" name="shell" /><br /> | ||
<label for="homedir">Home Dir:</label> | ||
<input type="text" name="homedir" /><br /> | ||
<label for="password">Password:</label> | ||
<input type="text" name="password" /><br /> | ||
<label for="sudo">SUDO:</label> | ||
<select name="sudo">Sudo: | ||
<option value="Yes" selected>Yes</option> | ||
<option value="No"> No</option> | ||
</select><br /> | ||
<label for="action">Action:</label> | ||
<select name="dropdown"> | ||
<option value="Create" selected>Create</option> | ||
<option value="Modify"> Modify</option> | ||
<option value="Delete"> Delete</option> | ||
</select><br /><br /> | ||
<input type="submit" /><br /> | ||
</form> | ||
</div> | ||
</div> | ||
</body> | ||
</html> |