2
\$\begingroup\$
fo=open("haproxyfile.txt","r")
users=[]
for lines in fo.readlines():
    if 'user' and 'password' in lines:
        items=lines.split() #converts to list"""
        users.append(items[1]) #append the second item that is the username"""

print users

The content of haproxyfile.txt is below

ssl-default-bind-ciphers EECDH+EDSA+ACM:CDH+aRSA+AEdfGCM:EECDH+ECDSA+SHA384:EEC+
ESA+SHA:EDH+aRSA+SHA384:EECDH+aRSA+SHA256:EDH:AES128-GCM-SHA256:AES128-SHA256:AES128-S
HA:EDH+SA:AES256-GCM-SHA384:AES-SHA256:AES256-SHA:!RC4:!aNULL:!eNULL:!LOW:!3D:!MD5:!EXP:
!PSK:!SRP:!DSS

        # Users
        userlist IntacctAdmins
          group admins users aasghar,achouchoulas,bwright,calla,gspiliotis,haris,pdam
          user aasghar password $1$CFdTKLSRSbQME/
          user achouchoulas password $1$uLy//uPCaVSNhfFG/
          user bwright password $1$q3Fk$kmqM.J531
          user calla password $1$f%g23a44$Bl.1fPj/
          user gspiliotis password $1$d/2OI.TQOiV1
          user haris password $1$mwQ$uG/1mUjE0
          user pdam password $1t24Z$K4FUH/

What I need to parse from the content

The line after having the words groups are the lines where my user names are located. They are the single words after user keyword.I have fetched it using the method above.Is there any better way to fetch it?

\$\endgroup\$
1
  • \$\begingroup\$ The file should be a little better specified, imo. For example, the way it currently looks, you could potentially just split the group admins users line by commas. :p \$\endgroup\$ Mar 26, 2017 at 18:22

3 Answers 3

4
\$\begingroup\$

There are quite a few possible improvements.

You should open files with the with keyword, this way they get closed no matter what (you don't even close your file).

if 'user' and 'password' in lines: does not mean what you think it does. All non-empty strings are truthy in Python, so if "user" is always True. So you only really check that the line contains "password". Fortunately you don't have any lines containing "password", but not "users", so this bug has not yet become obvious.

The easiest fix for this would be using this:

if "user" in lines and "password" in lines:
    # Stuff

In summary, I would re-write your code like this:

with open("haproxyfile.txt") as f:
    users = [line.split()[1] for line in f 
             if line.strip().startswith("user") and "password" in line]

print users

Note that I omitted the "r" parameter to open, because read-only is the default mode. I also used str.startswith to check if it starts with a string. The strip is probably needed, to get rid of the whitespace at the beginning of your lines. If that is a copy&paste error as well, omit it.

I also wrote it as a list-comprehension and used the fact that you can directly iterate over a file.

\$\endgroup\$
2
  • \$\begingroup\$ I am checking the line has user and password on it ,user aasghar password $1$CFdTKLSRSbQME/ as this lines has the both \$\endgroup\$
    – TaraGurung
    Mar 26, 2017 at 12:13
  • 3
    \$\begingroup\$ @TaraGurung No, if 'user' and 'password' in lines is the same as if True and 'password' in lines, which is the same as if 'password' in lines. You either want to do it like I do (which uses the extra information that "user" is the first word), or do if "user" in lines and "password" in lines or if all(x in lines for x in ["user", "password"]). \$\endgroup\$
    – Graipher
    Mar 26, 2017 at 12:16
0
\$\begingroup\$

It's not obvious what your code does or how it works. I have to figure out what the result of lines.split() looks like, and what items[1] represents — and all I have to go by, according to the code, is that the lines of interest contain the word 'password'.

I recommend doing it a completely different way, using regular expression matching, so that it is obvious what kind of text pattern you expect to extract. I would also write it using a list comprehension, so that the users list is defined declaratively, "all at once".

import re

with open('haproxyfile.txt') as f:
    users = [
        match.group(1) for match in (
            re.search(r'^\s*user\s+(\S+)\s+password', line) for line in f
        )
        if match
    ]

print users
\$\endgroup\$
-1
\$\begingroup\$

Shouldn't passwords be coded? If passwords are not coded-could it put user privacy and/or administrator settings at risk?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ The passwords look encrypted for me. Or what did you mean? \$\endgroup\$ Mar 26, 2017 at 12:03
  • \$\begingroup\$ Did you mean encrypted instead? \$\endgroup\$
    – Mast
    Mar 26, 2017 at 12:17
  • \$\begingroup\$ @Graipher It looks like a real attempt to answer to me, not a good one though. Related \$\endgroup\$ Mar 26, 2017 at 19:06
  • \$\begingroup\$ @Simon Fair enough, but I do agree with panta rei that the passwords do look encrypted/hashed, which made me think of this like more of a question asking for clarification when I saw it in the review queue. \$\endgroup\$
    – Graipher
    Mar 26, 2017 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.