SlideShare uma empresa Scribd logo
1 de 15
Baixar para ler offline
Abusing text/template
Arnaud Porterie - @icecrime - dotGo 2015
How can I get visibility into
my open source projects?
Collect
Store
Draw
Profit?
Filter
Rename
Enrich
Transform
1 {
2 "url": "https://api.github.com/repos/docker/docker/pulls/16603",
3 "id": 46083503,
4 "html_url": "https://github.com/docker/docker/pull/16603",
5 "diff_url": "https://github.com/docker/docker/pull/16603.diff",
6 "patch_url": "https://github.com/docker/docker/pull/16603.patch",
7 "issue_url": "https://api.github.com/repos/docker/docker/issues/16603",
8 "number": 16603,
9 "state": "closed",
10 "locked": false,
11 "title": "Add @vdemeester to MAINTAINERS",
12 "user": {
13 "login": "icecrime",
14 "id": 1564054,
15 "avatar_url": "https://avatars.githubusercontent.com/u/1564054?v=3",
16 "gravatar_id": "",
17 "url": "https://api.github.com/users/icecrime",
18 "html_url": "https://github.com/icecrime",
19 "followers_url": "https://api.github.com/users/icecrime/followers",
20 "following_url": "https://api.github.com/users/icecrime/following{/other_user}",
21 "gists_url": "https://api.github.com/users/icecrime/gists{/gist_id}",
22 "starred_url": "https://api.github.com/users/icecrime/starred{/owner}{/repo}",
23 "subscriptions_url": "https://api.github.com/users/icecrime/subscriptions",
24 "organizations_url": "https://api.github.com/users/icecrime/orgs",
25 "repos_url": "https://api.github.com/users/icecrime/repos",
26 "events_url": "https://api.github.com/users/icecrime/events{/privacy}",
27 "received_events_url": "https://api.github.com/users/icecrime/received_events",
28 "type": "User",
29 "site_admin": false
30 },
31 "body": ":tada:",
32 "created_at": "2015-09-26T15:16:23Z",
33 "updated_at": "2015-09-27T21:02:55Z",
34 "closed_at": "2015-09-27T19:14:39Z",
35 "merged_at": "2015-09-27T19:14:39Z",
36 "merge_commit_sha": "7fae194c5b4c694dc45a385866207df6bea57e61",
~~ ...
320 }
1 {
2 "url": "https://api.github.com/repos/docker/docker/pulls/16603",
3 "id": 46083503,
4 "html_url": "https://github.com/docker/docker/pull/16603",
5 "diff_url": "https://github.com/docker/docker/pull/16603.diff",
6 "patch_url": "https://github.com/docker/docker/pull/16603.patch",
7 "issue_url": "https://api.github.com/repos/docker/docker/issues/16603",
8 "number": 16603,
9 "state": "closed",
10 "locked": false,
11 "title": "Add @vdemeester to MAINTAINERS",
12 "user": {
13 "login": "icecrime",
14 "id": 1564054,
15 "avatar_url": "https://avatars.githubusercontent.com/u/1564054?v=3",
16 "gravatar_id": "",
17 "url": "https://api.github.com/users/icecrime",
18 "html_url": "https://github.com/icecrime",
19 "followers_url": "https://api.github.com/users/icecrime/followers",
20 "following_url": "https://api.github.com/users/icecrime/following{/other_user}",
21 "gists_url": "https://api.github.com/users/icecrime/gists{/gist_id}",
22 "starred_url": "https://api.github.com/users/icecrime/starred{/owner}{/repo}",
23 "subscriptions_url": "https://api.github.com/users/icecrime/subscriptions",
24 "organizations_url": "https://api.github.com/users/icecrime/orgs",
25 "repos_url": "https://api.github.com/users/icecrime/repos",
26 "events_url": "https://api.github.com/users/icecrime/events{/privacy}",
27 "received_events_url": "https://api.github.com/users/icecrime/received_events",
28 "type": "User",
29 "site_admin": false
30 },
31 "body": ":tada:",
32 "created_at": "2015-09-26T15:16:23Z",
33 "updated_at": "2015-09-27T21:02:55Z",
34 "closed_at": "2015-09-27T19:14:39Z",
35 "merged_at": "2015-09-27T19:14:39Z",
36 "merge_commit_sha": "7fae194c5b4c694dc45a385866207df6bea57e61",
~~ ...
320 }
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
"Hello dotGo!"
package main
import (
"os"
"text/template"
)
type Foo struct {
Bar string
}
type Something struct {
Foo Foo
}
const text = "Hello {{ .Foo.Bar }}!"
func main() {
obj := Something{
Foo{
Bar: "dotGo",
},
}
t, _ := template.New("").Parse(text)
t.Execute(os.Stdout, obj)
}
What if we...
● Fork text/template
● Substitute fmt.Fprint for a return
● Use the template syntax as a DSL for data transformation
● Describe the model in a TOML configuration file
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
Simple mapping
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
Tests
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
Loops
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
User defined functions
TOML
JSON
Profit!
Thank you
Arnaud Porterie - @icecrime
/icecrime/vossibility-collector

