Why do I get LocalDateTime error in Scala? - scala

Im trying to build a small web page for my school project in scala with cask. Im trying to use the LocalDateTime data type in my forms and in the post handlers. For some reason I get this error when trying to run the website:
could not find implicit value for parameter p: annotObject$macro$24.InputParser[java.time.LocalDateTime]
[error] def f (name: String, location: String, team: String, begins: LocalDateTime, ends: LocalDateTime, info: String) = {
I have no clue what's going on, any help is appreciated. This is my code:
import backend.Session
import backend.test.Test._
import scalatags.Text.all.{borderWidth, link, marginBottom, p, _}
import java.time.LocalDateTime
object MinimalApplication extends cask.MainRoutes{
basicUser()
var session = new Session(None, false)
#cask.postForm("/createEvent")
def f (name: String, location: String, team: String, begins: LocalDateTime, ends: LocalDateTime, info: String) = {
createEvent.post(name, location, team, begins, ends, info)
}
#cask.get("/createEvent")
def e () = createEvent.get()
initialize()
}
And the handlers look like this:
import scalatags.Text.all.{form, p, _}
import java.time.LocalDateTime
object createEvent {
def get() = {
html(
head(
link(
rel := "stylesheet",
href := "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
),
),
body(
div(width := "50%",height := "100vh", display := "flex", flexDirection := "column", padding := "50px", borderWidth :="3px", borderStyle:="solid", borderColor := "black", marginLeft := "25%")(
h1(marginBottom:="100px", alignSelf := "center")("Create a new event"),
form(action := "/createEvent", method := "post")(
div(width := "100%", height := "100%", display := "flex", justifyContent := "center", alignItems := "flex-start", flexDirection := "column", alignSelf:="center")(
input(
marginBottom := "10px",
`type` := "text",
name := "name",
placeholder := "Event name",
width := "70%",
borderWidth := "2px",
borderStyle := "solid",
backgroundColor := "White",
borderColor := "(240, 240, 240)",
borderRadius := "5px"
// userName.map(value := _)
),
input(
`type` := "text",
name := "location",
placeholder := "Location",
width := "50%",
borderWidth := "2px",
borderStyle := "solid",
backgroundColor := "White",
borderColor := "(240, 240, 240)",
borderRadius := "5px",
marginBottom := "10px"
// msg.map(value := _)
)
,
input(
`type` := "text",
name := "team",
placeholder := "Team",
width := "25%",
borderWidth := "2px",
borderStyle := "solid",
backgroundColor := "White",
borderColor := "(240, 240, 240)",
borderRadius := "5px",
marginBottom := "10px"
// msg.map(value := _)
),
div(display := "flex")(
div(display:= "flex", flexDirection := "column", marginRight := "20px")(
h6()("Begins"),
input(
`type` :="datetime-local",
min:="2021-11-12T19:30",
value := s"${LocalDateTime.now()}",
name := "begins",
width := "100%",
height := "30px",
borderWidth := "2px",
borderStyle := "solid",
backgroundColor := "White",
borderColor := "(240, 240, 240)",
borderRadius := "5px",
marginBottom := "10px"
)
),
div(display:= "flex", flexDirection := "column")(
h6()("Ends"),
input(
`type` :="datetime-local",
min:="2021-11-12T19:30",
value := s"${LocalDateTime.now()}",
name := "ends",
width := "100%",
height := "30px",
borderWidth := "2px",
borderStyle := "solid",
backgroundColor := "White",
borderColor := "(240, 240, 240)",
borderRadius := "5px",
marginBottom := "10px"
)
)
),
textarea(
`type` := "text",
name := "info",
placeholder := "Info",
width := "70%",
height := "150px",
borderWidth := "2px",
borderStyle := "solid",
backgroundColor := "White",
borderColor := "(240, 240, 240)",
borderRadius := "5px",
marginBottom := "10px"
// msg.map(value := _)
),
button(
alignSelf := "center",
`type` := "submit",
width := "15%",
height := "30px",
marginTop := "20px",
borderWidth := "1px",
borderStyle := "solid",
backgroundColor := "light-grey",
borderColor := "Black",
borderRadius := "5px")("Create")
)
)
)
)
)
}
def post(name: String, location: String, team: String, begins: LocalDateTime, ends: LocalDateTime, info: String) = {
if(name.nonEmpty && location.nonEmpty && team.nonEmpty) {
html(
head(),
body(
p()(s"nimi: ${name}"),
p()(s"paikka: ${location}"),
p()(s"tiimi: ${team}"),
p()(s"alkaa: ${begins}"),
p()(s"loppuu: ${ends}"),
p()(s"info: ${info}")
)
)
}
}
}

could not find implicit value for parameter p: InputParser[java.time.LocalDateTime]
You get the error because Cask doesn't know how to read a LocalDateTime from a request.
One way to solve the issue is to implement a implicit val reader: InputParser[LocalDateTime] = ???, or maybe Cask provides it through some other library or imports?
Another way is to read the parameters as regular Strings and do the parsing yourself in the f method.

Related

Bulk INSERT in Postgres in GO using pgx

I am trying to bulk insert keys in db in go here is the code
Key Struct
type tempKey struct {
keyVal string
lastKey int
}
Test Keys
data := []tempKey{
{keyVal: "abc", lastKey: 10},
{keyVal: "dns", lastKey: 11},
{keyVal: "qwe", lastKey: 12},
{keyVal: "dss", lastKey: 13},
{keyVal: "xcmk", lastKey: 14},
}
Insertion part
dbUrl := "db url...."
conn, err := pgx.Connect(context.Background(), dbUrl)
if err != nil {
println("Errrorr...")
}
defer conn.Close(context.Background())
sqlStr := "INSERT INTO keys (keyval,lastval) VALUES "
dollars := ""
vals := []interface{}{}
count := 1
for _, row := range data {
dollars = fmt.Sprintf("%s($%d, $%d),", dollars, count, count+1)
vals = append(vals, row.keyVal, row.lastKey)
count += 2
}
sqlStr += dollars
sqlStr = sqlStr[0 : len(sqlStr)-1]
fmt.Printf("%s \n", sqlStr)
_, erro := conn.Exec(context.Background(), sqlStr, vals)
if erro != nil {
fmt.Fprint(os.Stderr, "Error : \n", erro)
}
on running it throws error: expected 10 arguments, got 1
What is the correct way of bulk inserting.
You are crafting the SQL statement by hand, which is fine, but you are not leveraging pgx which can help with this (see below).
Appending to the SQL string like so can be inefficient for large inputs
dollars = fmt.Sprintf("%s($%d, $%d),", dollars, count, count+1)
but also the final value has a trailing , where instead you need a termination character ; to indicate the end of the statement.
BTW this string truncation line is redundant:
sqlStr = sqlStr[0 : len(sqlStr)-1] // this is a NOOP
Anyway, better to use something more performant like strings.Builder when crafting long strings.
From the pgx docs, use pgx.Conn.CopyFrom:
func (c *Conn) CopyFrom(tableName Identifier, columnNames []string, rowSrc CopyFromSource) (int, error)
CopyFrom uses the PostgreSQL copy protocol to perform bulk data
insertion. It returns the number of rows copied and an error.
example usage of Copy:
rows := [][]interface{}{
{"John", "Smith", int32(36)},
{"Jane", "Doe", int32(29)},
}
copyCount, err := conn.CopyFrom(
pgx.Identifier{"people"},
[]string{"first_name", "last_name", "age"},
pgx.CopyFromRows(rows),
)
use batch (https://github.com/jackc/pgx/blob/master/batch_test.go):
batch := &pgx.Batch{}
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q1", 1)
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q2", 2)
br := conn.SendBatch(context.Background(), batch)

How to trim specific text

I have some text in file.Text like below:
#cat tmp
host = "192.168.2.80"
port = 5432
user = "pnmsuser"
password = "PNMS$$$$$$"
dbname = "pnms"
Just I want text like below after trimming:
"192.168.2.80"
5432
"pnmsuser"
"PNMS$$$$$$"
"pnms"
I try to trim like below
func dbFileTrimming() {
dat, err := ioutil.ReadFile("tmp")
check(err)
for key, line := range strings.Split(strings.TrimRight(string(dat), "\n"), "\n") {
// println(key, line)
if key == 3 {
line := string([]rune(line)[11:])
fmt.Println(line)
} else if key == 4 {
line := string([]rune(line)[9:])
fmt.Println(line)
} else {
line := string([]rune(line)[7:])
fmt.Println(line)
}
}
}
Is there a simple method for this?
Chop the line after the =:
for _, line := range strings.Split(strings.TrimRight(string(dat), "\n"), "\n") {
line = line[strings.Index(line, " = ")+3:]
fmt.Println(line)
}
This looks like an INI file, or similar enough so that libraries like go-ini could work.
Alternatively, try Strings.split() and putting the result in a map. Quick and dirty / untested:
result := map[string]string
for _, line := range strings.Split(string(dat), "\n") {
split := strings.Split(line, "=")
key := strings.Trim(split[0])
value := strings.Trim(split[0])
result[key] = value
}

How to implement a Bit-Flipping attack on AES-CBC?

Performing a task with root-me.org, as I understand from the attack statement, it is necessary to perform a byte shift to receive is_member = true After reading some instructions, I supplement the message with a block and accordingly do xor with the previous one, but when I pass the token, the next decryption output
b'[id=546815648;name=iziziz;is_member=false;mail=blablacar;pad=00]r\xe5\xf2\x1dM\xa5\xcae\xff\x16\xa2\xc6\xbe\xd8~I'
Tell me what I could miss, my code:
var TOKEN =
"IRZjBh6GxjeYI7YZvxwfBHmxjY+Wd7bPr7s73wWwLHKaR+N8fPDIjT8/AlUIDSzniMgqCV9bJArQbec64kPYXQ=="
// [id=546815648;name=iziziz;is_member=false;mail=blablacar;pad=00]
func main() {
//block 16
tokenHex, err := base64.StdEncoding.DecodeString(TOKEN) // lenght 64
if err != nil {
log.Fatal(err)
}
block := 16
for i := 0; i < len(tokenHex); i += block {
fmt.Println(tokenHex[i : i+block])
}
tmp := make([]byte, block)
for i := 0; i < block; i++ {
tmp[i] = byte('a')
}
tokenHex = append(tokenHex,tmp...)
expected := []byte(`;is_member=true]`)
//last block
current := []byte{136 ,200 ,42 ,9 ,95 ,91, 36, 10 ,208 ,109, 231, 58, 226, 67 ,216, 93}
for i := 0; i < 16; i++ {
xor := expected[i] ^ current[i]
tokenHex[64+i] ^= xor
}
fmt.Println(base64.StdEncoding.EncodeToString(tokenHex))
}

raw socket didn't receive icmp response

I'm trying to send an icmp message whose TTL is just 1, and expect to receive a time exceeded message. that message does come(I see it from wireshark), but my program blocks on syscall.Recvfrom. Anyone knows why?
icmp.go
package main
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"os"
"syscall"
)
type ICMP struct {
Type uint8
Code uint8
Checksum uint16
Identifier uint16
SeqNo uint16
}
func Checksum(data []byte) uint16 {
var (
sum uint32
length int = len(data)
index int
)
for length > 1 {
sum += uint32(data[index])<<8 + uint32(data[index+1])
index += 2
length -= 2
}
if length > 0 {
sum += uint32(data[index])
}
sum += (sum >> 16)
return uint16(^sum)
}
func main() {
h := Header{
Version: 4,
Len: 20,
TotalLen: 20 + 8,
TTL: 1,
Protocol: 1,
// Dst:
}
argc := len(os.Args)
if argc < 2 {
fmt.Println("usage: program + host")
return
}
ipAddr, _ := net.ResolveIPAddr("ip", os.Args[1])
h.Dst = ipAddr.IP
icmpReq := ICMP{
Type: 8,
Code: 0,
Identifier: 0,
SeqNo: 0,
}
out, err := h.Marshal()
if err != nil {
fmt.Println("ip header error", err)
return
}
var icmpBuf bytes.Buffer
binary.Write(&icmpBuf, binary.BigEndian, icmpReq)
icmpReq.Checksum = Checksum(icmpBuf.Bytes())
icmpBuf.Reset()
binary.Write(&icmpBuf, binary.BigEndian, icmpReq)
fd, _ := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
addr := syscall.SockaddrInet4{
Port: 0,
}
copy(addr.Addr[:], ipAddr.IP[12:16])
pkg := append(out, icmpBuf.Bytes()...)
fmt.Println("ip length", len(pkg))
if err := syscall.Sendto(fd, pkg, 0, &addr); err != nil {
fmt.Println("Sendto err:", err)
}
var recvBuf []byte
if nBytes, rAddr, err := syscall.Recvfrom(fd, recvBuf, 0); err == nil {
fmt.Printf("recv %d bytes from %v\n", nBytes, rAddr)
}
}
additionally, I use header.go and helper.go from https://github.com/golang/net/tree/master/ipv4
As Andy pointed out, the raw(7) man page says:
An IPPROTO_RAW socket is send only. If you really want to receive
all IP packets, use a packet(7) socket with the ETH_P_IP protocol.
Note that packet sockets don't reassemble IP fragments, unlike raw
sockets.
I know I can receive ICMP reply if I set IPPROTO_ICMP as the protocol when I create the socket, but I need to set TTL to 1 which must be done in IP layer. Therefore I send the ICMP request with IPPROTO_RAW socket, after that I use net.ListenIP to receive ICMP messages. Here is the code:
package main
import (
"bytes"
"encoding/binary"
"log"
"net"
"os"
"syscall"
)
const icmpID uint16 = 43565 // use a magic number for now
type ICMP struct {
Type uint8
Code uint8
Checksum uint16
Identifier uint16
SeqNo uint16
}
func Checksum(data []byte) uint16 {
var (
sum uint32
length int = len(data)
index int
)
for length > 1 {
sum += uint32(data[index])<<8 + uint32(data[index+1])
index += 2
length -= 2
}
if length > 0 {
sum += uint32(data[index])
}
sum += (sum >> 16)
return uint16(^sum)
}
func main() {
h := Header{
Version: 4,
Len: 20,
TotalLen: 20 + 8,
TTL: 1,
Protocol: 1,
}
argc := len(os.Args)
if argc < 2 {
log.Println("usage: program + host")
return
}
ipAddr, _ := net.ResolveIPAddr("ip", os.Args[1])
h.Dst = ipAddr.IP
icmpReq := ICMP{
Type: 8,
Code: 0,
Identifier: icmpID,
SeqNo: 1,
}
out, err := h.Marshal()
if err != nil {
log.Println("ip header error", err)
return
}
var icmpBuf bytes.Buffer
binary.Write(&icmpBuf, binary.BigEndian, icmpReq)
icmpReq.Checksum = Checksum(icmpBuf.Bytes())
icmpBuf.Reset()
binary.Write(&icmpBuf, binary.BigEndian, icmpReq)
fd, _ := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
addr := syscall.SockaddrInet4{
Port: 0,
}
copy(addr.Addr[:], ipAddr.IP[12:16])
pkg := append(out, icmpBuf.Bytes()...)
if err := syscall.Sendto(fd, pkg, 0, &addr); err != nil {
log.Println("Sendto err:", err)
}
laddr, err := net.ResolveIPAddr("ip4:icmp", "0.0.0.0")
if err != nil {
log.Fatal(err)
}
c, err := net.ListenIP("ip4:icmp", laddr)
if err != nil {
log.Fatal(err)
}
for {
buf := make([]byte, 2048)
n, raddr, err := c.ReadFrom(buf)
if err != nil {
log.Println(err)
continue
}
icmpType := buf[0]
if icmpType == 11 {
if n == 36 { // Time exceeded messages
// A time exceeded message contain IP header(20 bytes) and first 64 bits of the original payload
id := binary.BigEndian.Uint16(buf[32:34])
log.Println("recv id", id)
if id == icmpID {
log.Println("recv Time Exceeded from", raddr)
}
}
}
}
}
Actually, I am writing a traceroute in go, if anyone is interested about that, the whole code is in github.
I think you need to give IPPROTO_ICMP as the protocol when you create your socket. The raw(7) man page says that an IPPROTO_RAW socket is send only. Also, if you use IPPROTO_ICMP, you don't give the IP header. (Note: I haven't actually tried this in Go.)

