using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data.OracleClient;
using System.Text;
using System.Data.OleDb;
using System.DirectoryServices;


public partial class Security_LoginPage : System.Web.UI.Page
{
    string LM = "";
    protected void Page_Load(object sender, EventArgs e)
    {
        HyperLink1.Visible = false;
        if (!IsPostBack)
        {
           // string strTempPath = HttpContext.Current.Server.ToString();
           // //strTempPath = Application.StartupPath;
            

            string currentPath = Environment.GetEnvironmentVariable("path");
            string dllPath = AppDomain.CurrentDomain.BaseDirectory + "/bin"; //ConfigurationManager.AppSettings["EncDllPath"] as string;
           if (!currentPath.Contains(dllPath))
               currentPath = currentPath + ";" + dllPath + ";";

            System.Environment.SetEnvironmentVariable("Path", currentPath);
            Helper.Read_APP_VersionNo();
            txtUserID.Focus();

            lbl_securityBanner.Text = "- This is a Controlled Access Application and only Authorized Users are Permitted. "
                                      + "<br />"
                                      + "- If you are not authorized to access thie service, please EXIT now. Unauthorized users may be subject to legal prosecution."
                                      + "<br />"
                                      + "- By continuing to use or access this application, the user signifies that they are an authorized user and consents to monitoring.";
        }

        LM = Helper.getParamByID("200");

        if (LM.Equals("AU"))
        {
            LoginActiveUser();
        }


    }

        
    private bool LoginUser(string userName, string password, ref string error)
    {
        string DBConnection = Helper.dbConnection();

        //OleDbConnection oracon1 = new OleDbConnection(DBConnection);
        //oracon1.Open();

        OracleConnection oracon = new OracleConnection(DBConnection);
        oracon.Open();

        OracleCommand oracom = new OracleCommand();
        oracom.Connection = oracon;

        oracom.CommandType = CommandType.StoredProcedure;
        oracom.CommandText = "sec_authenticate.authenticate_user_login";

        oracom.Parameters.Add("p_user_id", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("p_password", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("p_lang", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("p_res_code", OracleType.Number).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_res_type", OracleType.VarChar, 250).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_res_msg", OracleType.VarChar, 250).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_output", OracleType.Number).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_output1", OracleType.VarChar, 250).Direction = ParameterDirection.Output;

        oracom.Parameters["p_lang"].Value = "EN";
        oracom.Parameters["p_user_id"].Value = userName;
        oracom.Parameters["p_password"].Value = Helper.DecPassword( password );

        oracom.ExecuteNonQuery();
        oracon.Close();
        string output = oracom.Parameters["p_output"].Value.ToString();
        string output1 = oracom.Parameters["p_output1"].Value.ToString();
        
        string a = oracom.Parameters["p_res_code"].Value.ToString();
        error = oracom.Parameters["p_res_msg"].Value.ToString();
        if (a == "0")
        {
            Session["uid"] = output;
            Session["username"] = output1;
            //Helper.writeLog("Sucessfull Login");
            return true;
        }
        else if (a == "4")
        {
            HyperLink1.Visible = true;
            return false;
        }
        else
            return false;
    }

    private bool LoginUser(string userName, ref string error)
    {
        string DBConnection = Helper.dbConnection();

        //OleDbConnection oracon1 = new OleDbConnection(DBConnection);
        //oracon1.Open();

        OracleConnection oracon = new OracleConnection(DBConnection);
        oracon.Open();

        OracleCommand oracom = new OracleCommand();
        oracom.Connection = oracon;

        oracom.CommandType = CommandType.StoredProcedure;
        oracom.CommandText = "sec_authenticate.authenticate_user_login_AU";

        oracom.Parameters.Add("p_user_id", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("p_lang", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("p_res_code", OracleType.Number).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_res_type", OracleType.VarChar, 250).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_res_msg", OracleType.VarChar, 250).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_output", OracleType.Number).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_output1", OracleType.VarChar, 250).Direction = ParameterDirection.Output;

        oracom.Parameters["p_lang"].Value = "EN";
        oracom.Parameters["p_user_id"].Value = userName;

        oracom.ExecuteNonQuery();
        oracon.Close();
        string output = oracom.Parameters["p_output"].Value.ToString();
        string output1 = oracom.Parameters["p_output1"].Value.ToString();

        string a = oracom.Parameters["p_res_code"].Value.ToString();
        error = oracom.Parameters["p_res_msg"].Value.ToString();
        if (a == "0")
        {
            Session["uid"] = output;
            Session["username"] = output1;
            return true;
        }
        else if (a == "4")
        {
            HyperLink1.Visible = true;
            return false;
        }
        else
            return false;
    }

    protected void btnLogin_Click(object sender, EventArgs e)
    {
        string error = "";


        string clientIPAdd = Request.ServerVariables["REMOTE_ADDR"].ToString();
        
           if (this.txtUserID.Text.Equals(""))
            {
                this.lblError.Text = "Please enter a user ID.";
            }

            else
            {

                setMode();
                if (!LM.Equals("AU"))
                {
                    bool saved = false;
                    if (LM.Equals("DB"))
                    {
                        saved = LoginUser(txtUserID.Text.ToUpper(), txtPass1.Text, ref error);
                        if (saved)
                        {
                            Response.Redirect("../Security/ExecSecurityBanner.aspx");
                        }
                        else
                        {
                            lblError.Text = error;
                            txtPass1.Focus();

                            lbl_securityBanner.Text =
                                                "- If you have forgotten you sign-on or password please contact service Desk."
                                              + "- This is a monitored system and only Authorized Users are Permitted. "
                                              + "<br />"
                                              + "- If you are not authorized to access thie service, please EXIT now. Unauthorized users may be subject to legal prosecution.";

                            this.logUserLoginViolation(this.txtUserID.Text.ToUpper (), clientIPAdd);
                        }
                    }
                    else
                    {
                        saved = LoginActiveDirectoryWithoutGroups(txtUserID.Text.ToUpper(), txtPass1.Text, ref error);
                        if (saved)
                        {
                            Response.Redirect("../Security/ExecSecurityBanner.aspx");
                        }
                        else
                        {
                            lbl_securityBanner.Text =
                                                "- If you have forgotten you sign-on or password please contact service Desk."
                                              + "- This is a monitored system and only Authorized Users are Permitted. "
                                              + "<br />"
                                              + "- If you are not authorized to access thie service, please EXIT now. Unauthorized users may be subject to legal prosecution.";


                            lblError.Text = error;
                            txtPass1.Focus();

                            this.logUserLoginViolation(this.txtUserID.Text.ToUpper(), clientIPAdd);
                        }
                    }
                }
                else
                {
                    Response.Redirect("../Security/ExecSecurityBanner.aspx");
                }
            }
        
    }

    private String DecPassword(String pass)
    {
        string FsPassWord = "";
        String FsDecPassword = "";
        int pwd;

        for (int nCount = 0; nCount < pass.Length; nCount++)
        {
            FsPassWord = pass.Substring(nCount, 1);
            pwd = ((Encoding.ASCII.GetBytes(FsPassWord)[0]) + 15) - 12;
            FsDecPassword = FsDecPassword + Convert.ToString((Convert.ToChar(pwd)));
        }
        return FsDecPassword;
    }

    private void setMode()
    {
        if (rdLive.Checked)
        {
            Session["mode"] = "l";
        }
        else if (rdArchive.Checked)
        {
            Session["mode"] = "a";
        }
    }

    private void LoginActiveUser()
    {
        //begin LDAP
        rowuser.Visible = false;
        rowpass.Visible = false;
        string login = Context.User.Identity.Name.ToString();

        int number = login.IndexOf("\\");
        if (login.Substring(0, number).Equals(ConfigurationSettings.AppSettings["DOMAIN"]))
        {
            string username = login.Substring(number + 1, login.Length - number - 1);
            string error = "";
            setMode();
            bool saved = LoginUser(username, ref error);
            if (saved)
            {
                //Response.Redirect("../Business/Default.aspx");
                loginbutton.Visible = true;
                lblError.Text = "Please select application mode";
            }
            else
            {
                loginbutton.Visible = false;
                lblError.Text = error;
            }
        }
        else
        {
            lblError.Text = "Not a domain user ! <br>Please login with your domain user to be able to access this application";
            loginbutton.Visible = false;
        }
        //End LDAP
    }

    private bool LoginActiveDirectoryWithoutGroups(string userName, string password, ref string error)
    {
        ActiveDirectoryUser user;

        user = this.getUserDetails_FromAD(userName, password, ref error);

        //user = new ActiveDirectoryUser();
        //user.setUserId("99998"); for testing
        
        if (user != null)
        {
            if (this.isExistedUser(user.getUserId()))
            {
                return this.LoginUser(user.getUserId().ToUpper(), ref error);  // IRFAN_MOD 180315  
                
            }
            else
            {
                error = "Sorry your User ID is not register in ReconSS System.";
                return false;
            }
        }
        else
        {
            return false;
        }
    }

    private bool LoginActiveDirectory(string userName, string password, ref string error)
    {
        ActiveDirectoryUser user;

        user = this.getUserDetails_FromAD(userName, password, ref error);

        if (user != null)
        {
            bool isPermittedGroup = false;
            bool isExistedUser = false;

            bool isSuperUser = false;

           ArrayList groups = this.getUserGroups(userName, password);

            if (groups == null)
            {
                isPermittedGroup = false;

                error = "Sorry your Department is NOT authorized to use this application.";
            }
            else
            {
                isPermittedGroup = true;

                IEnumerator iterator = groups.GetEnumerator();

                string tempGroupName = "";

                while (iterator.MoveNext() )
                {
                    tempGroupName = (string)iterator.Current;

                    isPermittedGroup = this.isExistedGroup(tempGroupName);

                    if (isPermittedGroup) break;
                }

                if (isPermittedGroup)
                {
                    isSuperUser = (tempGroupName == Constants.AMINS_GROUP_NAME ? true : false);

                    //For alinma userid is not interger    --Irfan-14-05-14
                    //isExistedUser = this.isExistedUser(int.Parse(user.getUserId()));
                    isExistedUser = this.isExistedUser(user.getUserId());

                    if (isExistedUser && isSuperUser)
                    {
                        //Existed and Super user NOW, but not assigned to the current group.
                        if (! this.isUserAssignedToThisGroup((user.getUserId()), tempGroupName) )
                        {
                            this.assignUserToGroup(user.getUserId(), tempGroupName, true);
                        }
                    }
                    else if (isExistedUser && !isSuperUser)
                    {
                        //Existed and not Super user NOW, but not assigned to the current group.
                        if (!this.isUserAssignedToThisGroup((user.getUserId()), tempGroupName))
                        {
                            this.assignUserToGroup(user.getUserId(), tempGroupName, false);
                        }
                    }
                    else if (!isExistedUser && isSuperUser)
                    {
                        //Not existed in the system and super
                        this.addUser(user.getUserId(), user.getUserName(), tempGroupName, true, ref error);
                    }
                    else if (!isExistedUser && !isSuperUser)
                    {
                        //Not existed in the system and not super
                        this.addUser(user.getUserId(), user.getUserName(), tempGroupName, false, ref error);
                    }


                    this.LoginUser(user.getUserId(), ref error);
                }
                else
                {
                    error = "Sorry your Department is NOT authorized to use this application.";
                }
            }

            return isPermittedGroup;
        }
        else
        {
            return false;
        }
    }

  
    private void logUserLoginViolation(string enteredUserId, string clientIPAddess)
    {
        string DBConnection = Helper.dbConnection();

        OracleConnection oracon = new OracleConnection(DBConnection);
        oracon.Open();

        OracleCommand oracom = new OracleCommand();
        oracom.Connection = oracon;

        oracom.CommandType = CommandType.StoredProcedure;
        oracom.CommandText = "USER_AUDITOR.LOG_LOGIN_VIOLATION";

        oracom.Parameters.Add("P_USER_ID", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("P_IP_ADDRESS", OracleType.VarChar).Direction = ParameterDirection.Input;

        oracom.Parameters["P_USER_ID"].Value = enteredUserId;
        oracom.Parameters["P_IP_ADDRESS"].Value = clientIPAddess;

        oracom.ExecuteNonQuery();
        oracon.Close();
    }

    private ArrayList getUserGroups(string userName, string password)
    {
        ArrayList userGroups = new ArrayList();
        string domain = Helper.getParamByID("201");
        string domainAndUserName = userName;
        //string domain = @"LDAP://DC=anb,DC=net";
        //string domainAndUserName = @"anb-pdc-central\" + userName;

        DirectoryEntry directoryEntry = new DirectoryEntry(domain, domainAndUserName, password);

        DirectorySearcher searcher = new DirectorySearcher(directoryEntry);

        searcher.Filter = "(SAMAccountName=" + userName + ")";
        searcher.PropertiesToLoad.Add("memberOf");

        try
        {
            SearchResult result = searcher.FindOne();

            int foundGroupsCount = result.Properties["memberOf"].Count;

            string groupName;

            if (foundGroupsCount == 0)
            {
                return null;
            }
            else
            {

                for (int counter = 0; counter < foundGroupsCount; counter++)
                {
                    groupName = (string)result.Properties["memberOf"][counter];

                    groupName = groupName.Remove(groupName.IndexOf(","));

                    groupName = groupName.Replace("CN=", "");

                    userGroups.Add(groupName);
                }

            }
        }
        catch (Exception e)
        {            
            return null;
        }


        return userGroups;
    }

    private bool isExistedGroup (string groupName)
    {
        bool isExisted = false;

        string DBConnection = Helper.dbConnection();

        OracleConnection oracon = new OracleConnection(DBConnection);
        oracon.Open();

        OracleCommand oracom = new OracleCommand();
        oracom.Connection = oracon;

        oracom.CommandType = CommandType.StoredProcedure;
        oracom.CommandText = "SEC_GROUP_MAINTAIN.IS_EXISTED";

        oracom.Parameters.Add("p_group_name", OracleType.VarChar).Direction = ParameterDirection.Input;

        oracom.Parameters.Add("p_is_existed", OracleType.Number).Direction = ParameterDirection.Output;

        oracom.Parameters["p_group_name"].Value = groupName;

        OracleDataAdapter da = new OracleDataAdapter(oracom);
        DataSet ds = new DataSet();
        da.Fill(ds);

        oracon.Close();

        isExisted = (int.Parse(oracom.Parameters["p_is_existed"].Value.ToString()) == 1 ? true : false);

        return isExisted;
    }
 
    //    private bool isExistedUser(int userId)  Irfan-14-05-14
    private bool isExistedUser(string userId) // userId in alinma is varchar -- Irfan-14-05-14 
    {
        bool isExisted = false;

        string DBConnection = Helper.dbConnection();

        OracleConnection oracon = new OracleConnection(DBConnection);
        oracon.Open();

        OracleCommand oracom = new OracleCommand();
        oracom.Connection = oracon;

        oracom.CommandType = CommandType.StoredProcedure;
        oracom.CommandText = "sec_user_maintain.IS_USER_EXSITED";

        oracom.Parameters.Add("P_USER_ID", OracleType.VarChar).Direction = ParameterDirection.Input;

        oracom.Parameters.Add("P_IS_EXISTED", OracleType.Number).Direction = ParameterDirection.Output;

        oracom.Parameters["P_USER_ID"].Value = userId;

        OracleDataAdapter da = new OracleDataAdapter(oracom);
        DataSet ds = new DataSet();
        da.Fill(ds);

        oracon.Close();

        isExisted = (int.Parse(oracom.Parameters["P_IS_EXISTED"].Value.ToString()) == 1 ? true : false);

        return isExisted;
    }

    //Change userid from in to string Irfan-14-05-14
    private bool isUserAssignedToThisGroup(string userId, string groupName)
    {
        bool isAssigned = false;

        string DBConnection = Helper.dbConnection();

        OracleConnection oracon = new OracleConnection(DBConnection);
        oracon.Open();

        OracleCommand oracom = new OracleCommand();
        oracom.Connection = oracon;

        oracom.CommandType = CommandType.StoredProcedure;
        oracom.CommandText = "sec_user_maintain.IS_USER_ASSIGNED_THIS_GROUP";

        oracom.Parameters.Add("P_USER_ID", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("P_GROUP_NAME", OracleType.VarChar).Direction = ParameterDirection.Input;

        oracom.Parameters.Add("P_IS_ASSIGNED", OracleType.Number).Direction = ParameterDirection.Output;

        oracom.Parameters["P_USER_ID"].Value = userId;
        oracom.Parameters["P_GROUP_NAME"].Value = groupName;

        OracleDataAdapter da = new OracleDataAdapter(oracom);
        DataSet ds = new DataSet();
        da.Fill(ds);

        oracon.Close();

        isAssigned = (int.Parse(oracom.Parameters["P_IS_ASSIGNED"].Value.ToString()) == 1 ? true : false);

        return isAssigned;
    }

    private void assignUserToGroup(string userId, string groupName, bool isSuper)
    {
        string DBConnection = Helper.dbConnection();

        OracleConnection oracon = new OracleConnection(DBConnection);
        oracon.Open();

        OracleCommand oracom = new OracleCommand();
        oracom.Connection = oracon;

        oracom.CommandType = CommandType.StoredProcedure;
        oracom.CommandText = "sec_user_maintain.ASSIGN_USER_TO_GROUP";

        oracom.Parameters.Add("P_USER_ID", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("P_GROUP_NAME", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("P_IS_SUPER", OracleType.Number).Direction = ParameterDirection.Input;

        oracom.Parameters["P_USER_ID"].Value = userId;
        oracom.Parameters["P_GROUP_NAME"].Value = groupName;
        oracom.Parameters["P_IS_SUPER"].Value = (isSuper ? 1 : 0);

        oracom.ExecuteNonQuery();
        oracon.Close();
    }

    private ActiveDirectoryUser getUserDetails_FromAD(string userName, string password, ref string error)
    {
        string path = Helper.getParamByID("201"); // Active Directory

        string domainAndUserName =  userName;
        DirectoryEntry entry = new DirectoryEntry(path, domainAndUserName, password);

        ActiveDirectoryUser user = null;

        try
        {
            Object obj = entry.NativeObject;

            DirectorySearcher search = new DirectorySearcher(entry);

            search.Filter = "(SAMAccountName=" + userName + ")";
            search.PropertiesToLoad.Add("cn");
            search.PropertiesToLoad.Add("givenname");
            search.PropertiesToLoad.Add("sn");
            search.PropertiesToLoad.Add("sn");
            Helper.writeLog("Start Searching for "+domainAndUserName  + path);
            SearchResult result = search.FindOne();
            Helper.writeLog("End Successful Searching");
            user = new ActiveDirectoryUser();
            user.setUserId(userName);
            user.setUserName(result.GetDirectoryEntry().Properties["givenname"].Value.ToString() + " " +  
                             result.GetDirectoryEntry().Properties["sn"].Value.ToString());
        }
        catch (Exception ex)
        {
            error = ex.Message;
            Helper.writeLog(error);
            //Helper.writeLog(ex.InnerException.ToString());
            return null;
        }

        return user;
    }

    private bool addUser(string userId, string userName, string groupName,bool isSuper, ref string error)
    {
        string DBConnection = Helper.dbConnection();

        OracleConnection oracon = new OracleConnection(DBConnection);
        oracon.Open();

        OracleCommand oracom = new OracleCommand();
        oracom.Connection = oracon;

        oracom.CommandType = CommandType.StoredProcedure;
        oracom.CommandText = "sec_user_maintain.ADD_APPROVED_USER";

        oracom.Parameters.Add("P_USER_ID", OracleType.Number).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("P_USER_NAME", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("P_GROUP_NAME", OracleType.VarChar).Direction = ParameterDirection.Input;
        oracom.Parameters.Add("P_IS_SUPER", OracleType.Number).Direction = ParameterDirection.Input;
        
        oracom.Parameters.Add("p_res_code", OracleType.Number).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_res_type", OracleType.VarChar, 250).Direction = ParameterDirection.Output;
        oracom.Parameters.Add("p_res_msg", OracleType.VarChar, 250).Direction = ParameterDirection.Output;

        oracom.Parameters["P_USER_ID"].Value = userId;
        oracom.Parameters["P_USER_NAME"].Value = userName;
        oracom.Parameters["P_GROUP_NAME"].Value = groupName;
        oracom.Parameters["P_IS_SUPER"].Value = (isSuper ? 1 : 0);

        oracom.ExecuteNonQuery();
        oracon.Close();
        string a = oracom.Parameters["p_res_code"].Value.ToString();
        error = oracom.Parameters["p_res_msg"].Value.ToString();
        if (a == "0")
            return true;
        else
            return false;
    }
}
