• Welcome to Valhalla Legends Archive.
 

VB.Net User Managment

Started by Zer0, October 05, 2006, 01:27 PM

Previous topic - Next topic

Zer0

Ok i was wondering if i could get some ideas or feedback or somthn from my user managment system, there is one part i know i could do better but im not sure how to do it, so some ideas please...


Public Function userAdd(ByVal userName As String, ByVal userAcces As String, ByVal userAddedBy As String) As String
        If userName <> "" And userAcces <> "" And userAddedBy <> "" Then
            If File.Exists(App_Path() + "/users/" + userName + ".txt") = True Then
                'user exists (update user)
                Dim oRead As System.IO.StreamReader
                Dim oFile As System.IO.File
                Dim oWrite As System.IO.StreamWriter = oFile.CreateText(App_Path() + "/users/" + userName + ".txt")
                oWrite.WriteLine("Username=" & userName)
                oWrite.WriteLine("Acces=" & userAcces)
                oWrite.WriteLine("AddedBy=" & userAddedBy)
                oWrite.Close()
                Return "User updated [ " + userName + " ] added with acces [ " + userAcces + " ]"
            Else
                'user doesnt exist
                Dim fs As New FileStream(App_Path() + "/users/" + userName + ".txt", FileMode.Create, FileAccess.Write)
                fs.Close()
                Dim oRead As System.IO.StreamReader
                Dim oFile As System.IO.File
                Dim oWrite As System.IO.StreamWriter = oFile.CreateText(App_Path() + "/users/" + userName + ".txt")
                oWrite.WriteLine("Username=" & userName)
                oWrite.WriteLine("Acces=" & userAcces)
                oWrite.WriteLine("AddedBy=" & userAddedBy)
                oWrite.Close()
                Return "User [ " + userName + " ] added with acces [ " + userAcces + " ]"
            End If
        Else
            Return "Information In Unacceptable Format. Correct Format: [username] [userlevel]"
        End If
    End Function

    Public Function userDel(ByVal userName As String) As String
        If File.Exists(App_Path() + "/users/" + userName + ".txt") = True Then
            System.IO.File.Delete(App_Path() + "/users/" + userName + ".txt")
            Return "User [ " + userName + " ] removed from database."
        Else
            Return "User [ " + userName + " ] was not found in the database."
        End If
    End Function

    Public Function userFind(ByVal userName As String) As String
        If File.Exists(App_Path() + "/users/" + userName + ".txt") = True Then
            Dim oRead As System.IO.StreamReader
            Dim oFile As System.IO.File
            Dim a() As String
            Dim LineIn As String
            Dim userAcces As String
            Dim userAddedBy As String
            oRead = oFile.OpenText(App_Path() + "/users/" + userName + ".txt")

            While oRead.Peek <> -1
                LineIn = oRead.ReadLine()
                a = LineIn.Split("=")
                If a(0) = "Username" Then
                    userName = a(1)
                End If
                If a(0) = "Acces" Then
                    userAcces = a(1)
                End If
                If a(0) = "AddedBy" Then
                    userAddedBy = a(1)
                End If
            End While
            Return "User [" + userName + "] with acces of [" + userAcces + "], user was added by [" + userAddedBy + "]"
            oRead.Close()
        Else
            Return "User not found in database."
        End If
    End Function


here is the part i know could be done better (it is in the above code)


                'user doesnt exist
                Dim fs As New FileStream(App_Path() + "/users/" + userName + ".txt", FileMode.Create, FileAccess.Write)
                fs.Close()
                Dim oRead As System.IO.StreamReader
                Dim oFile As System.IO.File
                Dim oWrite As System.IO.StreamWriter = oFile.CreateText(App_Path() + "/users/" + userName + ".txt")

rabbit

You should store all the info in an array (using a Type declaration), and only access the file at certain times (IE: load on run, save on close, load/save on demand).  That would greatly improve the speed (I mean noticeably too, not by .02ms or something).
Grif: Yeah, and the people in the red states are mad because the people in the blue states are mean to them and want them to pay money for roads and schools instead of cool things like NASCAR and shotguns.  Also, there's something about ketchup in there.

Zer0

#2
let me just make sure i am understanding u right so

Program Starts -> Load Users Into Array

-edit question removed, answered on aim

Program Ends -> Save Array Back into Files

also can anyone help me with the save on close part  ;D

MyndFyre

Quote from: Zer0 on October 05, 2006, 02:26 PM
also can anyone help me with the save on close part  ;D
Yes.  When the program ends (Form.Closing event of your main Form), do the same thing you do when you have a save-on-demand.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

indulgence

#4
I would have created my user object, created a typed collection for the user object, marked both serializable, and serialized the user collection to file..

Serialization/Deserialization is much cleaner than the code to read - parse - proceed...


