Add custom user using django-allauth extra data - django

I would like to save data I get with allauth package after signing up using facebook.
I made a custom user :
class AppUser(models.Model):
birthdate = models.DateTimeField(null=True, blank=True)
address = adress_model.AddressField(null=True, blank=True)
image = models.ImageField(upload_to=get_image_path, blank=True, null=True)
gender = models.TextField(null=True, blank=True)
user = models.OneToOneField(User)
I would like to store all data in the database so I can easily access it from database.
P.S: If u can tell me how I can make a login page with button that will trigger it as well it would be great!

You can either use the save() method of the model to extract and save the data:
save(self, *wargs, **kwargs)
social_account = self.socialaccount_set.get(provider="facebook")
self.first_name = social_account.extra_data['first_name']
super(User, self).save(*wargs, **kwargs)
Or you can use the provided signal by allauth:
allauth.socialaccount.signals.social_account_added(request, sociallogin)
Check here for signal docs: http://django-allauth.readthedocs.io/en/latest/signals.html

Related

Django, getting data from another user (schema) in an Oracle 19 DB

I am using Django 4.1, Oracle 19 with the python package oracledb.
I am logged in as user djangousr and the schema I am trying to get the data from is "user123"
I am able to retrieve data in a file outside of Django with the same connection information.
But in Django, I keep getting the same error.
I hope you have a solution for me as I was not able to find anything elsewhere.
Thank you.
ORA-00942: table or view does not exist
Below is the SQL from the debug screen that I am able to run fine in SQL developer.
('SELECT "USER"."USER_ID" FROM "user123.USER_TABLE"')
I will also provide the model and the view:
class SecurityUserData(models.Model):
user_id = models.IntegerField(primary_key=True)
user_name = models.CharField(max_length=100)
user_password = models.CharField(max_length=100)
user_first_name = models.CharField(max_length=30, blank=True, null=True)
user_last_name = models.CharField(max_length=30, blank=True, null=True)
class Meta:
managed = False
db_table = 'SEC_USER'
And the view:
def display_user_data(request):
user_data = SecurityUserData.user123.all()
return render(request, 'all.html', {'user_data': user_data})

I don't understand how to use the django 3rd party library djangorestframework-api-key

I'm trying to set up an authentication that requires a user to send an API key and secret in the header of a request before being able to create the data. I'm using djangorestframework-api-key found here: https://florimondmanca.github.io/djangorestframework-api-key/guide/. However, I'm struggling with how to use it properly. My models.py looks something like this:
class UserTier(Base):
key = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
api_key = models.CharField(max_length=1000, null=True, blank=True)
tiers = models.ManyToManyField(Tier)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
def save(self, *args, **kwargs):
api_key, self.api_key = APIKey.objects.create_key(name=self.user.key)
super(UserTier, self).save(*args, **kwargs)
Here is an example API endpoint view that I have made:
class MLBTeams(ListAPIView):
serializer_class = MLBTeamSerializer
queryset = Team.objects.all()
permission_classes = [HasAPIKey]
I ran this to get the API Key and passed it through the header in postman:
print(APIKey.objects.get_from_key('V9Js7vY7.s1xiK0pWtzbp1ZQA3e2NrT95qhUk1kRV')) #key stored in the UserTier object
However, I'm still getting the following error:
{
"detail": "Authentication credentials were not provided."
}
Does anybody know how to use this library properly?

How to change data inside table django?

I have been creating clone of Twitter. User can register, login, write tweets. Tweet modal is here:
class TweetModel(models.Model):
text = models.TextField(max_length=300, blank=False)
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True)
username = models.CharField(max_length=100, blank=True)
def __str__(self):
return f'{self.username}: {self.text[0:15]}'
Once user changes his/her username, I want to change username in the tweets they write also.
How can I handle this? Thank you.
You don't need to store the username in TweetModel. You can have access to the username like this:
tweet = TweetModel.objects.get(pk=1).owner.username
owner is a ForeignKey which means it stores the user id and .owner means to find the user with this id and .username means to return the username field for that user.
Now you're directly accessing the User table so any changes will be there.

Django Admin: How do I serialize data and store it in a model so that it can be restored by the user?

