SlideShare a Scribd company logo
Domain Primitives in Action
- Making it Secure by Design
@DanielDeogun @danbjson
Explore DDD, Denver 2017
@DanielDeogun @danbjson #SecureByDesign #EDDD
About Us…
Dan Bergh Johnsson
Secure Domain Philosopher
Omegapoint, Sweden
Umeå
Malmö
Göteborg
Falun
New York
Stockholm
Daniel Deogun
Coder and Quality Defender
@DanielDeogun @danbjson #SecureByDesign #EDDD
Key Take Aways
Domain Primitives
- are native to your domain
- form a conceptual whole
- easy way to improve and secure existing code
@DanielDeogun @danbjson #SecureByDesign #EDDD
Modeling a Hotel Room
@DanielDeogun @danbjson #SecureByDesign #EDDD
Peano's Axioms
1. Zero is a number
2. If n is a number, the successor of n is a number
3. Zero isn’t the successor of a number
4. Two numbers of which the successors are equal are themselves equal
5. If a set S of numbers contains zero and also the successor of every
number in S, then every number is in S
Abelian group
• Closure: a + b = integer
• Associativity: a + (b + c) = (a + b) + c
• Commutativity: a + b = b + a
• Identity: a + 0 = a
• Inverse: a + (−a) = 0
It’s “just” an Integer?
@DanielDeogun @danbjson #SecureByDesign #EDDD
…or is it a String?
• What characters are legal?
• Which operations are allowed?
• Does this make sense?
@DanielDeogun @danbjson #SecureByDesign #EDDD
Math and Hotel are
different Contexts
Math Domain
Integer
Hotel Domain
Room Number
Hotel Domain
Math Domain
Integer
(a.k.a Room Number)
@DanielDeogun @danbjson #SecureByDesign #EDDD
Room Number
public final class RoomNumber {
private final int value;
public RoomNumber(final int value) {
isTrue(Floor.isValid(value));
inclusiveBetween(1, 50, value % 100);
this.value = value;
}
public Floor floor() {
return new Floor(value);
}
// other logic …
}
@DanielDeogun @danbjson #SecureByDesign #EDDD
Definition of
Domain Primitive
• Building block that’s native to your domain
• Valid in your context
• Immutable and resemble a value object
“A value object so precise in its definition that it, by its mere
existence, manifests its validity is called a Domain Primitive.”
- Secure by Design
@DanielDeogun @danbjson #SecureByDesign #EDDD
Less Simple
Domain Primitive
public void pay(final double money, final int recipientId) {
final String currency = CurrencyService.currencyFor(recipientId);
BankService.transfer(money, currency, recipientId);
}
public void pay(final Money money, final Recipient recipient) {
notNull(money);
notNull(recipient);
BankService.transfer(money, recipient);
}
But Money is a conceptual whole and
should be modeled as a domain primitive
@DanielDeogun @danbjson #SecureByDesign #EDDD
Intelligent Machines -
not just values
class Rate {

private final Currency from;

private final Currency to;



Rate(Currency from, Currency to) {

this.from = notNull(from);

this.to = notNull(to);

}


Money exchange(Money from) {
notNull(from);
isTrue(this.from
.equals(from.currency));
BigDecimal converted = . . .

return new Money(converted, to);

}

}
@DanielDeogun @danbjson #SecureByDesign #EDDD
Standing on the
Shoulders of Giants
• Domain Primitives act as building blocks
• Guy L. Steele Jr. “Growing a Language”
• Abelson, Sussman “Structure and
Interpretation of Computer Programs”
https://flic.kr/p/8cc44h https://creativecommons.org/licenses/by/2.0/
@DanielDeogun @danbjson #SecureByDesign #EDDD
… In Action
https://flic.kr/p/Q7zV https://creativecommons.org/licenses/by-sa/2.0/
vs
https://flic.kr/p/djYc9H https://creativecommons.org/licenses/by/2.0/
Green Field Brown Field
@DanielDeogun @danbjson #SecureByDesign #EDDD
“Draw the Line”
- Find a Semantic Border
https://flic.kr/p/nEZKMd https://creativecommons.org/licenses/by/2.0/
public void checkout(final int roomNumber) {
new RoomNumber(roomNumber); //throws exception if invalid
houseKeepingService.registerForCleaning(roomNumber);
minibarService.replenish(roomNumber);
// other operations ...
}
public void checkout(final int roomNumber) {
if (!RoomNumber.isValid(roomNumber)) {
reporter.logInvalidRoomNumber(roomNumber);
}
houseKeepingService.registerForCleaning(roomNumber);
minibarService.replenish(roomNumber);
// other operations ...
}
@DanielDeogun @danbjson #SecureByDesign #EDDD
Hardening your APIs
- Enforce Data Quality
Generic
Specific
public void checkout(final int roomNumber)
public void checkout(final RoomNumber roomNumber)
Enforce data quality
@DanielDeogun @danbjson #SecureByDesign #EDDD
Cluttered Entity
class Order {
private ArrayList<Object> items;
private boolean paid;



public void addItem(String isbn, int qty) {
if(this.paid == false) {
notNull(isbn);
inclusiveBetween(10, 10, isbn.length());
isTrue(isbn.matches("[0-9X]*"));
isTrue(isbn.matches("[0-9]{9}[0-9X]"));

Book book = bookCatalogue.findByISBN(isbn);

if (inventory.availableBooks(isbn) >= qty) {
items.add(new OrderLine(book, qty));
}
}
}
//Other logic...
}
@DanielDeogun @danbjson #SecureByDesign #EDDD
De-Cluttered Entity
class Order {
private ArrayList<Object> items;
private boolean paid;

public void addItem(ISBN isbn, Quantity qty) {
notNull(isbn);
notNull(qty);
if(this.paid == false) {
Book book = bookCatalogue.findByISBN(isbn);

if (inventory.availableBooks(isbn).greaterOrEqualTo(qty)) {
items.add(new OrderLine(book, qty));
}
}
}
//Other logic...
}
@DanielDeogun @danbjson #SecureByDesign #EDDD
Renovating Services
@DanielDeogun @danbjson #SecureByDesign #EDDD
Renovating Services
public interface ExchangeService {

double rate(String from, String to);

}

