Tickets anonymisieren

Hilfe zu Znuny Problemen aller Art
Locked
zora
Znuny newbie
Posts: 3
Joined: 26 Nov 2009, 14:44
Znuny Version: 2.4

Tickets anonymisieren

Post by zora »

Hallo,

ich habe ein kleines Skript zum Anonymisiseren von Tickets geschrieben, das ich hier mal vorstellen möchte.
OTRS selbst sieht ja aus Revisionsgründen nicht vor Kundendaten zu löschen. Aus Datenschutzgründen bin ich jedoch gehalten, Daten von ehemaligen Kunden nicht länger als unbedingt notwendig zu speichern. Da wir über keinen festen sondern über einen stark fluktuierenden Kundenstamm verfügen, wäre das manuelle Entfernen einzelner Kunden und ihrer Daten viel zu aufwendig.

Das Skript wird über den GenericAgent aufgerufen und auf alle Tickets angewendet, die seit 3 Monaten geschlossen sind. Es geht wie folgt vor:

1. löscht alle Artikel (Email, Anruf, Notiz) des Tickets inklusive Anhänge, abgesehen vom "Eröffnungsartikel"
2. prüft, ob der Kunde noch weitere Tickets im System hat
3. wenn dies nicht der Fall ist, löscht es den Kunden aus dem System
4. löscht es die Kundenverankerung und das evtl. Aktenzeichen aus dem Ticket
5. trägt die Aktion in die Tickethistory ein

Code: Select all

 #!/usr/bin/perl -w
 # --
 # uld.makeTicketAnonymous - a script addressed by GenericAgent to make Tickets anonymous
 # Copyright (C) 2010 ULD SH, http://www.datenschutzzentrum.de/
 # --
 # $Id: uld.makeTicketAnonymous,v 1.0 2010/01/27 11:22:17 tr Exp $
 # --
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU AFFERO General Public License as published by
 # the Free Software Foundation; either version 3 of the License, or
 # any later version.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 # or see http://www.gnu.org/licenses/agpl.txt.
 # --
 
 use strict;
 use warnings;
 
 # use ../ as lib location
 use File::Basename;
 use FindBin qw($RealBin);
 use lib dirname($RealBin);
 use lib dirname($RealBin) . "/Kernel/cpan-lib";
 
 use vars qw($VERSION);
 $VERSION = qw($Revision: 1.14 $) [1];
 
 use Kernel::Config;
 use Kernel::System::Encode;
 use Kernel::System::Time;
 use Kernel::System::Log;
 use Kernel::System::Main;
 use Kernel::System::DB;
 use Kernel::System::Ticket;
 use Kernel::System::User;
 use Kernel::System::Ticket::ArticleStorageDB;
 
 # common objects
 my %CommonObject = ();
 $CommonObject{ConfigObject} = Kernel::Config->new();
 $CommonObject{EncodeObject} = Kernel::System::Encode->new(%CommonObject);
 $CommonObject{LogObject}    = Kernel::System::Log->new(LogPrefix => 'OTRS-getTicketThread', %CommonObject,);
 $CommonObject{TimeObject}   = Kernel::System::Time->new(%CommonObject);
 $CommonObject{MainObject}   = Kernel::System::Main->new(%CommonObject);
 $CommonObject{DBObject}     = Kernel::System::DB->new(%CommonObject);
 $CommonObject{TicketObject} = Kernel::System::Ticket->new(%CommonObject);
 $CommonObject{UserObject}   = Kernel::System::User->new(%CommonObject);
 
 # -- get TicketID from CMD, generate TicketObject
 my $TicketID = shift || die 'Got no ARG[0]';
 my %Ticket = $CommonObject{TicketObject}->TicketGet( TicketID => $TicketID );
 
 # -- get UserID
 my $SQL = "SELECT user_id FROM ticket WHERE id = $TicketID";
    $CommonObject{DBObject}->Prepare(SQL => $SQL);
 my @Row = $CommonObject{DBObject}->FetchrowArray();
 
 
 # -- get articles to ticket in Array ArticleBox
 my @ArticleBox = $CommonObject{TicketObject}->ArticleGet(TicketID => $Ticket{TicketID});
 
 # -- first article shall be left as base ticketinfo
 if ( @ArticleBox > 1 ) {
    shift @ArticleBox;
 
    foreach my $Article ( @ArticleBox ) {
       # -- deletes articles and attachments - also the base ticketinfo!!! => ignore the smallest article_id (shift)
       my $Email = $CommonObject{TicketObject}->ArticleDelete(ArticleID => $Article->{ArticleID}, UserID => '$UserID');
    }
 }
 
 # -- check if customer_user has further tickets
 # -- customer_company is not used in our case
 $SQL = "SELECT id FROM ticket WHERE customer_id = '$Ticket{CustomerUserID}'";
    $CommonObject{DBObject}->Prepare(SQL => $SQL);
 
 my $Counter = 0;
 while ( @Row = $CommonObject{DBObject}->FetchrowArray() ) {
    $Counter++;
 }
 
 if ( $Counter == 1 ) {
    # -- customer_user has no further tickets, customerinfos should  be deleted
    $SQL = "DELETE FROM customer_user WHERE login = '$Ticket{CustomerUserID}'";
    $CommonObject{DBObject}->Do(SQL => $SQL);
 }
 
 # -- make ticket anonymos ( freetext3 is in our case the reference number )
 $SQL = "UPDATE ticket SET customer_user_id = NULL, customer_id = NULL, freetext3 = NULL WHERE id = $Ticket{TicketID}";
 $CommonObject{DBObject}->Do(SQL => $SQL);
 
 # -- HistoryAdd
 $CommonObject{TicketObject}->HistoryAdd(Name => '%%makeTicketAnonymous%%', 
                                         HistoryType => 'Misc', 
                                         TicketID => $Ticket{TicketID}, 
                                         CreateUserID => '1');
 
 1;
