-
Notifications
You must be signed in to change notification settings - Fork 81
Expand file tree
/
Copy pathmodels.py
More file actions
136 lines (110 loc) · 3.92 KB
/
models.py
File metadata and controls
136 lines (110 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""
Maintain all the database models used in authentication.
List of models corresponding to mysql tables: ['User' => 'user']
"""
import string
from typing import Any, Dict, Tuple, Type
from passlib.apps import custom_app_context as pwd_context
from sqlalchemy import Column, Integer, String, Text
import database
from database import Base, DeclEnum
class Role(DeclEnum):
"""Roles available for users."""
admin = "admin", "Admin"
user = "user", "User"
contributor = "contributor", "Contributor"
tester = "tester", "Tester"
class User(Base):
"""Model for an user."""
__tablename__ = 'user'
__table_args__ = {'mysql_engine': 'InnoDB'}
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
email = Column(String(255), unique=True, nullable=True)
github_token = Column(Text(), nullable=True)
password = Column(String(255), unique=False, nullable=False)
role = Column(Role.db_type())
def __init__(self, name, role=Role.user, email=None, password='', github_token=None) -> None:
"""
Parametrized constructor for the User model.
:param name: The value of the 'name' field of User model
:type name: str
:param role: The value of the 'role' field of User model
:type role: Role
:param email: The value of the 'email' field of User model (None by
default)
:type email: str
:param password: The value of the 'password' field of User model (
empty by default)
:type password: str
"""
self.name = name
self.email = email
self.password = password
self.role = role
self.github_token = github_token
def __repr__(self) -> str:
"""
Represent a User Model by its 'name' Field.
:return str(name): Returns the string containing 'name' field
of the User model
:rtype str(name): str
"""
return f'<User {self.name}>'
@staticmethod
def generate_hash(password: str) -> str:
"""
Generate a Hash value for a password.
:param password: The password to be hashed
:type password: str
:return : The hashed password
:rtype : str
"""
# Go for increased strength no matter what
return pwd_context.hash(password, category='admin')
@staticmethod
def create_random_password(length=16) -> str:
"""
Create a random password of default length 16.
:param length: If parameter is passed, length will be the parameter.
16 by default
:type length: int
:return : Randomly generated password
:rtype : str
"""
chars = string.ascii_letters + string.digits + '!@#$%^&*()'
import os
return ''.join(chars[ord(os.urandom(1)) % len(chars)] for i in range(length))
def is_password_valid(self, password) -> Any:
"""
Check the validity of the password.
:param password: The password to be validated
:type password: str
:return : Validity of password
:rtype : boolean
"""
return pwd_context.verify(password, self.password)
def update_password(self, new_password) -> None:
"""
Update the password to a new one.
:param new_password: The new password to be updated
:type new_password: str
"""
self.password = self.generate_hash(new_password)
@property
def is_admin(self):
"""
Verify if an User is a admin.
:return : Checks if User has an admin role
:rtype: boolean
"""
return self.role == Role.admin
def has_role(self, name) -> Any:
"""
Check whether the User has a particular role.
:param name: Role of the user
:type name: str
:return : Checks whether a User has 'name' role
:rtype: boolean
"""
return self.role.value == name or self.is_admin