In FLUTTER - DART using RSA algoritm i get a privateKey. I have this method for encode privateKey to PEM in PKCS#1 format but i need a method for encode the privateKey to PKCS#8 format. I can't finde nothing in internet for that.
Uint8List _encodePrivateKeyToPemPKCS1(RSAPrivateKey privateKey) {
var topLevel = new ASN1Sequence();
var version = ASN1Integer(BigInt.from(0));
var modulus = ASN1Integer(privateKey.n!);
var publicExponent = ASN1Integer(privateKey.exponent!);
var privateExponent = ASN1Integer(privateKey.privateExponent!);
var p = ASN1Integer(privateKey.p!);
var q = ASN1Integer(privateKey.q!);
var dP = privateKey.privateExponent! % (privateKey.p! - BigInt.from(1));
var exp1 = ASN1Integer(dP);
var dQ = privateKey.privateExponent! % (privateKey.q! - BigInt.from(1));
var exp2 = ASN1Integer(dQ);
var iQ = privateKey.q!.modInverse(privateKey.p!);
var co = ASN1Integer(iQ);
topLevel.add(version);
topLevel.add(modulus);
topLevel.add(publicExponent);
topLevel.add(privateExponent);
topLevel.add(p);
topLevel.add(q);
topLevel.add(exp1);
topLevel.add(exp2);
topLevel.add(co);
return topLevel.encodedBytes;
}
This code work for me. Thanks Topaco
https://raw.githubusercontent.com/Ephenodrom/Dart-Basic-Utils/master/lib/src/CryptoUtils.dart
https://raw.githubusercontent.com/Ephenodrom/Dart-Basic-Utils/master/lib/src/StringUtils.dart
Related
I need to take data from a basic excel form and paste it on a data table as many times as one of the cells form the form says.
This is the form:
Form
I've tried this:
function COPIARPEGAR() {
var Libro = SpreadsheetApp.getActiveSpreadsheet();
var Form = Libro.getSheetByName("Form")
var CON = Form.getRange('J18').getValue();
var Disciplina = Form.getRange('J20').getValue();
var Masculino = Form.getRange('L22').getValue();
var TituloMasculino = Form.getRange('L20').getValue();
var Femenino = Form.getRange('N22').getValue();
var TituloFemenino = Form.getRange('N20').getValue();
var BBDD = Libro.getSheetByName("BBDD2");
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length
for(var filamasc=UltimaFila+1;filamasc<=Masculino+1;filamasc++) {
BBDD.getRange(filamasc,1).setValue(Disciplina)
BBDD.getRange(filamasc,2).setValue(CON)
BBDD.getRange(filamasc,3).setValue(TituloMasculino)
for(var filafem=UltimaFila+1;filafem<=Femenino+1;filafem++) {
BBDD.getRange(filafem,1).setValue(Disciplina)
BBDD.getRange(filafem,2).setValue(CON)
BBDD.getRange(filafem,3).setValue(TituloFemenino)
}
Logger.log(UltimaFila);
Logger.log(CON);
Logger.log(Disciplina)
}
And as result I always get the smaller number overwrited by the largest number like this:
result
Thanks for yur help!
Your loops are the issue in that you aren't starting at the same rows. Consider running your code in debug mode so you can see your variables value on the right hand part of the screen (such as UltimaFila = 1). I looked at your code, and I think this would work with modifications, but again look at your variables on the right side of your code, and run in debug mode.
function COPIARPEGAR() {
var Libro = SpreadsheetApp.getActiveSpreadsheet();
var Form = Libro.getSheetByName("Form")
var CON = Form.getRange('J18').getValue();
var Disciplina = Form.getRange('J20').getValue();
var Masculino = Form.getRange('L22').getValue();
var TituloMasculino = Form.getRange('L20').getValue();
var Femenino = Form.getRange('N22').getValue();
var TituloFemenino = Form.getRange('N20').getValue();
var BBDD = Libro.getSheetByName("BBDD2");
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length;
//Updated the ending point
for (var filamasc = UltimaFila + 1; filamasc <= Masculino + 1 + UltimaFila; filamasc++) {
BBDD.getRange(filamasc, 1).setValue(Disciplina)
BBDD.getRange(filamasc, 2).setValue(CON)
BBDD.getRange(filamasc, 3).setValue(TituloMasculino)
}
//See the starting points change
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length
//Updated the ending point
for (var filafem = UltimaFila + 1; filafem <= Femenino + 1 + UltimaFila; filafem++) {
BBDD.getRange(filafem, 1).setValue(Disciplina)
BBDD.getRange(filafem, 2).setValue(CON)
BBDD.getRange(filafem, 3).setValue(TituloFemenino)
}
Logger.log(UltimaFila);
Logger.log(CON);
Logger.log(Disciplina)
}
How To Debug Your Code
I want to encrypt the value with public key, I used pointycastle package and RSA and PKCS1 v1.5 padding, but this didn't work.
publicKey: 7/ZVKLxKXsQnlVUozywoumbFGbSz8kbH178dT165ODd/a/dUMAsdvs90iCLZo4KVoxZbQpD9d5K/Qgs1wjjylQ==
plainText:
a57b4b30-6b96-11ec-a8cf-c308568a983a
String encrypt(String plaintext, String publicKey) {
var modulusBytes = base64.decode(publicKey);
var modulus = BigInt.parse(hex.encode(modulusBytes), radix: 16);
var exponent = BigInt.parse(hex.encode(base64.decode('AQAB')), radix: 16);
var engine = RSAEngine()
..init(
true,
PublicKeyParameter<RSAPublicKey>(RSAPublicKey(modulus, exponent)),
);
//PKCS1.5 padding
var k = modulusBytes.length;
var plainBytes = utf8.encode(plaintext);
var paddingLength = k - 3 - plainBytes.length;
var eb = Uint8List(paddingLength + 3 + plainBytes.length);
var r = Random.secure();
eb.setRange(paddingLength + 3, eb.length, plainBytes);
eb[0] = 0;
eb[1] = 2;
eb[paddingLength + 2] = 0;
for (int i = 2; i < paddingLength + 2; i++) {
eb[i] = r.nextInt(254) + 1;
}
print(plainBytes.length);
print(eb);
return base64.encode(
engine.process(eb),
);
}
A couple of comments first...
Let's assume that the "public key" you provide is the modulus of an RSA key. We have to assume that the exponent is 65537. You'd normally want to get the public key in a PEM or similar. If that is the modulus, it's painfully short at just 512 bytes.
There only version of PKCS1 that's less than 2.x is 1.5. In particular, pointy castle's implementation in PKCS1Encoding is an implementation of 1.5.
You can only encrypt bytes. So, how are we meant to turn your "plaintext" into bytes. It could be a string that we could just encode in utf8. But it looks like a UUID. Maybe you are meant to interpret it as its normal representation as a 128 bit number, in bytes.
Finally, the output of the encryption will be bytes. How are you meant to send those to the server? Does it want them converted to a string first? If so, how? In base64? In hex?
The following code assumes: yes, that's a 512 bit modulus; the plaintext is not a UUID that can be interpreted, but is just a string that should be converted to ASCII bytes; the output is just an array of bytes.
import 'dart:convert';
import 'dart:typed_data';
import 'package:convert/convert.dart';
import 'package:pointycastle/export.dart';
void main() {
final publicKey =
'7/ZVKLxKXsQnlVUozywoumbFGbSz8kbH178dT165ODd/a/dUMAsdvs90iCLZo4KVoxZbQpD9d5K/Qgs1wjjylQ==';
final plaintext = 'a57b4b30-6b96-11ec-a8cf-c308568a983a';
var modulusBytes = base64.decode(publicKey);
var modulus = BigInt.parse(hex.encode(modulusBytes), radix: 16);
var exponent = BigInt.from(65537);
var engine = PKCS1Encoding(RSAEngine())
..init(
true,
PublicKeyParameter<RSAPublicKey>(RSAPublicKey(modulus, exponent)),
);
print(engine.process(utf8.encode(plaintext) as Uint8List));
}
We have a requirement where we will get modulus from service call to be used for encrypting (JWE) some data at client side
Example of modulus, and exponent (cannot be changed formats)
{
"modulus": "27921539673885756361419156461021876226845445107119091471889357242434620975884246915491757578902818243635599516623468500514580405147004224500529164165175418080296534603814824585285975894063860621755306618118216921360279638839263914961253991832884140339596254323951288609833783395465326689135784495563016459486626252473786100255392919521063720839389818627863002071132030078117996952009416186398741189513852165509082498538217432301912889497439381201450665516807813007876250433333575497298297093128243716605741969339467610040987340399020751603712326128652340270376013354086995479489210853404012768884141354633100389617819",
"exponent": "65537",
}
I am trying to use JavaScript Jose library to generate JWE, but no luck.
I am following below example from internet, but my question is modulus I am using seems to be in biginteger (i guess) format, but the example showing different format.
Is there a better way I can use JOSE for JWE if I have modulus and exponent as shown above? Or can it be done as its shown below, but I am getting an error:
var cryptographer = new Jose.WebCryptographer();
var rsa_key = Jose.Utils.importRsaPublicKey(
{
n:
"c2:4b:af:0f:2d:2b:ad:36:72:a7:91:0f:ee:30:a0:95:d5:3a:46:82:86:96:7e:42:c6:fe:8f:20:97:af:49:f6:48:a3:91:53:ac:2e:e6:ec:9a:9a:e0:0a:fb:1c:db:44:40:5b:8c:fc:d5:1c:cb:b6:9b:60:c0:a8:ac:06:f1:6b:29:5e:2f:7b:09:d9:93:32:da:3f:db:53:9c:2e:ea:3b:41:7f:6b:c9:7b:88:9f:2e:c5:dd:42:1e:7f:8f:04:f6:60:3c:fe:43:6d:32:10:ce:8d:99:cb:76:f7:10:97:05:af:28:1e:39:0f:78:35:50:7b:8e:28:22:a4:7d:11:51:22:d1:0e:ab:6b:6f:96:cb:cf:7d:eb:c6:aa:a2:6a:2e:97:2a:93:af:a5:89:e6:c8:bc:9f:fd:85:2b:0f:b4:c0:e4:ca:b5:a7:9a:01:05:81:93:6b:f5:8d:1c:f7:f3:77:0e:6e:53:34:92:0f:48:21:34:33:44:14:5e:4a:00:41:3a:7d:cb:38:82:c1:65:e0:79:ea:a1:05:84:b2:6e:40:19:77:1a:0e:38:4b:28:1f:34:b5:cb:ac:c5:2f:58:51:d7:ec:a8:08:0e:7c:c0:20:c1:5e:a1:4d:b1:30:17:63:0e:e7:58:8e:7f:6e:9f:a4:77:8b:1e:a2:d2:2e:1b:e9",
e: 65537
},
"RSA-OAEP"
);
var encrypter = new Jose.JoseJWE.Encrypter(cryptographer, rsa_key);
encrypter
.encrypt("hello world")
.then(function(result) {
console.log(result);
})
.catch(function(err) {
console.error(err);
});
The decimal string representing the modulus must be converted to a hexadecimal string with the proper formatting. In the following code this is done by the convert function.
The example encrypts and decrypts a plaintext and is essentially taken from the description of js-jose. The converted modulus is used for the encryption. The validity of the conversion can be cross checked e.g. here (and can of course also be concluded from the successful decryption):
function convert(modulus){
var nHex = BigInt(modulus).toString(16); // Convert from dec to hex
var nHexPadded = nHex.length % 2 ? "0" + nHex : nHex; // Pad if necessary with a leading 0
var nHexPaddedFormatted = nHexPadded.match(/.{1,2}/g).join(':'); // Separate each byte with a :
return nHexPaddedFormatted;
}
var exponent = "65537";
var modulus = "24527552248658638593238312534622665239452237617916915035327410973877933321625015819725141075075211032977064656616272935088402961419107720169032602127557052115192166251022433499097931189631750439635561603835889998309453723345666313950232348492443075827282756304618422730925476259619200114387693134398859680038905017069367126679713008966792133309640987499113594495057801427098321936394744165577110835460409347737585308896989425915113198172049505101019813693205226199749749144689080410566381237890461144281136847243342701604504885554436502186579457750948522590884398208445448252725393629705457022749423572745479491820521";
console.log(convert(modulus).replace(/(.{60})/g,'$1\n'));
var publicKey = Jose.Utils.importRsaPublicKey(
{
/*
n: "c2:4b:af:0f:2d:2b:ad:36:72:a7:91:0f:ee:30:a0:95:d5:3a:46:82:86:96:7e:42:c6:fe:8f:20:97:af:49:f6:48:a3:91:53:ac:2e:e6:ec:9a:9a:e0:0a:fb:1c:db:44:40:5b:8c:fc:d5:1c:cb:b6:9b:60:c0:a8:ac:06:f1:6b:29:5e:2f:7b:09:d9:93:32:da:3f:db:53:9c:2e:ea:3b:41:7f:6b:c9:7b:88:9f:2e:c5:dd:42:1e:7f:8f:04:f6:60:3c:fe:43:6d:32:10:ce:8d:99:cb:76:f7:10:97:05:af:28:1e:39:0f:78:35:50:7b:8e:28:22:a4:7d:11:51:22:d1:0e:ab:6b:6f:96:cb:cf:7d:eb:c6:aa:a2:6a:2e:97:2a:93:af:a5:89:e6:c8:bc:9f:fd:85:2b:0f:b4:c0:e4:ca:b5:a7:9a:01:05:81:93:6b:f5:8d:1c:f7:f3:77:0e:6e:53:34:92:0f:48:21:34:33:44:14:5e:4a:00:41:3a:7d:cb:38:82:c1:65:e0:79:ea:a1:05:84:b2:6e:40:19:77:1a:0e:38:4b:28:1f:34:b5:cb:ac:c5:2f:58:51:d7:ec:a8:08:0e:7c:c0:20:c1:5e:a1:4d:b1:30:17:63:0e:e7:58:8e:7f:6e:9f:a4:77:8b:1e:a2:d2:2e:1b:e9",
*/
n: convert(modulus), // Apply the converted modulus
e: parseInt(exponent)
},
"RSA-OAEP"
);
var privateKey = Jose.Utils.importRsaPrivateKey(
{
n:
"00:c2:4b:af:0f:2d:2b:ad:36:72:a7:91:0f:ee:30:a0:95:d5:3a:46:82:86:96:7e:42:c6:fe:8f:20:97:af:49:f6:48:a3:91:53:ac:2e:e6:ec:9a:9a:e0:0a:fb:1c:db:44:40:5b:8c:fc:d5:1c:cb:b6:9b:60:c0:a8:ac:06:f1:6b:29:5e:2f:7b:09:d9:93:32:da:3f:db:53:9c:2e:ea:3b:41:7f:6b:c9:7b:88:9f:2e:c5:dd:42:1e:7f:8f:04:f6:60:3c:fe:43:6d:32:10:ce:8d:99:cb:76:f7:10:97:05:af:28:1e:39:0f:78:35:50:7b:8e:28:22:a4:7d:11:51:22:d1:0e:ab:6b:6f:96:cb:cf:7d:eb:c6:aa:a2:6a:2e:97:2a:93:af:a5:89:e6:c8:bc:9f:fd:85:2b:0f:b4:c0:e4:ca:b5:a7:9a:01:05:81:93:6b:f5:8d:1c:f7:f3:77:0e:6e:53:34:92:0f:48:21:34:33:44:14:5e:4a:00:41:3a:7d:cb:38:82:c1:65:e0:79:ea:a1:05:84:b2:6e:40:19:77:1a:0e:38:4b:28:1f:34:b5:cb:ac:c5:2f:58:51:d7:ec:a8:08:0e:7c:c0:20:c1:5e:a1:4d:b1:30:17:63:0e:e7:58:8e:7f:6e:9f:a4:77:8b:1e:a2:d2:2e:1b:e9",
e: 65537,
d:
"37:b6:4b:f4:26:17:a8:0b:3c:c5:1f:ab:59:b9:47:d2:ae:d9:8e:ee:4e:79:48:ab:0d:34:61:06:0f:78:8b:d4:ba:ef:6b:f4:7a:22:d8:c4:6f:70:89:5d:9c:b3:a1:8b:e8:88:57:dd:07:9e:c2:2b:12:52:a3:eb:b9:a8:24:01:7e:53:2b:7a:34:50:d7:0c:75:d8:69:a3:87:dd:4b:fc:c1:c3:2f:bd:0e:57:16:8d:ea:de:8e:de:ff:e4:9a:9f:aa:e8:d2:5f:b3:27:ef:f9:ca:50:97:2e:fd:99:1c:34:dd:0c:bb:dd:d0:b9:bf:4f:dc:9d:de:94:50:66:2c:58:7e:c2:31:8b:41:56:49:6a:e6:11:14:53:a1:45:0d:15:8b:26:79:0f:c9:dc:ac:dc:c7:bc:55:2c:96:ed:a7:29:09:04:ee:00:74:60:e1:bc:97:7b:0a:b6:f2:83:82:79:65:e0:aa:88:9f:90:b0:0d:76:4d:3c:08:7e:a5:05:19:d4:8b:54:d3:f1:c1:a3:e3:a5:1e:aa:d6:c4:94:ad:6c:b3:8f:85:06:8a:6f:52:f8:a3:c3:e0:8d:67:35:2f:d4:18:fc:70:f4:71:bf:18:88:d6:a7:b7:04:8e:d3:06:ca:83:c3:2d:21:98:65:c9:41:2c:77:bf:4c:7c:8c:2c:01",
p:
"00:fa:d6:06:46:5c:04:70:e6:ec:47:02:96:02:a5:e2:41:9d:bd:7b:97:28:a4:c5:3b:b5:9b:0a:6b:7d:b6:44:8a:28:1e:d1:ef:cb:44:ef:eb:4d:08:74:80:f5:cf:3b:b7:40:10:60:c9:18:1e:a5:76:4b:41:37:06:b2:71:03:60:25:77:db:d0:b2:21:dc:b0:32:90:a2:10:9a:d5:e6:e3:11:42:a1:9a:7a:26:3c:d3:12:56:db:25:07:69:be:ae:2c:b9:33:6c:29:e3:65:b9:5b:05:84:05:e6:da:c4:f4:3f:ab:84:60:6e:f0:5f:ba:a8:98:8f:72:2c:c8:40:d1",
q:
"00:c6:4b:ac:fe:40:1c:dc:6c:78:07:cc:3e:db:4e:d5:d0:17:3b:8f:04:f0:ae:c4:22:0d:8b:0a:4d:0f:9e:fe:c7:e6:38:b5:53:ba:a9:e8:f0:47:28:14:25:95:6a:79:ab:db:86:97:82:c5:1e:bd:80:a5:aa:a2:b7:a5:c7:48:17:c4:d9:c7:4f:50:2a:69:67:15:4c:0b:f5:e6:fb:20:23:5d:ea:ae:6c:c6:74:ba:cc:f8:06:2b:41:1f:b6:3f:2a:93:fa:f9:e1:ee:93:c3:92:ad:49:c7:8f:db:72:ff:6b:f0:f0:d6:2f:83:ce:1c:82:16:89:57:01:9f:49:2f:99",
dp:
"57:d4:c1:75:b9:9a:c4:7d:d7:96:35:cd:99:37:c4:b5:fd:29:f0:30:c9:c6:88:59:94:09:a9:e8:61:a8:84:ef:6b:84:ff:35:dc:13:53:7f:2d:06:1c:e5:5b:2d:29:57:cd:52:ee:d0:fb:65:1f:c3:00:2e:e1:b9:b2:99:e7:f8:ae:a5:fd:8e:62:11:81:59:21:1b:8b:e4:0c:93:81:b9:58:bd:e0:20:5b:4d:30:57:28:40:c9:93:79:b9:09:4f:ab:d1:5d:b4:2e:26:b5:e3:e5:7f:54:ef:4c:1a:a6:84:70:16:fa:cf:59:89:49:bb:ee:75:1d:25:79:90:d5:41",
dq:
"00:ab:eb:a8:8c:b7:21:4e:aa:6c:56:b6:6a:38:d1:dc:e6:91:7d:fd:bd:96:be:af:25:a7:00:49:6a:0e:85:16:f8:51:4e:11:48:0a:aa:8d:5e:e5:12:86:85:1f:4a:35:3b:1f:15:4d:fe:fe:d0:6c:14:41:8d:f3:8d:ad:99:5d:93:de:03:c2:9d:ad:2f:58:3b:1b:67:d7:66:d7:60:1a:b9:0f:10:0d:32:19:cd:d2:b7:2a:c2:8e:75:e3:fc:aa:3f:4c:15:68:d8:cd:74:27:37:e0:2d:fb:6b:6a:24:05:f7:9b:e9:f2:89:37:89:57:86:21:eb:e9:17:6a:f6:94:e1",
qi:
"0a:ed:5f:30:67:d5:e5:6e:4a:7a:35:49:fe:16:2f:1e:91:2b:39:c3:01:d3:d4:c0:4d:b3:fc:08:b0:66:e9:44:10:9e:5b:5a:ea:83:a5:9c:95:7a:58:70:35:28:e5:4d:ba:19:de:0d:66:f9:db:5c:f6:5b:24:27:9d:0b:2d:44:40:eb:33:3a:19:e2:1d:c0:b0:16:99:d1:c1:52:84:02:d6:67:06:32:f8:4d:cb:42:9f:7c:8a:e0:ad:df:40:6f:e4:8c:f6:f6:9e:1d:bd:43:e3:38:91:a2:d0:9e:60:ff:9d:8c:fb:72:5b:df:95:30:17:d2:f2:cb:7d:92:56:0a"
},
"RSA-OAEP"
);
// Example based on https://github.com/square/js-jose#example-encryption
var cryptographer = new Jose.WebCryptographer();
var encrypter = new Jose.JoseJWE.Encrypter(cryptographer, publicKey);
encrypter
.encrypt("The quick brown fox jumps over the lazy dog")
.then(function(jwe) {
console.log(jwe.replace(/(.{60})/g,'$1\n'));
var decrypter = new Jose.JoseJWE.Decrypter(cryptographer, privateKey);
decrypter
.decrypt(jwe)
.then(function(jwe_plain_text) {
console.log(jwe_plain_text.replace(/(.{60})/g,'$1\n'));
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-jose/0.2.2/jose.min.js"></script>
I'm trying to understand AudioComponents before instanciate them and understand/use AudioUnits...
I create an AudioComponentDescription by using wildcards:
var inDesc = AudioComponentDescription(componentType: OSType(),
componentSubType: OSType(),
componentManufacturer: OSType(),
componentFlags: UInt32(0),
componentFlagsMask: UInt32(0))
I look how many AudioComponent there is:
AudioComponentCount(&inDesc) // returns 98 in a playground (ok)
I focus the first AudioComponent by using "nil" as first parameter in AudioComponentFindNext:
var currentComp = AudioComponentFindNext(nil, &inDesc)
Looking at its name:
func getAudioComponentName (componentInit:AudioComponent) -> CFString {
var componentProp:AudioComponent = componentInit
var componentNameProp:CFString = "" as CFString
var unmanagedCurrentCompName:Unmanaged<CFString>?
AudioComponentCopyName(componentProp, &unmanagedCurrentCompName)
componentNameProp = unmanagedCurrentCompName!.takeRetainedValue()
return componentNameProp
}
var currentComponentName:CFString = "" as CFString
currentComponentName = getAudioComponentName(currentComp) // returns "Apple PAC3 Transcoder" (ok)
At this point, the following tries will not be "ok".
I want to know much more about this "Apple PAC3 Transcoder" and its description:
// Creating an empty AudioComponentDescription
var currentComponentDescription = AudioComponentDescription()
// Gettings currentComp's description (type)
AudioComponentGetDescription(currentComp, ¤tComponentDescription)
var compDescType:OSType = currentComponentDescription.componentType // returns 1633903715
At the last line of code, how could I get the letter code described in AUComponent.h:
enum
{
kAudioUnitType_Output = 'auou',
kAudioUnitType_MusicDevice = 'aumu',
kAudioUnitType_MusicEffect = 'aumf',
kAudioUnitType_FormatConverter = 'aufc',
kAudioUnitType_Effect = 'aufx',
kAudioUnitType_Mixer = 'aumx',
kAudioUnitType_Panner = 'aupn',
kAudioUnitType_Generator = 'augn',
kAudioUnitType_OfflineEffect = 'auol',
kAudioUnitType_MIDIProcessor = 'aumi'
};
for further compatibility I prefer to not have to reproduce this "enum" in my code.
componentType is an OSType which is 4 ASCII character codes packed into 32 bits.
1633903715 in hexadecimal is 0x61636463
0x61636463 in ascii is 'acdc' (0x61 = 'a', 0x63 = 'c', etc...)
I would like to use the Email Settings API with Apps Script to manage all users signatures on a Google Site. I have used Documents Data APIs before with 2-legged OAuth and it worked just fine. I am currently stuck on the authentication step for Email Settings API.
Code example:
// Setup OAuthServiceConfig
var oAuthConfig = UrlFetchApp.addOAuthService("signature");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken");
//I left scope empty to gain access to all APIs would this scope work scope=https://apps-apis.google.com/a/feeds/emailsettings/2.0/
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setConsumerKey("domain.com");
oAuthConfig.setConsumerSecret("consumerSecret");
// Setup optional parameters to point request at OAuthConfigService. The "signature"
// value matches the argument to "addOAuthService" above.
var options =
{
"method" : method,
"oAuthServiceName" : "signature",
"oAuthUseToken" : "always"
};
var result = UrlFetchApp.fetch("https://apps-apis.google.com/a/feeds/emailsettings/2.0/"+domainName+"/"+userName+"/signature", options);
Logger.log(result);
I get this error: "Unexpected Error (line 37)" which is
var result = UrlFetchApp.fetch("https://apps-apis.google.com/a/feeds/emailsettings/2.0/"+domainName+"/"+userName+"/signature", options);
Any thoughts on what I am doing wrong?
Scopes are here: http://support.google.com/a/bin/answer.py?hl=en&answer=162105
Hope this will help you. This is an working example which will get the user's HTML signature or Update HTML signature
/*
----------------------------------------------------------------------------------
This function will update the HTML signature of a user.
Input will be jason data
To disable signature, pass an empty string as signature value
sample parameter
ob = {user='hps', signature='<b>Regards</b><br>Waqar'}
To disable signature
ob = {user='hps', signature=''}
----------------------------------------------------------------------------------
*/
function updateSignature(ob) {
//ob = {};
//ob.user = "hps";
//ob.signature = "<b>Regards</b><br>Waqar";
var base = 'https://apps-apis.google.com/a/feeds/emailsettings/2.0/';
var xmlRaw = '<?xml version="1.0" encoding="utf-8"?>'+
'<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:apps="http://schemas.google.com/apps/2006">'+
'<apps:property name="signature" value="'+htmlEncode(ob.signature)+'" />'+
'</atom:entry>';
var fetchArgs = googleOAuth_('emailSetting',base);
fetchArgs.method = 'PUT';
fetchArgs.payload = xmlRaw;
fetchArgs.contentType = 'application/atom+xml';
var domain = UserManager.getDomain();
var url = base+domain+'/'+ob.user+'/signature';
var urlFetch = UrlFetchApp.fetch(url, fetchArgs);
var status = urlFetch.getResponseCode();
return status;
}
//-----------------------------------------------------------------------------------------------------------
//This function will retreive Signature settings as json.
/*Sample returned object
{user=hps, signature=<b>Regards</b><br>Waqar}
*/
//-----------------------------------------------------------------------------------------------------------
function retrieveSignature(user) {
var user = 'hps';
var base = 'https://apps-apis.google.com/a/feeds/emailsettings/2.0/';
var fetchArgs = googleOAuth_('emailSetting',base);
fetchArgs.method = 'GET';
var domain = UserManager.getDomain();
var url = base+domain+'/'+user+'/signature?alt=json';
var urlFetch = UrlFetchApp.fetch(url, fetchArgs);
var jsonString = urlFetch.getContentText();
var jsonArray = Utilities.jsonParse(jsonString).entry.apps$property;
var ob = {};
ob.user = user;
for(var i in jsonArray){
ob[jsonArray[i].name] = jsonArray[i].value;
}
return ob;
}
//Google oAuthConfig..
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
//This function will escape '<' and '>' characters from a HTML string
function htmlEncode(str){
str = str.replace(/</g,'<');
return str.replace(/>/g,'>')
}