I'm developing an app for adding a contact detail to google contacts using gdata and python. I can add a contact to "Other contacts" group but not to My Contact System Group.
here is the coding so far
def CreateMenu(self,nm,tp,em):
new_contact = gdata.contacts.data.ContactEntry(name=gdata.data.Name(full_name=gdata.data.FullName(text=nm)))
new_contact.phone_number.append(gdata.data.PhoneNumber(text=tp, primary='true', rel=gdata.data.WORK_REL))
new_contact.email.append(gdata.data.Email(address=em, rel=gdata.data.WORK_REL))
entry = self.gd_client.CreateContact(new_contact)
if entry:
print 'Creation successful!'
print 'ID for the new contact:', entry.id.text
else:
print 'Upload error.'
I found the solution:
feed = gd_client.GetGroups()
group = filter(lambda g: g.title.text == 'System Group: My Contacts', feed.entry)[0]
gmeminfo = gdata.contacts.data.GroupMembershipInfo(href=group.get_id())
new_contact.group_membership_info.append(gmeminfo)
Related
when a new AWS Account gets created or migrated into our environment the details get put into a DynamoDB, below is an example of the details of stored in the DDB:
{'Count': 57,
'Items': [{'AccountId': 'Account Number Here',
'AccountName': 'Account Name Here',
'Arn': 'arn:here',
'Email': 'email#somecompany.com',
'MainAccount': 'The Main Billing Account',
'Type': 'prod'},
}
I'm wondering if there is some way, I can possibly scan the DDB then when a new entry is added create a CloudWatch billing alarm using my code below, I understand this will need modifying and I'll admit this is very manual and not very automated, which is why I'm enquiring here:
import boto3
my_profile = input(
"Please input the profile name you will use stored in ~\.aws\config: \n"
)
sess = boto3.Session(profile_name=my_profile, region_name="us-east-1")
# US-East-1 as that is where Billing Alarms are handled.
sns_name = input("Enter SNS Topic name with no spaces, you can use underscores: \n")
sns_client = sess.client("sns")
# Creates SNS Topic
result = sns_client.create_topic(Name=sns_name)
for value in result.values():
print(value)
topic_arn = input(
"Copy & Paste Topic ARN from printed result above including arn: : \n"
)
print("Topic Created..")
subscribe_endpoint = input("Enter an email address for the subscription: \n")
print("Subscription created, check your emails and confirm the subscription.")
# Creates Subscription & Sets up email protocol for that particular topic, ammend Topic Arn from previous SNS topic and change enpoint to respective email address.
sns_client.subscribe(
TopicArn=topic_arn, # Grab ARN from list_topics API call.
Protocol="email",
Endpoint=subscribe_endpoint, # Input email address here
ReturnSubscriptionArn=True,
)
cw = sess.client("cloudwatch")
alarm_name = input("Enter an alarm name: \n")
alarm_desc = input("Enter an alarm description: \n")
alarm_threshold = int(input("Enter the alarm threshold in integer values: \n"))
if alarm_threshold == "":
print("please enter integer values only")
exit()
metrics_id = input("Please enter a metric ID,: \n")
linked_account_id = input(
"Please type the account ID in reference to your billing alarm, please note it can take 24hrs for this to appear if recently migrated: \n"
)
# Below creates the alarm, change Name, Description, Threshold and LinkedAccount & Label
cw.put_metric_alarm(
AlarmName=alarm_name,
ActionsEnabled=True,
MetricName="EstimatedCharges",
Namespace="AWS/Billing",
Statistic="Maximum",
Dimensions=[
{"Name": "Currency", "Value": "USD"},
{"Name": "LinkedAccount", "Value": linked_account_id},
],
Period=21600,
AlarmDescription=alarm_desc,
AlarmActions=[topic_arn],
EvaluationPeriods=1,
DatapointsToAlarm=1,
Threshold=alarm_threshold,
ComparisonOperator="GreaterThanOrEqualToThreshold",
TreatMissingData="missing",
)
print("\n")
print(
f"Alarm: {alarm_name} has been created, actioning on topic {topic_arn}. The threshold is {alarm_threshold} to linked account {linked_account_id}, an Email will be sent to {subscribe_endpoint} if this threshold is breached/exceeded."
)
I appreciate the code relies on User Input, however if there is some way to generalize or grab some information from the DDB and use it similar to below:
sns_name = #This can relate to the account name Maybe "AccName_SNS_Topic"
topic_arn = "the topic arn" #I'm fairly new to Python
# so I'm not sure how to pull the exact topic arn from it once it's created and stored
# in the variable.
subscribe_endpoint = "The email address linked to the account in DDB"
alarm_name = "AccountName - Dev or Prod (Stored in type on DDB) - Billing Alarm"
alarm_desc = "As above"
alarm_threshold = 700
# We can skip metrics ID, I don't think we actually need it
linked_account_id = "Account Number stored in AccountId in DDB"
The end goal is to be able to get this into a lambda with an event bridge or something similar. Please note some accounts already have billing alarms set so it would only be for new accounts only. I appreciate any advice or input you may be able to assist me with, Thanks in advance.
I am trying to create a service account via the Ldap3 library in Python. The service account is successfully created, but there is a small problem. The "User cannot change password" checkboxes is not selected.
I did some research and found that to set this property I need to follow some steps given here : https://learn.microsoft.com/en-us/windows/win32/adsi/modifying-user-cannot-change - password-ldap-provider . The logic given in this link is in a different programming language than Python, so i tried to replicate the same logic in Python. From what we understand, I’ve implemented the feature, which executed successfully, but didn't see the expected effect on the AD server ("User cannot change password" checkbox is still unchecked).
Below is the code used to create and add the ACL object to the service account.
def create_object_ace(privguid, sid):
print("creating ace object")
nace = ldaptypes.ACE()
nace['AceType'] = ldaptypes.ACCESS_DENIED_OBJECT_ACE.ACE_TYPE
nace['AceFlags'] = 0x00
acedata = ldaptypes.ACCESS_DENIED_OBJECT_ACE()
acedata['Mask'] = ldaptypes.ACCESS_MASK()
acedata['Mask']['Mask'] = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_CONTROL_ACCESS
acedata['ObjectType'] = string_to_bin(privguid)
acedata['InheritedObjectType'] = b''
acedata['Sid'] = ldaptypes.LDAP_SID()
acedata['Sid'].fromCanonical(sid)
assert sid == acedata['Sid'].formatCanonical()
acedata['Flags'] = ldaptypes.ACCESS_DENIED_OBJECT_ACE.ACE_OBJECT_TYPE_PRESENT
nace['Ace'] = acedata
return nace
s = Server('ad_server.com', get_info=ALL)
c = Connection(s, user="testdomain\\username", password="password", authentication=NTLM)
c.search(search_base="DC=testad,DC=com", search_filter="(CN=svc_account_47)",
search_scope=SUBTREE, attributes=['objectSid', 'sAMAccountName'])
entry = c.entries[0]
usersid = entry['objectSid'].value
controls = security_descriptor_control(sdflags=0x04)
c.search(search_base="DC=testahs,DC=com", search_filter='(&(objectCategory=domain))',
attributes=['SAMAccountName', 'nTSecurityDescriptor'], controls=controls)
entry = c.entries[0]
secDescData =. entry['nTSecurityDescriptor'].raw_values[0]
secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData)
secDesc['Dacl']['Data'].append(create_object_ace('ab721a53-1e2f-11d0-9819-00aa0040529b', usersid)) # This GUID is for 'User cannot change password'
dn = entry.entry_dn
data = secDesc.getData()
c.modify(dn, {'nTSecurityDescriptor': (ldap3.MODIFY_REPLACE, [data])}, controls=controls)
print(c.result)
# gives -> {'result': 0, 'description': 'success', 'dn': '', 'message': '', 'referrals': None, 'type': 'modifyResponse'}
The Python code reference is from the following link:
https://github.com/SecureAuthCorp/impacket/blob/master/impacket/examples/ntlmrelayx/attacks/ldapattack.py
Can someone help me here. Thanks in advance.
New to Python and am working on a task my friend gave me. The objective for this portion is to find user information that was previously added to a dictionary. I am trying to find a way that if the user is searching for a particular user, only that user's info will be returned. So far this is the code I have for this portion of the project:
selection = input('Please select an option 1 - 4:\t')
if selection == '1':
print('Add user - Enter the information for the new user:\t')
first_name = input('First name:\t')
last_name = input('Last name:\t')
hair_color = input('Hair color:\t')
eye_color = input('Eye color:\t')
age = input('Age:\t')
user_info = {}
user_info['First name'] = first_name
user_info['Last name'] = last_name
user_info['Hair color'] = hair_color
user_info['Eye color'] = eye_color
user_info['Age'] = age
Skipping code for sake of space on post
if selection == '3':
print('\nChoose how to look up a user')
print('1 - First name')
print('2 - Last name')
print('3 - Hair color')
print('4 - Eye color')
print('5 - Age')
print('6 - Exit to main menu\n')
search_option = input('Enter option:\t')
if search_option == '1' or search_option == 'First name' or search_option == 'first name':
input('Enter the first name of the user you are looking for:\t')
Any and all help is much appreciated!!
Depending on your project, using a dictionary might be difficult in the future. Let's not go down a dark road. Take a moment and assess the situation.
We know that we want to collect some information from the user, such as:
first name
last name
hair color
...etc
We also want to store the User object to retrieve later based on a particular ID. In your code, you search for other users based on attributes, but what if two or more users share the same attribute, for example, first name?
What your asking for are attributes associated with a particular user. Why not create a class called User?
class User:
def __init__(self, id, first_name, last_name, hair_color):
# You can also check if any attributes are blank and throw an exception.
self._id = id
self._first_name = first_name
self._last_name = last_name
self._hair_color = hair_color
# add more attributes if you want
# a getter to access the self._id property
#property
def id(self):
return self._id
def __str__(self):
return f"ID: {self._id} Name: {self._first_name} {self._last_name}
Hair Color: {self._hair_color}"
In your main function, you can now ask for the user details and store them in a class which you can append to a List.
from User import User
def ask_for_input(question):
answer = input(question)
return answer.strip() # strip any user created white space.
def main():
# Store our users
users = []
# Collect the user info
id = ask_for_input(question = "ID ")
first_name = ask_for_input(question = "First Name ")
last_name = ask_for_input(question = "Last Name ")
hair_color= ask_for_input(question = "Hair Color ")
# Create our user object
user = User(id=id, first_name=first_name, last_name=last_name, hair_color=hair_color)
print(user)
# accessing the id property
print(user.id)
users.append(user)
if __name__ == '__main__':
main()
You may also want to improve on the above class, for example, error checking, and adding type hints to make the code more readable.
If you're just storing the user information, a data class might be more appropriate.
If your looking for a broad suggestion, you could use mongob, it makes a great way to store data to be retrieved later, here is an example i built for another question. The prerequisites is that you'd have to get the mongod server running before you can use the pip install:
Here is an example of how to get it going and how easy it easy to retrieve data like yours
pip3 install pymongo
from pymongo import MongoClient
client = MongoClient()
client = MongoClient('localhost', 27017)
db = client.pymongo_test
posts = db.posts
post_data = {
'title': 'The title of this post',
'content': 'pymongo is awesome',
'author': 'Bill'
}
result = posts.insert_one(post_data)
print('One post: {0}'.format(result.inserted_id))
bills_post = posts.find_one({'author': 'Bill'})
print(bills_post)
#One post: 5dc61c0cc2b75ebc458da31f
#{'_id': ObjectId('5dc61bf76071bde943ca262b'), 'title': 'The title of this post', 'content': 'pymongo is awesome', 'author': 'Bill'}
I cannot create a simple Ad with an external link to a mobile app. I have properly set access, can create a Campaign, an AdSet, load an image, but during an Ad creation I get an error:
Ads and ad creatives must be associated with a Facebook Page. Try connecting your ad or ad creative to a Page and resubmit your ad.
But I have associated a page! Here is my code:
# No problem with these ones
adset = ...
image_hash = '...'
url = 'https://itunes.apple.com/app/96...'
page_id = '25036...'
# Create an Ad Creative
creative = AdCreative()
creative['_parent_id'] = my_ads_acc_id
creative[AdCreative.Field.title] = 'Aivan Test Creative'
creative[AdCreative.Field.body] = 'Aivan Test Ad Creative Body'
creative[AdCreative.Field.actor_id] = page_id
creative[AdCreative.Field.link_url] = url
creative[AdCreative.Field.object_url] = url
creative[AdCreative.Field.object_type] = AdCreative.ObjectType.domain
creative[AdCreative.Field.call_to_action_type] = AdCreative.CallToActionType.use_mobile_app
creative[AdCreative.Field.image_hash] = image_hash
# Create an Ad
ad = Ad()
ad['_parent_id'] = my_ads_acc_id
ad[Ad.Field.name] = 'Aivan Ad'
ad[Ad.Field.adset_id] = adset[AdSet.Field.id]
ad[Ad.Field.creative] = creative
# This line generates an exception:
ad.remote_create(params={
'status': Ad.Status.paused,
})
I have specified the actor_id field, also I have tried other different code samples, but nothing works well. How can I connect a page?
Additional info:
My app is in development mode. I cannot turn the production mode because it needs a review which needs a completed app.
I have tried to use object_story_spec with link_data in it, but it creates other error because it doesn't work in development mode.
The app and the page are linked with Facebook Business Manager.
The results is the same if I init the API with app token or system user token: FacebookAdsApi.init(app_id, app_secret, app_access_token / system_user_token). The system user has access to both Ads Account and the Page.
I've solved the problem a long time ago, and since that time my server app successfully created lots of Facebook ads of both types, for websites and mobile apps. The first step to solve the problem was to understand that these ads types are completely different on Facebook, they need different settings for Campaign, AdSet & Ad. Here is my code for mobile ads creation.
1) Create Campaign object. account_id must be the ID of your Ad Account.
campaign = Campaign()
campaign['_parent_id'] = account_id
campaign[Campaign.Field.name] = 'Some Campaign Name'
campaign[Campaign.Field.objective] = 'APP_INSTALLS'
campaign.remote_create()
campaign_id = str(campaign[Campaign.Field.id])
2) Create AdSet object.
adset = AdSet()
adset['_parent_id'] = account_id
adset.update({
AdSet.Field.name: 'Some AdSet Name',
AdSet.Field.campaign_id: campaign_id,
AdSet.Field.lifetime_budget: budget * 100,
AdSet.Field.bid_strategy: 'LOWEST_COST_WITHOUT_CAP',
AdSet.Field.billing_event: AdSet.BillingEvent.link_clicks,
AdSet.Field.optimization_goal: AdSet.OptimizationGoal.link_clicks,
AdSet.Field.promoted_object: {
'object_store_url': app_store_url,
'application_id': ad_app_id,
},
AdSet.Field.targeting: targeting_object,
AdSet.Field.start_time: '2018-12-01 00:00:00',
AdSet.Field.end_time: '2018-12-30 23:59:00',
})
adset.remote_create()
adset_id = str(adset[AdSet.Field.id])
Note that to create mobile ad, you initially need to register your mobile app as a Facebook app (here you will get ad_app_id) and specify links to Apple App Store and Google Play Market. So, the value of app_store_url must be equal to one of those links in your Facebook app settings. Unfortunately, app can be registered only manually (if you know how to do it programmatically – write a comment, please).
Also note that billing_event and optimization_goal are connected with ads type (mobile/web) and with each other, you cannot just choose another one. (But if you know that this is possible, or there are some docs on this topics – let me know.)
budget is a money amount in the currency of your Ad Account. You can specify either lifetime_budget or something like day_budget, read the docs about it.
3) Then, you have to create AdCreative object with some other sub objects. Note that some of these lines of code are necessary for FB ad only, others for IG, others for both of them, but together they work well for everything. You can find description for all the formats here.
link_data = AdCreativeLinkData()
link_data[AdCreativeLinkData.Field.name] = main_text
link_data[AdCreativeLinkData.Field.message] = title
link_data[AdCreativeLinkData.Field.link] = app_store_url
link_data[AdCreativeLinkData.Field.image_hash] = image_hash
link_data[AdCreativeLinkData.Field.call_to_action] = {
'type': 'INSTALL_MOBILE_APP',
'value': {
'application': ad_app_id,
'link': app_store_url,
},
}
object_story_spec = AdCreativeObjectStorySpec()
object_story_spec[AdCreativeObjectStorySpec.Field.page_id] = page_id
object_story_spec[AdCreativeObjectStorySpec.Field.link_data] = link_data
creative = AdCreative()
creative['_parent_id'] = account_id
creative[AdCreative.Field.object_story_spec] = object_story_spec
creative[AdCreative.Field.title] = main_text
creative[AdCreative.Field.body] = title
creative[AdCreative.Field.actor_id] = page_id
creative[AdCreative.Field.link_url] = app_store_url
creative[AdCreative.Field.image_hash] = image_hash
To upload an image and get image_hash, check out this doc. The page_id must be an ID of the page which name and logo will be shown as the author of the ad.
You must note that the user, who creates the ad, must have an access to this page, to the mobile app registered on FB (ad_app_id), and to the Ad Account (account_id). In my server application I use Facebook system users for all the work with API.
4) And finally, create the Ad object itself:
ad = Ad()
ad['_parent_id'] = account_id
ad[Ad.Field.name] = 'Some Ad Name'
ad[Ad.Field.adset_id] = adset_id
ad[Ad.Field.creative] = creative
ad.remote_create(params={
'status': Ad.Status.active,
})
ad_id = str(ad[Ad.Field.id])
That's all!
Maybe someone will need to use or just want to see the difference when creating FB/IG ads for websites, it is a little bit simpler. So, here is my code for website ads creation.
1) Create Campaign object. Notice that website ads has a different objective. account_id must be the ID of your Ad Account.
campaign = Campaign()
campaign['_parent_id'] = account_id
campaign[Campaign.Field.name] = 'Some Campaign Name'
campaign[Campaign.Field.objective] = 'LINK_CLICKS'
campaign.remote_create()
campaign_id = str(campaign[Campaign.Field.id])
2) Create AdSet object. Note that billing_event and optimization_goal are connected with ads type (mobile/web) and with each other. Also, here you don't need to specify promoted_object in the AdSet.
adset = AdSet()
adset['_parent_id'] = account_id
adset.update({
AdSet.Field.name: 'Some AdSet Name',
AdSet.Field.campaign_id: campaign_id,
AdSet.Field.lifetime_budget: budget * 100,
AdSet.Field.bid_strategy: 'LOWEST_COST_WITHOUT_CAP',
AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
AdSet.Field.targeting: targeting_object,
AdSet.Field.start_time: '2018-12-01 00:00:00',
AdSet.Field.end_time: '2018-12-30 23:59:00',
})
adset.remote_create()
adset_id = str(adset[AdSet.Field.id])
Rules for budget are the same: budget is a money amount in the currency of your Ad Account. You can specify either lifetime_budget or something like day_budget, read the docs about it.
3) Then, you have to create AdCreative object with some other sub objects. You can find description for all the formats here.
link_data = AdCreativeLinkData()
link_data[AdCreativeLinkData.Field.name] = main_text
link_data[AdCreativeLinkData.Field.message] = title
link_data[AdCreativeLinkData.Field.link] = website_url
link_data[AdCreativeLinkData.Field.image_hash] = image_hash
object_story_spec = AdCreativeObjectStorySpec()
object_story_spec[AdCreativeObjectStorySpec.Field.page_id] = page_id
object_story_spec[AdCreativeObjectStorySpec.Field.link_data] = link_data
creative = AdCreative()
creative['_parent_id'] = account_id
creative[AdCreative.Field.object_story_spec] = object_story_spec
creative[AdCreative.Field.title] = main_text
creative[AdCreative.Field.body] = title
creative[AdCreative.Field.actor_id] = page_id
creative[AdCreative.Field.link_url] = website_url
creative[AdCreative.Field.object_type] = AdCreative.ObjectType.domain
creative[AdCreative.Field.image_hash] = image_hash
To upload an image and get image_hash, check out this doc. The page_id must be an ID of the page which name and logo will be shown as the author of the ad. Note that the user, who creates the ad, must have an access to this page, to the mobile app registered on FB (ad_app_id), and to the Ad Account (account_id).
4) And finally, create the Ad object itself:
ad = Ad()
ad['_parent_id'] = account_id
ad[Ad.Field.name] = 'Some Ad Name'
ad[Ad.Field.adset_id] = adset_id
ad[Ad.Field.creative] = creative
ad.remote_create(params={
'status': Ad.Status.active,
})
ad_id = str(ad[Ad.Field.id])
As you can see, to promote websites you don't need to register them on Facebook (in contrast to mobile ads).
In python xmpp module, I'm able to retrieve the nickname of any contacts as follows:
self.connection.auth(userJid.getNode(), self.password)
self.roster = self.connection.getRoster()
name = self.roster.getName(buddyJid)
..where buddyJid is of the form user#gmail.com.
Now, I need to retrieve the nickname of the user who authenticates the connection (userJid). I cannot find the name using the above method.
Which method can I use retrieve the name of the current user?
This information is not in the roster. You will need to query the clients individually and get their vCard by sending this IQ :
<iq from='stpeter#jabber.org/roundabout'
id='v1'
type='get'>
<vCard xmlns='vcard-temp'/>
</iq>
Thank you nicholas_o, this is a sample function I put together based your suggestion. (The XML logic isn't ideal, but it was sufficient for the simple task I needed this for)
def vcard(disp, jid):
msg = xmpp.protocol.Iq()
msg.setType('get')
msg.setTo(jid)
qc = msg.addChild('vCard')
qc.setAttr('xmlns', 'vcard-temp')
rep = disp.SendAndWaitForResponse(msg)
# to see what other fields are available in the XML output:
# print rep
userid=fname=lname=title=department=region=None
for i in rep.getChildren():
for j in i.getChildren():
if j.getName() == "TITLE":
title = j.getData().encode('utf-8')
for k in j.getChildren():
if k.getName() == "GIVEN":
fname = k.getData().encode('utf-8')
if k.getName() == "FAMILY":
lname = k.getData().encode('utf-8')
if k.getName() == "ORGUNIT":
department = k.getData().encode('utf-8')
if k.getName() == "REGION":
region = k.getData().encode('utf-8')
return fname, lname, title, department, region