# Theoriefrage : Programm-zugriffsrechte auf Netzlaufwerk



## Tallan (20. Aug 2009)

Hallo zusammen,
ich grüble grade über folgendem Problem.

Ich will ein Programm schreiben an dem sich mehrere User mit verschiedenen Berechtigungen anmelden können. Dieses Programm läuft auf einem Clientrechner und ist mit einer SQL - DB verbunden welche u.a Links auf Dateien in einem Netzlaufwerk (in diesem Fall wird Samba genutzt ) liegt.

Der User kann nun je nach berechtigung Dateien auf dem Netzlaufwerk öffnen.

Meine frage ist nun wie kann ich dem Programm selbst rechte an dem Netzlaufwerk geben die der User selbst aber nicht hat.


Beispiel :

Auf dem Server läuft MySql in der Tabelle stehen 2 links, auf a.pdf und b.pdf
Die beiden Dateien befinden sich im selben Ordner.
User1 soll a lesen können aber nicht b 
User2 soll b lesen können aber nicht a

Auf Clientseite läuft eine Javaanwendung die es ermöglicht die pdf dateien zu öffnen.

User1 logt sich ein, bekommt nur den link auf a.pdf
User2 logt sich ein und bekommt nur den link auf b.pdf

Problem :
Wie realisiere ich den Zugriff auf das Netzlaufwerk so, das es User1 nicht möglich ist b.pdf zu lesen.


----------



## sparrow (20. Aug 2009)

Über Dateirechte würde ich das gar nicht machen. Sprich: die Benutzer haben über das Dateisystem gar keinen Zugriff auf die Daten.
Entweder speicherst du die Dateien mit in der Datenbank (IMHO der einzig gute Grund Binärdaten in einer Datenbank zu speichern sind die Zugriffsrechte) oder baust eine Applikation die die Dateien an deinen Client ausliefern kann.
In beiden Fällen speicherst du die Zugriffsrechete in der Datenbank.


----------



## Tallan (20. Aug 2009)

sparrow hat gesagt.:


> Über Dateirechte würde ich das gar nicht machen. Sprich: die Benutzer haben über das Dateisystem gar keinen Zugriff auf die Daten.
> Entweder speicherst du die Dateien mit in der Datenbank (IMHO der einzig gute Grund Binärdaten in einer Datenbank zu speichern sind die Zugriffsrechte) oder baust eine Applikation die die Dateien an deinen Client ausliefern kann.
> In beiden Fällen speicherst du die Zugriffsrechete in der Datenbank.




die idee die pdf datei in die datenbank zu schreiben ist denke ich ganz gut, kennst du ein tutorial das beschreibt wie man sie reinschreibt und später wieder ausließt/öffnet ?
ich konnte bis jetzt dazu noch nichts finden


----------



## sparrow (20. Aug 2009)

http://www.java-forum.org/datenbankprogrammierung/86312-objekte-datenbank-speichern.html


----------



## Tallan (20. Aug 2009)

sparrow hat gesagt.:


> http://www.java-forum.org/datenbankprogrammierung/86312-objekte-datenbank-speichern.html



Klasse danke, ich hab demzufolge jetzt in einem kleinen testprogramm eine pdf datei in die datenbank geschrieben das scheint soweit auch zu klappen.
Jetzt habe ich aber ein problem beim wiederherstellen bzw öffnen in einem PDF Reader.

Generell nutze ich dafür

```
public static void openPDF(String adr) throws IOException
	 {
		    Desktop
                         .getDesktop()
                         .open( new File(adr));
	 }
```

Zum auslesen habe ich bis jetzt folgendes gemacht


```
dbc = dbc.getInstance(); // DB 
		java.sql.PreparedStatement st = dbc.cn.prepareStatement("SELECT * FROM attachment");
		ResultSet rs = st.executeQuery();
		rs.next();

                //rs ist nun die erste Zeile der mysql Tabelle
```

Meine Frage / Problem jetzt, wie öffne ich die Daten der DB im PDF Reader?

Datenbank ist zu testzwecken folgendermaßen aufgebaut
Name der Datei | Longblobdaten | application
test.pdf           | longblob..        | application/pdf


----------



## sparrow (20. Aug 2009)

Indem du die Datei erstmal auf der Festplatte speicherst und anschließend wieder löschst. Das Problem ist es den PDF-Reader etwas lesen zu lassen. Der kann das sicher nur aus einer Datei.

Aber: Es gibt auch Bibliotheken für Java die dir eine PDF darstellen können. Dann könnte deine Applikation selbst die PDF darstellen und uU direkt mit dem Obejekt gefüttert werden.


----------



## Tallan (20. Aug 2009)

sparrow hat gesagt.:


> Indem du die Datei erstmal auf der Festplatte speicherst und anschließend wieder löschst. Das Problem ist es den PDF-Reader etwas lesen zu lassen. Der kann das sicher nur aus einer Datei.
> 
> Aber: Es gibt auch Bibliotheken für Java die dir eine PDF darstellen können. Dann könnte deine Applikation selbst die PDF darstellen und uU direkt mit dem Obejekt gefüttert werden.



die möglichkeiten habe ich beide schon in betracht gezogen, momentan hängt es aber daran wie ich die pdf erstellen kann.

