Sunday 17 March 2024

simple GIN file server

First, ensure you have Gin installed:


bash

Copy code

go get -u github.com/gin-gonic/gin

Here's the file server implementation:


go

Copy code

package main


import (

"log"

"net/http"


"github.com/gin-gonic/gin"

)


// Define your secret token

const secretToken = "your_secret_token"


// AuthMiddleware is a middleware to authenticate requests

func AuthMiddleware() gin.HandlerFunc {

return func(c *gin.Context) {

// Extract the token from the Authorization header

token := c.GetHeader("Authorization")


// Check if the token is valid

if token != "Bearer "+secretToken {

c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})

c.Abort()

return

}


// Token is valid, continue processing

c.Next()

}

}


func main() {

// Initialize Gin

r := gin.Default()


// Apply the authentication middleware to all routes

r.Use(AuthMiddleware())


// Define a route to serve files

r.Static("/files", "./files")


// Start the server

log.Printf("Server started. Listening on port 8080...")

r.Run(":8080")

}

Ensure you have a directory named files in the same directory as your Go file, and place the files you want to serve inside it.


Now, let's create a Dockerfile to containerize our application:


Dockerfile

Copy code

# Use the official Golang image as base

FROM golang:alpine AS builder


# Set the current working directory inside the container

WORKDIR /app


# Copy the local package files to the container's workspace

COPY . .


# Build the Go app

RUN go build -o file-server .


# Start a new stage from scratch

FROM alpine:latest


# Copy the binary from the builder stage to the new stage

COPY --from=builder /app/file-server /app/file-server


# Expose port 8080 to the outside world

EXPOSE 8080


# Command to run the executable

CMD ["/app/file-server"]

Finally, let's create a docker-compose.yml file to define and run our Docker services:


yaml

Copy code

version: '3'

services:

  file-server:

    build:

      context: .

    ports:

      - "8080:8080"

    volumes:

      - ./files:/app/files

Now, you can run your file server and Dockerize it using Docker Compose:


bash

Copy code

docker-compose up --build

Your file server will now be running in a Docker container, and you can access it at http://localhost:8080/files. Remember to replace "your_secret_token" with your actual secret token. 

Thursday 14 March 2024

Go, pointers, lazy assignment, function returns, libraries, JWT web example

GO WITH JWT example :

https://www.youtube.com/watch?v=ma7rUS_vW9M

* go get is use as package in go code

* go install is to use as cmd line


-------------------------------------------------------------------

Go installation:

https://www.digitalocean.com/community/tutorials/how-to-install-go-on-ubuntu-20-04

replace version with latest version found :

https://go.dev/doc/install

--------------------------------------------------

to start getting libraries, go must init module:

https://go.dev/doc/tutorial/create-module


Create a greetings directory for your Go module source code.

For example, from your home directory use the following commands:


mkdir greetings

cd greetings

Start your module using the go mod init command.

Run the go mod init command, giving it your module path -- here, use example.com/greetings. If you publish a module, this must be a path from which your module can be downloaded by Go tools. That would be your code's repository.


For more on naming your module with a module path, see Managing dependencies.


$ go mod init example.com/greetings

go: creating new go.mod: module example.com/greetings

--------------------------------------------------------------------------------------

commonly used go libraries

-------------------------------------------

decrypt -> save pwd to db

https://pkg.go.dev/golang.org/x/crypto#section-readme

go get -u golang.org/x/crypto/bycrypt

-------------------------------------------

GORM  -> ORM (object relation model) easy mapping from DB to GO

https://gorm.io/docs/

go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

GORM drivers:
https://gorm.io/docs/connecting_to_the_database.html
-------------------------------------------

GIN -> popular GO web framework

https://gin-gonic.com/docs/quickstart/

go get -u github.com/gin-gonic/gin


* GIN uses env varialbe PORT for all ports if not defined :

am going to add a new behaviour to Engine.Run().

  • Back-compatible: it will continue working as expected when an address is provided: router.Run(":3000")
  • NEW: no parameter: router.Run()
    Under this API, gin will try to read the PORT environment variable and use it.
    If the PORT variable is not defined, ":8080" would be used by default.
  • Under discussion: Support for App Engine
    can we detect in runtime that we are running under the app engine environment?
    if so, router.Run() should use the app engine's api.
https://github.com/joho/godotenv
https://stackoverflow.com/questions/74179363/how-to-modify-the-default-port-of-go-gin-my-8080-port-is-in-use

-------------------------------------------

JWT-GO -> JWT token lbirary for GO

https://github.com/golang-jwt/jwt

go get -u github.com/golang-jwt/jwt/v5

-------------------------------------------

GODOTENV -> GO environment virable

go get github.com/joho/godotenv

https://github.com/joho/godotenv

-------------------------------------------

ComplieDaemon -> watch for file change and complie on the fly

https://github.com/githubnemo/CompileDaemon

go get github.com/githubnemo/CompileDaemon
go install github.com/githubnemo/CompileDaemon

CompileDaemon --command='./go-jwt'   (generated binary location and name)

-------------------------------------------


 detailed go lang pointer explanation :

https://www.youtube.com/watch?v=sTFJtxJXkaY


*int (pointer type)

*p(derefernecing pointer)


i := 3

p = &i

*p


: = lazy assignment:

https://go.dev/tour/basics/10

-------------------------------------------------------------------

blank identifiers:

_ (https://www.educative.io/answers/what-is-the-blank-identifier-in-go) for unused variables

https://gobyexample.com/multiple-return-values

GO function returns two values 


package main
import "fmt"

The (int, int) in this function signature shows that the function returns 2 ints.

func vals() (int, int) {
    return 3, 7
}
func main() {

Here we use the 2 different return values from the call with multiple assignment.

    a, b := vals()
    fmt.Println(a)
    fmt.Println(b)

If you only want a subset of the returned values, use the blank identifier _.

    _, c := vals()
    fmt.Println(c)
}

Wednesday 13 March 2024

openssl RSA key generation, encrypt dedcrypt, base 64 encoded data

 https://travistidwell.com/jsencrypt/

genereatekey:

openssl genrsa -out rsa_1024_priv.pem 1024
  • This generates a private key, which you can see by doing the following...
cat rsa_1024_priv.pem #if you are on mac you can | pbcopy to copy to the clipboard
  • You can then copy and paste this in the Private Key section of the demo page.
  • Next, you can then get the public key by executing the following command.
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem


https://stackoverflow.com/questions/42300795/openssl-decrypting-with-a-private-key


For encryption:

openssl rsautl -encrypt -in /path/to/your/file -out /path/to/your/encrypted -pubin -inkey /path/to/your/public_key.pem

For decryption:

openssl rsautl -decrypt -in /path/to/your/encrypted -out /path/where/you/want/your/decrypted.txt -inkey /path/to/your/private_key.pem

Note: If you have this decryption error: RSA_EAY_PRIVATE_DECRYPT:data greater than mod len try this command before decrypt your file:

cat yourEncryptedFile| base64 --decode > yourEncryptedRawFile

https://stackoverflow.com/questions/23205592/openssl-data-greater-than-mod-len
Asymmetric RSA keys can encrypt/decrypt only data of limited length i.e. RSAES-PKCS1-v1_5 encryption scheme defined in RFC3447 can operate on messages of length up to k - 11 octets (k is the octet length of the RSA modulus) so if you are using 2048-bit RSA key then maximum length of the plain data to be encrypted is 245 bytes.