private double convertForeignPrice(

double priceForeignCurrency,

String foreignCurrency) {



double rate = exchange.rate(foreignCurrency, "USD");

double priceUSD = priceForeignCurrency * rate;

// … and some rounding
return priceUSD;

}

public interface ExchangeService {

Rate rate(Currency from, Currency to);

}

private Money convertForeignPrice(

Money priceForeignCurrency,

Currency foreignCurrency) {



Rate rate = exchange.rate(foreignCurrency, USD);

Money priceUSD = rate.exchange(priceForeignCurrency);

return priceUSD;

}
@DanielDeogun @danbjson #SecureByDesign #EDDD
But…
https://flic.kr/p/eGYhMw
https://creativecommons.org/licenses/by/2.0/
… what about performance?
https://flic.kr/p/2pvb2T
https://creativecommons.org/licenses/by/2.0/
… it becomes a lot of classes!
… isn’t it overly complex?
https://flic.kr/p/7Ro4HU
https://creativecommons.org/licenses/by/2.0/
@DanielDeogun @danbjson #SecureByDesign #EDDD
… Making it
Secure by Design
OWASP:
• Injection Flaw
• Cross-site scripting (XSS)
Seals lots of small holes
https://flic.kr/p/85qctm
https://creativecommons.org/licenses/by/2.0/
Confidentiality
Integrity
Availability
@DanielDeogun @danbjson #SecureByDesign #EDDD
Contains several
concepts from DDD
40% Discount code
ctweddd17
Design secure
software without
“thinking” about
security
There’s a Book…
Shameless plug…
@DanielDeogun @danbjson #SecureByDesign #EDDD
Key Take Aways
Domain Primitives
- are native to your domain
- form a conceptual whole
- easy way to improve and secure existing code
@DanielDeogun @danbjson #SecureByDesign #EDDD
Q&A
https://flic.kr/p/9ksxQa https://creativecommons.org/licenses/by-nc-nd/2.0/
Thanks
@DanielDeogun @danbjson #SecureByDesign #EDDD