Mais conteúdo relacionado

Mais procurados

Go for the would be network programmer
Go for the would be network programmerGo for the would be network programmer
Go for the would be network programmer
Eleanor McHugh
 
Distributed Data Structures
Distributed Data StructuresDistributed Data Structures
Distributed Data Structures
PDX Web & Design
 
Assignment no39
Assignment no39Assignment no39
Assignment no39
Jay Patel
 
Study of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramStudy of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proram
Meenakshi Devi
 

Mais procurados (20)

Binomial heap
Binomial heapBinomial heap
Binomial heap
 
Go for the would be network programmer
Go for the would be network programmerGo for the would be network programmer
Go for the would be network programmer
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giants
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Arp
ArpArp
Arp
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
 
Distributed Data Structures
Distributed Data StructuresDistributed Data Structures
Distributed Data Structures
 
Assignment no39
Assignment no39Assignment no39
Assignment no39
 
QA Fest 2019. Saar Rachamim. Developing Tools, While Testing
QA Fest 2019. Saar Rachamim. Developing Tools, While TestingQA Fest 2019. Saar Rachamim. Developing Tools, While Testing
QA Fest 2019. Saar Rachamim. Developing Tools, While Testing
 
Usp
UspUsp
Usp
 
Playing 44CON CTF for fun and profit
Playing 44CON CTF for fun and profitPlaying 44CON CTF for fun and profit
Playing 44CON CTF for fun and profit
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
Introduzione a C#
Introduzione a C#Introduzione a C#
Introduzione a C#
 
C++ Lambda and concurrency
C++ Lambda and concurrencyC++ Lambda and concurrency
C++ Lambda and concurrency
 
Mozilla とブラウザゲーム
Mozilla とブラウザゲームMozilla とブラウザゲーム
Mozilla とブラウザゲーム
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy Cresine
 
C++ TUTORIAL 7
C++ TUTORIAL 7C++ TUTORIAL 7
C++ TUTORIAL 7
 
part2
part2part2
part2
 
Study of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramStudy of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proram
 
Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoF
 

Semelhante a Abusing text/template for data transformation

Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @Moldcamp
Alexei Gorobets
 

Semelhante a Abusing text/template for data transformation (20)

Scala & sling
Scala & slingScala & sling
Scala & sling
 
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 
Back to Basics Webinar 2 - Your First MongoDB Application
Back to  Basics Webinar 2 - Your First MongoDB ApplicationBack to  Basics Webinar 2 - Your First MongoDB Application
Back to Basics Webinar 2 - Your First MongoDB Application
 
Back to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationBack to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB Application
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @Moldcamp
 
Avro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSONAvro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSON
 
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
 
Introduction to Azure DocumentDB
Introduction to Azure DocumentDBIntroduction to Azure DocumentDB
Introduction to Azure DocumentDB
 
GraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup SlidesGraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup Slides
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and moreScaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
 
Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015
 
ELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboardELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboard
 
Elasticsearch in 15 Minutes
Elasticsearch in 15 MinutesElasticsearch in 15 Minutes
Elasticsearch in 15 Minutes
 
Introduction to ReasonML
Introduction to ReasonMLIntroduction to ReasonML
Introduction to ReasonML
 
ZH爱丽丝梦游仙境
ZH爱丽丝梦游仙境ZH爱丽丝梦游仙境
ZH爱丽丝梦游仙境
 

Mais de Arnaud Porterie

Mais de Arnaud Porterie (10)

Docker Barcelona Meetup - An Introduction to BuildKit
Docker Barcelona Meetup - An Introduction to BuildKitDocker Barcelona Meetup - An Introduction to BuildKit
Docker Barcelona Meetup - An Introduction to BuildKit
 
Building software: the lessons from open source
Building software: the lessons from open sourceBuilding software: the lessons from open source
Building software: the lessons from open source
 
DockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
DockerCon US 2016 - Extending Docker With APIs, Drivers, and PluginsDockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
DockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
 
DockerCon US 2016 - Scaling Open Source operations
DockerCon US 2016 - Scaling Open Source operationsDockerCon US 2016 - Scaling Open Source operations
DockerCon US 2016 - Scaling Open Source operations
 
The rise of Docker, and the future of computing
The rise of Docker, and the future of computingThe rise of Docker, and the future of computing
The rise of Docker, and the future of computing
 
DockerCon EU 2015 - Windows Server Containers
DockerCon EU 2015 - Windows Server ContainersDockerCon EU 2015 - Windows Server Containers
DockerCon EU 2015 - Windows Server Containers
 
DockerCon US 2015 - Engine Breakout Session
DockerCon US 2015 - Engine Breakout SessionDockerCon US 2015 - Engine Breakout Session
DockerCon US 2015 - Engine Breakout Session
 
DockerCon EU 2015 - The Latest on Docker Engine
DockerCon EU 2015 - The Latest on Docker EngineDockerCon EU 2015 - The Latest on Docker Engine
DockerCon EU 2015 - The Latest on Docker Engine
 
Arnaud Porterie - Using Machine & Docker to develop & build Docker
Arnaud Porterie - Using Machine & Docker to develop & build DockerArnaud Porterie - Using Machine & Docker to develop & build Docker
Arnaud Porterie - Using Machine & Docker to develop & build Docker
 
Arnaud Porterie - The Truth About C++
Arnaud Porterie - The Truth About C++Arnaud Porterie - The Truth About C++
Arnaud Porterie - The Truth About C++
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Último (20)

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 

Abusing text/template for data transformation

  • 1. Abusing text/template Arnaud Porterie - @icecrime - dotGo 2015
  • 2. How can I get visibility into my open source projects?
  • 4. Filter Rename Enrich Transform 1 { 2 "url": "https://api.github.com/repos/docker/docker/pulls/16603", 3 "id": 46083503, 4 "html_url": "https://github.com/docker/docker/pull/16603", 5 "diff_url": "https://github.com/docker/docker/pull/16603.diff", 6 "patch_url": "https://github.com/docker/docker/pull/16603.patch", 7 "issue_url": "https://api.github.com/repos/docker/docker/issues/16603", 8 "number": 16603, 9 "state": "closed", 10 "locked": false, 11 "title": "Add @vdemeester to MAINTAINERS", 12 "user": { 13 "login": "icecrime", 14 "id": 1564054, 15 "avatar_url": "https://avatars.githubusercontent.com/u/1564054?v=3", 16 "gravatar_id": "", 17 "url": "https://api.github.com/users/icecrime", 18 "html_url": "https://github.com/icecrime", 19 "followers_url": "https://api.github.com/users/icecrime/followers", 20 "following_url": "https://api.github.com/users/icecrime/following{/other_user}", 21 "gists_url": "https://api.github.com/users/icecrime/gists{/gist_id}", 22 "starred_url": "https://api.github.com/users/icecrime/starred{/owner}{/repo}", 23 "subscriptions_url": "https://api.github.com/users/icecrime/subscriptions", 24 "organizations_url": "https://api.github.com/users/icecrime/orgs", 25 "repos_url": "https://api.github.com/users/icecrime/repos", 26 "events_url": "https://api.github.com/users/icecrime/events{/privacy}", 27 "received_events_url": "https://api.github.com/users/icecrime/received_events", 28 "type": "User", 29 "site_admin": false 30 }, 31 "body": ":tada:", 32 "created_at": "2015-09-26T15:16:23Z", 33 "updated_at": "2015-09-27T21:02:55Z", 34 "closed_at": "2015-09-27T19:14:39Z", 35 "merged_at": "2015-09-27T19:14:39Z", 36 "merge_commit_sha": "7fae194c5b4c694dc45a385866207df6bea57e61", ~~ ... 320 }
  • 5. 1 { 2 "url": "https://api.github.com/repos/docker/docker/pulls/16603", 3 "id": 46083503, 4 "html_url": "https://github.com/docker/docker/pull/16603", 5 "diff_url": "https://github.com/docker/docker/pull/16603.diff", 6 "patch_url": "https://github.com/docker/docker/pull/16603.patch", 7 "issue_url": "https://api.github.com/repos/docker/docker/issues/16603", 8 "number": 16603, 9 "state": "closed", 10 "locked": false, 11 "title": "Add @vdemeester to MAINTAINERS", 12 "user": { 13 "login": "icecrime", 14 "id": 1564054, 15 "avatar_url": "https://avatars.githubusercontent.com/u/1564054?v=3", 16 "gravatar_id": "", 17 "url": "https://api.github.com/users/icecrime", 18 "html_url": "https://github.com/icecrime", 19 "followers_url": "https://api.github.com/users/icecrime/followers", 20 "following_url": "https://api.github.com/users/icecrime/following{/other_user}", 21 "gists_url": "https://api.github.com/users/icecrime/gists{/gist_id}", 22 "starred_url": "https://api.github.com/users/icecrime/starred{/owner}{/repo}", 23 "subscriptions_url": "https://api.github.com/users/icecrime/subscriptions", 24 "organizations_url": "https://api.github.com/users/icecrime/orgs", 25 "repos_url": "https://api.github.com/users/icecrime/repos", 26 "events_url": "https://api.github.com/users/icecrime/events{/privacy}", 27 "received_events_url": "https://api.github.com/users/icecrime/received_events", 28 "type": "User", 29 "site_admin": false 30 }, 31 "body": ":tada:", 32 "created_at": "2015-09-26T15:16:23Z", 33 "updated_at": "2015-09-27T21:02:55Z", 34 "closed_at": "2015-09-27T19:14:39Z", 35 "merged_at": "2015-09-27T19:14:39Z", 36 "merge_commit_sha": "7fae194c5b4c694dc45a385866207df6bea57e61", ~~ ... 320 } { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", }
  • 6. "Hello dotGo!" package main import ( "os" "text/template" ) type Foo struct { Bar string } type Something struct { Foo Foo } const text = "Hello {{ .Foo.Bar }}!" func main() { obj := Something{ Foo{ Bar: "dotGo", }, } t, _ := template.New("").Parse(text) t.Execute(os.Stdout, obj) }
  • 7. What if we... ● Fork text/template ● Substitute fmt.Fprint for a return ● Use the template syntax as a DSL for data transformation ● Describe the model in a TOML configuration file
  • 8. { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}"
  • 9. [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}" { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } Simple mapping
  • 10. [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}" { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } Tests
  • 11. [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}" { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } Loops
  • 12. [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}" { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } User defined functions
  • 14.
  • 15. Profit! Thank you Arnaud Porterie - @icecrime /icecrime/vossibility-collector