So what I have so far is a model called Registration and a model called Deleted Registration. I overrode the deleted_selected admin action for Registration so that instead of deleting the query, it would make Deleted Registrations. The thing is, it only saves the most important parts. Registrations have a few foreign keys and one-to-one fields. Apparently just saving the most important data isn't good enough and we want to serialize all the data in the selected registration models and store it with the deleted registration. This way, when you select a few deleted registrations, you can click on Restore deleted registrations
I'll reiterate what I want so it's a little but more clear: I want to be able to "delete" registrations, where a new deleted registration is created. This way, they can view deleted registrations and, if need be, restore them.
Here is the registration model:
class Registration(models.Model):
objects = RegistrationManager()
# Used to identify this object securely in urls without giving the actual primary key
uuid = models.UUIDField(default=uuid.uuid4, editable=False)
sibs_event = models.ForeignKey("EventInstance", null=True, blank=True)
date_registered = models.DateTimeField(auto_now_add=True)
# sibs event for this registration
sibs_weekend = models.ForeignKey(SibsWeekend, null=False)
payment_delegation = models.OneToOneField("PaymentDelegation", null=True, blank=True, related_name="registration", on_delete=models.SET_NULL)
Here is the deleted registration model:
class DeletedRegistration(models.Model):
"""
Just in case of bugs with purging registrants, store
important registrant information in this model.
"""
registrant_name = models.CharField(max_length=100)
registrant_email = models.EmailField(null=True, blank=True)
registrant_phone_num = models.CharField(max_length=13, null=True, blank=True)
delegate_name = models.CharField(max_length=100, null=True, blank=True)
delegate_email = models.EmailField(null=True, blank=True)
num_of_participants = models.PositiveSmallIntegerField(null=True, default=1)
special_event = models.CharField(max_length=100, null=True)
Here is the overridden delete_selected for registrations:
def delete_selected(modeladmin, request, queryset):
"""
This overrides the defult deleted_selected because we want to gather the data from the registration and create a
DeletedRegistration object before we delete it.
"""
for registration in queryset:
reg = registration.get_registrant()
if registration.payment_delegation:
delegate_name = registration.payment_delegation.name
delegate_email = registration.payment_delegation.email
else:
delegate_name = None
delegate_email = None
registration_to_delete = DeletedRegistration.objects.create(
registrant_name = reg.full_name(),
registrant_email = reg.email,
registrant_phone_num = reg.phone,
delegate_name = delegate_name,
delegate_email = delegate_email,
# Filtering out people (with True) who couldn't participate in events because we are only interested in the people
# we had to reserve space and prepare materials for.
num_of_participants = registration.get_num_party_members(True),
special_event = registration.sibs_event,
)
registration.delete()
I appreciate your help! I just don't know what to do from here; I've been searching online for the ways I can do it but I cant wrap my mind around it. I want to save the serialized registration data as a field in deleted registration so that way I can have an admin action take that field and create a new registration from it.

How to encrypt TextField before saving in database

Here I am Trying to create Model where i can save Password, here my model:
class Server(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=20, null=True)
hostname = models.CharField(max_length=50, null=True, blank=True)
ip = models.GenericIPAddressField()
ip2 = models.GenericIPAddressField(null=True, blank=True)
user_name = models.CharField(max_length=20, null=True)
password = models.TextField(max_length=500, null=True, blank=True)
ssh_key = models.FileField(null=True, blank=True, upload_to='Keys/')
till now i read lot of blogs and posts but i haven't found any good way to save encrypted text in database
i was trying this method but it is also not working for me please check my View.py below,
from cryptography.fernet import Fernet
class HostCreate(CreateView):
model = Server
template_name = 'inventory/host_create.html'
form_class = HostForm
# after getting POST data of fields (name, hostname, ip, pass, key) adding user and saving
def form_valid(self, form):
host = form.save(commit=False)
host.user = User.objects.get(pk=self.request.user.pk)
host.password = self.ecrypt(host.password)
host.save()
return redirect('inventory:hosts')
def ecrypt(self, password): # need password and return cipher password
key = 'wgjSSyfVKgz0EjyTilqeJSaANLDu7TzHKdpAXUeZPbM='
cipher_suite = Fernet(key)
cipher_text = cipher_suite.encrypt(password)
return cipher_text
here i am getting error,
Exception Type: TypeError
Exception Value: data must be bytes.
Exception Location: /usr/lib64/python2.7/site-packages/cryptography/fernet.py in _encrypt_from_parts, line 55
Is there any builtin django functionality for password field?
You can do it in two possible ways.
Write custom save method for your model like this
class Server(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=20, null=True)
hostname = models.CharField(max_length=50, null=True, blank=True)
ip = models.GenericIPAddressField()
ip2 = models.GenericIPAddressField(null=True, blank=True)
user_name = models.CharField(max_length=20, null=True)
password = models.TextField(max_length=500, null=True, blank=True)
ssh_key = models.FileField(null=True, blank=True, upload_to='Keys/')
def save(self, *args, **kwargs):
if not self.pk:
# encrypt_field_value_here
super(Server, self).save(*args, **kwargs)
You can use custom model fields. You can get documentation on this from here. Also check BaseEncryptedField from here.
You can also use this package.
For the password field, Django uses its own hashing. You can change it though.
There are a few encryption methods in Django. You can use them like AES. It can be imported from crypto cipher.
Otherwise you can use the default Django Signer.
I solved it by using django-encrypted-fields Packages
Steps are :
on Project Root directory open terminal and Execute commands.
Install Package django-encrypted-fields
$ pip install django-encrypted-fields
Create a basic keyczar keyset. AES-256 in this case.
$ mkdir fieldkeys
$ keyczart create --location=fieldkeys --purpose=crypt
$ keyczart addkey --location=fieldkeys --status=primary --size=256
Add settings In your settings.py
ENCRYPTED_FIELDS_KEYDIR = os.path.join(BASE_DIR, 'fieldkeys')
Now in models.py
from django.db import models
import encrypted_fields
class Server(models.Model):
password = encrypted_fields.EncryptedCharField(max_length=500)
for more details please visit here
hope this will help someone in future
You can use the django-fernet-fields library, which defines EncryptedXXXField for you:
from django.db import models
from fernet_fields import EncryptedTextField
class MyModel(models.Model):
name = EncryptedTextField()
The values are saved with symmetric encryption, and by default uses SECRET_KEY as en encryption key, so all you need to do is keep your SECRET_KEY constant over time.