Skip to content

Instantly share code, notes, and snippets.

@sameh-sharaf
Created September 12, 2016 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sameh-sharaf/19e24ca2f1386f30ce0685960d9c36b4 to your computer and use it in GitHub Desktop.
Save sameh-sharaf/19e24ca2f1386f30ce0685960d9c36b4 to your computer and use it in GitHub Desktop.
This code is from an API code which tracks sessions and links them to their respective personal profiles. It connects to AWS DynamoDB which stores link account-session in an already created table.
package main
import (
"fmt"
"net/http"
"os"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/bugsnag/bugsnag-go"
)
/*##############
This code is from an API code which tracks sessions and links them to their respective personal profiles.
It connects to AWS DynamoDB which stores link account-session in an already created table.
##############*/
func clientAccountHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "", http.StatusMethodNotAllowed)
return
}
accountAttributes := make(map[string]string)
clientID := r.FormValue("clientId")
if clientID == "" {
http.Error(w, "clientId is required", http.StatusBadRequest)
return
}
accountAttributes["clientId"] = clientID
accountID := r.FormValue("accountId")
if accountID == "" {
http.Error(w, "accountId is required", http.StatusBadRequest)
return
}
sessionID := r.FormValue("sessionId")
if sessionID == "" {
http.Error(w, "sessionId is required", http.StatusBadRequest)
return
}
accountAttributes["sessionId"] = sessionID
domain := r.FormValue("domain")
if domain == "" {
http.Error(w, "domain is required", http.StatusBadRequest)
return
}
accountAttributes["domain"] = domain
timestamp := r.FormValue("timestamp")
if timestamp == "" {
http.Error(w, "timestamp is required", http.StatusBadRequest)
return
}
accountAttributes["accountLinkedAt"] = timestamp
clientKey := fmt.Sprintf("%s %s %s", timestamp, domain, clientID)
attributeNames := make(map[string]*string, 0)
attributeValues := make(map[string]*dynamodb.AttributeValue, 0)
updateExpressions := []string{}
for key, value := range accountAttributes {
if value == "" {
continue
}
attrName := fmt.Sprintf("#%s", key)
attrVar := fmt.Sprintf(":%s", key)
attributeNames[attrName] = aws.String(key)
attributeValues[attrVar] = &dynamodb.AttributeValue{
S: aws.String(value),
}
expr := fmt.Sprintf("%s = %s", attrName, attrVar)
updateExpressions = append(updateExpressions, expr)
}
clientSession, err := getClientSessionAttributes(clientID, sessionID, domain, timestamp)
if err != nil {
bugsnag.Notify(err)
http.Error(w, "", http.StatusServiceUnavailable)
return
}
for key, value := range clientSession {
if value != nil && *value.S == "" {
continue
}
if _, ok := accountAttributes[key]; ok {
continue
}
key := strings.Replace(key, ".", "_", -1)
attrName := fmt.Sprintf("#%s", key)
attrVar := fmt.Sprintf(":%s", key)
attributeNames[attrName] = aws.String(key)
attributeValues[attrVar] = value
expr := fmt.Sprintf("%s = %s", attrName, attrVar)
updateExpressions = append(updateExpressions, expr)
}
req := &dynamodb.UpdateItemInput{
TableName: aws.String(os.Getenv("TABLE_ACCOUNT_CLIENTS")),
Key: map[string]*dynamodb.AttributeValue{
"accountId": {
S: aws.String(accountID),
},
"clientKey": {
S: aws.String(clientKey),
},
},
ExpressionAttributeNames: attributeNames,
ExpressionAttributeValues: attributeValues,
UpdateExpression: aws.String("SET " + strings.Join(updateExpressions, ",")),
}
_, err = db.UpdateItem(req)
if err != nil {
bugsnag.Notify(err)
http.Error(w, "", http.StatusServiceUnavailable)
return
}
}
func getClientSessionAttributes(clientID, sessionID, domain, timestamp string) (map[string]*dynamodb.AttributeValue, error) {
sessionKey := fmt.Sprintf("%s %s %s", timestamp, domain, sessionID)
getItemInput := dynamodb.GetItemInput{
TableName: aws.String(os.Getenv("TABLE_CLIENT_SESSIONS")),
Key: map[string]*dynamodb.AttributeValue{
"clientId": {
S: aws.String(clientID),
},
"sessionKey": {
S: aws.String(sessionKey),
},
},
}
out, err := db.GetItem(&getItemInput)
if err != nil {
return nil, err
}
if out.Item == nil {
return nil, nil
}
return out.Item, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment