Skip to content

Commit 9b61363

Browse files
committed
Added credentials configuration
1 parent 03354d9 commit 9b61363

25 files changed

+483
-93
lines changed

backup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ def obfuscate_all(destination_engine):
405405
obfuscate_user_table("user", destination_engine)
406406
r.truncate_table("dataexport")
407407
r.truncate_table("usersearchhistory")
408+
r.truncate_table("credentials")
408409

409410

410411
#### SQLite
@@ -512,6 +513,7 @@ def backup_workspace(run_info):
512513
print("--------------------")
513514

514515
tablemapping = {
516+
"./instance_credentials" : ["instance_credentials"],
515517
"./instance_entries" : ["instance_linkdatamodel"],
516518
"./instance_domains" : ["instance_domains"],
517519
"./instance_sourcecategories" : ["instance_sourcecategories"],
@@ -587,6 +589,7 @@ def restore_workspace(run_info):
587589

588590
# order is important
589591
tablemapping = [
592+
["./instance_credentials" , ["instance_credentials"]],
590593
["./instance_sourcecategories" , ["instance_sourcecategories"]],
591594
["./instance_sourcessubcategories" , ["instance_sourcesubcategories"]],
592595
["./instance_sources" , ["instance_sourcedatamodel"]],
@@ -658,6 +661,7 @@ def run_sql_for_workspaces(run_info, sql_command):
658661

659662
# order is important
660663
tablemapping = [
664+
"instance_credentials",
661665
"instance_apikeys",
662666
"instance_applogging",
663667
"instance_backgroundjob",

rsshistory/configuration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
if a change requires the model to be changed, then second digit is updated, patch is set to 0
2323
if something should be released to public, then release version changes
2424
"""
25-
__version__ = "2.11.9"
25+
__version__ = "2.12.0"
2626

2727

2828
class Configuration(object):

rsshistory/forms.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
DataExport,
2525
EntryRules,
2626
ApiKeys,
27+
Credentials,
2728
Browser,
2829
SearchView,
2930
)
@@ -208,8 +209,7 @@ class Meta:
208209
"export_data",
209210
"local_path",
210211
"remote_path",
211-
"user",
212-
"password",
212+
"credentials",
213213
"db_user",
214214
"export_entries",
215215
"export_entries_bookmarks",
@@ -310,6 +310,27 @@ def __init__(self, *args, **kwargs):
310310
super().__init__(*args, **kwargs)
311311

312312

313+
class CredentialsForm(forms.ModelForm):
314+
"""
315+
Category choice form
316+
"""
317+
318+
class Meta:
319+
model = Credentials
320+
fields = [
321+
"name",
322+
"credential_type",
323+
"username",
324+
"password",
325+
"token",
326+
"secret",
327+
"owner",
328+
]
329+
330+
def __init__(self, *args, **kwargs):
331+
super().__init__(*args, **kwargs)
332+
333+
313334
class UserConfigForm(forms.ModelForm):
314335
"""
315336
Category choice form
@@ -683,8 +704,7 @@ class Meta:
683704
"auto_tag",
684705
"favicon",
685706
"auto_update_favicon",
686-
"username",
687-
"password",
707+
"credentials",
688708
"proxy_location",
689709
]
690710
widgets = {}

rsshistory/models/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
from .apikeys import (
4747
ApiKeys,
4848
)
49+
from .credentials import (
50+
Credentials,
51+
)
4952
from .useractions import (
5053
UserVotes,
5154
UserComments,

rsshistory/models/credentials.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""
2+
Security is a made up word.
3+
"""
4+
from cryptography.fernet import Fernet
5+
from django.conf import settings
6+
from django.db import models
7+
8+
from ..apps import LinkDatabase
9+
10+
11+
FERNET_KEY = settings.FERNET_KEY
12+
fernet = Fernet(FERNET_KEY)
13+
14+
15+
class Credentials(models.Model):
16+
"""
17+
You can define access to multiple sources here
18+
"""
19+
name = models.CharField(max_length=1000, blank=True) # github etc
20+
credential_type = models.CharField(max_length=1000, blank=True) # refresh token, auth token, etc.
21+
username = models.CharField(max_length=1000, blank=True)
22+
password = models.CharField(max_length=1000, blank=True)
23+
secret = models.CharField(max_length=1000, blank=True)
24+
token = models.CharField(max_length=1000, blank=True)
25+
26+
owner = models.ForeignKey(
27+
settings.AUTH_USER_MODEL,
28+
on_delete=models.CASCADE,
29+
related_name=str(LinkDatabase.name) + "_credentials",
30+
null=True,
31+
blank=True,
32+
help_text="Owner of credentials"
33+
)
34+
35+
class Meta:
36+
ordering = ["owner"]
37+
38+
def encrypt(self):
39+
"""Still the better way than Facebook plaintext."""
40+
if self.secret:
41+
self.secret = fernet.encrypt(self.secret.encode()).decode()
42+
if self.token:
43+
self.token = fernet.encrypt(self.token.encode()).decode()
44+
if self.password:
45+
self.password = fernet.encrypt(self.password.encode()).decode()
46+
47+
def decrypt(self):
48+
if self.secret:
49+
self.secret = fernet.decrypt(self.secret.encode()).decode()
50+
if self.token:
51+
self.token = fernet.decrypt(self.token.encode()).decode()
52+
if self.password:
53+
self.password = fernet.decrypt(self.password.encode()).decode()
54+
return None
55+
56+
def __str__(self):
57+
return "{}/{}".format(self.name, self.credential_type)

rsshistory/models/export.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from utils.dateutils import DateUtils
66

7+
from .credentials import Credentials
78
from .system import AppLogging
89

910

@@ -43,17 +44,13 @@ class DataExport(models.Model):
4344
blank=True,
4445
help_text="Example: https://github.com/rumca-js/Django-link-archive.git. Can be empty",
4546
)
46-
user = models.CharField(
47-
default="",
48-
max_length=2000,
49-
blank=True,
50-
help_text="Repo user name. Can be empty",
51-
)
52-
password = models.CharField(
53-
default="",
54-
max_length=2000,
47+
48+
credentials = models.ForeignKey(
49+
Credentials,
50+
on_delete=models.CASCADE,
51+
related_name="export",
5552
blank=True,
56-
help_text="Repo password, or token. Can be empty",
53+
null=True,
5754
)
5855

5956
db_user = models.CharField(

rsshistory/models/sources.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from ..webtools import UrlLocation
55

66
from ..apps import LinkDatabase
7+
from .credentials import Credentials
78

89

910
class SourceCategories(models.Model):
@@ -148,16 +149,19 @@ class SourceDataModel(models.Model):
148149
fetch_period = models.IntegerField(
149150
default=900, help_text="Source is checked for new data after [x] seconds"
150151
)
151-
username = models.CharField(
152-
max_length=1000, blank=True, help_text="User name required to access source"
153-
)
154-
password = models.CharField(
155-
max_length=1000, blank=True, help_text="Password required to access source"
156-
)
152+
157153
auto_tag = models.CharField(
158154
max_length=1000, blank=True, help_text="Automatic tag for new entries"
159155
)
160156

157+
credentials = models.ForeignKey(
158+
Credentials,
159+
on_delete=models.CASCADE,
160+
related_name="sources",
161+
blank=True,
162+
null=True,
163+
)
164+
161165
category = models.ForeignKey(
162166
SourceCategories,
163167
on_delete=models.SET_NULL,

rsshistory/pluginsources/emailsourceplugin.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import socket
2-
31
from utils.services import EmailReader
42
from utils.dateutils import DateUtils
53

@@ -25,12 +23,20 @@ def __init__(self, source_id, options=None):
2523

2624
def read_entries(self):
2725
source = self.get_source()
26+
if not source.credentials:
27+
AppLogging.error(
28+
"Source:{} Credentials were not defined for source.".format(source.id)
29+
)
30+
return
2831

2932
day_to_remove = Configuration.get_object().get_entry_remove_date()
3033

3134
try:
3235
reader = EmailReader(source.url, time_limit=day_to_remove)
33-
if not reader.connect(source.username, source.password):
36+
credentials = source.credentials
37+
credentials.decrypt()
38+
39+
if not reader.connect(credentials.username, credentials.password):
3440
AppLogging.error(
3541
"Source:{} Could not login to service.".format(source.id)
3642
)

rsshistory/templates/rsshistory/admin_page.html

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,31 +52,26 @@ <h2>Managment links</h2>
5252
{% endif %}
5353
</a>
5454
</li>
55+
5556
<li class="list-group-item">
56-
<a href="{% url 'rsshistory:entry-rules' %}" title="Entry Rules allow to define URL based rules. Block domains, etc." class="nav-link">
57-
<img src="{% static 'rsshistory/icons/account.png' %}" class="content-icon" />
58-
Entry rules</a>
59-
</li>
60-
<li class="list-group-item">
61-
<a href="{% url 'rsshistory:api-keys' %}" title="API keys allow to define URL based rules. Block domains, etc." class="nav-link">
62-
<img src="{% static 'rsshistory/icons/account.png' %}" class="content-icon" />
63-
API keys</a>
64-
</li>
65-
<li class="list-group-item">
66-
<a href="{% url 'rsshistory:browsers' %}" title="Browser managment" class="nav-link">
67-
<img src="{% static 'rsshistory/icons/icons8-paper-64.png' %}" class="content-icon" />
68-
Browsers</a>
57+
<a href="{% url 'rsshistory:searchviews' %}" title="Searchviews" class="nav-link">
58+
<img src="{% static 'rsshistory/icons/icons8-search-100.png' %}" class="content-icon" />
59+
Search views</a>
6960
</li>
70-
7161
<li class="list-group-item">
7262
<a href="{% url 'rsshistory:data-exports' %}" title="Configured Data Exports" class="nav-link">
7363
<img src="{% static 'rsshistory/icons/icons8-database-export-100.png' %}" class="content-icon" />
7464
Data Exports</a>
7565
</li>
7666
<li class="list-group-item">
77-
<a href="{% url 'rsshistory:searchviews' %}" title="Searchviews" class="nav-link">
78-
<img src="{% static 'rsshistory/icons/icons8-search-100.png' %}" class="content-icon" />
79-
Search views</a>
67+
<a href="{% url 'rsshistory:entry-rules' %}" title="Entry Rules allow to define URL based rules. Block domains, etc." class="nav-link">
68+
<img src="{% static 'rsshistory/icons/icons8-paper-64.png' %}" class="content-icon" />
69+
Entry rules</a>
70+
</li>
71+
<li class="list-group-item">
72+
<a href="{% url 'rsshistory:browsers' %}" title="Browser managment" class="nav-link">
73+
<img src="{% static 'rsshistory/icons/icons8-paper-64.png' %}" class="content-icon" />
74+
Browsers</a>
8075
</li>
8176
{% if 0 %}
8277
<li class="list-group-item">
@@ -96,6 +91,16 @@ <h2>Managment links</h2>
9691
</li>
9792
{% endif %}
9893

94+
<li class="list-group-item">
95+
<a href="{% url 'rsshistory:api-keys' %}" title="API keys allow to define URL based rules. Block domains, etc." class="nav-link">
96+
<img src="{% static 'rsshistory/icons/account.png' %}" class="content-icon" />
97+
API keys</a>
98+
</li>
99+
<li class="list-group-item">
100+
<a href="{% url 'rsshistory:credentials' %}" title="Credentials" class="nav-link">
101+
<img src="{% static 'rsshistory/icons/account.png' %}" class="content-icon" />
102+
System credentials</a>
103+
</li>
99104
<li class="list-group-item">
100105
<a href="{% url 'rsshistory:appusers' %}" title="User administration" class="nav-link">
101106
<img src="{% static 'rsshistory/icons/account.png' %}" class="content-icon" />
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{% extends base_generic %}
2+
{% load static %}
3+
{% block content %}
4+
5+
<div class="contentbuttonmenu">
6+
<a href="{% url 'rsshistory:credential-edit' object.id %}" class="btn btn-primary" role="button">
7+
{% include "rsshistory/icon_edit.html" %}
8+
</a>
9+
<a href="{% url 'rsshistory:credential-remove' object.id %}" class="btn btn-primary" role="button">
10+
<img src="{% static 'rsshistory/icons/icons8-trash-100.png' %}" class="content-icon" />
11+
</a>
12+
</div>
13+
14+
<div>ID: {{object.id}}</div>
15+
16+
<h1>{{object.name}}</h1>
17+
<div>Credentials type: {{object.credential_type}}</div>
18+
<div>UserName: {{object.username}}</div>
19+
20+
{% if object.owner %}
21+
{% with user=object.owner %}
22+
<div>OwnerID: {{user.id}}</div>
23+
<div>Owner Name: {{user.username}}</div>
24+
{% endwith %}
25+
{% endif %}
26+
27+
{% endblock %}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{% extends base_generic %}
2+
{% load static %}
3+
{% block content %}
4+
5+
<div class="container">
6+
<a href="{% url 'rsshistory:credential-add' %}" title="Add new api key" class="btn btn-primary" role="button">
7+
{% include "rsshistory/icon_add.html" %}
8+
</a>
9+
</div>
10+
11+
<h1>Credentials</h1>
12+
{% if content_list %}
13+
<div class="list-group">
14+
{% for cred_object in content_list %}
15+
<div class="list-group-item">
16+
<div>
17+
Name: {{cred_object.name}}
18+
19+
<a href="{% url 'rsshistory:credential-edit' cred_object.id %}" title="Edit credential" class="btn btn-secondary btn-sm ms-auto" role="button">
20+
{% include "rsshistory/icon_edit.html" %}
21+
</a>
22+
<a href="{% url 'rsshistory:credential-remove' cred_object.id %}" title="Remove credential" class="btn btn-secondary btn-sm" role="button">
23+
{% include "rsshistory/icon_remove.html" %}
24+
</a>
25+
</div>
26+
</div>
27+
{% endfor %}
28+
{% else %}
29+
No credentials yet
30+
{% endif %}
31+
32+
{% endblock %}

rsshistory/templates/rsshistory/entries_library.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ function getEntryReadLaterBar(entry) {
494494
</a>
495495
496496
<a id="${id}" class="remove-button ms-auto" href="${remove_link}" >
497-
<img src="{% static 'rsshistory/icons/icons8-trash-100.png' %}" class="content-icon" />
497+
{% include "rsshistory/icon_remove.html" %}
498498
</a>
499499
</div>
500500
</div>

rsshistory/templates/rsshistory/entryrules_detail.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
{% include "rsshistory/icon_enable.html" %}
1111
</a>
1212
<a href="{% url 'rsshistory:entry-rule-remove' object.id %}" class="btn btn-primary" role="button">
13-
<img src="{% static 'rsshistory/icons/icons8-trash-100.png' %}" class="content-icon" />
13+
{% include "rsshistory/icon_remove.html" %}
1414
</a>
1515
</div>
1616

0 commit comments

Comments
 (0)