More Related Content

What's hot

もし太陽のコアがIntelCoreだったら
もし太陽のコアがIntelCoreだったらもし太陽のコアがIntelCoreだったら
もし太陽のコアがIntelCoreだったら
京大 マイコンクラブ
 
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeNA
 
Kotlinアンチパターン
KotlinアンチパターンKotlinアンチパターン
Kotlinアンチパターン
Recruit Lifestyle Co., Ltd.
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
Norishige Fukushima
 
BERT入門
BERT入門BERT入門
BERT入門
Ken'ichi Matsui
 
M5StackをRustで動かす
M5StackをRustで動かすM5StackをRustで動かす
M5StackをRustで動かす
Kenta IDA
 
バーチャルライブ配信アプリREALITYの3Dアバターシステムの全容について
バーチャルライブ配信アプリREALITYの3Dアバターシステムの全容についてバーチャルライブ配信アプリREALITYの3Dアバターシステムの全容について
バーチャルライブ配信アプリREALITYの3Dアバターシステムの全容について
gree_tech
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
murachue
 
モバイルゲームの「大規模な開発」かつ「高頻度の更新」を実現するための開発環境整備の取り組み
モバイルゲームの「大規模な開発」かつ「高頻度の更新」を実現するための開発環境整備の取り組みモバイルゲームの「大規模な開発」かつ「高頻度の更新」を実現するための開発環境整備の取り組み
モバイルゲームの「大規模な開発」かつ「高頻度の更新」を実現するための開発環境整備の取り組み
MorioImai
 
C#で速度を極めるいろは
C#で速度を極めるいろはC#で速度を極めるいろは
C#で速度を極めるいろは
Core Concept Technologies
 
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
NTT DATA Technology & Innovation
 
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
Drecom Co., Ltd.
 
Blenderとコード
BlenderとコードBlenderとコード
Blenderとコード
Tetsuo Mitsuda
 
次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて
Yoshimasa Tanabe
 
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
Yoshiro Tokumasu
 
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
NTT DATA Technology & Innovation
 
世界一わかりやすいClean Architecture release-preview
世界一わかりやすいClean Architecture release-preview世界一わかりやすいClean Architecture release-preview
世界一わかりやすいClean Architecture release-preview
Atsushi Nakamura
 
情報科学における18のメタテクニック
情報科学における18のメタテクニック情報科学における18のメタテクニック
情報科学における18のメタテクニック
nakano_lab
 
【Unite Tokyo 2018】スマホVTuber向け揺れモノシステムを「ユニティちゃんライセンス」で無料公開!
【Unite Tokyo 2018】スマホVTuber向け揺れモノシステムを「ユニティちゃんライセンス」で無料公開!【Unite Tokyo 2018】スマホVTuber向け揺れモノシステムを「ユニティちゃんライセンス」で無料公開!
【Unite Tokyo 2018】スマホVTuber向け揺れモノシステムを「ユニティちゃんライセンス」で無料公開!
UnityTechnologiesJapan002
 
セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)
kazkiti
 

What's hot (20)

もし太陽のコアがIntelCoreだったら
もし太陽のコアがIntelCoreだったらもし太陽のコアがIntelCoreだったら
もし太陽のコアがIntelCoreだったら
 
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
 
Kotlinアンチパターン
KotlinアンチパターンKotlinアンチパターン
Kotlinアンチパターン
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
 
BERT入門
BERT入門BERT入門
BERT入門
 
M5StackをRustで動かす
M5StackをRustで動かすM5StackをRustで動かす
M5StackをRustで動かす
 
