#!/usr/bin/env python
# File Name: user-management
# Version: 2.0
# Purpose:  USERS ( adding, removing, recovering, repairing, and login options )
#			PASSWORDS ( changing user passwords )
# Authors: Dave and minor modifications by anticapitalista
# Acknowledgements: AntiX forum _("Users") for suggestions, testing, and input
# Special Acknowledgements: anticapitalista for testing, suggestions, input

# Copyright (C) Tuesday, Feb. 7, 2011  by Dave / david.dejong02@gmail.com
# License: gplv2
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#################################################################################################################################################

import pygtk
pygtk.require('2.0')
import gtk
import re
import os
import sys
import gettext
gettext.install("user-management", "/usr/share/locale")
from desktop_tool import DesktopToolWidget
from desktop_tool import get_icon as get_icon

##STRINGS
not1 = _("Notice!\n\
        All of the users files will remain in their \n\
        home directory, unless completely remove\n\
        is checked. \n\
        Even so, it is recomended that the\n\
        files be backed up!")
not2 = _("Notice!\n\
        A user can only be recovered if the user\n\
        has not been completely removed!")
warn1 = _("Warning!\n\
        Attempting a user repair may restore more\n\
        programs to original settings than you intend!\n\
        It is highly recommended that you first do a\n\
        backup of all files in your home directory.")

class Error:
    def __init__(self, error):
       cmdstring = "yad --image=\"error\"\
       --title=\"user-management error\"\
       --text=\"user-management has run into an error,\
       \nplease rerun and correct the following error!\
       \n\n%s\n\"\
       --button=\"gtk-ok:0\"" % (error)
       os.system(cmdstring) 

