Skip to content

Commit

Permalink
user credentials in database serializers
Browse files Browse the repository at this point in the history
  • Loading branch information
KTZgraph committed Jan 8, 2021
1 parent cca3377 commit edc8faf
Show file tree
Hide file tree
Showing 25 changed files with 188 additions and 283 deletions.
25 changes: 10 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,20 @@ Description in progress
Sarenka is local web application for Windows.

#### Config
Rirst release gathers data from two search engines.
example sarenka/backend/connectors/credentials.json

User have to crete account on services:
censys:
shodan:
Next on **<server>/api/user_credentials** via post request user can add credentials:
```json
{
"censys": {
"base_url": "https://censys.io/",
"API_ID": "<my_user>",
"Secret": "<my_api_key>",
"API_URL": "https://censys.io/api/v1"
},
"shodan": {
"base_url": "https://www.shodan.io/",
"user": "<my_user>",
"api_key": "<my_api_key>"
}
{
"censys.api_id": "<censys_API_ID>",
"censys.secret" : "<censys_Secret>",
"shodan.user": "<shodan_user>",
"shodan.api_key": "<shodan_api_key>"
}
```


# Features
- gets data from **https://censys.io/** by ip
- get data from **https://www.shodan.io/** by ip
Expand Down
21 changes: 21 additions & 0 deletions sarenka/backend/api_searcher/migrations/0007_auto_20210108_1321.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 3.1.4 on 2021-01-08 12:21

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('api_searcher', '0006_censyscredentailsmodel_shodancredentailsmodel'),
]

operations = [
migrations.RenameModel(
old_name='CensysCredentailsModel',
new_name='CensysCredentialsModel',
),
migrations.RenameModel(
old_name='ShodanCredentailsModel',
new_name='ShodanCredentialsModel',
),
]
4 changes: 2 additions & 2 deletions sarenka/backend/api_searcher/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.db import models


class CensysCredentailsModel(models.Model):
class CensysCredentialsModel(models.Model):
"""Model przechowujący informacje o danych uwierzytelniajacych użytkownika do serwisu http://censys.io/
Może istnieć tylko jedna instancja przechowująca dane użytkownika"""
api_id = models.CharField(max_length=72, unique=True, default="")
Expand All @@ -21,7 +21,7 @@ def save(self, *args, **kwargs):
return super().save(*args, **kwargs)


class ShodanCredentailsModel(models.Model):
class ShodanCredentialsModel(models.Model):
"""Model przechowujący informacje o danych uwierzytelniajacych użytkownika do serwisu https://www.shodan.io/
Może istnieć tylko jedna instancja przechowująca dane użytkownika"""
user = models.CharField(max_length=200, unique=True, default="")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from api_searcher.models import CensysCredentailsModel
from django.conf import settings
USER_CREDENTIALS_DB = settings.USER_CREDENTIALS_DB_NAME

from api_searcher.models import CensysCredentialsModel

class CensysCredentialsError(Exception):
"""Zgłasza wyjątek gdy nie można utworzyć obiketu przechowujące dane użytkownika do seriwsu http://censys.io/"""
Expand All @@ -8,26 +11,36 @@ def __init__(self, message=None, errors=None):


class CensysCredentials:
"""Klasa przechowująca wymagane dane dla seriwsu trzeciego http://censys.io/.
"""Sinleton - Klasa przechowująca wymagane dane dla seriwsu trzeciego http://censys.io/.
Daje także możliwość aktualizacji danych uwierzytelniających użytkownika np. w przypadku przekroczenia ilości
wyszukiwań na darmowym koncie w serwisie."""
__instance = None

def __init__(self):
if not CensysCredentials.__instance:
credentials_obj = CensysCredentialsModel.objects.using(self.db_name).all().first()
if not credentials_obj:
credentials_obj = CensysCredentialsModel.objects.using(self.db_name).create()

def __init__(self, credentials_db_name:str):
# obiekt bazy danych z danymi uwierzytelniajacymi użytkownika
self.__db_name = credentials_db_name
self.__base_url = credentials_obj.base_url
self.__api_id = credentials_obj.api_id
self.__secret = credentials_obj.secret
self.__api_url = credentials_obj.api_url
else:
self.getInstance()

credentials_obj = CensysCredentailsModel.objects.using(self.credentials_db_name).all().first()
if not credentials_obj:
credentials_obj = CensysCredentailsModel.objects.using(self.credentials_db_name).create()
@classmethod
def getInstance(cls):
"""Metoda klasy wymaga dla klasy typu Singleton
- zwraca instancję klasy, gwarantuje istnienie tylko jednego obiektu z danymi wuierzytleniajacmi użytkownika."""
if not cls.__instance:
cls.__instance = CensysCredentials()
return cls.__instance

self.__base_url = credentials_obj.base_url
self.__api_id = credentials_obj.api_id
self.__secret = credentials_obj.secret
self.__api_url = credentials_obj.api_url

@property
def credentials_db_name(self):
return self.__db_name
def db_name(self):
return USER_CREDENTIALS_DB

@property
def base_url(self):
Expand All @@ -39,7 +52,10 @@ def api_id(self):

def update_api_id(self, new_api_id):
"""Metoda do aktualizacji danych "API_ID" dla konta użytkownika do serwisu http://censys.io/ """
credentials_obj = CensysCredentailsModel.objects.using(self.credentials_db_name).first()
if not new_api_id:
raise CensysCredentialsError('Censys "API_ID" value is empty.')

