diff options
| author | Tobias Kellner <imcybot@gmail.com> | 2016-01-15 00:45:15 +0100 | 
|---|---|---|
| committer | Tobias Kellner <tobias.kellner@iaik.tugraz.at> | 2016-03-14 17:23:00 +0100 | 
| commit | 9cc4fcbe2eab39846d8cd7532bcab26bad85d59d (patch) | |
| tree | c0b53464f257b621134fcb85f7b23ea754bce711 /pdf-over-gui/src | |
| parent | f3270ff28da75e0afdcdfa515b1b6807df452752 (diff) | |
| download | pdf-over-9cc4fcbe2eab39846d8cd7532bcab26bad85d59d.tar.gz pdf-over-9cc4fcbe2eab39846d8cd7532bcab26bad85d59d.tar.bz2 pdf-over-9cc4fcbe2eab39846d8cd7532bcab26bad85d59d.zip | |
Add QR code display for A-Trust Handy-Signatur app
Diffstat (limited to 'pdf-over-gui/src')
8 files changed, 757 insertions, 27 deletions
| diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/MobileBKUConnector.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/MobileBKUConnector.java index c97a59c3..06b60155 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/MobileBKUConnector.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/MobileBKUConnector.java @@ -19,7 +19,10 @@ package at.asit.pdfover.gui.bku;  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
 +import at.asit.pdfover.gui.bku.mobile.ATrustHandler;
 +import at.asit.pdfover.gui.bku.mobile.ATrustStatus;
  import at.asit.pdfover.gui.bku.mobile.MobileBKUHandler;
 +import at.asit.pdfover.gui.bku.mobile.MobileBKUStatus;
  import at.asit.pdfover.gui.workflow.states.MobileBKUState;
  import at.asit.pdfover.signator.BkuSlConnector;
  import at.asit.pdfover.signator.SLRequest;
 @@ -105,26 +108,54 @@ public class MobileBKUConnector implements BkuSlConnector {  			}
  			do {
 -				// Get TAN
 -				this.state.checkTAN();
 +				MobileBKUStatus status = this.state.getStatus();
 +				boolean enterTAN = true;
 +				String responseData = null;
 +				if (status instanceof ATrustStatus) {
 +					ATrustStatus aStatus = (ATrustStatus) status;
 +					ATrustHandler aHandler = (ATrustHandler) handler;
 +					if (aStatus.getQRCode() != null) {
 +						this.state.showQR();
 +						if (this.state.getStatus().getErrorMessage() != null &&
 +								this.state.getStatus().getErrorMessage().equals("cancel")) //$NON-NLS-1$
 +							throw new SignatureException(new IllegalStateException());
 +						if (aStatus.getQRCode() == null) {
 +							try {
 +								String response = aHandler.postSMSRequest();
 +								log.trace("Response from mobile BKU: " + response); //$NON-NLS-1$
 +								handler.handleCredentialsResponse(response);
 +							} catch (Exception ex) {
 +								log.error("Error in PostCredentialsThread", ex); //$NON-NLS-1$
 +								this.state.setThreadException(ex);
 +								this.state.displayError(ex);
 +								throw new SignatureException(ex);
 +							}
 +						} else {
 +							enterTAN = false;
 +						}
 +					}
 +				}
 +				if (enterTAN) {
 +					// Get TAN
 +					this.state.checkTAN();
 -				if (this.state.getStatus().getErrorMessage() != null &&
 -						this.state.getStatus().getErrorMessage().equals("cancel")) //$NON-NLS-1$
 -					throw new SignatureException(new IllegalStateException());
 +					if (this.state.getStatus().getErrorMessage() != null &&
 +							this.state.getStatus().getErrorMessage().equals("cancel")) //$NON-NLS-1$
 +						throw new SignatureException(new IllegalStateException());
 -				// Post TAN
 -				try {
 -					String responseData = handler.postTAN();
 -		
 -					// Now we have received some data lets check it:
 -					log.trace("Response from mobile BKU: " + responseData); //$NON-NLS-1$
 -		
 -					handler.handleTANResponse(responseData);
 -				} catch (Exception ex) {
 -					log.error("Error in PostTanThread", ex); //$NON-NLS-1$
 -					this.state.setThreadException(ex);
 -					this.state.displayError(ex);
 -					throw new SignatureException(ex);
 +					// Post TAN
 +					try {
 +						responseData = handler.postTAN();
 +						log.trace("Response from mobile BKU: " + responseData); //$NON-NLS-1$
 +
 +						// Now we have received some data lets check it:
 +						handler.handleTANResponse(responseData);
 +					} catch (Exception ex) {
 +						log.error("Error in PostTanThread", ex); //$NON-NLS-1$
 +						this.state.setThreadException(ex);
 +						this.state.displayError(ex);
 +						throw new SignatureException(ex);
 +					}
  				}
  			} while (this.state.getStatus().getErrorMessage() != null);
  			if (this.state.getStatus().getTanTries() == -1)
 diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustHandler.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustHandler.java index 1a796565..b7e457c3 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustHandler.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustHandler.java @@ -18,9 +18,12 @@ package at.asit.pdfover.gui.bku.mobile;  // Imports  import java.awt.Desktop;  import java.io.IOException; +import java.io.InputStream;  import java.net.URI;  import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.GetMethod;  import org.apache.commons.httpclient.methods.PostMethod;  import org.apache.commons.lang3.StringEscapeUtils;  import org.eclipse.swt.SWT; @@ -137,6 +140,7 @@ public class ATrustHandler extends MobileBKUHandler {  		String sessionID = status.getSessionID();  		String refVal = null;  		String signatureDataURL = null; +		String qrCode = null;  		status.setErrorMessage(null); @@ -192,11 +196,18 @@ public class ATrustHandler extends MobileBKUHandler {  			// credentials ok! TAN entry  			log.debug("Credentials accepted - TAN required"); //$NON-NLS-1$  			sessionID = MobileBKUHelper.extractTag(responseData, "signature.aspx?sid=", "\""); //$NON-NLS-1$ //$NON-NLS-2$ -			viewState = MobileBKUHelper.extractTag(responseData, "id=\"__VIEWSTATE\" value=\"", "\""); //$NON-NLS-1$  //$NON-NLS-2$ -			eventValidation = MobileBKUHelper.extractTag(responseData, "id=\"__EVENTVALIDATION\" value=\"", "\""); //$NON-NLS-1$  //$NON-NLS-2$ -			refVal = MobileBKUHelper.extractTag(responseData, "id='vergleichswert'><b>Vergleichswert:</b>", "</div>");  //$NON-NLS-1$//$NON-NLS-2$ -			signatureDataURL = status.getBaseURL() + "/ShowSigobj.aspx" +  //$NON-NLS-1$ -					MobileBKUHelper.extractTag(responseData, "ShowSigobj.aspx", "'");  //$NON-NLS-1$//$NON-NLS-2$ +			viewState = MobileBKUHelper.extractTag(responseData, "id=\"__VIEWSTATE\" value=\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$ +			eventValidation = MobileBKUHelper.extractTag(responseData, "id=\"__EVENTVALIDATION\" value=\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$ +			refVal = MobileBKUHelper.extractTag(responseData, "id='vergleichswert'><b>Vergleichswert:</b>", "</div>"); //$NON-NLS-1$ //$NON-NLS-2$ +			signatureDataURL = status.getBaseURL() + "/ShowSigobj.aspx" + //$NON-NLS-1$ +					MobileBKUHelper.extractTag(responseData, "ShowSigobj.aspx", "'"); //$NON-NLS-1$ //$NON-NLS-2$ +			try { +				qrCode = MobileBKUHelper.extractTag(responseData, "<img class='qrcode' src='", "'"); //$NON-NLS-1$ //$NON-NLS-2$ +				log.debug("QR Code found: " + qrCode); //$NON-NLS-1$ +				status.setQRCode(qrCode); +			} catch (Exception e) { +				log.debug("No QR Code found"); //$NON-NLS-1$ +			}  		} else if (responseData.contains("sl:InfoboxReadResponse")) { //$NON-NLS-1$  			// credentials ok! InfoboxReadResponse  			log.debug("Credentials accepted - Response given"); //$NON-NLS-1$ @@ -298,6 +309,93 @@ public class ATrustHandler extends MobileBKUHandler {  		}  	} +	/** +	 * Cancel QR process, request SMS TAN +	 * @return the response +	 * @throws IOException Error during posting +	 */ +	public String postSMSRequest() throws IOException { +		ATrustStatus status = getStatus(); + +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = BKUHelper.getHttpClient(); + +		PostMethod post = new PostMethod(status.getBaseURL() +				+ "/signature.aspx?sid=" + status.getSessionID()); //$NON-NLS-1$ +		post.getParams().setContentCharset("utf-8"); //$NON-NLS-1$ +		post.addParameter("__VIEWSTATE", status.getViewstate()); //$NON-NLS-1$ +		post.addParameter( +				"__EVENTVALIDATION", status.getEventvalidation()); //$NON-NLS-1$ +		post.addParameter("__EVENTTARGET", "SmsButton"); //$NON-NLS-1$ //$NON-NLS-2$ +		post.addParameter("__EVENTARGUMENT", ""); //$NON-NLS-1$ //$NON-NLS-2$ + +		return executePost(client, post); +	} + +	/** +	 * Get the QR code image +	 * @return the QR code image as a String +	 */ +	public InputStream getQRCode() { +		ATrustStatus status = getStatus(); + +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = BKUHelper.getHttpClient(); + +		GetMethod get = new GetMethod(status.getBaseURL() + "/" + //$NON-NLS-1$ +				status.getQRCode()); + +		try { +			log.debug("Getting " + get.getURI()); //$NON-NLS-1$ +			int returnCode = client.executeMethod(get); + +			if (returnCode != HttpStatus.SC_OK) { +				log.error("Error getting QR code"); //$NON-NLS-1$ +				return null; +			} + +			return get.getResponseBodyAsStream(); +		} catch (Exception e) { +			log.error("Error getting QR code", e); //$NON-NLS-1$ +			return null; +		} +	} + +	/** +	 * Get Signature page after scanning QR code +	 * @return the response +	 * @throws IOException Error during get +	 */ +	public String getSignaturePage() throws IOException { +		ATrustStatus status = getStatus(); + +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = BKUHelper.getHttpClient(); + +		GetMethod get = new GetMethod(status.getBaseURL() +				+ "/signature.aspx?sid=" + status.getSessionID()); //$NON-NLS-1$ + +		return executeGet(client, get); +	} + +	/** +	 * Parse QR code response +	 * @param responseData +	 * @return whether a SL response was received +	 */ +	public boolean handleQRResponse(String responseData) { +		getStatus().setErrorMessage(null); +		if (responseData.contains("sl:CreateXMLSignatureResponse xmlns:sl") || //$NON-NLS-1$ +		    responseData.contains("sl:CreateCMSSignatureResponse xmlns:sl")) { //$NON-NLS-1$ +			// success !! + +			getSigningState().setSignatureResponse( +					new SLResponse(responseData, getStatus().getServer(), null, null)); +			return true; +		} +		return false; +	} +  	@Override  	public ATrustStatus getStatus() {  		return (ATrustStatus) getState().getStatus(); diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustStatus.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustStatus.java index 3fedf73e..a97826b2 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustStatus.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustStatus.java @@ -37,6 +37,7 @@ public class ATrustStatus extends AbstractMobileBKUStatusImpl {  	private String viewstate;  	private String eventvalidation; +	private String qrcode = null;  	/**  	 * Constructor @@ -69,7 +70,7 @@ public class ATrustStatus extends AbstractMobileBKUStatusImpl {  	public void setViewstate(String viewstate) {  		this.viewstate = viewstate;  	} -	 +  	/**  	 * @return the eventvalidation  	 */ @@ -83,4 +84,20 @@ public class ATrustStatus extends AbstractMobileBKUStatusImpl {  	public void setEventvalidation(String eventvalidation) {  		this.eventvalidation = eventvalidation;  	} + +	/** +	 * @return the QR code +	 */ +	public String getQRCode() { +		return this.qrcode; +	} + +	/** +	 * @param qrcode +	 *            the QR code to set +	 */ +	public void setQRCode(String qrcode) { +		this.qrcode = qrcode; +	} +	  } diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/MobileBKUHandler.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/MobileBKUHandler.java index 429000f1..6c6b9f84 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/MobileBKUHandler.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/MobileBKUHandler.java @@ -238,8 +238,11 @@ public abstract class MobileBKUHandler {  				Matcher m = pat.matcher(responseData);  				if (m.find()) {  					String content = m.group(1); -					int start = content.indexOf("URL=") +9; //$NON-NLS-1$ -					redirectLocation  = content.substring(start, content.length() - 5); +					int start = content.indexOf("URL="); //$NON-NLS-1$ +					if (start != -1) { +						start += 9; +						redirectLocation  = content.substring(start, content.length() - 5); +					}  				}  			} else {  				throw new HttpException( @@ -261,4 +264,84 @@ public abstract class MobileBKUHandler {  		return responseData;  	} + +	/** +	 * Execute a get from the mobile BKU, following redirects +	 * @param client the HttpClient +	 * @param get the GetMethod +	 * @return the response +	 * @throws IOException IO error +	 */ +	protected String executeGet(HttpClient client, GetMethod get) throws IOException { +		log.debug("Getting " + get.getURI()); //$NON-NLS-1$ +		int returnCode = client.executeMethod(get); + +		String redirectLocation = null; + +		GetMethod get2 = null; + +		String responseData = null; + +		String server = null; + +		// Follow redirects +		do { +			// check return code +			if (returnCode == HttpStatus.SC_MOVED_TEMPORARILY || +				returnCode == HttpStatus.SC_MOVED_PERMANENTLY) { + +				Header locationHeader = get.getResponseHeader("location"); //$NON-NLS-1$ +				if (locationHeader != null) { +					redirectLocation = locationHeader.getValue(); +				} else { +					throw new IOException( +							"Got HTTP 302 but no location to follow!"); //$NON-NLS-1$ +				} +			} else if (returnCode == HttpStatus.SC_OK) { +				if (get2 != null) { +					responseData = get2.getResponseBodyAsString(); +					Header serverHeader = get2.getResponseHeader( +							LocalBKUState.BKU_RESPONSE_HEADER_SERVER); +					if (serverHeader != null) +						server = serverHeader.getValue(); +				} else { +					responseData = get.getResponseBodyAsString(); + +					Header serverHeader = get.getResponseHeader( +							LocalBKUState.BKU_RESPONSE_HEADER_SERVER); +					if (serverHeader != null) +						server = serverHeader.getValue(); +				} +				redirectLocation = null; +				String p = "<meta [^>]*http-equiv=\"refresh\" [^>]*content=\"([^\"]*)\""; //$NON-NLS-1$ +				Pattern pat = Pattern.compile(p); +				Matcher m = pat.matcher(responseData); +				if (m.find()) { +					String content = m.group(1); +					int start = content.indexOf("URL="); //$NON-NLS-1$ +					if (start != -1) { +						start += 9; +						redirectLocation  = content.substring(start, content.length() - 5); +					} +				} +			} else { +				throw new HttpException( +						HttpStatus.getStatusText(returnCode)); +			} + +			if (redirectLocation != null) { +				redirectLocation = getStatus().ensureSessionID(redirectLocation); +				log.debug("Redirected to " + redirectLocation); //$NON-NLS-1$ +				get2 = new GetMethod(redirectLocation); +				get2.setFollowRedirects(true); +				returnCode = client.executeMethod(get2); +			} +		} while (redirectLocation != null); + +		getStatus().setServer(server); +		if (server != null) +			log.info("Server: " + server); //$NON-NLS-1$ + +		return responseData; +	}  } diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/MobileBKUQRComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/MobileBKUQRComposite.java new file mode 100644 index 00000000..206dcc40 --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/MobileBKUQRComposite.java @@ -0,0 +1,405 @@ +/* + * Copyright 2012 by A-SIT, Secure Information Technology Center Austria + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + */ +package at.asit.pdfover.gui.composites; + +// Imports +import java.awt.Desktop; +import java.io.InputStream; +import java.net.URI; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.asit.pdfover.gui.Constants; +import at.asit.pdfover.gui.utils.Messages; +import at.asit.pdfover.gui.workflow.states.State; + +/** + * Composite for displaying the QR code for the mobile BKU + */ +public class MobileBKUQRComposite extends StateComposite { + +	/** +	 *  +	 */ +	private final class SMSSelectionListener extends SelectionAdapter { +		/** +		 * Empty constructor +		 */ +		public SMSSelectionListener() { +		} + +		@Override +		public void widgetSelected(SelectionEvent e) { +			if(!MobileBKUQRComposite.this.btn_sms.getEnabled()) { +				return; +			} + +			MobileBKUQRComposite.this.setUserSMS(true); +			MobileBKUQRComposite.this.btn_sms.setEnabled(false); +		} +	} + +	/** +	 *  +	 */ +	private final class CancelSelectionListener extends SelectionAdapter { +		/** +		 * Empty constructor +		 */ +		public CancelSelectionListener() { +		} + +		@Override +		public void widgetSelected(SelectionEvent e) { +			MobileBKUQRComposite.this.setUserCancel(true); +		} +	} + +	/** +	 * SLF4J Logger instance +	 **/ +	static final Logger log = LoggerFactory +			.getLogger(MobileBKUQRComposite.class); + +	private Label lblQR; + +	boolean userCancel = false; +	boolean userSMS = false; +	boolean done = false; + +	private Label lblRefVal; + +	String refVal; + +	String signatureData; + +	/** +	 * @return the signatureData +	 */ +	public String getSignatureData() { +		return this.signatureData; +	} + +	/** +	 * @param signatureData +	 *            the signatureData to set +	 */ +	public void setSignatureData(String signatureData) { +		this.signatureData = signatureData; +	} + +	private Label lblError; +	private Label lblRefValLabel; +	private Label lblQRLabel; + +	Button btn_sms; +	Button btn_cancel; + +	Link lnk_sig_data; + +	/** +	 * @return the userCancel +	 */ +	public boolean isUserCancel() { +		return this.userCancel; +	} + +	/** +	 * @return the userSMS +	 */ +	public boolean isUserSMS() { +		return this.userSMS; +	} + +	/** +	 * @return the done +	 */ +	public boolean isDone() { +		return this.done; +	} + +	/** +	 * Set an error message +	 * @param errorMessage the error message +	 */ +	public void setErrorMessage(String errorMessage) { +		if (errorMessage == null) +			this.lblError.setText(""); //$NON-NLS-1$ +		else +			this.lblError.setText( +					Messages.getString("error.Title") + ": " + errorMessage); //$NON-NLS-1$ //$NON-NLS-2$ +	} + +	/** +	 * @param userCancel +	 *            the userCancel to set +	 */ +	public void setUserCancel(boolean userCancel) { +		this.userCancel = userCancel; +	} + +	/** +	 * @param userSMS +	 *            the userSMS to set +	 */ +	public void setUserSMS(boolean userSMS) { +		this.userSMS = userSMS; +	} + +	/** +	 * @param done +	 *            the done to set +	 */ +	public void setDone(boolean done) { +		this.done = done; +	} + +	/** +	 * @return the reference value +	 */ +	public String getRefVal() { +		return this.refVal; +	} + +	/** +	 * @param refVal +	 *            the reference value to set +	 */ +	public void setRefVal(String refVal) { +		this.refVal = refVal.trim(); + +		if (this.refVal != null) { +			this.lblRefVal.setText(this.refVal); +		} else { +			this.lblRefVal.setText(""); //$NON-NLS-1$ +		} + +	} + +	/** +	 * @param qrcode +	 *            the qrcode to set +	 */ +	public void setQR(InputStream qrcode) { +		if (qrcode == null) { +			setErrorMessage(Messages.getString("error.FailedToLoadQRCode")); //$NON-NLS-1$ +			return; +		} +		Image qr = new Image(Display.getCurrent(), qrcode); +		this.lblQR.setImage(qr); +	} + +	/** +	 * Selection Listener for open button +	 */ +	private final class ShowSignatureDataListener extends SelectionAdapter { +		/** +		 * Empty constructor +		 */ +		public ShowSignatureDataListener() { +		} + +		@Override +		public void widgetSelected(SelectionEvent e) { +			try { +				String signatureData = MobileBKUQRComposite.this +						.getSignatureData(); +				if (signatureData != null && !signatureData.equals("")) { //$NON-NLS-1$ +					log.debug("Trying to open " + signatureData); //$NON-NLS-1$ +					if (Desktop.isDesktopSupported()) { +						Desktop.getDesktop().browse(new URI(signatureData)); +					} else { +						log.info("SWT Desktop is not supported on this platform"); //$NON-NLS-1$ +						Program.launch(signatureData); +					} +				} +			} catch (Exception ex) { +				log.error("OpenSelectionListener: ", ex); //$NON-NLS-1$ +			} +		} +	} + +	/** +	 * Create the composite. +	 *  +	 * @param parent +	 * @param style +	 * @param state +	 */ +	public MobileBKUQRComposite(Composite parent, int style, State state) { +		super(parent, style, state); +		setLayout(new FormLayout()); + +		final Composite containerComposite = new Composite(this, SWT.NATIVE); +		containerComposite.addPaintListener(new PaintListener() { +			@Override +			public void paintControl(PaintEvent e) { +				Rectangle clientArea = containerComposite.getClientArea(); + +				// e.gc.setForeground(); +				e.gc.setForeground(Constants.MAINBAR_ACTIVE_BACK_DARK); +				e.gc.setLineWidth(3); +				e.gc.setLineStyle(SWT.LINE_SOLID); +				e.gc.drawRoundRectangle(clientArea.x, clientArea.y, +						clientArea.width - 2, clientArea.height - 2, 10, 10); +			} +		}); +		containerComposite.setLayout(new FormLayout()); +		FormData fd_containerComposite = new FormData(); +		fd_containerComposite.top = new FormAttachment(50, -120); +		fd_containerComposite.bottom = new FormAttachment(50, 120); +		fd_containerComposite.left = new FormAttachment(50, -200); +		fd_containerComposite.right = new FormAttachment(50, 200); +		containerComposite.setLayoutData(fd_containerComposite); + +		this.lblRefValLabel = new Label(containerComposite, SWT.NATIVE); +		this.lblRefValLabel.setAlignment(SWT.RIGHT); +		FormData fd_lblRefValLabel = new FormData(); +		// fd_lblRefValLabel.left = new FormAttachment(0, 20); +		fd_lblRefValLabel.right = new FormAttachment(50, -10); +		fd_lblRefValLabel.top = new FormAttachment(30, -10); +		//fd_lblRefValLabel.bottom = new FormAttachment(50, -10); +		this.lblRefValLabel.setLayoutData(fd_lblRefValLabel); + +		Label lbl_image = new Label(containerComposite, SWT.NATIVE); + +		ImageData data = new ImageData(this.getClass().getResourceAsStream( +				Constants.RES_IMG_MOBILE)); +		Image mobile = new Image(getDisplay(), data); + +		FormData fd_lbl_image = new FormData(); +		fd_lbl_image.top = new FormAttachment(50, -1 * (data.width / 2)); +		fd_lbl_image.bottom = new FormAttachment(50, data.width / 2); +		fd_lbl_image.left = new FormAttachment(0, 10); +		fd_lbl_image.width = data.width; +		lbl_image.setLayoutData(fd_lbl_image); +		lbl_image.setImage(mobile); + +		this.lblRefVal = new Label(containerComposite, SWT.NATIVE); +		FormData fd_lblRefVal = new FormData(); +		fd_lblRefVal.left = new FormAttachment(50, 10); +		fd_lblRefVal.right = new FormAttachment(100, -20); +		fd_lblRefVal.top = new FormAttachment(30, -10); +		//fd_lblRefVal.bottom = new FormAttachment(50, -10); +		this.lblRefVal.setLayoutData(fd_lblRefVal); +		this.lblRefVal.setText(""); //$NON-NLS-1$ + +		this.lblQRLabel = new Label(containerComposite, SWT.NATIVE); +		this.lblQRLabel.setAlignment(SWT.RIGHT); +		FormData fd_lblQRLabel = new FormData(); +		// fd_lblQRLabel.left = new FormAttachment(0, 20); +		fd_lblQRLabel.right = new FormAttachment(50, -10); +		fd_lblQRLabel.top = new FormAttachment(this.lblRefValLabel, 10); +		// fd_lblQRLabel.bottom = new FormAttachment(50, 15); +		this.lblQRLabel.setLayoutData(fd_lblQRLabel); + +		this.lblQR = new Label(containerComposite, SWT.NATIVE); +		FormData fd_lblQR = new FormData(); +		fd_lblQR.left = new FormAttachment(50, 10); +		fd_lblQR.right = new FormAttachment(100, -20); +		fd_lblQR.top = new FormAttachment(this.lblRefVal, 10); +		this.lblQR.setLayoutData(fd_lblQR); + +		this.lnk_sig_data = new Link(containerComposite, SWT.NATIVE | SWT.RESIZE); + +		FormData fd_lnk_data = new FormData(); +		fd_lnk_data.right = new FormAttachment(100, -20); +		fd_lnk_data.top = new FormAttachment(0, 20); +		this.lnk_sig_data.setEnabled(true); +		this.lnk_sig_data.setLayoutData(fd_lnk_data); +		this.lnk_sig_data.addSelectionListener(new ShowSignatureDataListener()); + +		this.btn_cancel = new Button(containerComposite, SWT.NATIVE); +		this.btn_sms = new Button(containerComposite, SWT.NATIVE); + +		this.lblError = new Label(containerComposite, SWT.WRAP | SWT.NATIVE); +		FormData fd_lbl_error = new FormData(); +		// fd_lbl_error.left = new FormAttachment(15, 5); +		fd_lbl_error.right = new FormAttachment(this.btn_sms, -10); +		// fd_lbl_error.top = new FormAttachment(70, -15); +		fd_lbl_error.bottom = new FormAttachment(100, -20); +		this.lblError.setLayoutData(fd_lbl_error); + +		FormData fd_btn_cancel = new FormData(); +		// fd_btn_cancel.left = new FormAttachment(95, 0); +		fd_btn_cancel.right = new FormAttachment(100, -20); +		//fd_btn_cancel.left = new FormAttachment(100, -70); +		fd_btn_cancel.bottom = new FormAttachment(100, -20); + +		this.btn_cancel.setLayoutData(fd_btn_cancel); +		this.btn_cancel.addSelectionListener(new CancelSelectionListener()); + +		FormData fd_btn_sms = new FormData(); +		// fd_btn_sms.left = new FormAttachment(95, 0); +		fd_btn_sms.right = new FormAttachment(this.btn_cancel, -20); +		//fd_btn_sms.left = new FormAttachment(100, -70); +		fd_btn_sms.bottom = new FormAttachment(100, -20); + +		this.btn_sms.setLayoutData(fd_btn_sms); +		this.btn_sms.addSelectionListener(new SMSSelectionListener()); + +		reloadResources(); +	} + +	@Override +	protected void checkSubclass() { +		// Disable the check that prevents subclassing of SWT components +	} + +	/* +	 * (non-Javadoc) +	 *  +	 * @see at.asit.pdfover.gui.composites.StateComposite#doLayout() +	 */ +	@Override +	public void doLayout() { +		// Nothing to do +	} + +	/* +	 * (non-Javadoc) +	 *  +	 * @see at.asit.pdfover.gui.composites.StateComposite#reloadResources() +	 */ +	@Override +	public void reloadResources() { +		this.lblRefValLabel.setText(Messages +				.getString("tanEnter.ReferenceValue")); //$NON-NLS-1$ +		this.lblQRLabel.setText(Messages.getString("tanEnter.QR")); //$NON-NLS-1$ +		this.lnk_sig_data.setText(Messages.getString("mobileBKU.show")); //$NON-NLS-1$ +		this.lnk_sig_data.setToolTipText(Messages.getString("mobileBKU.show_tooltip")); //$NON-NLS-1$ +		this.btn_cancel.setText(Messages.getString("common.Cancel")); //$NON-NLS-1$ +		this.btn_sms.setText(Messages.getString("tanEnter.SMS")); //$NON-NLS-1$ +	} +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java index 5d97262c..bd88b48d 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java @@ -15,6 +15,10 @@   */  package at.asit.pdfover.gui.workflow.states; +import java.io.InputStream; +import java.util.Timer; +import java.util.TimerTask; +  // Imports  import org.eclipse.swt.SWT;  import org.eclipse.swt.widgets.Display; @@ -32,6 +36,7 @@ import at.asit.pdfover.gui.bku.mobile.MobileBKUHandler;  import at.asit.pdfover.gui.bku.mobile.MobileBKUStatus;  import at.asit.pdfover.gui.composites.MobileBKUEnterNumberComposite;  import at.asit.pdfover.gui.composites.MobileBKUEnterTANComposite; +import at.asit.pdfover.gui.composites.MobileBKUQRComposite;  import at.asit.pdfover.gui.composites.WaitingComposite;  import at.asit.pdfover.gui.controls.Dialog.BUTTONS;  import at.asit.pdfover.gui.controls.ErrorDialog; @@ -70,7 +75,7 @@ public class MobileBKUState extends State {  	/**  	 * SLF4J Logger instance  	 **/ -	private static final Logger log = LoggerFactory +	static final Logger log = LoggerFactory  			.getLogger(MobileBKUState.class);  	SigningState signingState; @@ -85,6 +90,8 @@ public class MobileBKUState extends State {  	MobileBKUEnterTANComposite mobileBKUEnterTANComposite = null; +	MobileBKUQRComposite mobileBKUQRComposite = null; +  	WaitingComposite waitingComposite = null;  	WaitingComposite getWaitingComposite() { @@ -106,6 +113,16 @@ public class MobileBKUState extends State {  		return this.mobileBKUEnterTANComposite;  	} +	MobileBKUQRComposite getMobileBKUQRComposite() { +		if (this.mobileBKUQRComposite == null) { +			this.mobileBKUQRComposite = getStateMachine() +					.getGUIProvider().createComposite( +							MobileBKUQRComposite.class, SWT.RESIZE, this); +		} + +		return this.mobileBKUQRComposite; +	} +  	MobileBKUEnterNumberComposite getMobileBKUEnterNumberComposite() {  		if (this.mobileBKUEnterNumberComposite == null) {  			this.mobileBKUEnterNumberComposite = getStateMachine() @@ -311,6 +328,79 @@ public class MobileBKUState extends State {  		});  	} +	/** +	 * Show QR code +	 */ +	public void showQR() { +		final ATrustStatus status = (ATrustStatus) this.getStatus(); +		final ATrustHandler handler = (ATrustHandler) this.getHandler(); + +		final Timer checkDone = new Timer(true); +		checkDone.scheduleAtFixedRate(new TimerTask() { +			 +			@Override +			public void run() { +				// ping signature page to see if code has been scanned +				try { +					String resp = handler.getSignaturePage(); +					if (handler.handleQRResponse(resp)) { +						log.debug("Signature page response: " + resp); //$NON-NLS-1$ +						getMobileBKUQRComposite().setDone(true); +						Display display = getStateMachine().getGUIProvider(). +								getMainShell().getDisplay(); +						display.wake(); +					} +					Display.getDefault().wake(); +				} catch (Exception e) { +					log.error("Error getting signature page", e); //$NON-NLS-1$ +				} +			} +		}, 0, 5000); +		Display.getDefault().syncExec(new Runnable() { +			@Override +			public void run() { +				MobileBKUQRComposite qr = getMobileBKUQRComposite(); +		 +				qr.setRefVal(status.getRefVal()); +				qr.setSignatureData(status.getSignatureDataURL()); +				qr.setErrorMessage(status.getErrorMessage()); +				InputStream qrcode = handler.getQRCode(); +				if (qrcode == null) { +					MobileBKUState.this.threadException = new Exception( +							Messages.getString("error.FailedToLoadQRCode")); //$NON-NLS-1$ +				} +				qr.setQR(qrcode); +				getStateMachine().getGUIProvider().display(qr); + +				Display display = getStateMachine().getGUIProvider().getMainShell().getDisplay();  +				while (!qr.isUserCancel() && !qr.isUserSMS() && !qr.isDone()) { +					if (!display.readAndDispatch()) { +						display.sleep(); +					} +				} +				checkDone.cancel(); + +				if (qr.isUserCancel()) { +					qr.setUserCancel(false); +					status.setErrorMessage("cancel"); //$NON-NLS-1$ +					return; +				} + +				if (qr.isUserSMS()) { +					qr.setUserSMS(false); +					status.setQRCode(null); +				} + +				if (qr.isDone()) +					qr.setDone(false); + +				// show waiting composite +				getStateMachine().getGUIProvider().display( +						MobileBKUState.this.getWaitingComposite()); +			} +		}); +	} +  	/*  	 * (non-Javadoc)  	 *  diff --git a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties index cc751588..a3668580 100644 --- a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties +++ b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages.properties @@ -111,6 +111,7 @@ error.Details=Details  error.EnteredReferenceValue=You entered the reference value\!  error.FailedToGetSignedDocument=Failed to get signed document.  error.FailedToLoadEmblem=Failed to load the signature logo +error.FailedToLoadQRCode=Failed to load the QR code  error.FailedToOpenDocument=Failed to open signed document\: %s.  error.FailedToSaveSettings=Failed to save configuration file\!  error.FileNotExist=File %s does not exist\! @@ -205,7 +206,9 @@ simple_config.Note_Tooltip=Add an optional note to display on your Signature  simple_config.PhoneNumber=Mobile number\:  simple_config.SigBlockLang_Title=Signature block lan&guage\:  simple_config.SigBlockLang_ToolTip=Select the language to be used in the signature block displayed on the signed document +tanEnter.QR=QR code\:  tanEnter.ReferenceValue=Reference value\: +tanEnter.SMS=Request &SMS  tanEnter.TAN=TAN\:  tanEnter.tries=%d tries left\!  tanEnter.try=Only 1 try left\! diff --git a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages_de.properties b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages_de.properties index 33e1c785..70b1662b 100644 --- a/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages_de.properties +++ b/pdf-over-gui/src/main/resources/at/asit/pdfover/gui/messages_de.properties @@ -111,6 +111,7 @@ error.Details=Details  error.EnteredReferenceValue=Sie haben den Vergleichswert eingegeben\!  error.FailedToGetSignedDocument=Konnte signiertes Dokument nicht erhalten.  error.FailedToLoadEmblem=Konnte Bildmarke nicht speichern +error.FailedToLoadQRCode=Konnte den QR code nicht laden  error.FailedToOpenDocument=Konnte signiertes Dokument nicht \u00F6ffnen\: %s.  error.FailedToSaveSettings=Konnte Konfigurationsdatei nicht speichern\!  error.FileNotExist=Datei %s existiert nicht\! @@ -205,7 +206,9 @@ simple_config.Note_Tooltip=Ein optionaler Hinweis, der in Ihrer Signatur angezei  simple_config.PhoneNumber=Handynummer\:  simple_config.SigBlockLang_Title=Sp&rache des Signaturblocks\:  simple_config.SigBlockLang_ToolTip=W\u00E4hlen Sie eine Sprache f\u00FCr den Signaturblock, der am signierten Dokument erscheint +tanEnter.QR=QR Code\:  tanEnter.ReferenceValue=Vergleichswert\: +tanEnter.SMS=&SMS anfordern  tanEnter.TAN=TAN\:  tanEnter.tries=%d Versuche \u00FCbrig\!  tanEnter.try=Nur noch 1 Versuch \u00FCbrig\! | 
