Test Failed
Pull Request — master (#284)
by
unknown
01:44
created

kytos.utils.decorators.kytos_auth.authenticate()   A

Complexity

Conditions 4

Size

Total Lines 31
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.5021

Importance

Changes 0
Metric Value
cc 4
eloc 24
nop 1
dl 0
loc 31
ccs 12
cts 22
cp 0.5455
crap 5.5021
rs 9.304
c 0
b 0
f 0
1
"""Decorators for Kytos-utils."""
2 1
import logging
3 1
import os
4 1
import sys
5 1
from getpass import getpass
6
7 1
import requests
8
9 1
from kytos.utils.config import KytosConfig
10
11 1
LOG = logging.getLogger(__name__)
12
13
14
# This class is used as decorator, so this class name is lowercase and the
15
# invalid-name warning from pylint is disabled below.
16 1
class kytos_auth:  # pylint: disable=invalid-name
17
    """Class to be used as decorator to require authentication."""
18
19 1
    def __init__(self, func):
20
        """Init method.
21
22
        Save the function on the func attribute and bootstrap a new config.
23
        """
24 1
        self.func = func
25 1
        self.config = KytosConfig().config
26 1
        self.cls = None
27 1
        self.obj = None
28
29 1
    def __call__(self, *args, **kwargs):
30
        """Code run when func is called."""
31 1
        if not (
32
            self.config.has_option("napps", "api")
33
            and self.config.has_option("napps", "repo")
34
        ):
35 1
            uri = input("Enter the kytos napps server address: ")
36 1
            self.config.set("napps", "api", os.path.join(uri, "api", ""))
37 1
            self.config.set("napps", "repo", os.path.join(uri, "repo", ""))
38
39 1
        if not self.config.has_option("auth", "user"):
40 1
            user = input("Enter the username: ")
41 1
            self.config.set("auth", "user", user)
42
        else:
43
            user = self.config.get("auth", "user")
44
45 1
        if not self.config.has_option("auth", "token"):
46 1
            token = self.authenticate()
47
        else:
48
            token = self.config.get("auth", "token")
49
50
        # Ignore private attribute warning. We don't wanna make it public only
51
        # because of a decorator.
52 1
        config = self.obj._config  # pylint: disable=protected-access
53 1
        config.set("auth", "user", user)
54 1
        config.set("auth", "token", token)
55 1
        self.func.__call__(self.obj, *args, **kwargs)
56
57 1
    def __get__(self, instance, owner):
58
        """Deal with owner class."""
59 1
        self.cls = owner
60 1
        self.obj = instance
61
62 1
        return self.__call__
63
64 1
    def authenticate(self):
65
        """Check the user authentication."""
66 1
        endpoint = os.path.join(self.config.get("napps", "api"), "auth", "")
67 1
        username = self.config.get("auth", "user")
68 1
        password = getpass("Enter the password for {}: ".format(username))
69 1
        response = requests.get(endpoint, auth=(username, password))
70 1
        if response.status_code == 401:
71 1
            invTokenStr = (
72
                '{"error":"Token not sent or expired: Signature has expired"}\n'
73
            )
74
            # invTokenStr =  "{\"error\":\"Invalid authentication: User not found.\"}\n"
75 1
            if invTokenStr == str(response.content, encoding="UTF-8"):
76
                print(
77
                    'Seems the token was not set or is expired! Please run "kytos napps upload" again.'
78
                )
79
                LOG.error(response.content)
80
                LOG.error("ERROR: %s: %s", response.status_code, response.reason)
81
                print("Press Ctrl+C or CTRL+Z to stop the process.")
82
                user = input("Enter the username: ")
83
                self.config.set("auth", "user", user)
84
                self.authenticate()
85
                # sys.exit(1)
86
87 1
        if response.status_code != 201:
88
            LOG.error(response.content)
89
            LOG.error("ERROR: %s: %s", response.status_code, response.reason)
90
            sys.exit(1)
91
        else:
92 1
            data = response.json()
93 1
            KytosConfig().save_token(username, data.get("hash"))
94
            return data.get("hash")
95