バーチャルライブ配信アプリREALITYの3Dアバターシステムの全容について
バーチャルライブ配信アプリREALITYの3Dアバターシステムの全容についてバーチャルライブ配信アプリREALITYの3Dアバターシステムの全容について
バーチャルライブ配信アプリREALITYの3Dアバターシステムの全容について
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
モバイルゲームの「大規模な開発」かつ「高頻度の更新」を実現するための開発環境整備の取り組み
モバイルゲームの「大規模な開発」かつ「高頻度の更新」を実現するための開発環境整備の取り組みモバイルゲームの「大規模な開発」かつ「高頻度の更新」を実現するための開発環境整備の取り組み
モバイルゲームの「大規模な開発」かつ「高頻度の更新」を実現するための開発環境整備の取り組み
 
C#で速度を極めるいろは
C#で速度を極めるいろはC#で速度を極めるいろは
C#で速度を極めるいろは
 
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
 
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
 
Blenderとコード
BlenderとコードBlenderとコード
Blenderとコード
 
次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて
 
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
 
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
 
世界一わかりやすいClean Architecture release-preview
世界一わかりやすいClean Architecture release-preview世界一わかりやすいClean Architecture release-preview
世界一わかりやすいClean Architecture release-preview
 
情報科学における18のメタテクニック
情報科学における18のメタテクニック情報科学における18のメタテクニック
情報科学における18のメタテクニック
 
【Unite Tokyo 2018】スマホVTuber向け揺れモノシステムを「ユニティちゃんライセンス」で無料公開!
【Unite Tokyo 2018】スマホVTuber向け揺れモノシステムを「ユニティちゃんライセンス」で無料公開!【Unite Tokyo 2018】スマホVTuber向け揺れモノシステムを「ユニティちゃんライセンス」で無料公開!
【Unite Tokyo 2018】スマホVTuber向け揺れモノシステムを「ユニティちゃんライセンス」で無料公開!
 
セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)
 

Similar to Domain Primitives In Action - Explore DDD 2017

Domain Primitives in Action - DataTjej 2018
Domain Primitives in Action - DataTjej 2018Domain Primitives in Action - DataTjej 2018
Domain Primitives in Action - DataTjej 2018
Omegapoint Academy
 
Devoxx PL 2017 - Cracking the Code to Secure Software
Devoxx PL 2017 - Cracking the Code to Secure SoftwareDevoxx PL 2017 - Cracking the Code to Secure Software
Devoxx PL 2017 - Cracking the Code to Secure Software
Daniel Sawano
 
DevDays LT 2017 - Secure by Design
DevDays LT 2017 - Secure by DesignDevDays LT 2017 - Secure by Design
DevDays LT 2017 - Secure by Design
Daniel Sawano
 
GeeCon Prague 2017 - Cracking the Code to Secure Software
GeeCon Prague 2017 - Cracking the Code to Secure SoftwareGeeCon Prague 2017 - Cracking the Code to Secure Software
GeeCon Prague 2017 - Cracking the Code to Secure Software
Daniel Sawano
 
Domain driven security_java_zone2016
Domain driven security_java_zone2016Domain driven security_java_zone2016
Domain driven security_java_zone2016
Omegapoint Academy
 
Secure by Design - Jfokus 2018 tutorial
Secure by Design - Jfokus 2018 tutorialSecure by Design - Jfokus 2018 tutorial
Secure by Design - Jfokus 2018 tutorial
Omegapoint Academy
 
Building a Location-based platform with MongoDB from Zero.
Building a Location-based platform with MongoDB from Zero.Building a Location-based platform with MongoDB from Zero.
Building a Location-based platform with MongoDB from Zero.Ravi Teja
 
Designing software with security in mind?
Designing software with security in mind?Designing software with security in mind?
Designing software with security in mind?
Omegapoint Academy
 
Designing software with security in mind
Designing software with security in mindDesigning software with security in mind
Designing software with security in mind
Omegapoint Academy
 
Fast REST APIs Development with MongoDB
Fast REST APIs Development with MongoDBFast REST APIs Development with MongoDB
Fast REST APIs Development with MongoDB
MongoDB
 
Managing complexity
Managing complexityManaging complexity
Managing complexitySmartLogic
 
Minds-on DDD
Minds-on DDDMinds-on DDD
Minds-on DDD
Paulo Gandra de Sousa
 
