Unable to Delete Multiple users from LDAP with Ldap3 Python - python-3.7

I am writing a python script that deletes all the users under an OU.
ou=people,cn=AdministrativeLdap,cn=Windchill_11.0,o=ptc.
I am trying to delete the entries by performing the following code but it fails with error " cannot be removed because it has subordinate entries", 'referrals': None, 'type': 'delResponse"
Is there a way by which I can remove the entries alone?
Thank you so much!
from ldap3 import Server, Connection, ALL
s = Server('<IP-ADDRESS>', get_info=ALL)
print(s)
c = Connection(s, user='xxxxxx', password='xxxxxxxxxx')
c.bind()
c.delete('ou=people,cn=AdministrativeLdap,cn=Windchill_11.0,o=ptc',force=True)
print(c.result)
c.unbind()

In LDAP you can’t delete a “container” object if it contains other object. The DELETE operation expect a single object to delete. You have to remove each object with delete(). Only when the container object doesn’t contain any other object it can be removed.
You can also try the Subtree Delete Control that lets you remove a whole branch of the LDAP tree, but you must check if your ldap server supports it.

Related

Automatically download emails from Outlook with SAS or Outlook rule

I am trying to create a program to automatically download the attached files that are sent to us from a certain email and then transform the delimiter with SAS, of those csv that are attached to us and pass those csv through a flow that I have already created.
I have managed to create a program that treats the csv as I want and the delimiter that I want, the problem is that when it comes to automating the download of files from Outlook it does not work.
What I have done is create a rule with the following VB code that I found on the internet:
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "C:\Users\ES010246\Desktop"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
I have changed the path to my personal path where i want the files are downloaded.
website: https://es.extendoffice.com/documents/outlook/3747-outlook
The problem is that this code does not work for me, it does absolutely nothing for me and no matter how much I search the internet, only this code appears.
Is there any other way to do with SAS what I want? What is it to automatically download 8 csv files sent to me by Outlook, or has someone experienced the same thing as me with VBA?
I have followed all the steps about 7 times so I think the error is not in copying the code or selecting certain options wrong, in fact I had copied and pasted the code and later I modified the path where I wanted those to be saved. files but it doesn't work, does anyone know why?
I will be tremendously grateful, thank you very much for everything!
First of all, you need to make sure the file name and path doesn't include forbidden symbols.
The VBA macro used for a rule in Outlook is absolutely valid except that a mail item may contain the attached files with the same name, so a file saved to the disk may be overwritten (saved with the same name). That's why I'd suggest generating a file name with your own unique IDs making sure that DisplayName property is not empty and has a valid name what can be used for file names (exclude forbidden symbols).
Also you may consider handling the NewMailEx event of the Application class which is fired when a new message arrives in the Inbox and before client rule processing occurs. Use the Entry ID returned in the EntryIDCollection string to call the NameSpace.GetItemFromID method and process the item. This event fires once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem.
The Items.ItemAdd event can be helpful when items are moved to a folder (from Inbox). This event does not run when a large number of items are added to the folder at once.

JupyterHub populate user home with notebooks (and data)

I have a JupyterHub server hosted on an Ubuntu machine.
(Mainly) since I want to avoid adding hundreds of potential users to the machine I opted to use c.JupyterHub.authenticator_class = 'jupyterhub.auth.DummyAuthenticator' (with a password)
The Spawner I use is
c.JupyterHub.spawner_class = 'jupyterhub.spawner.SimpleLocalProcessSpawner' although I also tried 'jupyterhub.spawner.LocalProcessSpawner'.
I want users to have some pre-populated notebooks once they log in.
I first tried https://tljh.jupyter.org/en/latest/howto/content/share-data.html putting the data in /etc/skel put it wasn't copied.
Then, according to various docs I could set c.Spawner.pre_spawn_hook = populate_user_home (tried also c.SimpleLocalProcessSpawner.pre_spawn_hook = populate_user_home) and have that method copy the files I want over to the user's home.
The method I have looks something like:
def populate_user_home(spawner):
username = spawner.user.name
# DummyAuthenticator creates users in /tmp
volume_path = os.path.join('/tmp', username)
if not os.path.exists(volume_path):
os.mkdir(volume_path, 0o777)
copyDirectory(<path_to_tutorials>, os.path.join(volume_path, 'tutorials'))
Problem is that this method is never called!
What am I doing wrong?
Is there another (simpler?) way to populate the home of new users?
The problem was not pre_spawn_hook, but several other small issues.
Calling print in the hook's code doesn't reach the log. Method was called.
Apparently SimpleLocalProcessSpawner creates the user folder before calling the hook, so copy was never called
the os.mkdir actually causes copytree to fail because dest folder exists