class Password:        
    
    def applyPassword(self, widget):
        model = self.combobox.get_model()
        index = self.combobox.get_active()			
        user = model[index][0]
        
        password1 = self.passwd1.get_text()
        
        password2 = self.passwd2.get_text()
        
        defaultUser = self.defaultLogin.get_active()			
        
        autoUser = self.autoLogin.get_active()			
        
        if re.search(r' ', password1):
            sys.exit(Error(_("The password cannot contain spaces")))
        elif ( password1 == "" ):
            sys.exit(Error(_("You need to enter a password")))
        elif (password1 != password2):
            sys.exit(Error(_("First and second password must be identical")))
        else:
            password=password1
            
        if (user == _("No User Selected:")):
            sys.exit(Error(_("You must choose a user")))
        else:
            cmdstring = "UM-set -p %s %s %s %s" % ((user), (password), (defaultUser), (autoUser))
            os.system(cmdstring)

    def __init__(self):
        self.frame = gtk.Frame()
        self.frame.set_border_width(10)
        self.frame.show()

        vbox = gtk.VBox()
        self.frame.add(vbox)
        vbox.show()

        label = gtk.Label(_("Password Manager"))
        vbox.pack_start(label)
        label.show()
        
        frame = gtk.Frame(_("You must choose a user"))
        vbox.pack_start(frame)
        frame.show()
        
        self.combobox = gtk.combo_box_new_text()
        frame.add(self.combobox)
        self.combobox.show()
        self.combobox.append_text(_("No User Selected:"))
        self.combobox.append_text('Root')
    
        for line in open("/etc/passwd", "r").xreadlines():
            if re.search(r':x:1[0-9][0-9][0-9]', line):
                pieces = line.split(':')
                self.combobox.append_text(pieces[0])
        
        #combobox.connect('changed', self.changed_cb)
        self.combobox.set_active(0)
        
        frame = gtk.Frame(_("User Password"))
        vbox.pack_start(frame)
        frame.show()
        
        passbox = gtk.VBox()
        frame.add(passbox)
        passbox.show()
        
        self.passwd1 = gtk.Entry()
        self.passwd1.set_text(_("password"))
        passbox.pack_start(self.passwd1)
        self.passwd1.show()
        
        self.passwd2 = gtk.Entry()
        self.passwd2.set_text(_("password again"))
        passbox.pack_start(self.passwd2)
        self.passwd2.show()
        
        frame = gtk.Frame(_("User Login"))
        vbox.pack_start(frame)
        frame.show()
        
        loginbox = gtk.VBox()
        frame.add(loginbox)
        loginbox.show()
        
        self.defaultLogin = gtk.CheckButton()
        self.defaultLogin.set_label(_("Set as Default User"))
        loginbox.pack_start(self.defaultLogin)
        self.defaultLogin.show()
        
        self.autoLogin = gtk.CheckButton()
        self.autoLogin.set_label(_("Set User for Automatic Login"))
        loginbox.pack_start(self.autoLogin)
        self.autoLogin.show()
        
        buttonbox = gtk.HButtonBox()
        vbox.pack_start(buttonbox)
        buttonbox.show()
        
        okbutton = gtk.Button()
        icon_button = DesktopToolWidget(_('Apply'), 'dialog-ok', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        okbutton.add(icon_button)
        okbutton.connect("clicked", self.applyPassword)
        okbutton.set_size_request(100,50)
        buttonbox.add(okbutton)
        okbutton.show()
        
        closebutton = gtk.Button()
        icon_button = DesktopToolWidget(_('Close'), 'dialog-close', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        closebutton.add(icon_button)
        closebutton.connect("clicked", lambda w: gtk.main_quit())
        closebutton.set_size_request(100,50)
        buttonbox.add(closebutton)
        closebutton.show()

        self.label = gtk.Label(_("Passwords"))

class Add:
    def applyNewUser(self, widget):
        user = self.name.get_text()
        
        password1 = self.passwd1.get_text()
        
        password2 = self.passwd2.get_text()
        
        model = self.combobox.get_model()
        index = self.combobox.get_active()			
        shell = model[index][0]
        
        defaultUser = self.defaultLogin.get_active()			
        
        autoUser = self.autoLogin.get_active()			
        
        if re.search(r' ', password1):
            sys.exit(Error(_("The password cannot contain spaces")))
        elif ( password1 == "" ):
            sys.exit(Error(_("You need to enter a password")))
        elif (password1 != password2):
            sys.exit(Error(_("First and second password must be identical")))
        else:
            password=password1
            
        if re.search(r' ', user):
            sys.exit(Error(_("The username cannot contain spaces")))
        elif ( user == "" ):
            sys.exit(Error(_("You need to enter a username")))
        elif ( shell == _("No Shell Selected:") ):
            sys.exit(Error(_("You need to choose a shell")))
        else:
            cmdstring = "UM-set -a %s %s %s %s %s" % ((user), (password), (defaultUser), (autoUser), (shell))
            os.system(cmdstring)
            
    def __init__(self):
        self.frame = gtk.Frame()
        self.frame.set_border_width(10)
        self.frame.show()

        vbox = gtk.VBox()
        self.frame.add(vbox)
        vbox.show()

        label = gtk.Label(_("Add Users"))
        vbox.pack_start(label)
        label.show()
        
        frame = gtk.Frame(_("Enter Username"))
        vbox.pack_start(frame)
        frame.show()
        
        self.name = gtk.Entry()
        self.name.set_text("antiXDemo")
        frame.add(self.name)
        self.name.show()
        
        frame = gtk.Frame(_("User Password"))
        vbox.pack_start(frame)
        frame.show()
        
        passbox = gtk.VBox()
        frame.add(passbox)
        passbox.show()
        
        self.passwd1 = gtk.Entry()
        self.passwd1.set_text(_("password"))
        passbox.pack_start(self.passwd1)
        self.passwd1.show()
        
        self.passwd2 = gtk.Entry()
        self.passwd2.set_text(_("password again"))
        passbox.pack_start(self.passwd2)
        self.passwd2.show()
        
        frame = gtk.Frame(_("User Shell"))
        vbox.pack_start(frame)
        frame.show()
        
        self.combobox = gtk.combo_box_new_text()
        frame.add(self.combobox)
        self.combobox.show()
        self.combobox.append_text('/bin/bash')    
        
        #combobox.connect('changed', self.changed_cb)
        self.combobox.set_active(0)
        
        frame = gtk.Frame(_("User Login"))
        vbox.pack_start(frame)
        frame.show()
        
        loginbox = gtk.VBox()
        frame.add(loginbox)
        loginbox.show()
        
        self.defaultLogin = gtk.CheckButton()
        self.defaultLogin.set_label(_("Set as Default User"))
        loginbox.pack_start(self.defaultLogin)
        self.defaultLogin.show()
        
        self.autoLogin = gtk.CheckButton()
        self.autoLogin.set_label(_("Set User for Automatic Login"))
        loginbox.pack_start(self.autoLogin)
        self.autoLogin.show()
        
        buttonbox = gtk.HButtonBox()
        vbox.pack_start(buttonbox)
        buttonbox.show()
        
        okbutton = gtk.Button()
        icon_button = DesktopToolWidget(_('Apply'), 'dialog-ok', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        okbutton.add(icon_button)
        okbutton.connect("clicked", self.applyNewUser)
        okbutton.set_size_request(100,50)
        buttonbox.add(okbutton)
        okbutton.show()
        
        closebutton = gtk.Button()
        icon_button = DesktopToolWidget(_('Close'), 'dialog-close', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        closebutton.add(icon_button)
        closebutton.connect("clicked", lambda w: gtk.main_quit())
        closebutton.set_size_request(100,50)
        buttonbox.add(closebutton)
        closebutton.show()

        self.label = gtk.Label(_("Add User"))

class Repair:
    def applyRepair(self, widget):
        model = self.combobox.get_model()
        index = self.combobox.get_active()			
        user = model[index][0]
        
        save1 = self.firefox.get_active()			
        save2 = self.claws.get_active()			
        save3 = self.conky.get_active()			
        save4 = self.icewm.get_active()			
        save5 = self.flux.get_active()			
        save6 = self.jwm.get_active()	
        saveList = self.specifySave.get_text()	
        
        if (user == nouserpsel):
            sys.exit(Error(_("You must choose a user")))
        elif re.search(r'.list|.of|.configs|.to|.save', saveList):
            sys.exit(Error(_("The list of configs need to be empty or your own configs")))
        else:
            cmdstring = "UM-set -r %s %s %s %s %s %s %s %s" % ((user),(saveList),(save1),(save2),(save3),(save4),(save5),(save6))
            #print (cmdstring)
            os.system(cmdstring)
            
    def __init__(self):
        self.frame = gtk.Frame()
        self.frame.set_border_width(10)
        self.frame.show()

        vbox = gtk.VBox()
        self.frame.add(vbox)
        vbox.show()

        label = gtk.Label(_("User Repair"))
        vbox.pack_start(label)
        label.show()

        label = gtk.Label(warn1)
        vbox.pack_start(label)
        label.show()
        
        frame = gtk.Frame(_("Choose User"))
        vbox.pack_start(frame)
        frame.show()
        
        self.combobox = gtk.combo_box_new_text()
        frame.add(self.combobox)
        self.combobox.show()
        self.combobox.append_text(_("No User Selected:"))
        self.combobox.append_text('Root')
    
        for line in open("/etc/passwd", "r").xreadlines():
            if re.search(r':x:1[0-9][0-9][0-9]', line):
                pieces = line.split(':')
                self.combobox.append_text(pieces[0])
        
        #combobox.connect('changed', self.changed_cb)
        self.combobox.set_active(0)
        
        frame = gtk.Frame(_("Items to skip repair"))
        vbox.pack_start(frame)
        frame.show()
        
        saveVbox = gtk.VBox()
        frame.add(saveVbox)
        saveVbox.show()
        
        saveHbox = gtk.HBox()
        saveVbox.pack_start(saveHbox)
        saveHbox.show()
        
        appbox = gtk.VBox()
        saveHbox.pack_start(appbox)
        appbox.show()
        
        self.firefox = gtk.CheckButton()
        self.firefox.set_label("firefox")
        appbox.pack_start(self.firefox)
        self.firefox.show()
        
        self.claws = gtk.CheckButton()
        self.claws.set_label("Claws Mail")
        appbox.pack_start(self.claws)
        self.claws.show()
        
        self.conky = gtk.CheckButton()
        self.conky.set_label("Conky System Moniter")
        appbox.pack_start(self.conky)
        self.conky.show()
        
        wmbox = gtk.VBox()
        saveHbox.pack_start(wmbox)
        wmbox.show()
        
        self.icewm = gtk.CheckButton()
        self.icewm.set_label("iceWM")
        wmbox.pack_start(self.icewm)
        self.icewm.show()
        
        self.flux = gtk.CheckButton()
        self.flux.set_label("Fluxbox")
        wmbox.pack_start(self.flux)
        self.flux.show()
        
        self.jwm = gtk.CheckButton()
        self.jwm.set_label("JWM")
        wmbox.pack_start(self.jwm)
        self.jwm.show()
        
        self.specifySave = gtk.Entry()
        self.specifySave.set_text(".list|.of|.configs|.to|.save")
        saveVbox.pack_start(self.specifySave)
        self.specifySave.show()
        
        buttonbox = gtk.HButtonBox()
        vbox.pack_start(buttonbox)
        buttonbox.show()
        
        okbutton = gtk.Button()
        icon_button = DesktopToolWidget('Apply', 'dialog-ok', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        okbutton.add(icon_button)
        okbutton.connect("clicked", self.applyRepair)
        okbutton.set_size_request(100,50)
        buttonbox.add(okbutton)
        okbutton.show()
        
        closebutton = gtk.Button()
        icon_button = DesktopToolWidget('Close', 'dialog-close', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        closebutton.add(icon_button)
        closebutton.connect("clicked", lambda w: gtk.main_quit())
        closebutton.set_size_request(100,50)
        buttonbox.add(closebutton)
        closebutton.show()

        self.label = gtk.Label(_("Repair User"))

class Remove:
    def applyRemove(self, widget):
        model = self.combobox.get_model()
        index = self.combobox.get_active()			
        user = model[index][0]
        
        completeRemove = self.complete.get_active()			
        
        if (user == _("No User Selected:")):
            sys.exit(Error(_("You must choose a user")))
        else:
            cmdstring = "UM-set -rm %s %s " % ((user),(completeRemove))
            #print (cmdstring)
            os.system(cmdstring)
            
    def __init__(self):
        self.frame = gtk.Frame()
        self.frame.set_border_width(10)
        self.frame.show()

        vbox = gtk.VBox()
        self.frame.add(vbox)
        vbox.show()

        label = gtk.Label(_("User Removal"))
        vbox.pack_start(label)
        label.show()

        label = gtk.Label(not1)
        vbox.pack_start(label)
        label.show()
        
        frame = gtk.Frame(_("Choose User"))
        vbox.pack_start(frame)
        frame.show()
        
        self.combobox = gtk.combo_box_new_text()
        frame.add(self.combobox)
        self.combobox.show()
        self.combobox.append_text(_("No User Selected:"))
        self.combobox.append_text('Root')
    
        for line in open("/etc/passwd", "r").xreadlines():
            if re.search(r':x:1[0-9][0-9][0-9]', line):
                pieces = line.split(':')
                self.combobox.append_text(pieces[0])
        
        #combobox.connect('changed', self.changed_cb)
        self.combobox.set_active(0)
        
        frame = gtk.Frame(_("Completely Remove User?"))
        vbox.pack_start(frame)
        frame.show()
        
        self.complete = gtk.CheckButton()
        self.complete.set_label(_("Completely Remove User"))
        frame.add(self.complete)
        self.complete.show()
        
        buttonbox = gtk.HButtonBox()
        vbox.pack_start(buttonbox)
        buttonbox.show()
        
        okbutton = gtk.Button()
        icon_button = DesktopToolWidget('Apply', 'dialog-ok', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        okbutton.add(icon_button)
        okbutton.connect("clicked", self.applyRemove)
        okbutton.set_size_request(100,50)
        buttonbox.add(okbutton)
        okbutton.show()
        
        closebutton = gtk.Button()
        icon_button = DesktopToolWidget('Close', 'dialog-close', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        closebutton.add(icon_button)
        closebutton.connect("clicked", lambda w: gtk.main_quit())
        closebutton.set_size_request(100,50)
        buttonbox.add(closebutton)
        closebutton.show()

        self.label = gtk.Label(_("Remove User"))
        
class Recover:
    def applyRecover(self, widget):
        user = self.name.get_text()
        
        password1 = self.passwd1.get_text()
        
        password2 = self.passwd2.get_text()
        
        defaultUser = self.defaultLogin.get_active()			
        
        autoUser = self.autoLogin.get_active()			
        
        if re.search(r' ', password1):
            sys.exit(Error(_("The password cannot contain spaces")))
        elif ( password1 == "" ):
            sys.exit(Error(_("You need to enter a password")))
        elif (password1 != password2):
            sys.exit(Error(_("First and second password must be identical")))
        else:
            password=password1
            
        if re.search(r' ', user):
            sys.exit(Error(_("The username cannot contain spaces")))
        elif ( user == "" ):
            sys.exit(Error(_("You need to enter a username")))
        else:
            cmdstring = "UM-set -rc %s %s %s %s" % ((user), (password), (defaultUser), (autoUser))
            os.system(cmdstring)
            
    def __init__(self):
        self.frame = gtk.Frame()
        self.frame.set_border_width(10)
        self.frame.show()

        vbox = gtk.VBox()
        self.frame.add(vbox)
        vbox.show()

        label = gtk.Label(_("Recover User"))
        vbox.pack_start(label)
        label.show()
        label = gtk.Label(not2)
        vbox.pack_start(label)
        label.show()
        
        frame = gtk.Frame(_("Enter Username"))
        vbox.pack_start(frame)
        frame.show()
        
        self.name = gtk.Entry()
        self.name.set_text("antiXDemo")
        frame.add(self.name)
        self.name.show()
        
        frame = gtk.Frame(_("User Password"))
        vbox.pack_start(frame)
        frame.show()
        
        passbox = gtk.VBox()
        frame.add(passbox)
        passbox.show()
        
        self.passwd1 = gtk.Entry()
        self.passwd1.set_text(_("password"))
        passbox.pack_start(self.passwd1)
        self.passwd1.show()
        
        self.passwd2 = gtk.Entry()
        self.passwd2.set_text(_("password again"))
        passbox.pack_start(self.passwd2)
        self.passwd2.show()
        
        frame = gtk.Frame(_("User Login"))
        vbox.pack_start(frame)
        frame.show()
        
        loginbox = gtk.VBox()
        frame.add(loginbox)
        loginbox.show()
        
        self.defaultLogin = gtk.CheckButton()
        self.defaultLogin.set_label(_("Set as Default User"))
        loginbox.pack_start(self.defaultLogin)
        self.defaultLogin.show()
        
        self.autoLogin = gtk.CheckButton()
        self.autoLogin.set_label(_("Set User for Automatic Login"))
        loginbox.pack_start(self.autoLogin)
        self.autoLogin.show()
        
        buttonbox = gtk.HButtonBox()
        vbox.pack_start(buttonbox)
        buttonbox.show()
        
        okbutton = gtk.Button()
        icon_button = DesktopToolWidget('Apply', 'dialog-ok', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        okbutton.add(icon_button)
        okbutton.connect("clicked", self.applyRecover)
        okbutton.set_size_request(100,50)
        buttonbox.add(okbutton)
        okbutton.show()
        
        closebutton = gtk.Button()
        icon_button = DesktopToolWidget('Close', 'dialog-close', 32, gtk.ORIENTATION_HORIZONTAL, wrap = 7)
        closebutton.add(icon_button)
        closebutton.connect("clicked", lambda w: gtk.main_quit())
        closebutton.set_size_request(100,50)
        buttonbox.add(closebutton)
        closebutton.show()
        
        self.label = gtk.Label(_("Recover User"))       
        

class NotebookExample:
	
    def make_icon(self,icon,label):
		#Code from lagopus's script from #START# marker to #END# marker
		########START##########
        self.tab_box = gtk.HBox(False, 2)
        self.tab_box.set_spacing(8)
        tab_label = gtk.Label(label)

        pixbuf = get_icon(icon, 24)
        tab_icon = gtk.Image()
        tab_icon.set_from_pixbuf(pixbuf)
                
        tab_icon.set_size_request(-1, 60)
        self.tab_box.pack_start(tab_icon, False)
        self.tab_box.pack_start(tab_label, False)

        # needed, otherwise even calling show_all on the notebook won't
        # make the hbox contents appear.
        self.tab_box.show_all()
        ###########END##########

    def delete(self, widget, event=None):
        gtk.main_quit()
        return False

    def __init__(self):
        ROOTCHECK=os.getuid()
        if ( ROOTCHECK != 0 ):
            sys.exit(Error(_("You MUST be root to use this application!")))
            
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_title("User-Management")
        window.connect("destroy", lambda w: gtk.main_quit())
        window.set_border_width(10)

        table = gtk.Table(2,3,False)
        window.add(table)

        # Create a new notebook, place the position of the tabs
        self.notebook = gtk.Notebook()
        self.notebook.set_tab_pos(gtk.POS_LEFT)
        self.notebook.set_size_request(500,400)
        table.attach(self.notebook, 0,3,0,1, xoptions=gtk.FILL, yoptions=gtk.FILL)
        self.notebook.show()
        
        #Start Password Class
        self.make_icon("dialog-password",_("Password"))
        self.notebook.append_page(Password().frame, self.tab_box)
        
        #Start add/repair Class
        self.make_icon("list-add",_("Add User"))
        self.notebook.append_page(Add().frame, self.tab_box)
        self.make_icon("edit-undo",_("Repair User"))
        self.notebook.append_page(Repair().frame, self.tab_box)
        
        #Start remove/recover Class
        self.make_icon("list-remove",_("Remove"))
        self.notebook.append_page(Remove().frame, self.tab_box)
        self.make_icon("edit-redo",_("Recover"))
        self.notebook.append_page(Recover().frame, self.tab_box)
        
        self.notebook.set_current_page(0)

        table.show()
        window.show()

def main():
    gtk.main()
    return 0

if __name__ == "__main__":
    NotebookExample()
    main()
