I am trying to making my own signature system, just for the challenge sake. I have done like 3/4 of it.
Canonical string and String-to-sign is matching with what they except, so I will only post my signature calculation part.
signature := hmac.New(sha256.New, kSigningSum)
signature.Write([]byte(stringToSign))
signatureSum := signature.Sum(nil)
var signatureSumHexed = make([]byte, hex.EncodedLen(len(signatureSum)))
I am trying to set kSigningSum as key, and stringToSign as value, as its documented.
kSigningSum:
kSecret := AppCred.IAMSecretAccess
kDate := hmac.New(sha256.New, []byte("AWS4"+kSecret))
kDate.Write([]byte(time.Now().UTC().Format("20060102")))
kDateSum := kDate.Sum(nil)
kRegion := hmac.New(sha256.New, kDateSum)
kRegion.Write([]byte("us-east-1"))
kRegionSum := kRegion.Sum(nil)
kService := hmac.New(sha256.New, kRegionSum)
kService.Write([]byte("execute-api"))
kServiceSum := kService.Sum(nil)
kSigning := hmac.New(sha256.New, []byte("aws4_request"))
kSigning.Write(kServiceSum)
kSigningSum := kSigning.Sum(nil)
this is basically
kSigningSum = HMAC(HMAC(HMAC(HMAC("AWS4" +
kSecret,"20150830"),"us-east-1"),"iam"),"aws4_request")
AuthHeader:
var authHeader = fmt.Sprintf("AWS4-HMAC-SHA256 Credential=%s, SignedHeaders=%s, Signature=%x, X-Amz-Date=%s", AppCred.IAMClientID+"/"+credentialScope, signedHeaders, signatureSumHexed, GetTime())
I cant understand what I am doing wrong. stringToSign is String-to-sign and it is correct, 1:1 match with what Amazon expects so data is correct. There is something wrong with kSigningSum and cant understand it. help?
Related
I wrote a code where user filters a source number from the table, the code get the source number and open an Excel file with the same number in a folder, write other data into the file and then save to temp folder. The program worked for some of the Excel files in the folder, but it won't work for the majority of the files. When it finishes running it'll say Exception from HRESULT: 0x800A01A8, the file gets saved into temp folder but the data is not written into it.
https://i.stack.imgur.com/kHtbC.png
I have searched all over Google but it seems like no one had encountered the same issue as I am and I have no idea what this exception means. Below is the code.
ProductionOrder - OnAfterGetRecord()
CLEAR(xlApplication);
CLEAR(xlWorkbooks);
CLEAR(xlWorksheet);
CLEAR(xlshape);
// Open excel
IF CREATE(xlApplication, FALSE, TRUE) THEN BEGIN
xlApplication.SheetsInNewWorkbook := 1;
xlApplication.ScreenUpdating(TRUE);
xlWorkbooks := xlApplication.Workbooks;
END ELSE ERROR('Could not start Excel.');
xlWorkbooks.Open('C:\PROCESS CHECKSHEET\' + ProductionOrder."Source No." + '.xlsx');
xlWorkbook := xlApplication.ActiveWorkbook;
xlSheets := xlWorkbook.Worksheets;
FOR i := 1 TO xlSheets.Count DO BEGIN
xlWorksheet := xlSheets.Item(i);
xlWorksheet.Activate;
xlRange := xlWorksheet.Range(xlsCell(14,7));
xlRange.Value := ProductionOrder."No.";
xlRange := xlWorksheet.Range(xlsCell(14,8));
xlRange.Value := FORMAT(ProductionOrder.Quantity);
xlWorkbook._SaveAs('C:\temp\' + ProductionOrder."Source No.");
xlWorkbook.Close(TRUE);
xlApplication.Quit;
END;
CurrReport.QUIT;
LOCAL xlsCol(col : Integer) : Text
IF col > 26 THEN BEGIN
ColFirst := col DIV 26;
col := col MOD 26;
END
ELSE
ColFirst := 0;
Letters := 'ABCDEFGHIJKLMNOPQRSTUVYWXYZ';
IF ColFirst <> 0 THEN
EXIT (STRSUBSTNO('%1%2',Letters[ColFirst],Letters[col]))
ELSE
EXIT (STRSUBSTNO('%1',Letters[col]));
LOCAL xlsCell(col : Integer;row : Integer) : Text[15]
EXIT (STRSUBSTNO('%1%2',xlsCol(col),row));
Edit:
I have tried to debug. Debugger says error is on line "xlWorksheet := xlSheets.Item(i);". There is only one sheet in the Excel file that I am trying to access. What I don't understand is that it would work on other Excel files, just not on this file that I am currently trying to access.
I also found out that if I copy the content into a new Excel file, then the code would work on the new Excel file. Could it also be a problem of Excel version?
I solved this on my own.
Because the Excel files were given to me by my HOD at work (and these Excel files were written by other department), I did not know that there was a hidden sheet inside those Excel files, hence it output the exception error because my code was only indexing Excel file that only has one sheet. I changed my index to 2 and it worked. Note to self, next time gotta check for hidden sheets.
I don't know if there is a for each sheet equivalent for C/AL programming because I'm new to the language, so I used 2 for loops to solve the problem.
CLEAR(xlApplication);
CLEAR(xlWorkbooks);
CLEAR(xlWorksheet);
IF CREATE(xlApplication, FALSE, TRUE) THEN BEGIN
xlApplication.SheetsInNewWorkbook := 1;
xlApplication.ScreenUpdating(TRUE);
xlWorkbooks := xlApplication.Workbooks;
END ELSE ERROR('Could not start Excel.');
xlWorkbooks.Open('C:\13. PROCESS CHECKSHEET\' + ProductionOrder."Source No." + '.xlsx');
xlWorkbook := xlApplication.ActiveWorkbook;
xlSheets := xlWorkbook.Worksheets;
FOR I := 1 TO xlSheets.Count DO BEGIN
xlWorksheet := xlSheets.Item(I);
xlWorksheet.Activate;
xlRange := xlWorksheet.Range(xlsCell(14,7));
xlRange.Value := ProductionOrder."No.";
xlRange := xlWorksheet.Range(xlsCell(14,8));
xlRange.Value := FORMAT(ProductionOrder.Quantity);
END;
FOR I := 2 TO xlSheets.Count DO BEGIN
xlWorksheet := xlSheets.Item(I);
xlWorksheet.Activate;
IF (FORMAT(xlWorksheet.Name) = 'PROCESS CHECKSHEET') OR (FORMAT(xlWorksheet.Name) = 'Process Checksheet') THEN BEGIN
xlRange := xlWorksheet.Range(xlsCell(14,7));
xlRange.Value := ProductionOrder."No.";
xlRange := xlWorksheet.Range(xlsCell(14,8));
xlRange.Value := FORMAT(ProductionOrder.Quantity);
END;
END;
xlWorkbook.SaveAs('C:\13. PROCESS CHECKSHEET\temp\' + ProductionOrder."Source No.");
MESSAGE('Success');
xlWorkbook.Close(TRUE);
xlApplication.Quit;
CurrReport.QUIT;
I'm trying to create slice of slices.
In all the examples the inner slices are integer based.
I'm trying to create a slice of string slices.
Example:
[
[Name1,State1,Tags.Owner1]
[Name2,State2,Tags.Owner2]
[Name3,State3,Tags.Owner3]
]
I'm trying to do it this way:
outerList := [][]string{}
i := 0
for _,c := range clusters {
input := &eks.DescribeClusterInput{
Name: aws.String(c),
}
resp,err := svc.DescribeCluster(input)
if err != nil {
errorOut(`clusterData function: `+err.Error())
}
record := resp.Cluster
data,_ := json.Marshal(record)
error := json.Unmarshal(data, &cluster)
if error != nil {errorOut(error.Error())}
innerList := [...]string{cluster.Name,cluster.Tags["Vsad"],cluster.Status}
outerList[string(i)] = innerList
}
I get the below error:
non-integer slice index string(i)
cannot use innerList (type [3]string) as type []string in assignment
I know in Python I can simply do:
outerList = list()
for c in cluster:
a = [c.Name,c.State,c.Tags.Owner]
outerList.append(a)
You can use append. Formatted as follows:
// make room for clusters
outerList := make([][]string, len(clusters))
// iterate and fill cluster data
for i, c := range clusters {
// some processing where cluster variable is setupped
// add new inner slice
outerList[i] = append(outerList[i], cluster.Name, cluster.Tags["Vsad"], cluster.Status)
}
I'm trying to convert the following ES6 script to bucklescript and I cannot for the life of me figure out how to create a "closure" in bucklescript
import {Socket, Presence} from "phoenix"
let socket = new Socket("/socket", {
params: {user_id: window.location.search.split("=")[1]}
})
let channel = socket.channel("room:lobby", {})
let presence = new Presence(channel)
function renderOnlineUsers(presence) {
let response = ""
presence.list((id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
response += `<br>${id} (count: ${count})</br>`
})
document.querySelector("main[role=main]").innerHTML = response
}
socket.connect()
presence.onSync(() => renderOnlineUsers(presence))
channel.join()
the part I cant figure out specifically is let response = "" (or var in this case as bucklescript always uses vars):
function renderOnlineUsers(presence) {
let response = ""
presence.list((id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
response += `<br>${id} (count: ${count})</br>`
})
document.querySelector("main[role=main]").innerHTML = response
}
the closest I've gotten so far excludes the result declaration
...
...
let onPresenceSync ev =
let result = "" in
let listFunc = [%raw begin
{|
(id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
result += `${id} (count: ${count})\n`
}
|}
end
] in
let _ =
presence |. listPresence (listFunc) in
[%raw {| console.log(result) |} ]
...
...
compiles to:
function onPresenceSync(ev) {
var listFunc = (
(id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
result += `${id} (count: ${count})\n`
}
);
presence.list(listFunc);
return ( console.log(result) );
}
result is removed as an optimization beacuse it is considered unused. It is generally not a good idea to use raw code that depends on code generated by BuckleScript, as there's quite a few surprises you can encounter in the generated code.
It is also not a great idea to mutate variables considered immutable by the compiler, as it will perform optimizations based on the assumption that the value will never change.
The simplest fix here is to just replace [%raw {| console.log(result) |} ] with Js.log result, but it might be enlightening to see how listFunc could be written in OCaml:
let onPresenceSync ev =
let result = ref "" in
let listFunc = fun [#bs] id item ->
let count = Js.Array.length item##meta in
result := {j|$id (count: $count)\n|j}
in
let _ = presence |. (listPresence listFunc) in
Js.log !result
Note that result is now a ref cell, which is how you specify a mutable variable in OCaml. ref cells are updated using := and the value it contains is retrieved using !. Note also the [#bs] annotation used to specify an uncurried function needed on functions passed to external higher-order functions. And the string interpolation syntax used: {j| ... |j}
It seems that the "complex" (getC) function is blocked. I assume the channel is destroyed once it is read therefore I'm wondering how can I share the sC channel with both getC function and the main function without get into deadlock ( current snippet )
package main
func main() {
//simple function and complex function/channel
sC := make(chan string)
go getS(sC)
cC := make(chan string)
go getC(sC, cC)
//collect the functions result
s := <-sC
//do something with `s`. We print but we may want to use it in a `func(s)`
print(s)
//after a while we do soemthing with `c`
c := <-cC
print(c)
}
func getS(sC chan string) {
s := " simple completed "
sC <- s
}
func getC(sC chan string, cC chan string) {
//we do some complex stuff
print("complex is not complicated\n")
//Now we need the simple value so we try wait for the s channel.
s := <-sC
c := s + " more "
cC <- c //send complex value
}
You should not try to get value from sC channel in main function because the only value you send to it is consumed by getC function in seperate go routine. While trying to read sC channel main function blocks waiting for something and it never ends. Go routine getS is finished, go routine getC has consumed value from channel sC and has also finished. There is nothing in channel sC anymore.
The possible solution is to create another channel s2C and send to it value received from sC channel.
The complete correct code would look like this:
package main
func main() {
sC := make(chan string)
go getS(sC)
s2C := make(chan string)
cC := make(chan string)
go getC(s2C, cC)
s := <-sC
println(s)
s2C <- s
c := <-cC
println(c)
}
func getS(sC chan string) {
s := " simple completed "
sC <- s
}
func getC(sC chan string, cC chan string) {
s := <-sC
c := s + " more "
cC <- c
}
I should have sent s from getS. Code below
package main
import "time"
func main() {
//simple function and complex function/channel
sC := make(chan string)
go getS(sC)
cC := make(chan string)
go getC(sC, cC)
//collect the functions result
s := <-sC
//do something with `s`. We print but we may want to use it in a `func(s)`
print(s)
//after a while we do soemthing with `c`
c := <-cC
print(c)
}
func getS(sC chan string) {
s := " simple completed \n"
sC <- s
print("sent s back so that main can read it too")
sC <- s
}
func getC(sC chan string, cC chan string) {
time.Sleep(1 * time.Second)
//we do some complex stuff
print("complex is not complicated\n")
//Now we need the simple value so we try wait for the s channel.
s := <-sC
c := s + " more "
cC <- c //send complex value
}
I think the problem is with the synchronization. Using a sleep may solve the problem. When you send a value on a channel, it should be received on the other end or else it will show deadlock error.
package main
import "sync"
import "time"
import "fmt"
var wg sync.WaitGroup
func main() {
sC := make(chan string)
wg.Add(1)
go getS(sC)
cC := make(chan string)
wg.Add(1)
go getC(sC, cC)
time.Sleep(1 * time.Millisecond)
select {
case s := <-sC:
print(s)
case c := <-cC:
print(c)
}
wg.Wait()
}
func getS(sC chan string) {
defer wg.Done()
s := " simple completed "
fmt.Println(s)
sC <- s
}
func getC(sC chan string, cC chan string) {
defer wg.Done()
fmt.Println("complex is not complicated\n")
s := <-sC
c := s + " more "
cC <- c //send complex value
}
I'm trying to do a notification message when doing a process on submit but is not working
DECLARE
l_sendto NUMBER := :P22_SEND_TO;
l_user_groups NUMBER := :P22_USER_GROUP;
l_media NUMBER := :P22_MEDIA;
l_usersessionid NUMBER := :APP_SESSION;
SINGLE_USER CONSTANT number :=0;
l_aux NUMBER;
e EXCEPTION;
BEGIN
--verify if user
select userid into l_aux FROM SURV_TEMP_SENDTO WHERE userid = l_user_groups and usersessionid= l_usersessionid and rownum =1;
IF l_aux > 0 THEN
RAISE e;
ELSE
IF l_sendto = SINGLE_USER THEN
--if selected all types of medias of one user
INSERT INTO SURV_TEMP_SENDTO (userid, mediatypeid, usersessionid)
(SELECT zm.userid, zm.mediatypeid, l_usersessionid
FROM z.media zm, Z.media_type zmt
WHERE zmt.mediatypeid = zm.mediatypeid
AND zm.userid = l_user_groups);
apex_application.g_print_success_message := 'Inserting OK';
END IF;
EXCEPTION
WHEN e THEN
apex_application.g_global_notification:= 'Error inserting values';
--apex_application.g_print_success_message := 'Error inserting values';
END;
In the raise EXCEPTION it doesn't show any msg but if he enters the ELSE it writes the success msg.
Anyone know why it doesn't work in EXCEPTION?
In the ELSE you are using g_print_success_message. That will work in the EXCEPTION section too. When I tried it, g_global_notification didn't work in either main body or exception section, but only appeared if an exception was raised and not handled - I don't know why though.