MongoDB, PHP and the cloud - php cloud summit 2011
MongoDB, PHP and the cloud - php cloud summit 2011MongoDB, PHP and the cloud - php cloud summit 2011
MongoDB, PHP and the cloud - php cloud summit 2011
Steven Francia
 
MongoDB and PHP ZendCon 2011
MongoDB and PHP ZendCon 2011MongoDB and PHP ZendCon 2011
MongoDB and PHP ZendCon 2011Steven Francia
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
Trisha Gee
 
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile AppsMongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB
 
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB
 
Clean Code 2
Clean Code 2Clean Code 2
Clean Code 2
Fredrik Wendt
 
Working with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSONWorking with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSON
SV.CO
 
San Francisco Java User Group
San Francisco Java User GroupSan Francisco Java User Group
San Francisco Java User Groupkchodorow
 

Similar to Domain Primitives In Action - Explore DDD 2017 (20)

Domain Primitives in Action - DataTjej 2018
Domain Primitives in Action - DataTjej 2018Domain Primitives in Action - DataTjej 2018
Domain Primitives in Action - DataTjej 2018
 
Devoxx PL 2017 - Cracking the Code to Secure Software
Devoxx PL 2017 - Cracking the Code to Secure SoftwareDevoxx PL 2017 - Cracking the Code to Secure Software
Devoxx PL 2017 - Cracking the Code to Secure Software
 
DevDays LT 2017 - Secure by Design
DevDays LT 2017 - Secure by DesignDevDays LT 2017 - Secure by Design
DevDays LT 2017 - Secure by Design
 
GeeCon Prague 2017 - Cracking the Code to Secure Software
GeeCon Prague 2017 - Cracking the Code to Secure SoftwareGeeCon Prague 2017 - Cracking the Code to Secure Software
GeeCon Prague 2017 - Cracking the Code to Secure Software
 
Domain driven security_java_zone2016
Domain driven security_java_zone2016Domain driven security_java_zone2016
Domain driven security_java_zone2016
 
Secure by Design - Jfokus 2018 tutorial
Secure by Design - Jfokus 2018 tutorialSecure by Design - Jfokus 2018 tutorial
Secure by Design - Jfokus 2018 tutorial
 
Building a Location-based platform with MongoDB from Zero.
Building a Location-based platform with MongoDB from Zero.Building a Location-based platform with MongoDB from Zero.
Building a Location-based platform with MongoDB from Zero.
 
Designing software with security in mind?
Designing software with security in mind?Designing software with security in mind?
Designing software with security in mind?
 
Designing software with security in mind
Designing software with security in mindDesigning software with security in mind
Designing software with security in mind
 
Fast REST APIs Development with MongoDB
Fast REST APIs Development with MongoDBFast REST APIs Development with MongoDB
Fast REST APIs Development with MongoDB
 
Managing complexity
Managing complexityManaging complexity
Managing complexity
 
Minds-on DDD
Minds-on DDDMinds-on DDD
Minds-on DDD
 
MongoDB, PHP and the cloud - php cloud summit 2011
MongoDB, PHP and the cloud - php cloud summit 2011MongoDB, PHP and the cloud - php cloud summit 2011
MongoDB, PHP and the cloud - php cloud summit 2011
 
MongoDB and PHP ZendCon 2011
MongoDB and PHP ZendCon 2011MongoDB and PHP ZendCon 2011
MongoDB and PHP ZendCon 2011
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
 
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile AppsMongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
 
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
 
Clean Code 2
Clean Code 2Clean Code 2
Clean Code 2
 
Working with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSONWorking with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSON
 
San Francisco Java User Group
San Francisco Java User GroupSan Francisco Java User Group
San Francisco Java User Group
 

More from Omegapoint Academy

Making Software Secure by Design
Making Software Secure by DesignMaking Software Secure by Design
Making Software Secure by Design
Omegapoint Academy
 
Designing Testable Software
Designing Testable SoftwareDesigning Testable Software
Designing Testable Software
Omegapoint Academy
 
