Test Failed
Pull Request — master (#73)
by macartur
01:46
created

UsersManager   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
c 1
b 0
f 0
dl 0
loc 122
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 17 1
D make_question() 0 36 8
B register() 0 29 3
A valid_attribute() 0 11 1
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 register(self):
68
        """Method used to register a new user.
69
70
        This method will as for user attributes and create that in
71
        Napps server, when All required fields is filled.
72
73
        Returns:
74
            result(string): Response of user registration process.
75
        """
76
        user = {}
77
78
        print('--------------------------------------------------------------')
79
        print('Welcome to the user registration process.')
80
        print('--------------------------------------------------------------')
81
        print("To continue you must fill the follow fields.")
82
        for attribute, value in self.attributes.items():
83
84
            is_required = attribute in self.required
85
            question = value['question']
86
            pattern = value['pattern']
87
88
            if attribute != 'password':
89
                user[attribute] = self.make_question(question, pattern,
90
                                                     is_required)
91
            else:
92
                user[attribute] = self.make_question(question, pattern,
93
                                                     password=True)
94
95
        return self._users_client.register(user)
96
97
    def make_question(self, question, pattern=NAME_PATTERN, required=False,
98
                      password=False):
99
        """Method used to make a question and get the input values.
100
101
        This method will validade the input values.
102
        Args:
103
            question(string): Question used to ask for input value.
104
            pattern(string): Pattern to validate the input value.
105
            required(bool): Boolean value if the input value is required.
106
            password(bool): Boolean value to get input password with mask.
107
        Returns:
108
            input_value(string): Input value validated.
109
        """
110
        input_value = ""
111
112
        while not input_value:
113
            input_value = getpass(question) if password else input(question)
114
115
            if not input_value:
116
                if not required:
117
                    break
118
                else:
119
                    continue
120
121
            if password:
122
                confirm_password = getpass('Confirm your password: ')
123
                if confirm_password != input_value:
124
                    print("Password don't match.")
125
                    input_value = ""
126
127
            if not self.valid_attribute(input_value, pattern[1]):
128
                error_message = "Invalid field, you should:\n{}"
129
                print(error_message.format(pattern[0]))
130
                input_value = ""
131
132
        return input_value
133
134
    @classmethod
135
    def valid_attribute(cls, attribute, pattern):
136
        """Check the validity of the given 'attribute' using the pattern given.
137
138
        Args:
139
            attribute(string): String with the value of an attribute
140
            pattern(string): Pattern used to validate the attribute value.
141
        Returns:
142
            pattern_found(bool): Return True if the pattern match.
143
        """
144
        return attribute and re.match(pattern, attribute)
145