Namespace Management
    <Serializable()> Public Class User
        Public Name As String
        Public Password As String

        <XmlIgnore()> Public hash As New System.Security.Cryptography.HMACSHA1(System.Text.ASCIIEncoding.ASCII.GetBytes("mykey"))

        Public Sub New()

        End Sub
        Public Sub New(ByVal _Name As String, ByVal _Password As String)
            Name = _Name
            Password = _Password
        End Sub

        Public Function Validate(ByVal ClearTextPW As String) As Boolean
            Return GetPasswordHash(ClearTextPW).Equals(Password)
        End Function
        Public Function SetPassword(ByVal CleartextOldPW As String, ByVal CleartextNewPW As String) As Boolean
            If Validate(CleartextOldPW) Then
                Password = GetPasswordHash(CleartextNewPW)
                Return True
            End If
            Return False
        End Function

        Private Function GetPasswordHash(ByVal ClearTextPW As String) As String
            Return BitConverter.ToString(hash.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(ClearTextPW)))
        End Function
    End Class
    <Serializable()> Public Class UserCollection
        Inherits CollectionBase

        Private _Serializer As XmlSerializer = New System.Xml.Serialization.XmlSerializer(GetType(UserCollection))

        Default Public Property Items(ByVal index As Integer) As User
            Get
                If index >= 0 And index < list.Count Then Return DirectCast(List(index), User)
            End Get
            Set(ByVal Value As User)
                If index >= 0 And index < list.Count Then list(index) = Value
            End Set
        End Property
        Default Public Property Items(ByVal Name As String) As User
            Get
                Dim index As Integer = Me.IndexOf(Name)
                If Not index < 0 Then Return DirectCast(List(index), User)
            End Get
            Set(ByVal Value As User)
                Dim index As Integer = Me.IndexOf(Name)
                If Not index < 0 Then list(index) = Value
            End Set
        End Property

        Public Overloads Function Equals(ByVal Users As UserCollection) As Boolean
            If Not Users.Count = list.Count Then Return False

            For index As Integer = 0 To List.Count - 1
                If Not Users(index).Equals(Me(index)) Then Return False
            Next
            Return True
        End Function

        Public Function Add(ByVal Item As User) As Integer
            If Not Me.Contains(Item) Then Return list.Add(Item)
        End Function

        Public Function Contains(ByVal Item As User) As Boolean
            Return list.Contains(Item)
        End Function

        Public Sub CopyTo(ByVal Array As User(), ByVal index As Integer)
            list.CopyTo(Array, index)
        End Sub
        Public Sub CopyTo(ByVal Array As IList, ByVal index As Integer)
            For Each item As User In Me.List
                Array.Add(item)
            Next
        End Sub

        Public Function IndexOf(ByVal Item As User) As Integer
            Return list.IndexOf(Item)
        End Function
        Public Function IndexOf(ByVal Name As String) As Integer
            For index As Integer = 0 To list.Count - 1
                If Name.ToLower.Equals(Me(index).Name.ToLower) Then
                    Return index
                End If
            Next
            Return -1
        End Function

        Public Sub Insert(ByVal Index As Integer, ByVal Item As User)
            list.Insert(Index, Item)
        End Sub

        Public Sub Remove(ByVal Item As User)
            list.Remove(Item)
        End Sub
        Public Sub Remove(ByVal Name As String)
            For index As Integer = 0 To list.Count - 1
                If Me(index).Name.Equals(Name) Then
                    list.RemoveAt(index)
                    Exit For
                End If
            Next
        End Sub

        Public Function Save(ByVal Path As String) As Boolean
            Dim fs As IO.FileStream
            Try
                IO.File.Copy(Path, Path & ".bak")
                fs = IO.File.Open(Path, IO.FileMode.Truncate, IO.FileAccess.Write)
                _Serializer.Serialize(fs, Me)
                IO.File.Delete(Path & ".bak")
                fs.Close()
            Catch
                fs.Close()
                IO.File.Delete(Path)
                IO.File.Move(Path & ".bak", Path)
            End Try
            Return True
        End Function
        Public Sub New(ByVal Path As String)
            Dim fs As IO.FileStream
            Try
                fs = IO.File.Open(Path, IO.FileMode.Open, IO.FileAccess.Read)
                Dim lc As UserCollection = _Serializer.Deserialize(fs)
                lc.CopyTo(Me.List, 0)
            Finally
                fs.Close()
            End Try
        End Sub
        Public Sub New()

        End Sub
    End Class
End Namespace


It's long - but you can edit users, add user, delete users from the UserCollection, and call the save method to save it... [you'd want to update the save routine to meet your specs for the filename etc...] and by calling the overloaded new on UserCollection it will deserialize the file into a collection of your user objects.

XML ftw?
<3

MyndFyre

While I don't disagree, you can serialize List<T> into XML as long as you provide a root node name in metadata....  I have to look through my test projects at work, it's possible.  Then you just pass the List<User> into the XML serializer.

However, I disagree on the use of the serialization framework.  XML is probably not so much an evildoer in this instance, but for sure the binary formatter does not emit version-flexible output.  Doing custom serialization as far as custom output or even writing custom XML files is FAR more flexible than trusting it to the serialization framework.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

indulgence

Quote from: MyndFyre[vL] on November 16, 2006, 12:37 AM
However, I disagree on the use of the serialization framework.  XML is probably not so much an evildoer in this instance, but for sure the binary formatter does not emit version-flexible output.  Doing custom serialization as far as custom output or even writing custom XML files is FAR more flexible than trusting it to the serialization framework.
True, but not as simple, nor as quick.  The inability to (de)serialize DateTime objects is the killer - and you have to hack in a timespan and convert it
<3

MyndFyre

Quote from: indulgence on November 16, 2006, 11:40 AM
Quote from: MyndFyre[vL] on November 16, 2006, 12:37 AM
However, I disagree on the use of the serialization framework.  XML is probably not so much an evildoer in this instance, but for sure the binary formatter does not emit version-flexible output.  Doing custom serialization as far as custom output or even writing custom XML files is FAR more flexible than trusting it to the serialization framework.
True, but not as simple, nor as quick.  The inability to (de)serialize DateTime objects is the killer - and you have to hack in a timespan and convert it
What?  DateTime is serializable.

You can also do custom serialization via using DateTime.FromFileTime and DateTime.ToFileTime().
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.