Related
A user is assigned to a student group and from the group remove delete_permission, but the below code returns true.
student_group = Group.objects.get(name='student')
content_type = ContentType.objects.get_for_model(Department)
department_permission = Permission.objects.filter(content_type=content_type)
user = User.objects.get(email='test#gmail.com')
student_group.user_set.add(user)
for perm in department_permission:
if perm.codename == "delete_department":
student_group.permissions.remove(perm)
print(user.has_perm("quiz.delete_department"), "Quiz Permission after")
Permissions are cached on the user object see Django documentation. Also refresh_from_db() won't work you need to fetch the user again see this issue.
In your case:
student_group = Group.objects.get(name='student')
content_type = ContentType.objects.get_for_model(Department)
department_permission = Permission.objects.filter(content_type=content_type)
user = User.objects.get(email='test#gmail.com')
student_group.user_set.add(user)
for perm in department_permission:
if perm.codename == "delete_department":
student_group.permissions.remove(perm)
# re-fetch the user from the database after permission change
user = User.objects.get(email='test#gmail.com')
print(user.has_perm("quiz.delete_department"), "Quiz Permission after")
I have two models: User and UserSettings because I decided to divide user related properties and privacy settings.
I am using PeeweeORM for building models and creating tables. Here is a short part of my code:
class User(BaseModel):
id = UUIDField(primary_key=True, default=uuid4)
tg_id = BigIntegerField(unique=True, null=True)
class UserSettings(BaseModel):
user: User = ForeignKeyField(User, backref='settings', unique=True)
show_location: bool = BooleanField(default=True)
As far as I know peewee itself has no built-in OneToOne relation support and I have decided to use playhouse's django-like signals described in peewee docs so that there is one record in UserSettings table for each one User. As it was defined in docs, I have inherited my BaseModel class from playhouse.signal Model class to make signals working. Here is a signal itself:
#post_save(sender=User)
def on_user_created(model_class: User, instance: User, created: bool):
print("works1") # Signal is working correctly. I see this output in console
if created: # DOES NOT WORK HERE! I AM GETTING False value on created
print('works2')
us = UserSettings()
us.user = instance
us.save(force_insert=True)
So this is the way I am creating new users:
def create_or_update_user_tg(tg_id: int, name: str, age: int, city: str,
gender: Gender, search_gender: SearchGender,
profile_description: str = None, location: Location = None,
medias: typing.List[tuple[str]] = None) -> \
typing.Union[User, None]:
u, is_creating = User.get_or_none(tg_id=tg_id), False
if not u:
u, is_creating = User(), True
u.tg_id = tg_id
u.name = name
u.age = age
u.city = city
u.gender = gender.value
u.search_gender = search_gender.value
u.profile_description = profile_description
if location:
u.longitude = location.longitude
u.latitude = location.latitude
u.save(force_insert=is_creating)
upload_user_medias(u.tg_id, medias, delete_existing=True)
return u
Thanks for responses guys! Waiting for your advices.
It seems to be working fine for me. Here's a stripped-down, simplified example:
from peewee import *
from playhouse.signals import Model, post_save
from uuid import uuid4
db = SqliteDatabase(':memory:')
class User(Model):
id = UUIDField(default=uuid4)
username = TextField()
class Meta:
database = db
db.create_tables([User])
#post_save(sender=User)
def on_save(model_class, instance, created=None):
print(instance.username, created)
u = User()
u.username='foo'
u.save(force_insert=True)
u.save()
The output, as expected:
foo True
foo False
I am creating a EC2 instance using CfnInstance in CDK and I would like to use the ARN later in an IAM role, so I can give permission to that specific resource and to avoid to use *. How can I access the ARN of the EC2 instance just created. The code is as follows:
instance_profile = self.create_instance_profile()
self.instance = ec2.CfnInstance(self, 'Client',
image_id = image_id,
instance_type = instance_type,
subnet_id = subnet_id,
iam_instance_profile = instance_profile.ref,
security_group_ids = [cluster_security_group_id],
user_data = core.Fn.base64('\n'.join(self.user_data_commands)),
tags = [{ 'key': 'Name', 'value': 'MskEc2Client' }],
)
def create_instance_profile(self):
role = iam.Role(self, 'Role', assumed_by = iam.ServicePrincipal('ec2.amazonaws.com'))
ssm_policy_statement = iam.PolicyStatement(
resources = ['*'], #TODO GIVE PERMISSION TO THE SPECIFIC RESOURCE (EC2)
actions = [
'ssm:UpdateInstanceInformation', 'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel', 'ssmmessages:OpenControlChannel', 'ssmmessages:OpenDataChannel'])
ssm_policy = iam.Policy(self, 'SessionManagerPolicy', statements = [ssm_policy_statement])
self.add_w12_suppression(ssm_policy, 'Session Manager actions do not support resource level permissions')
ssm_policy.attach_to_role(role)
msk_policy = iam.Policy(self, 'MskPolicy', #TODO GIVE PERMISSION TO SPECIFIC RESOURCES (EC2)
statements = [iam.PolicyStatement(resources = ['*'], actions = ['kafka:DescribeCluster', 'kafka:GetBootstrapBrokers'])]
)
self.add_w12_suppression(msk_policy, 'MSK actions do not support resource level permissions')
msk_policy.attach_to_role(role)
cfn_role = role.node.default_child
return iam.CfnInstanceProfile(self, 'InstanceProfile', roles = [cfn_role.ref])
You can use the default return value of the instance to construct the arn to populate the resources
ssm_policy_statement = iam.PolicyStatement(
resources = [f'arn:{self.partition}:ec2:{self.region}:{self.account}:instance/{self.instance.ref}'],
actions = [
'ssm:UpdateInstanceInformation', 'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel', 'ssmmessages:OpenControlChannel', 'ssmmessages:OpenDataChannel'
]
)
I configure Django with ldap. the authorization in ldap seems to work. but the group membership does'nt work. The user fall back to the login.
here the settings.py and the Debug
------------------- Config ------------------------------
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, NestedActiveDirectoryGroupType
# Baseline configuration.
AUTH_LDAP_SERVER_URI = "ldap://srv.domain.com"
AUTH_LDAP_BIND_DN = "cn=ldapreader,ou=admins,ou=City,dc=domain,dc=com"
AUTH_LDAP_BIND_PASSWORD = "LdapreadeR"
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=City,dc=domain,dc=com",
ldap.SCOPE_SUBTREE, "(sAMAccountName=%(user)s)")
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=xgroups,ou=City,dc=domain,dc=com",
ldap.SCOPE_SUBTREE, "(objectClass=group)"
)
AUTH_LDAP_GROUP_TYPE = NestedActiveDirectoryGroupType()
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
"is_active": "cn=django,ou=xgroups,ou=City,dc=domain,dc=com",
"is_staff": "cn=django_staff,ou=xgroups,ou=City,dc=domain,dc=com",
"is_superuser": "cn=django_admin,ou=xgroups,ou=City,dc=domain,dc=com"
}
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_PROFILE_FLAGS_BY_GROUP = {
"is_awesome": "cn=awesome,ou=django,ou=groups,dc=example,dc=com",
}
AUTH_LDAP_MIRROR_GROUPS = True
------------------ DEBUG ----------------------------------
search_s('ou=City,dc=domain,dc=com', 2, '(sAMAccountName=%(user)s)') returned 1 objects: cn=Farmer Nic,ou=users,ou=City,dc=domain,dc=com
Populating Django user fn000000
search_s('ou=xgroups,ou=City,dc=domain,dc=com', 2, '(& (objectClass=group)(|(member=cn=Farmer Nic,ou=users,ou=City,dc=domain,dc=com)))') returned 4 objects:
cn=django_admin,ou=xgroups,ou=City,dc=domain,dc=com;
cn=django,ou=xgroups,ou=City,dc=domain,dc=com;
cn=pbspot_op,ou=xgroups,ou=City,dc=domain,dc=com;
cn=xxx_super,ou=xgroups,ou=City,dc=domain,dc=com
search_s('ou=xgroups,ou=City,dc=domain,dc=com', 2, '(&(objectClass=group)(|
(member=cn=django_admin,ou=xgroups,ou=City,dc=domain,dc=com)
(member=cn=django,ou=xgroups,ou=City,dc=domain,dc=com)
(member=cn=pbspot_op,ou=xgroups,ou=City,dc=domain,dc=com)
(member=cn=xxx_super,ou=xgroups,ou=City,dc=domain,dc=com)))')
returned 0 objects:
cn=Farmer Nic,ou=users,ou=City,dc=domain,dc=com is a member of cn=django_admin,ou=xgroups,ou=City,dc=domain,dc=com
cn=Farmer Nic,ou=users,ou=City,dc=domain,dc=com is not a member of cn=django_staff,ou=xgroups,ou=City,dc=domain,dc=com
cn=Farmer Nic,ou=users,ou=City,dc=domain,dc=com is a member of cn=django,ou=xgroups,ou=City,dc=domain,dc=com
Django found, that the user Member of django_admin Group is, but he got not the admin-page.
what is wrong?
Thx
I resolve the problem by myself.
User must be member in cn=django_admin.. and cn=django_staff.. group. Now "Farmer Nick" can login. Ich changed the row "is_staff" to "is_staff": "django_admin..." and all things would be ok.
I've Patient, Doctor, Story Model. Each Story have a patient_id and a doctor_id. I want to retrieve a list of doctors the patient have visited ever.
class Patient(Person):
def visits(self):
doctor_visits = []
for v in self.stories.values('doctor').annotate(visits=Count('doctor')):
# replace the doctor id with doctor object
v['doctor'] = Doctor.objects.get(id=v['doctor'])
doctor_visits.append(v)
return doctor_visits
Here is my tastypie Resource
class PatientResource(ModelResource):
stories = fields.ToManyField('patients.api.StoryResource', 'stories', null=True)
visits = fields.ListField(attribute='visits', readonly=True)
class Meta:
queryset = Patient.objects.all()
excludes = ['id', 'login', 'password']
with the above tastypie results the following
{
address:"ADDRESS",
dob:"1985-12-04",
email:"EMAIL",
name:"Nogen",
resource_uri:"/patients/api/v1/patient/9/",
sex:"M",
stories:[
"/patients/api/v1/story/1/",
"/patients/api/v1/story/2/",
"/patients/api/v1/story/4/"
],
visits:[
{
doctor:"Dr. X",
visits:2
},
{
doctor:"Dr. Y",
visits:1
}
]
}
See Its caling the __unicode__ method of Doctor rather I expected this to be a link /patients/api/v1/doctor/<doctor_id>/ Do I need to construct the path manually or There is some other way around ?
I've tried using dehydrate possibly incorrectly
class PatientResource(ModelResource):
stories = fields.ToManyField('patients.api.StoryResource', 'stories', null=True)
visits = fields.ListField(attribute='visits', readonly=True)
class Meta:
queryset = Patient.objects.all()
excludes = ['id', 'login', 'password']
def dehydrate_visits(self, bundle):
for visit in bundle.data['visits']:
visit['doctor'] = DoctorResource(visit['doctor'])
return bundle
Which Results in maximum recursion depth exceeded while calling a Python object Exception
Not sure why you get maximum recursion depth but your method is wrong.
class PatientResource(ModelResource):
[...]
def dehydrate_visits(self, bundle):
# Make sure `bundle.data['visits'][0]['doctor'] isn't string.
# If it's already dehydrated string: try use `bundle.obj.visits` instead.
for visit in bundle.data['visits']:
visit['doctor'] = DoctorResource.get_resource_uri(visit['doctor'])
return bundle
I didn't test that. So fill free to comment if its incorrect.