How does one keep an Elasticsearch index up-to-date using elasticsearch-dsl-py?

I developed a small personal information directory that my client accesses and updates through a Django admin interface. That information needs to be searchable, so I set up my Django site to keep that data in a search index. I originally used Haystack and Whoosh for the search index, but I recently had to move away from those tools, and switched to Elasticsearch 5.
Previously, whenever anything in the directory was updated, the code simply cleared the entire search index and rebuilt it from scratch. There's only a few hundred entries in this directory, so that wasn't onerously non-performant. Unfortunately, attempting to do the same thing in Elasticsearch is very unreliable, due to what I presume to be a race-condition of some sort in my code.
Here's the code I wrote that uses elasticsearch-py and elasticsearch-dsl-py:
import elasticsearch
import time
from django.apps import apps
from django.conf import settings
from elasticsearch.helpers import bulk
from elasticsearch_dsl.connections import connections
from elasticsearch_dsl import DocType, Text, Search
# Create the default Elasticsearch connection using the host specified in settings.py.
elasticsearch_host = "{0}:{1}".format(
settings.ELASTICSEARCH_HOST['HOST'], settings.ELASTICSEARCH_HOST['PORT']
)
elasticsearch_connection = connections.create_connection(hosts=[elasticsearch_host])
class DepartmentIndex(DocType):
url = Text()
name = Text()
text = Text(analyzer='english')
content_type = Text()
class Meta:
index = 'departmental_directory'
def refresh_index():
# Erase the existing index.
try:
elasticsearch_connection.indices.delete(index=DepartmentIndex().meta.index)
except elasticsearch.exceptions.NotFoundError:
# If it doesn't exist, the job's already done.
pass
# Wait a few seconds to give enough time for Elasticsearch to accept that the
# DepartmentIndex is gone before we try to recreate it.
time.sleep(3)
# Rebuild the index from scratch.
DepartmentIndex.init()
Department = apps.get_model('departmental_directory', 'Department')
bulk(
client=elasticsearch_connection,
actions=(b.indexing() for b in Department.objects.all().iterator())
)
I had set up the Django signals to call refresh_index() whenever a Department got saved. But refresh_index() was frequently crashing due this error:
elasticsearch.exceptions.RequestError: TransportError(400, u'index_already_exists_exception', u'index [departmental_directory/uOQdBukEQBWvMZk83eByug] already exists')
Which is why I added that time.sleep(3) call. I'm assuming that the index hasn't been fully deleted by the time DepartmentIndex.init() is called, which was causing the error.
My guess is that I've simply been going about this in entirely the wrong way. There's got to be a better way to keep an elasticsearch index up-to-date using elasticsearch-dsl-py, but I just don't know what it is, and I haven't been able to figure it out through their docs.
Searching for "rebuild elasticsearch index from scratch" on google gives loads of results for "how to reindex your elasticsearch data", but that's not what I want. I need to replace the data with new, more up-to-date data from my app's database.
Maybe this will help: https://github.com/HonzaKral/es-django-example/blob/master/qa/models.py#L137-L146
Either way you want to have 2 methods: batch loading all of your data into new index (https://github.com/HonzaKral/es-django-example/blob/master/qa/management/commands/index_data.py) and, optionally, a synchronization using methods/or signals as mentioned above.

Powershell and Lotus Notes - How to extract user names with employees numbers?

I have specific problem. I need to extract domain names from active directory and combine them with employees numbers which are in Lotus Notes. I get the domain names with Get-QADUser (snapin from quest.com), that was no problem, but how to get the employees numbers and combine them? Thank you
Edit(18.5. 11:56): Now I'm using this script (posted by Christian) and I figured out how to get the name of LN database - right-click on DB in Lotus notes workspace, then application/properties.
# Create LN Object
$DomSession = New-Object -ComObject Lotus.NotesSession
# Initialize LN Object
# You'll be asking for LN password to your id
$DomSession.Initialize()
# Connect to Server, select db and display the name
$DomDatabase = $DomSession.GetDatabase("LN007","IT\HW.nsf")
Write-Host "Database open : " $DomDatabase.Title
# Open specific View (By Serial Number)
$DomView = $DomDatabase.GetView('Serial Number')
Write-Host "View read : " $DomView.Name
# Show number of documents
$DomNumOfDocs = $DomView.AllEntries.Count
Write-Host "Num of Docs : " $DomNumOfDocs
# Get First Document in the View
$DomDoc = $DomView.GetFirstDocument()
If you have access to the database and a Notes client, you can open the database in Notes Designer and review what views are available. You should then be able to find one or create one that contains the data you need.
If you don't have access to Lotus Notes, you're close enough with your powershell script that you can use the com API to get the information. The NotesDatabase object (i.e. $DomDatabase) has a Views property which will return NotesView objects. You can iterate over those and print out the names as a start. Likewise once you've found the view you want, you can access the columns within that view using the NotesView's Columns property.
You'll want to check out the COM api docs here for more help: http://blagoevgrad.court-bg.org/help/help85_designer.nsf/Main?OpenFrameSet (see the section LotusScript/COM/OLE Classes)
Depending on how comfortable you are with Powershell vs the com api, you could probably handle this a few ways, either by extracting all the documents in the view and getting the data out, or perhaps using the built in NotesView.GetDocumentByKey method that would act as a lookup in your script. With a view sorted on the key you're querying on (and set as your view's first column), you could call that method and get back the document with that key. Then use that NotesDocument object to retrieve any value within it (i.e. the employee name or number or whatever)
You can retrieve data from Lotus Notes using com object.
Suggested links:
http://davidmoravec.blogspot.it/2008/08/retrieve-data-from-lotus-notes-with.html
Lotus Notes comobject
Is the database you are opening called "names.nsf" by any chance? If so, that's the standard Domino Directory database and you should be using the "People" view, and the item name you are looking for should be "EmployeeID" -- unless the customer has customized the database with their own field names.
If it is a custom database you are working with, then in addition to using the Notes client and Domino Designer, get yourself a copy of NotesPeek. It's free. Download here
It gives you a tree view of the database. It shows you everything that is stored in the database -- but it only shows you what is stored, so computed fields that you can see in the Notes client but aren't accessible through the Notes classes won't confuse you. (The document properties dialog in the Notes client won't show you computed values either if you use it while you have a document selected in a view, but it will show them to you if you use while you have a document actually open.)

How to implement copy paste of a resource in REST?

How would you implement copy-paste support in a RESTful way?
Let's say I have book store resource. And books in every store
http://mydomain.com/rest/book-stores/1
http://mydomain.com/rest/book-stores/1/books/12
I need the client to be able to invoke copy paste of a book to another store.
Implementing the following:
PUT http://mydomain.com/rest/books/1/copy-paste
seems very RPC like. Do you have any suggestion how can this operation be modeled in a RESTful way?
Copy = GET http://mydomain.com/book/1
Paste = PUT http://mydomain.com/book/2 or POST http://mydomain.com/book
This is only a problem if your resources are organized to mimic a hierarchical system. Like a file system.
I prefer non-hierarchical resources. The "path" to a file would just be a property of the file. To copy-paste, there are two options.
If you really just want another "path" reference, add another entry for the "path" property. The same exact file is "in" both "folders".
If you need to new version of the file, effectively forking changes thereafter, create a new resource (different URI) with a different "path" property.
To move, just change the "path" property.
If you must insist on hierarchical, just mimic how a file system does copy-paste and move.
The copy is easy. A GET for the resource to copy.
To paste, a POST, because you are creating a new resource, a new URI.
If you need to do a move, you probably need to DELETE the old resource.
If you want, you can specify a location in the delete request, allowing the server to redirect users looking for the moved resource at its old location.
I would have it so that the user executes PUT command to execute the action.
So something like a variable in the form data is contains the correct action to perform.