unstructred inner document with mgo

I have a document which has this following structure
{ "_id" : "736722976", "value" : { "total_visit" : 4, "FIFA World Cup 2014" : 1, "Germany" : 1, "Algeria" : 1, "Thomas Muller" : 1, "Mesut Ozil" : 1, "Monsoon" : 1, "India Meteorological Department (IMD)" : 1, "Web Exclusive" : 2, "Specials" : 1, "Tapas Pal" : 1, "Twitter Trends" : 1, "Sunanda Pushkar" : 1, "Shashi Tharoor" : 1, "AIIMS" : 1, "special" : 1 } }
THE MOST IMPORTANT thing is that the sub document structure under the key "value" is variable so I can not create a structure for that. I tried to follow the suggestion here - Unstructured MongoDB collections with mgo
And I came with this code ---
package main
import ("fmt"
"labix.org/v2/mgo" //importing mgo
"labix.org/v2/mgo/bson"
_ "reflect"
)
type AnalysisStruct struct{
Id string `bson:"_id,omitempty"`
Value bson.M `bson:",inline"`
}
func main() {
var m AnalysisStruct
//connecting to localhost mongodb
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
c := session.DB("my_analysis_db").C("analysis_mid_2")
iter := c.Find(nil).Iter()
for{
if iter.Next(&m){
fmt.Println(m.Value["value"]["total_visit"])
}else{
break
}
}
}
When I try to build this using go build -v -o analyzer it shows me this error---
./analyzer.go:32: invalid operation: m.Value["value"]["total_visit"] (index of type interface {})
I am terribly stuck with this. Can not get anything going. Please can somebody help?
Thanks
I cam up with this code after doing some research. Not the most optimized one for sure. But for my case it works. Took help from
http://blog.denevell.org/golang-interface-type-assertions-switch.html
https://groups.google.com/forum/#!topic/mgo-users/JYE-CP15az4
package main
import ("fmt"
"labix.org/v2/mgo" //importing mgo
"labix.org/v2/mgo/bson"
_ "reflect"
)
type AnalysisStruct struct{
Id string `bson:"_id,omitempty"`
Value bson.M `bson:",inline"`
}
func main() {
var m AnalysisStruct
//connecting to localhost mongodb
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
c := session.DB("consumergenepool_db").C("analysis_mid_2")
iter := c.Find(nil).Iter()
for{
if iter.Next(&m){
s := m.Value["value"].(bson.M)
data, _ := bson.Marshal(s)
var m bson.M
_ = bson.Unmarshal(data, &m)
fmt.Println(m)
for k, v := range m{
fmt.Print(k)
fmt.Print(" :: ")
fmt.Println(v)
}
}else{
break
}
}
}
Let me know your thoughts on this.
Thanks
When testing something new always use a lot of fmt.Printf's to get a feel for it, that being said.
Value bson.M `bson:",inline"`
Should be
Value bson.M `bson:"value,omitempty"`
And
fmt.Println(m.Value["value"]["total_visit"])
Should be:
fmt.Printf("%#v\n", m)
fmt.Println(m.Value["total_visit"])
Your m.Value is "value", so you can use m.Value["total_visit"] directly.
playground
//edit
You can only use inline to catch any fields that that aren't a part of the original struct, but since your struct only has 2 fields (Id and Value), you don't need it.
Now if you were to keep ,inline you would use it like this:
if v, ok := m.Value["value"].(bson.M); ok {
fmt.Println(v["total_visit"])
}
Because m.Value["value"] is an interface{}, you have to type assert it back to it's original value, bson.M before you could use it.