Domain Driven Security Jfokus 2016
Domain Driven Security Jfokus 2016Domain Driven Security Jfokus 2016
Domain Driven Security Jfokus 2016
Omegapoint Academy
 
Arm yourself with Domain Driven Security. It's time to slay some security trolls
Arm yourself with Domain Driven Security. It's time to slay some security trollsArm yourself with Domain Driven Security. It's time to slay some security trolls
Arm yourself with Domain Driven Security. It's time to slay some security trolls
Omegapoint Academy
 
Failing Continuous Delivery, Devoxx Poland, 2015
Failing Continuous Delivery, Devoxx Poland, 2015Failing Continuous Delivery, Devoxx Poland, 2015
Failing Continuous Delivery, Devoxx Poland, 2015
Omegapoint Academy
 
Studentkonferens 2015 - Alla pratar om risker, men vad är det?
Studentkonferens 2015 - Alla pratar om risker, men vad är det?Studentkonferens 2015 - Alla pratar om risker, men vad är det?
Studentkonferens 2015 - Alla pratar om risker, men vad är det?
Omegapoint Academy
 
Studentkonferens 2015 1 + 1 = 1 (The Omegapoint Way)
Studentkonferens 2015 1 + 1 = 1 (The Omegapoint Way)Studentkonferens 2015 1 + 1 = 1 (The Omegapoint Way)
Studentkonferens 2015 1 + 1 = 1 (The Omegapoint Way)
Omegapoint Academy
 
Studenkonferens 2015 - Craftsmanship
Studenkonferens 2015 - CraftsmanshipStudenkonferens 2015 - Craftsmanship
Studenkonferens 2015 - Craftsmanship
Omegapoint Academy
 
Agile Enterprise: frukostseminarium
Agile Enterprise: frukostseminariumAgile Enterprise: frukostseminarium
Agile Enterprise: frukostseminarium
Omegapoint Academy
 

More from Omegapoint Academy (9)

Making Software Secure by Design
Making Software Secure by DesignMaking Software Secure by Design
Making Software Secure by Design
 
Designing Testable Software
Designing Testable SoftwareDesigning Testable Software
Designing Testable Software
 
Domain Driven Security Jfokus 2016
Domain Driven Security Jfokus 2016Domain Driven Security Jfokus 2016
Domain Driven Security Jfokus 2016
 
Arm yourself with Domain Driven Security. It's time to slay some security trolls
Arm yourself with Domain Driven Security. It's time to slay some security trollsArm yourself with Domain Driven Security. It's time to slay some security trolls
Arm yourself with Domain Driven Security. It's time to slay some security trolls
 
Failing Continuous Delivery, Devoxx Poland, 2015
Failing Continuous Delivery, Devoxx Poland, 2015Failing Continuous Delivery, Devoxx Poland, 2015
Failing Continuous Delivery, Devoxx Poland, 2015
 
Studentkonferens 2015 - Alla pratar om risker, men vad är det?
Studentkonferens 2015 - Alla pratar om risker, men vad är det?Studentkonferens 2015 - Alla pratar om risker, men vad är det?
Studentkonferens 2015 - Alla pratar om risker, men vad är det?
 
Studentkonferens 2015 1 + 1 = 1 (The Omegapoint Way)
Studentkonferens 2015 1 + 1 = 1 (The Omegapoint Way)Studentkonferens 2015 1 + 1 = 1 (The Omegapoint Way)
Studentkonferens 2015 1 + 1 = 1 (The Omegapoint Way)
 
Studenkonferens 2015 - Craftsmanship
Studenkonferens 2015 - CraftsmanshipStudenkonferens 2015 - Craftsmanship
Studenkonferens 2015 - Craftsmanship
 
Agile Enterprise: frukostseminarium
Agile Enterprise: frukostseminariumAgile Enterprise: frukostseminarium
Agile Enterprise: frukostseminarium
 

Recently uploaded

Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
kalichargn70th171
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 

Recently uploaded (20)

Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 