Da die Rumpfdaten des Tickets erhalten bleiben, können sie noch zu einfachen Statistikzwecken genutzt werden.

Vielleicht hat ja noch jemand Verwendung für das Skript oder Anregungen?
Testbetrieb: OTRS: 2.4.5
Echtbetrieb: OTRS::ITSM 1.3.1
OS: Ubuntu 8.04
Apache2/MySQL 5
ferrosti
Znuny superhero
Posts: 723
Joined: 10 Oct 2007, 14:30
Znuny Version: 3.0
Location: Hamburg, Germany

Tickets anonymisieren

Post by ferrosti »

Ich würde die Daten nicht auf NULL setzen. Die Kundennamen oder IDs würde ich generisch umwandeln, so dass man Vorgänge immer noch einem anonymen Kunden zuordnen kann. Für die Recherche ist es besser, wenn Informationen auf Personen Basis nachvollzogen werden können, auch wenn die Person nicht mehr identifiziert werden kann.
Nach Deinem Script ist es nicht mehr möglich z.B. eine durchschnittliche Anzahl an Tickets pro Kunde zu errechnen etc. Wenn nur der Kundenname und die ID anonymisiert werden, wäre dies kein Problem.
openSuSE on ESX
IT-Helpdesk: OTRS 3.0
Customer Service: OTRS 3.0 (upgraded from 2.3)
Customer Service (subsidiary): OTRS 3.0
+additional test and development systems
zora
Znuny newbie
Posts: 3
Joined: 26 Nov 2009, 14:44
Znuny Version: 2.4

Tickets anonymisieren

Post by zora »

ferrosti wrote:Nach Deinem Script ist es nicht mehr möglich z.B. eine durchschnittliche Anzahl an Tickets pro Kunde zu errechnen etc. Wenn nur der Kundenname und die ID anonymisiert werden, wäre dies kein Problem.
Stimmt. Aber solche Auswertungen sind bei uns auch generell nicht gestattet :D
Testbetrieb: OTRS: 2.4.5
Echtbetrieb: OTRS::ITSM 1.3.1
OS: Ubuntu 8.04
Apache2/MySQL 5
jojo
Znuny guru
Posts: 15020
Joined: 26 Jan 2007, 14:50
Znuny Version: Git Master
Contact:

Tickets anonymisieren

Post by jojo »

Hallo,

grundsätzlich passen Revisionssicherheit und Datenschutz leider nicht zusammen.

Bzgl. Deines Scripts: Du solltest nicht direkt in der Datenbank "rumpfuschen"... Ich würde versuchen das ganze per SOAP zu lösen und damit entsprechende Funktionen der OTRS API zu nutzen.

Was spricht eigentlich dagegen die Tickets zu löschen und vorher über Statistiken die Daten zu verdichten?
"Production": OTRS™ 8, OTRS™ 7, STORM powered by OTRS
"Testing": ((OTRS Community Edition)) and git Master

Never change Defaults.pm! :: Blog
Professional Services:: http://www.otrs.com :: enjoy@otrs.com
zora
Znuny newbie
Posts: 3
Joined: 26 Nov 2009, 14:44
Znuny Version: 2.4

Tickets anonymisieren

Post by zora »

Die Erhebung von statistischen Daten ist bei uns ebenfalls an hohe organisatorische Hürden geknüpft (Vier-Augen-Prinzip, Beteiligung Personalrat, nicht automatisiert). Sie wird also vorraussichtlich nur jährlich bzw. in Ausnahmefällen möglich sein.
Daher ist es einfacher, technisch eine "gesäuberte" Datenbasis bereitzuhalten.

Der Hinweis mit SOAP ist berechtigt. Da ich mich damit überhaupt nicht auskenne, war es nicht meine erste Wahl...
Testbetrieb: OTRS: 2.4.5
Echtbetrieb: OTRS::ITSM 1.3.1
OS: Ubuntu 8.04
Apache2/MySQL 5
Locked