credentials_obj = CensysCredentialsModel.objects.using(self.db_name).all().first()
credentials_obj.api_id = new_api_id
credentials_obj.save()

Expand All @@ -52,7 +68,10 @@ def secret(self):

def update_secret(self, new_secret):
"""Metoda niezbędne do aktualizacji danych "Secret" dla konta użytkownika do serwisu http://censys.io/ """
credentials_obj = CensysCredentailsModel.objects.using(self.credentials_db_name).all().first()
if not new_secret:
raise CensysCredentialsError('Censys "Secret" value is empty.')

credentials_obj = CensysCredentialsModel.objects.using(self.db_name).all().first()
credentials_obj.secret = new_secret
credentials_obj.save()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from api_searcher.models import ShodanCredentailsModel
from django.conf import settings
USER_CREDENTIALS_DB = settings.USER_CREDENTIALS_DB_NAME

from api_searcher.models import ShodanCredentialsModel


class ShodanCredentialsError(Exception):
Expand All @@ -9,26 +12,35 @@ def __init__(self, message=None, errors=None):


class ShodanCredentials:
"""Klasa przechowująca wymagane dane dla seriwsu trzeciego https://shodan.io/.
"""Singleton - Klasa przechowująca wymagane dane dla seriwsu trzeciego https://shodan.io/.
Daje także możliwość aktualizacji danych uwierzytelniających użytkownika np. w przypadku przekroczenia ilości
wyszukiwań na darmowym koncie w serwisie."""

def __init__(self, credentials_db_name:str):
print("self.credentials_db_name: ", credentials_db_name)
self.__db_name = credentials_db_name
__instance = None

credentials_obj = ShodanCredentailsModel.objects.using(self.credentials_db_name).all().first()
if not credentials_obj:
credentials_obj = ShodanCredentailsModel.objects.using(self.credentials_db_name).create()
def __init__(self):
if not ShodanCredentials.__instance:
credentials_obj = ShodanCredentialsModel.objects.using(self.db_name).all().first()
if not credentials_obj:
credentials_obj = ShodanCredentialsModel.objects.using(self.db_name).create()

self.__base_url = credentials_obj.base_url
self.__api_key = credentials_obj.api_key
self.__user = credentials_obj.user
self.__base_url = credentials_obj.base_url
self.__api_key = credentials_obj.api_key
self.__user = credentials_obj.user
else:
self.getInstance()

@classmethod
def getInstance(cls):
"""Metoda klasy wymaga dla klasy typu Singleton
- zwraca instancję klasy, gwarantuje istnienie tylko jednego obiektu z danymi wuierzytleniajacmi użytkownika."""
if not cls.__instance:
cls.__instance = ShodanCredentials()
return cls.__instance

@property
def credentials_db_name(self):
return self.__db_name
def db_name(self):
return USER_CREDENTIALS_DB

@property
def base_url(self):
Expand All @@ -40,7 +52,10 @@ def api_key(self):

def update_api_key(self, new_api_key):
"""Metoda do aktualizacji danych "user" dla konta użytkownika do serwisu https://shodan.io/ """
credentials_obj = ShodanCredentailsModel.objects.using(self.credentials_db_name).all().first()
if not new_api_key:
raise ShodanCredentialsError('Shodan "api_key" value is empty.')

credentials_obj = ShodanCredentialsModel.objects.using(self.db_name).all().first()
credentials_obj.api_key = new_api_key
credentials_obj.save()

Expand All @@ -53,9 +68,13 @@ def user(self):

def update_user(self, new_user):
"""Metoda do aktualizacji danych "api_key" dla konta użytkownika do serwisu https://shodan.io/"""
credentials_obj = ShodanCredentailsModel.objects.using(self.credentials_db_name).all().first()
if not new_user:
raise ShodanCredentialsError('Shodan "user" value is empty.')

credentials_obj = ShodanCredentialsModel.objects.using(self.db_name).all().first()
credentials_obj.user = new_user
credentials_obj.save()