Domain Primitives In Action - Explore DDD 2017

  • 1. Domain Primitives in Action - Making it Secure by Design @DanielDeogun @danbjson Explore DDD, Denver 2017
  • 2. @DanielDeogun @danbjson #SecureByDesign #EDDD About Us… Dan Bergh Johnsson Secure Domain Philosopher Omegapoint, Sweden Umeå Malmö Göteborg Falun New York Stockholm Daniel Deogun Coder and Quality Defender
  • 3. @DanielDeogun @danbjson #SecureByDesign #EDDD Key Take Aways Domain Primitives - are native to your domain - form a conceptual whole - easy way to improve and secure existing code
  • 4. @DanielDeogun @danbjson #SecureByDesign #EDDD Modeling a Hotel Room
  • 5. @DanielDeogun @danbjson #SecureByDesign #EDDD Peano's Axioms 1. Zero is a number 2. If n is a number, the successor of n is a number 3. Zero isn’t the successor of a number 4. Two numbers of which the successors are equal are themselves equal 5. If a set S of numbers contains zero and also the successor of every number in S, then every number is in S Abelian group • Closure: a + b = integer • Associativity: a + (b + c) = (a + b) + c • Commutativity: a + b = b + a • Identity: a + 0 = a • Inverse: a + (−a) = 0 It’s “just” an Integer?
  • 6. @DanielDeogun @danbjson #SecureByDesign #EDDD …or is it a String? • What characters are legal? • Which operations are allowed? • Does this make sense?
  • 7. @DanielDeogun @danbjson #SecureByDesign #EDDD Math and Hotel are different Contexts Math Domain Integer Hotel Domain Room Number Hotel Domain Math Domain Integer (a.k.a Room Number)
  • 8. @DanielDeogun @danbjson #SecureByDesign #EDDD Room Number public final class RoomNumber { private final int value; public RoomNumber(final int value) { isTrue(Floor.isValid(value)); inclusiveBetween(1, 50, value % 100); this.value = value; } public Floor floor() { return new Floor(value); } // other logic … }
  • 9. @DanielDeogun @danbjson #SecureByDesign #EDDD Definition of Domain Primitive • Building block that’s native to your domain • Valid in your context • Immutable and resemble a value object “A value object so precise in its definition that it, by its mere existence, manifests its validity is called a Domain Primitive.” - Secure by Design
  • 10. @DanielDeogun @danbjson #SecureByDesign #EDDD Less Simple Domain Primitive public void pay(final double money, final int recipientId) { final String currency = CurrencyService.currencyFor(recipientId); BankService.transfer(money, currency, recipientId); } public void pay(final Money money, final Recipient recipient) { notNull(money); notNull(recipient); BankService.transfer(money, recipient); } But Money is a conceptual whole and should be modeled as a domain primitive
  • 11. @DanielDeogun @danbjson #SecureByDesign #EDDD Intelligent Machines - not just values class Rate {
 private final Currency from;
 private final Currency to;
 
 Rate(Currency from, Currency to) {
 this.from = notNull(from);
 this.to = notNull(to);
 } 
 Money exchange(Money from) { notNull(from); isTrue(this.from .equals(from.currency)); BigDecimal converted = . . .
 return new Money(converted, to);
 }
 }
  • 12. @DanielDeogun @danbjson #SecureByDesign #EDDD Standing on the Shoulders of Giants • Domain Primitives act as building blocks • Guy L. Steele Jr. “Growing a Language” • Abelson, Sussman “Structure and Interpretation of Computer Programs” https://flic.kr/p/8cc44h https://creativecommons.org/licenses/by/2.0/
  • 13. @DanielDeogun @danbjson #SecureByDesign #EDDD … In Action https://flic.kr/p/Q7zV https://creativecommons.org/licenses/by-sa/2.0/ vs https://flic.kr/p/djYc9H https://creativecommons.org/licenses/by/2.0/ Green Field Brown Field
  • 14. @DanielDeogun @danbjson #SecureByDesign #EDDD “Draw the Line” - Find a Semantic Border https://flic.kr/p/nEZKMd https://creativecommons.org/licenses/by/2.0/ public void checkout(final int roomNumber) { new RoomNumber(roomNumber); //throws exception if invalid houseKeepingService.registerForCleaning(roomNumber); minibarService.replenish(roomNumber); // other operations ... } public void checkout(final int roomNumber) { if (!RoomNumber.isValid(roomNumber)) { reporter.logInvalidRoomNumber(roomNumber); } houseKeepingService.registerForCleaning(roomNumber); minibarService.replenish(roomNumber); // other operations ... }
  • 15. @DanielDeogun @danbjson #SecureByDesign #EDDD Hardening your APIs - Enforce Data Quality Generic Specific public void checkout(final int roomNumber) public void checkout(final RoomNumber roomNumber) Enforce data quality
  • 16. @DanielDeogun @danbjson #SecureByDesign #EDDD Cluttered Entity class Order { private ArrayList<Object> items; private boolean paid;
 
 public void addItem(String isbn, int qty) { if(this.paid == false) { notNull(isbn); inclusiveBetween(10, 10, isbn.length()); isTrue(isbn.matches("[0-9X]*")); isTrue(isbn.matches("[0-9]{9}[0-9X]"));
 Book book = bookCatalogue.findByISBN(isbn);
 if (inventory.availableBooks(isbn) >= qty) { items.add(new OrderLine(book, qty)); } } } //Other logic... }
  • 17. @DanielDeogun @danbjson #SecureByDesign #EDDD De-Cluttered Entity class Order { private ArrayList<Object> items; private boolean paid;
 public void addItem(ISBN isbn, Quantity qty) { notNull(isbn); notNull(qty); if(this.paid == false) { Book book = bookCatalogue.findByISBN(isbn);
 if (inventory.availableBooks(isbn).greaterOrEqualTo(qty)) { items.add(new OrderLine(book, qty)); } } } //Other logic... }
  • 18. @DanielDeogun @danbjson #SecureByDesign #EDDD Renovating Services
  • 19. @DanielDeogun @danbjson #SecureByDesign #EDDD Renovating Services public interface ExchangeService {
 double rate(String from, String to);
 }
 private double convertForeignPrice(
 double priceForeignCurrency,
 String foreignCurrency) {
 
 double rate = exchange.rate(foreignCurrency, "USD");
 double priceUSD = priceForeignCurrency * rate;
 // … and some rounding return priceUSD;
 }
 public interface ExchangeService {
 Rate rate(Currency from, Currency to);
 }
 private Money convertForeignPrice(
 Money priceForeignCurrency,
 Currency foreignCurrency) {
 
 Rate rate = exchange.rate(foreignCurrency, USD);
 Money priceUSD = rate.exchange(priceForeignCurrency);
 return priceUSD;
 }
  • 20. @DanielDeogun @danbjson #SecureByDesign #EDDD But… https://flic.kr/p/eGYhMw https://creativecommons.org/licenses/by/2.0/ … what about performance? https://flic.kr/p/2pvb2T https://creativecommons.org/licenses/by/2.0/ … it becomes a lot of classes! … isn’t it overly complex? https://flic.kr/p/7Ro4HU https://creativecommons.org/licenses/by/2.0/
  • 21. @DanielDeogun @danbjson #SecureByDesign #EDDD … Making it Secure by Design OWASP: • Injection Flaw • Cross-site scripting (XSS) Seals lots of small holes https://flic.kr/p/85qctm https://creativecommons.org/licenses/by/2.0/ Confidentiality Integrity Availability
  • 22. @DanielDeogun @danbjson #SecureByDesign #EDDD Contains several concepts from DDD 40% Discount code ctweddd17 Design secure software without “thinking” about security There’s a Book… Shameless plug…
  • 23. @DanielDeogun @danbjson #SecureByDesign #EDDD Key Take Aways Domain Primitives - are native to your domain - form a conceptual whole - easy way to improve and secure existing code
  • 24. @DanielDeogun @danbjson #SecureByDesign #EDDD Q&A https://flic.kr/p/9ksxQa https://creativecommons.org/licenses/by-nc-nd/2.0/