Blacklisting URLs in PhantomJS and GhostDriver is pretty straightforward. First initialize the driver with a handler:
PhantomJSDriver driver = new PhantomJSDriver();
driver.executePhantomJS(loadFile("/phantomjs/handlers.js"))
And configure the handler:
this.onResourceRequested = function (requestData, networkRequest) {
var allowedUrls = [
/https?:\/\/localhost.*/,
/https?:\/\/.*\.example.com\/?.*/
];
var disallowedUrls = [
/https?:\/\/nonono.com.*/
];
function isUrlAllowed(url) {
function matches(url) {
return function(re) {
return re.test(url);
};
}
return allowedUrls.some(matches(url)) && !disallowedUrls.some(matches(url));
}
if (!isUrlAllowed(requestData.url)) {
console.log("Aborting disallowed request (# " + requestData.id + ") to url: '" + requestData.url + "'");
networkRequest.abort();
}
};
I haven't found a good way to do this with HtmlUnitDriver. There's the ScriptPreProcessor mentioned in How to filter javascript from specific urls in HtmlUnit, but it uses WebClient, not HtmlUnitDriver. Any ideas?
Extend HtmlUnitDriver and implement a ScriptPreProcessor (for editing content) and a HttpWebConnection (for allowing/blocking URLs):
public class FilteringHtmlUnitDriver extends HtmlUnitDriver {
private static final String[] ALLOWED_URLS = {
"https?://localhost.*",
"https?://.*\\.yes.yes/?.*",
};
private static final String[] DISALLOWED_URLS = {
"https?://spam.nono.*"
};
public FilteringHtmlUnitDriver(DesiredCapabilities capabilities) {
super(capabilities);
}
#Override
protected WebClient modifyWebClient(WebClient client) {
WebConnection connection = filteringWebConnection(client);
ScriptPreProcessor preProcessor = filteringPreProcessor();
client.setWebConnection(connection);
client.setScriptPreProcessor(preProcessor);
return client;
}
private ScriptPreProcessor filteringPreProcessor() {
return (htmlPage, sourceCode, sourceName, lineNumber, htmlElement) -> editContent(sourceCode);
}
private String editContent(String sourceCode) {
return sourceCode.replaceAll("foo", "bar"); }
private WebConnection filteringWebConnection(WebClient client) {
return new HttpWebConnection(client) {
#Override
public WebResponse getResponse(WebRequest request) throws IOException {
String url = request.getUrl().toString();
WebResponse emptyResponse = new WebResponse(
new WebResponseData("".getBytes(), SC_OK, "", new ArrayList<>()), request, 0);
for (String disallowed : DISALLOWED_URLS) {
if (url.matches(disallowed)) {
return emptyResponse;
}
}
for (String allowed : ALLOWED_URLS) {
if (url.matches(allowed)) {
return super.getResponse(request);
}
}
return emptyResponse;
}
};
}
}
This enables both editing of content, and blocking of URLs.
Related
I have a Controller with the following method:
public void ExportList()
{
var out = GenExport();
CsvExport<LiveViewListe> csv = new CsvExport<LiveViewListe>(out);
Response.Write(csv.Export());
}
this should generate a csv file which the user can download.
I call this method via a jQuery request in my view:
$.getJSON('../Controller2/ExportList', function (data) {
//...
});
the problem is, that I don't get any download and I don't know why. The method is called but without a download.
What is wrong here?
Your controller methods need to always return an ActionResult. So the method should look more like
public ActionResult ExportList()
{
var export = GenExport();
CsvExport<LiveViewListe> csv = new CsvExport<LiveViewListe>(export);
return new CsvResult(csv);
}
Where CsvResult is a class inheriting from ActionResult and doing the necessary to prompt the user for download of your Csv results.
For example, if you really need to Response.Write this could be:
public class CsvResult : ActionResult
{
private CsvExport<LiveViewListe> data;
public CsvResult (CsvExport<LiveViewListe> data)
{
this.data = data;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = "text/csv";
response.AddHeader("Content-Disposition", "attachment; filename=file.csv"));
if (data!= null)
{
response.Write(data.Export());
}
}
}
You could also think about making this more generic, if your CsvExport class has the Export method:
public class CsvResult<T> : ActionResult
{
private CsvExport<T> data;
public CsvResult (CsvExport<T> data)
{
this.data = data;
}
.... same ExecuteResult code
}
Now it supports any of your csv downloads, not just LiveViewListe.
I am trying to learn React with ASP.NET Core 3.0 and I have some issues with calling Controllers' methods. If controller has single method like Get() everything is fine. But if it has more than one, then it turns out as error. Something like Multiple Endpoint conflict. I can't understand and can't find any information about this.
I call methods with code like this:
await FetchData(){
const response = await fetch('api/article/makenewpost/?id=');
const data = await response.json();
this.setState({data:data});
}
async fetchData() {
const response = await fetch('api/article/getarticles/?id=' + this.props.id);
const data = await response.json();
this.setState({ blocktitle: this.props.blocktitle, data: data, id: this.props.id });
}
As temporary solution I made Get method in controller with switch statement, but it looks very bad to me.
public IActionResult Get(int? id, string method){
switch (method)
{
case "GetArticles":
{...}
case "MakeNewPost":
{...}
}
}
UPDATE:
Tried saidutt's solution. There is no conflict anymore, but in response I have something like manifest file, so it's error as I read. Why I can't get correct response? I just separated my methods from single switch method.
[Route("api/[controller]")]
public class ArticleController : Controller
{
private readonly DzikanContext _context;
public ArticleController(DzikanContext context)
{
_context = context;
}
// GET: api/<controller>
[Route("api/[controller]/getarticles")]
public IActionResult GetArticles(int id)
{
var titles = _context.Post.Where(p => p.TypeId == id).Select(p => p);
var filtered = titles.Skip(Math.Max(0, titles.Count() - 3)).ToList();
Dictionary<int, string> icons = new Dictionary<int, string>
{
{1, "someUrl" },
{2, "someUrl2"},
{3, "someUrl3" }
};
List<PostsPayload> articles = new List<PostsPayload>();
foreach (var title in filtered)
{
articles.Add(new PostsPayload
{
IconUrl = icons[title.ResourceId],
ArticleBody = title.Title
});
}
return Json(articles.ToArray());
}
[Route("api/[controller]/makenewpost")]
public IActionResult MakeNewPost(int id)
{
var articles = _context.Post.Where(p => p.Id == id).Select(p => p);
var title = articles.Select(p => p.Title).First();
var body = articles.Select(p => p.Body).First();
List<Post> posts = new List<Post>{
new Post
{
Title = title,
Body = body
}};
return Json(posts.ToArray());
}
}
As I said earlier, when I use single method with switch (nothing has been changed in methods when I separated them) it works fine.
Add Routes to individual endpoints in the controller.
[Route("api/posts/createnewpost")]
public IActionResult CreateNewPost(...) { /* your logic */ }
[Route("api/[controller]")]
[ApiController]
public class ArticleController : Controller
{
private readonly DzikanContext _context;
public ArticleController(DzikanContext context)
{
_context = context;
}
// GET: api/<controller>
[HttpGet]
public IActionResult GetArticles(int id)
{
var titles = _context.Post.Where(p => p.TypeId == id).Select(p => p);
var filtered = titles.Skip(Math.Max(0, titles.Count() - 3)).ToList();
Dictionary<int, string> icons = new Dictionary<int, string>
{
{1, "someUrl" },
{2, "someUrl2"},
{3, "someUrl3" }
};
List<PostsPayload> articles = new List<PostsPayload>();
foreach (var title in filtered)
{
articles.Add(new PostsPayload
{
IconUrl = icons[title.ResourceId],
ArticleBody = title.Title
});
}
return Json(articles.ToArray());
}
// api/<controller>/makenewpost
[HttpGet("makenewpost")]
public IActionResult MakeNewPost(int id)
{
var articles = _context.Post.Where(p => p.Id == id).Select(p => p);
var title = articles.Select(p => p.Title).First();
var body = articles.Select(p => p.Body).First();
List<Post> posts = new List<Post>{
new Post
{
Title = title,
Body = body
}};
return Json(posts.ToArray());
}
}
This used to be a 415 error question.
Now it is a a receiving null values on the server side question.
I am having difficulty trying to get my values in the object myMessage over to the server side.
I have so far tried to add JSON.stringify to newMessage which is being console.logged in the service file.
I tried many ways to alter or make the object the way it would be recognized such as JSON.stringify() and creating a url ending with the correct parameters.
Sorry if it seems like I am dumping code below, but I have been working on this for a second day and don't understand why I can't do a simple post request with three parameters. One string, one int, and one datetime.
If anyone can see where I have gone wrong I would so appreciate it. I will be desperately waiting.
Below I am trying to hit api/SlgCorpNotes/Edit in backend from updateMessage(message: any) in the service in service.ts
slg-corp-notes.service.ts
import { Component, Injectable, Inject } from '#angular/core';
import { HttpClient, HttpHeaders, HttpResponse } from '#angular/common/http';
import { Observable, Subject, BehaviorSubject } from 'rxjs';
import { SLGReportParams, CorpNotes } from './models/slg.model';
import { SlgOverviewComponent } from './slg-overview/slg-overview.component';
import { SlgNote } from './models/slg-notes';
#Injectable({
providedIn: 'root'
})
export class SlgCorpNotesService {
constructor(private http: HttpClient, #Inject('BASE_URL') private baseUrl: string) { }
getWeekTempValue(endDate, department) {
var Params = '?endDate=' + endDate + '&department=' + department;
return this.http.get<any>(this.baseUrl + 'api/SlgCorpNotes/getWeekTempValue' + Params);
}
updateMessage(message: any) {
console.log("at service")
console.log(message)
var newMessage = new CorpNotes(message['departments'], message['noteBody'], message['weeks'].weekEnding)
var Params = '?Department=' + message['departments'] + '&Note=' + message['noteBody'] + '&WeekEnding=' + message['weeks'].weekEnding
console.log(newMessage)
console.log(JSON.stringify(newMessage))
console.log(Params)
const headers = new HttpHeaders()
.set('Content-Type', 'application/json;charset=UTF-8')
let options = { headers: headers };
return this.http.post(this.baseUrl + 'api/SlgCorpNotes/Edit', JSON.stringify(newMessage), options).subscribe(res => {
console.log(res);
}, error => {
console.log(error);
});;
}
}
model.ts
export class CorpNotes {
constructor(
public department: number,
public note: string,
public weekEnding: Date
) { }
}
SLGCorpNotesController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using mocHub2.Models;
using mocHub2.Models.Enterprise;
using Microsoft.EntityFrameworkCore;
using System.Data.SqlClient;
namespace mocHub2.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SlgCorpNotesController : Controller
{
SLGContext _SLGContext;
BRDataContext _BRDataContext;
//injects new context
public SlgCorpNotesController(SLGContext context, BRDataContext context2)
{
_SLGContext = context;
_BRDataContext = context2;
}
// GET: api/SlgCorpNotes
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET: api/SlgCorpNotes/5
[HttpGet("{id}", Name = "Get")]
public string Get(int id)
{
return "value";
}
// POST: api/SlgCorpNotes
[HttpPost]
public void Post([FromBody] string value)
{
}
// Get Corporate Notes
[HttpGet("[action]")]
public JsonResult getWeekTempValue(DateTime endDate, int department)
{
// Find the WeekID from the weekending from SLGHeaderTemplate table
var WeekID = (from x in _SLGContext.SlgheaderTemplate
where x.WeekEnding == endDate
select x.Id).ToList();
// Find Department name by ID
var DepartmentString = (from x in _BRDataContext.Departments
where x.Department == department
select x.Description).ToList();
// Get the Note.
var DeptNote = from x in _SLGContext.SLGCorpNotes
where x.Department == DepartmentString[0]
&& x.WeekID == WeekID[0]
select x.Notes;
// Create return object
var notes = new Notes();
// If Note exists then return Json containing note and department for display, else return empty string.
if (DeptNote.Any() && WeekID.Count() > 0 && DepartmentString.Count() > 0)
{
var ReturnDeptNote = DeptNote.First();
notes = new Notes() { WeekID = WeekID[0], Department = DepartmentString[0], Note = ReturnDeptNote };
}
else
{
var ReturnDeptNote = "";
notes = new Notes() { WeekID = WeekID[0], Department = DepartmentString[0], Note = ReturnDeptNote };
}
return Json(notes);
}
[HttpPost]
[Route("Edit")]
public void Edit([FromForm] CorpNotes item)
{
_SLGContext.Entry(item).State = EntityState.Modified;
_SLGContext.SaveChanges();
}
}
public class CorpNotes
{
public int department { get; set; }
public string note { get; set; }
public DateTime weekEnding { get; set; }
}
public class Notes
{
public int ID { get; set; }
public int WeekID { get; set; }
public string Department { get; set; }
public string Note { get; set; }
}
}
Results of console.logs in the service file.
at service
slg-corp-notes.service.ts:22 {departments: 2, weeks: SLGTime, noteBody: "asdf"}
slg-corp-notes.service.ts:25 CorpNotes {department: 2, note: "asdf", weekEnding: "2019-11-02T00:00:00"}
slg-corp-notes.service.ts:26 {"department":2,"note":"asdf","weekEnding":"2019-11-02T00:00:00"}
slg-corp-notes.service.ts:27 ?Department=2&Note=asdf&WeekEnding=2019-11-02T00:00:00
slg-corp-notes.service.ts:28 Observable {_isScalar: false, source: Observable, operator: MapOperator}
app.module.ts
This is in my app.module.ts where I specify routes
{ path: 'slg-corp-notes', component: SlgCorpNotesComponent },
{ path: 'slg-corp-notes/edit/', component: SlgCorpNotesComponent }
slg-corp-notes.component.ts
save() {
console.log("at save")
if (!this.optionsForm.valid) {
return;
}
//this.Notes.note = this.optionsForm.get['noteBody'].value;
console.log(this.Notes);
this._slgCorpNotesService.updateMessage(this.optionsForm.value)
.subscribe((data) => {
this._router.navigate(['/slg-corp-notes']); //This will navigate back to the mochhub2 index where the message will be displayed
}, error => this.errorMessage = error)
}
Please let me know if additional info is needed.
1) You need to set the Content-Type header to application/json.
2) stringify the message.
const headers = new HttpHeaders()
.set('Content-Type', 'application/json;charset=UTF-8')
let options = { headers : headers };
this.http.post(this.baseUrl + 'api/SlgCorpNotes/Edit', JSON.stringify(newMessage), options);
At your angular side update your method like this
updateMessage(message: any) {
console.log("at service")
console.log(message)
var newMessage = new CorpNotes(message['departments'], message['noteBody'], message['weeks'].weekEnding)
var Params = '?Department=' + message['departments'] + '&Note=' + message['noteBody'] + '&WeekEnding=' + message['weeks'].weekEnding
console.log(newMessage)
console.log(JSON.stringify(newMessage))
console.log(Params)
var item = {
"Departments": message["Departments"],
"Note": message["noteBody"],
"WeekEnding": message["weeks"]
}
return this.http.post(this.baseUrl + 'api/SlgCorpNotes/Edit', item).subscribe(res
=> {
console.log(res);
}, error => {
console.log(error);
});
}
I'm setting up an environment where I pass 4 parameters (Encrypted file, Key File, Pass Phase and Default File name) to a .Jar and it decrypts the file.
I have achieved it via Bouncycastle API and it works fine on the eclipse IDE.
Now I have to set this up in my servicenow mid-server.
So the javascript probe should call this jar file and pass the parameters as strings and the encrypted file (which resides on the mid-server) gets decrypted.
I have tried creating a mid-server script include in servicenow and a probe but it returns with an error that the method is not found (which is actually there)
CLASS INSIDE .JAR
package pgpDecrypt;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Iterator;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import org.bouncycastle.util.io.Streams;
public class PGPDecryption {
public static void decryptFile(String inputFileName, String keyFileName, char[] passwd, String defaultFileName)
throws IOException, NoSuchProviderException {
Security.addProvider(new BouncyCastleProvider());
InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));
InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName));
decryptFiles(in, keyIn, passwd, defaultFileName);
System.out.print("Default File Name : "+ defaultFileName);
keyIn.close();
in.close();
}
/**
* decrypt the passed in message stream
*/
public static void decryptFiles(InputStream in, InputStream keyIn, char[] passwd, String defaultFileName)
throws IOException, NoSuchProviderException {
in = PGPUtil.getDecoderStream(in);
try {
JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
//
// the first object might be a PGP marker packet.
//
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}
//
// find the secret key
//
Iterator it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn),
new JcaKeyFingerprintCalculator());
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
sKey = PGPUtilE.findSecretKey(pgpSec, pbe.getKeyID(), passwd);
}
if (sKey == null) {
throw new IllegalArgumentException("secret key for message not found.");
}
InputStream clear = pbe
.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));
JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
PGPCompressedData cData = (PGPCompressedData) plainFact.nextObject();
InputStream compressedStream = new BufferedInputStream(cData.getDataStream());
JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(compressedStream);
Object message = pgpFact.nextObject();
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
String outFileName = ld.getFileName();
if (outFileName.length() == 0) {
outFileName = defaultFileName;
}
InputStream unc = ld.getInputStream();
OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName));
Streams.pipeAll(unc, fOut);
fOut.close();
} else if (message instanceof PGPOnePassSignatureList) {
throw new PGPException("encrypted message contains a signed message - not literal data.");
} else {
throw new PGPException("message is not a simple encrypted file - type unknown.");
}
if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
System.err.println("message failed integrity check");
} else {
System.err.println("message integrity check passed");
}
} else {
System.err.println("no message integrity check");
}
} catch (PGPException e) {
System.err.println(e);
if (e.getUnderlyingException() != null) {
e.getUnderlyingException().printStackTrace();
}
}
}
private static void encryptFile(String outputFileName, String inputFileName, String encKeyFileName, boolean armor,
boolean withIntegrityCheck) throws IOException, NoSuchProviderException, PGPException {
OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
PGPPublicKey encKey = PGPUtilE.readPublicKey(encKeyFileName);
encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);
out.close();
}
private static void encryptFile(OutputStream out, String fileName, PGPPublicKey encKey, boolean armor,
boolean withIntegrityCheck) throws IOException, NoSuchProviderException {
if (armor) {
out = new ArmoredOutputStream(out);
}
try {
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setWithIntegrityPacket(withIntegrityCheck)
.setSecureRandom(new SecureRandom()).setProvider("BC"));
cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
OutputStream cOut = cPk.open(out, new byte[1 << 16]);
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP);
PGPUtil.writeFileToLiteralData(comData.open(cOut), PGPLiteralData.BINARY, new File(fileName),
new byte[1 << 16]);
comData.close();
cOut.close();
if (armor) {
out.close();
}
} catch (PGPException e) {
System.err.println(e);
if (e.getUnderlyingException() != null) {
e.getUnderlyingException().printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
if (args.length == 0) {
System.err.println(
"usage: PGPDecryption -d file [secretKeyFile passPhrase|pubKeyFile]");
return;
}
if (args[0].equals("-e")) {
if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia")) {
encryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].indexOf('i') > 0));
} else if (args[1].equals("-i")) {
encryptFile(args[2] + ".bpg", args[2], args[3], false, true);
} else {
encryptFile(args[1] + ".bpg", args[1], args[2], false, false);
}
} else if (args[0].equals("-d")) {
decryptFile(args[1], args[2], args[3].toCharArray(), new File(args[1]).getName() + ".out");
} else {
System.err.println(
"usage: PGPDecryption -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
}
}
}
SCRIPT INCLUDE :
var ProcessPGP = Class.create();
ProcessPGP.prototype = {
initialize: function() {
this.Pgp = Packages.pgpDecrypt.PGPDecryption.decryptFile;
this.inputFile = probe.getParameter("inputFile");
this.secretFile = probe.getParameter("secretFile");
this.passPhase = probe.getParameter("passPhase");
this.defaultName = probe.getParameter("defaultName");
},
execute: function() {
var pgpObj = new this.Pgp(this.inputFile, this.secretFile, this.passPhase, this.defaultName);
},
type: ProcessPGP
};
PROBE :
var jspr = new JavascriptProbe('ANIRUDGU-68LCS_Dev1');
jspr.setName('TestPGPDemo5');
jspr.setJavascript('var pdf = new ProcessPGP(); res = pdf.execute();');
jspr.addParameter("inputFile", "C:\Users\anirudgu\Desktop\PGPTestKey\TestRun2.pgp");
jspr.addParameter("secretFile", "C:\Users\anirudgu\Desktop\PGPTestKey\anirudguciscocomprivate.asc");
jspr.addParameter("passPhase", "Hello");
jspr.addParameter("defaultName", "FilefromProbe");
jspr.create();
But I am facing the below mentioned error :
08/22/19 23:21:58 (097) Worker-Standard:JavascriptProbe-ce4567ebdb9b330045bb9b81ca961910 WARNING *** WARNING *** org.mozilla.javascript.EvaluatorException: Can't find method pgpDecrypt.PGPDecryption.decryptFile(java.lang.String,java.lang.String,java.lang.String,java.lang.String). (script_include:ProcessPGP; line 32)
EvaluatorException(var pdf = new ProcessPGP(); res = pdf.execute();)
The method decryptFile is static. The new keyword can only be used to create instances.
Therefore, try:
var pgpObj = this.Pgp(this.inputFile, this.secretFile, this.passPhase, this.defaultName);
Try to remove "new" from:
jspr.setJavascript('var pdf = new ProcessPGP(); res =
pdf.execute();');
hello i have this problem:
I have a addins for office(word);
I want to send a copy of current file (.docx) to C# controller, i have this code now, at this stage of the code i get a array of chars or somethis in the "yourfile", how ca i get a .docx file?
JavaScript
function sendFile() {
Office.context.document.getFileAsync("compressed",
{ sliceSize: 100000 },
function (result) {
if (result.status == Office.AsyncResultStatus.Succeeded) {
var myFile = result.value;
var state = {
file: myFile,
counter: 0,
sliceCount: myFile.sliceCount
};
getSlice(state);
}
});
}
function getSlice(state) {
state.file.getSliceAsync(state.counter, function (result) {
if (result.status == Office.AsyncResultStatus.Succeeded) {
sendSlice(result.value, state);
}
});
}
function myEncodeBase64(str)
{
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
function sendSlice(slice, state) {
var data = slice.data;
if (data) {
var fileData = myEncodeBase64(data);
var _url = '../../api/file';
useAjax(_url, 'Post', JSON.stringify(fileData), _contentType).done(function (data) {
writeData(data);
app.showNotification("Translation was successfully done!");
});
}
}
And the C# CONTROLLER:
public static string filemame = #"c:\yourfile";
[Route("file")]
[HttpPost]
public void getFile([FromBody] string data)
{
Base64ToFile(data,filemame);
}
public static void Base64ToFile(string base64String, string filename)
{
byte[] fileByteArray = Convert.FromBase64String(base64String);
// Instantiate FileStream to create a new file
System.IO.FileStream writeFileStream = new System.IO.FileStream(filename, System.IO.FileMode.Create, System.IO.FileAccess.Write);
// Write converted base64String to newly created file
writeFileStream.Write(fileByteArray, 0, fileByteArray.Length);
// Clean up / disposal
writeFileStream.Close();
}
Late to the party, but I'm adding the answer here nonetheless, in case someone else will need it at some later date.
Instead of using myEncodeBase64 you should use
var fileData = OSF.OUtil.encodeBase64(data);
It's a function that is part of the Office API, so you don't have to define anything else.
I have been struggling to construct a correct pptx serverside. Eventually this is what I came up with.
Javascript
function sendSlice(slice, state) {
var data = slice.data;
if (data) {
var isLastSlice = state.counter >= (state.sliceCount -1);
var ajaxData = {
isLastSlice: isLastSlice,
counter: state.counter,
documentData: btoa(data)
}
$.ajax({
url: "/api/Constructpptx", method: "POST", data: ajaxData, success: function (result) {
state.counter++;
if (isLastSlice) {
closeFile(state);
}
else {
getSlice(state);
}
}, error: function (xhr, status, error) {
}
});
}
}
And as an API backend I use this
C# ApiController
public class ConstructpptxController : ApiController
{
public static List<byte> Document { get; set; } = new List<byte>();
public string Post([FromBody]ConstructpptxPayload payload)
{
if (payload.counter == 0)
Document.Clear();
var payloadData = Convert.FromBase64String(payload.documentData);
var pptBytes = Encoding.UTF8.GetString(payloadData).Split(',').Select(byte.Parse).ToArray();
Document.AddRange(pptBytes);
if(payload.isLastSlice)
{
var path = #"C:/Some/Local/Path/Presentation.pptx";
var fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite);
fileStream.Write(Document.ToArray(), 0, Document.Count());
fileStream.Close();
Document.Clear();
}
return $"Counter: {payload.counter}, isLast: {payload.isLastSlice}, docLength: {Document.Count}";
}
}
public class ConstructpptxPayload
{
public bool isLastSlice { get; set; }
public int counter { get; set; }
public string documentData { get; set; }
}
Please note: only use this example as a quick starting point, as you don't want to save the bytes in a static List Document. Instead you want to make your webserver stateless.