Passed
Pull Request — master (#73)
by macartur
01:41
created

UsersManager.get_user_by_username()   A

Complexity

Conditions 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
c 1
b 0
f 0
dl 0
loc 11
rs 9.4285
1
"""Module used to handle Users in Napps Server."""
2
import logging
3
import re
4
from getpass import getpass
5
6
from kytos.utils.client import UsersClient
7
from kytos.utils.config import KytosConfig
8
9
log = logging.getLogger(__name__)
10
11
NAME_PATTERN = ("\t- insert only letters", r'[a-zA-Z][a-zA-Z]{2,}$')
12
USERNAME_PATTERN = ("\t- start with letter\n"
13
                    "\t- insert only numbers and letters",
14
                    r'[a-zA-Z][a-zA-Z0-9_]{2,}$')
15
PASSWORD_PATTERN = ("\t- insert only the caracters:"
16
                    " [letters, numbers, _, %, &, -, $]",
17
                    r'[a-zA-Z0-9_%\-&$]{2,}$')
18
EMAIL_PATTERN = ("\t- follow the format: <login>@<domain>\n"
19
                 "\t\te.g. [email protected]", r'[^@]+@[^@]+\.[^@]+')
20
PHONE_PATTERN = ("\t- insert only numbers", r'\d*$')
21
22
23
class UsersManager:
24
    """Class used to handle users stored by Napps server."""
25
26
    attributes = {
27
        "username": {"question": "Please insert your Username(Required): ",
28
                     "pattern": USERNAME_PATTERN},
29
        "first_name": {"question": "Please insert your First Name(Required): ",
30
                       "pattern": NAME_PATTERN},
31
        "last_name": {"question": "Please insert your Last Name: ",
32
                      "pattern": NAME_PATTERN},
33
        "password": {"question": "Please insert your Password(Required): ",
34
                     "pattern": PASSWORD_PATTERN},
35
        "email": {"question": "Please insert a Email(Required): ",
36
                  "pattern": EMAIL_PATTERN},
37
        "phone": {"question": "Please insert your Phone: ",
38
                  "pattern": PHONE_PATTERN},
39
        "city": {"question": "Please insert your City: ",
40
                 "pattern": NAME_PATTERN},
41
        "state": {"question": "Please insert your State: ",
42
                  "pattern": NAME_PATTERN},
43
        "country": {"question": "Please insert your Country: ",
44
                    "pattern": NAME_PATTERN}
45
    }
46
47
    required = ["username", "first_name", "password", "email"]
48
49
    def __init__(self, controller=None):
50
        """If controller is not informed, the necessary paths must be.
51
52
        If ``controller`` is available, NApps will be (un)loaded at runtime and
53
        you don't need to inform the paths. Otherwise, you should inform the
54
        required paths for the methods called.
55
56
        Args:
57
            controller (kytos.Controller): Controller to (un)load NApps.
58
            install_path (str): Folder where NApps should be installed. If
59
                None, use the controller's configuration.
60
            enabled_path (str): Folder where enabled NApps are stored. If None,
61
                use the controller's configuration.
62
        """
63
        self._controller = controller
64
        self._config = KytosConfig().config
65
        self._users_client = UsersClient()
66
67
    def get_users(self):
68
        """Method used to get all users registered in Napps server.
69
70
        Returns:
71
            users(list): List of python dict with user attributes.
72
        """
73
        return [user for user in self._users_client.get_users().values()]
74
75
    def get_user_by_username(self, username):
76
        """Method used to get a user by username.
77
78
        Args:
79
            username(string): Name of a user registered in Napps server.
80
        return
81
            user_dict(dict): Python dict with attributes of a user found.
82
        """
83
        for user in self.get_users():
84
            if username == user['username']:
85
                return user
86
87
    def search(self, pattern):
88
        """Search all server Users matching pattern.
89
90
        Args:
91
            pattern (str): Python regular expression.
92
        """
93
        users = self._users_client.get_users()
94
95
        def match(user):
96
            """Method used to find a pattern in user's attributes."""
97
            strings = [str(attribute) for attribute in user.values()]
98
            return any([pattern.match(string) for string in strings])
99
100
        return [user for user in users.values() if match(user)]
101
102
    def register(self):
103
        """Method used to register a new user.
104
105
        This method will as for user attributes and create that in
106
        Napps server, when All required fields is filled.
107
108
        Returns:
109
            result(string): Response of user registration process.
110
        """
111
        user = {}
112
113
        print('--------------------------------------------------------------')
114
        print('Welcome to the user registration process.')
115
        print('--------------------------------------------------------------')
116
        print("To continue you must fill the follow fields.")
117
        for attribute, value in self.attributes.items():
118
119
            is_required = attribute in self.required
120
            question = value['question']
121
            pattern = value['pattern']
122
123
            if attribute != 'password':
124
                user[attribute] = self.make_question(question, pattern,
125
                                                     is_required)
126
            else:
127
                user[attribute] = self.make_question(question, pattern,
128
                                                     password=True)
129
130
        return self._users_client.register(user)
131
132
    def make_question(self, question, pattern=NAME_PATTERN, required=False,
133
                      password=False):
134
        """Method used to make a question and get the input values.
135
136
        This method will validade the input values.
137
        Args:
138
            question(string): Question used to ask for input value.
139
            pattern(string): Pattern to validate the input value.
140
            required(bool): Boolean value if the input value is required.
141
            password(bool): Boolean value to get input password with mask.
142
        Returns:
143
            input_value(string): Input value validated.
144
        """
145
        input_value = ""
146
147
        while not input_value:
148
            input_value = getpass(question) if password else input(question)
149
150
            if not input_value:
151
                if not required:
152
                    break
153
                else:
154
                    continue
155
156
            if password:
157
                confirm_password = getpass('Confirm your password: ')
158
                if confirm_password != input_value:
159
                    print("Password don't match.")
160
                    input_value = ""
161
162
            if not self.valid_attribute(input_value, pattern[1]):
163
                error_message = "Invalid field, you should:\n{}"
164
                print(error_message.format(pattern[0]))
165
                input_value = ""
166
167
        return input_value
168
169
    @classmethod
170
    def valid_attribute(cls, attribute, pattern):
171
        """Check the validity of the given 'attribute' using the pattern given.
172
173
        Args:
174
            attribute(string): String with the value of an attribute
175
            pattern(string): Pattern used to validate the attribute value.
176
        Returns:
177
            pattern_found(bool): Return True if the pattern match.
178
        """
179
        return attribute and re.match(pattern, attribute)
180