# aktualizacja danych obiektu
self.__user = new_user

Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ def get_data(self, ip_address):
connector = ShodanConnector(shodan_credentials)
response = connector.search_by_ip(ip_address)
return response.to_json # TODO zmienić na serializatory
except ShodanHostSearchError as ex:
except ShodanCredentialsError as ex:
raise ShodanHostSearchError("Invalid settings for service https://censys.io/. " + str(ex))
12 changes: 2 additions & 10 deletions sarenka/backend/api_searcher/search_engines/user_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
Moduł do przechowywania danych użytkownika takich jak klucze do serwisów,
które wymagają kont dla korzystania z ich api i/lub funkcjonalności.
"""
import json
from .censys_engine.censys_credentials import CensysCredentials, CensysCredentialsError
from .shodan_engine.shodan_credentials import ShodanCredentials, ShodanCredentialsError
import os


class UserCredentialsError(Exception):
Expand All @@ -20,22 +18,16 @@ def __init__(self, message=None, errors=None):
class UserCredentials:
"""Singleton - Klasa przechowująca dane użytkownika do serwisów trzecich niezbędne do korzystania z ich funkcjonalności."""
__instance = None
__db_name = "user_credentials"

@property
def db_name(self):
"""Metoda klasy zwracajaca ścieżkę do pliku konfiguracyjnego użytkownika."""
return self.__db_name

def __init__(self):
if not UserCredentials.__instance:

try:
self.__censys = CensysCredentials(self.db_name)
self.__censys = CensysCredentials()
except CensysCredentialsError as ex:
raise UserCredentialsError(str(ex))
try:
self.__shodan = ShodanCredentials(self.db_name)
self.__shodan = ShodanCredentials()
except ShodanCredentialsError as ex:
raise UserCredentialsError(str(ex))
else:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import json
import os

from .user_credentials import UserCredentials, UserCredentialsError


Expand All @@ -24,7 +21,6 @@ def __init__(self, user_data):
def user_data(self):
return self.__user_data


def __update_censys_credentials(self):
"""Metoda pomocnicza aktualizująca dane uwierzytelniające użytkownika do serwisu http://censys.io/
Aktualizuje obiekt przechowujący dane oraz plik konfiguracyjny."""
Expand All @@ -36,7 +32,6 @@ def __update_censys_credentials(self):
self.user_credentials.censys.update_api_id(new_api_id)
self.user_credentials.censys.update_secret(new_secret)


def __update_shodan_credentials(self):
"""Metoda pomocnicza aktualizująca dane uwierzytelniające użytkownika do serwisu https://shodan.io/
Aktualizuje obiekt przechowujący dane oraz plik konfiguracyjny."""
Expand All @@ -47,7 +42,6 @@ def __update_shodan_credentials(self):
self.user_credentials.shodan.update_user(new_shodan_user)
self.user_credentials.shodan.update_api_key(new_shodan_api_key)


def update(self):
"""Metoda aktualizująca i zapisujaca do pliku dane uwierzytelniające użytkownika do serwisów trzeich,
które udostępniaja swoje dane tylko po utworzeniu konta z uniklanym kluczem przypisanym użytkownikowi."""
Expand All @@ -56,3 +50,4 @@ def update(self):
self.__update_shodan_credentials()
except Exception as ex:
raise UserCredentialsUpdaterError(str(ex))

4 changes: 2 additions & 2 deletions sarenka/backend/api_searcher/searcher_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def get_censys_data(self):
raise CredentialsNotFoundError("UserCredentials object does not exist.")

except CredentialsNotFoundError as ex:
settings_url = self.host_address + reverse('settings')
settings_url = self.host_address + reverse("user_credentials")
return {
"censys": {
"error": "Unable to get credentials for service http://censys.io/. "
Expand Down Expand Up @@ -77,7 +77,7 @@ def get_shodan_data(self):
raise CredentialsNotFoundError("UserCredentials object does not exist.")

except CredentialsNotFoundError as ex:
settings_url = self.host_address + reverse('settings')
settings_url = self.host_address + reverse("user_credentials")
return {
"shodan": {
"error": "Unable to get credentials for service https://www.shodan.io/. "
Expand Down
25 changes: 21 additions & 4 deletions sarenka/backend/api_searcher/serializers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
from rest_framework import serializers
from django.shortcuts import get_object_or_404
from .models import CensysCredentialsModel, ShodanCredentialsModel


class CensysCredentailsSerializer(serializers.ModelSerializer):
"""Serializer dla danych uwierzytelniajacych użytkownika do serwisu https://censys.io/"""
class Meta:
model = CensysCredentialsModel
fields = ["api_id", "secret"]



class ShodanCredentailsSerializer(serializers.ModelSerializer):
"""Serializer dla danych uwierzytelniajacych użytkownika do serwisu https://www.shodan.io/"""
class Meta:
model = ShodanCredentialsModel
fields = ["user", "api_key"]


class UserCredentialsSerializer(serializers.Serializer):
"""Serializuje klucze użytkownika do serwisów trzeich jak censys.io oraz shodan.io"""
censys_API_ID = serializers.CharField(max_length=72)
censys_Secret = serializers.CharField(max_length=64)
shodan_user = serializers.CharField(max_length=200)
shodan_api_key = serializers.CharField(max_length=64)
censys = CensysCredentailsSerializer(read_only=False, many=False)
shodan = ShodanCredentailsSerializer(read_only=False, many=False)



class ProductSerializer(serializers.Serializer):
vendor = serializers.CharField()
Expand Down
Loading

0 comments on commit edc8faf

Please sign in to comment.