Ich vermute mal das ich die entsprechenden Daten aus der DB auslesen muß und dann per FileOutputStream in eine Datei schreibe ?
Falls du da ein beispiel zur hand hättest wäre ich happy, da ich nicht weiß wie ich die daten im longbob format als datei schreiben soll.


mein ansatz war



```
dbc = dbc.getInstance();
		java.sql.PreparedStatement st = dbc.cn.prepareStatement("SELECT * FROM attachment");
		ResultSet rs = st.executeQuery();
		rs.next();
		//System.out.println(rs.getObject("c"));
	    FileOutputStream fos = new FileOutputStream("Z://demo.pdf");
	    ByteArrayInputStream in = (ByteArrayInputStream) rs.getBinaryStream("c");
	    byte nextByte;
	    while ( ( nextByte = (byte) in.read() ) != -1  ){
	    	fos.write(nextByte);
	    }
```

was leider nur eine nicht lesbare pdf datei erzeugt


----------



## sparrow (20. Aug 2009)

In dem Thread den ich verlinkt habe wird erklärt wir man das Speichern in der DB und holen der Daten aus der DB am Besten mit einem Prepared Statement löst.
Da bekommt man dann ein Obejct zurück und kann das dann in das casten was es vorher war. In deinem Fall ein File-Object oder byte-Array.


----------



## Tallan (20. Aug 2009)

Casten geht leider nicht

```
dbc = dbc.getInstance();
		java.sql.PreparedStatement st = dbc.cn.prepareStatement("SELECT * FROM attachment");
		ResultSet rs = st.executeQuery();
		rs.next();
		Object object = rs.getObject("c"); // ist das feld mit den longbob daten
		File f = (File)object;
```

Exception in thread "main" java.lang.ClassCastException: [B cannot be cast to java.io.File
	at tests.dbtest.<init>(dbtest.java:55)         // ist der Cast
	at tests.dbtest.main(dbtest.java:78)


mein Problem ist also nachwievor das ich nicht weiß wie ich die File erzeugen / erhalten / umwandeln / casten soll.

Vielen dank im übrigen für die viele Mühe!


----------



## sparrow (20. Aug 2009)

Wie schreibst du denn in die Datenbank?


----------



## Tallan (20. Aug 2009)

```
java.sql.PreparedStatement pst = dbc.cn.prepareStatement("INSERT INTO attachment (a, b, c, d) VALUES ( ?, ?, ?, ?)");
		File file = new File("Z:\\test2.pdf");
		pst.setInt(1, 2);
		pst.setString(2, file.getName());
		pst.setBinaryStream(3, new FileInputStream(file), (int)file.length());
		pst.setString(4, "application/pdf");
		pst.execute();
```


----------



## sparrow (20. Aug 2009)

Ok, du schreibst als mit BinararyStreams. In dem anderen Thread hat genau das nicht geklappt. Ich persönlich bin so auch noch nicht vor gegangen sondern habe immer ein Objekt abgelegt (siehe meine Posts in dem verlinkten Thread).
Was bei dir gehen sollte ist da holen des Inhalts mit getBinaryStream beim auslesen (statt getObject)


----------



## Tallan (20. Aug 2009)

also mit setObject  steht in der db bei einer filegröße von 140kb nur 80b

pst.setObject(3, (Object)file);

alternativ
pst.setObject(3, file);


und per 

File f = (File) rs.getObject("c");

kommt die selbe exception..

per getObject  selbiger fehler


----------



## sparrow (20. Aug 2009)

Sorry, mein Fehler.
Mit setObject kannst du natürlich ein Object ablegen das serialisierbar ist. Allerdings ist File qusi nur ein Verweis auf die Datei, der eigentliche Inhalt der Datei ist darin nicht gespeichert.

Du müsstest, wenn du das mit einem Object machen willst, also erst den Inhalt irgendwie in ein Object bringen.


----------



## Tallan (20. Aug 2009)

damit gehts


```
///rauslesen
		dbc = dbc.getInstance();
		java.sql.PreparedStatement st = dbc.cn.prepareStatement("SELECT * FROM attachment");
		ResultSet rs = st.executeQuery();
		rs.next();

	    FileOutputStream fos = new FileOutputStream("Z://demo3.pdf");
	    ByteArrayInputStream in = (ByteArrayInputStream) rs.getBinaryStream("c");
	    int nextByte;
	    
	    while ( ( nextByte =  in.read() ) != -1  ){
	    	fos.write(nextByte);
	    
	    }
```

es ist nur brechend langsam ich hoffe wenn ich noch einen buffer hinzufüge geht es etwas fixer.

und hier noch die schnelle varaiante


```
dbc = dbc.getInstance();
		java.sql.PreparedStatement st = dbc.cn.prepareStatement("SELECT * FROM attachment");
		ResultSet rs = st.executeQuery();
		rs.next();

	    FileOutputStream fos = new FileOutputStream("Z://demo7.pdf");
	    ByteArrayInputStream in = (ByteArrayInputStream)rs.getBinaryStream("c");
	    fos.write(rs.getBytes("c"));
```

danke für die hilfe @ sparrow


----------

