diff --git a/.obsidian/core-plugins.json b/.obsidian/core-plugins.json index 56b44a5..1d8661f 100644 --- a/.obsidian/core-plugins.json +++ b/.obsidian/core-plugins.json @@ -1,21 +1,30 @@ -[ - "file-explorer", - "global-search", - "switcher", - "graph", - "backlink", - "canvas", - "outgoing-link", - "tag-pane", - "properties", - "page-preview", - "daily-notes", - "templates", - "note-composer", - "command-palette", - "editor-status", - "bookmarks", - "outline", - "word-count", - "file-recovery" -] \ No newline at end of file +{ + "file-explorer": true, + "global-search": true, + "switcher": true, + "graph": true, + "backlink": true, + "canvas": true, + "outgoing-link": true, + "tag-pane": true, + "page-preview": true, + "daily-notes": true, + "templates": true, + "note-composer": true, + "command-palette": true, + "slash-command": false, + "editor-status": true, + "bookmarks": true, + "markdown-importer": false, + "zk-prefixer": false, + "random-note": false, + "outline": true, + "word-count": true, + "slides": false, + "audio-recorder": false, + "workspaces": false, + "file-recovery": true, + "publish": false, + "sync": false, + "properties": true +} \ No newline at end of file diff --git a/Software Engineering/Backend Engineering/Are you friends already on Yelp?.png b/Software Engineering/Backend Engineering/Are you friends already on Yelp?.png new file mode 100644 index 0000000..d7beec6 Binary files /dev/null and b/Software Engineering/Backend Engineering/Are you friends already on Yelp?.png differ diff --git a/Software Engineering/Backend Engineering/Backend Communication Design Patterns.md b/Software Engineering/Backend Engineering/Backend Communication Design Patterns.md new file mode 100644 index 0000000..8c99c26 --- /dev/null +++ b/Software Engineering/Backend Engineering/Backend Communication Design Patterns.md @@ -0,0 +1,5 @@ +# Explanation +- + +# Sources +- [Fundamentals of Backend Engineering - ] diff --git a/Software Engineering/Backend Engineering/Backend Engineering.md b/Software Engineering/Backend Engineering/Backend Engineering.md new file mode 100644 index 0000000..6e62dfd --- /dev/null +++ b/Software Engineering/Backend Engineering/Backend Engineering.md @@ -0,0 +1,14 @@ +# Topics +- Backend Communication Design Patterns: + - [[Request - Response]] + - Asynchronous Communication + - Pushing + - Short Polling + - Long Polling + - Server Sent Events + - Pub/Sub +- [[OAuth and OpenID Connect]] +- [[WebSockets]] +- Proxies + - [[Forward Proxies]] + - [[Reverse Proxies]] diff --git a/Software Engineering/Backend Engineering/Delegated Authorization 1.png b/Software Engineering/Backend Engineering/Delegated Authorization 1.png new file mode 100644 index 0000000..3214291 Binary files /dev/null and b/Software Engineering/Backend Engineering/Delegated Authorization 1.png differ diff --git a/Software Engineering/Backend Engineering/Delegated Authorization 2.png b/Software Engineering/Backend Engineering/Delegated Authorization 2.png new file mode 100644 index 0000000..ccccfae Binary files /dev/null and b/Software Engineering/Backend Engineering/Delegated Authorization 2.png differ diff --git a/Software Engineering/Backend Engineering/Forward Proxies.md b/Software Engineering/Backend Engineering/Forward Proxies.md new file mode 100644 index 0000000..b2faba4 --- /dev/null +++ b/Software Engineering/Backend Engineering/Forward Proxies.md @@ -0,0 +1,20 @@ +# Explanation +- *Forward Proxy*: a server that sits in front of a group of client machines. When those computers make requests to sites and services on the Internet, the proxy server intercepts those requests and then communicates with web servers on behalf of those clients, like a middleman. + - Sometimes called a proxy, proxy server, or web proxy. +- + +## Illustration +![[Forward Proxy Flow.png]] + +## Use Cases +- Get around state or institutional browsing restrictions by letting users connect to a proxy rather than directly to the sites they are visiting. +- Block a group of users from accessing certain sites. + - **Example**: a school network might be configured to connect to the web through a proxy which enables content filtering rules, refusing to forward responses from Facebook and other social media sites. +- Protect a user's identity online. +- [[Cache]] frequently accessed content. + - If another client requests the same content, the proxy can serve it directly from its cache, reducing the need to retrieve it again from the origin server. +- Enable logging of client requests, useful for monitoring website usage or identifying suspicious activity. + +# Sources +- [Hussein Nasser - Proxy vs Reverse Proxy Server Explained](https://www.youtube.com/watch?v=SqqrOspasag) +- [Cloudflare - What is a reverse proxy? | Proxy servers explained](https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/) \ No newline at end of file diff --git a/Software Engineering/Backend Engineering/Forward Proxy Flow.png b/Software Engineering/Backend Engineering/Forward Proxy Flow.png new file mode 100644 index 0000000..cfa6523 Binary files /dev/null and b/Software Engineering/Backend Engineering/Forward Proxy Flow.png differ diff --git a/Software Engineering/Backend Engineering/OAuth 2.0 authorization code flow.png b/Software Engineering/Backend Engineering/OAuth 2.0 authorization code flow.png new file mode 100644 index 0000000..83f7a1e Binary files /dev/null and b/Software Engineering/Backend Engineering/OAuth 2.0 authorization code flow.png differ diff --git a/Software Engineering/Backend Engineering/OAuth and OpenID Connect.md b/Software Engineering/Backend Engineering/OAuth and OpenID Connect.md new file mode 100644 index 0000000..d6f6260 --- /dev/null +++ b/Software Engineering/Backend Engineering/OAuth and OpenID Connect.md @@ -0,0 +1,53 @@ +# Explanation + +## Problem (Delegated Authorization) +- Before the advent of OAuth 2.0, granting third-party applications access to user data on another service often required users to share their credentials directly with the application. +- This practice posed significant security risks, as it exposed user credentials to potentially untrustworthy applications. +- OAuth 2.0 was developed to solve this "delegated authorization problem" by allowing users to grant limited access to their data without sharing their credentials. +- Illustration: + - 1: ![[Delegated Authorization 1.png]] + - 2: ![[Delegated Authorization 2.png]] + +### The Yelp Example +- In the early days of the internet, companies like Yelp attempted to solve this problem by asking users for their email login credentials. +- This practice was highly insecure and highlighted the need for a more robust solution. +- Don't do this: ![[Are you friends already on Yelp?.png]] + +## Terminology +- **Resource Owner:** The user who owns the protected data and grants permission to access it. +- **Client:** The application requesting access to protected resources on behalf of the user. +- **Authorization Server:** The system responsible for user authentication, obtaining consent, and issuing access tokens and ID tokens. +- **Resource Server:** The system hosting the protected resources, responsible for verifying access tokens and granting access to data. +- **Access Token:** A credential provided to the client after successful authorization, allowing access to protected resources on the resource server within the defined scope. +- **Authorization Code:** A temporary code issued by the authorization server after user consent, which is exchanged for an access token on the back channel. +- **Scopes:** Defines the specific permissions an application requests, controlling the level of access granted to the client. + +## OAuth 2.0 Authorization Code Flow +### Explanation +1. **Requesting Authorization:** The client initiates the flow by directing the user's browser to the authorization server. The request includes the client ID, requested scopes, and the redirect URI. +2. **User Authentication and Consent:** The authorization server authenticates the user and presents a consent screen detailing the scopes requested by the client. The user can then choose to grant or deny access. +3. **Issuing the Authorization Code:** Upon user consent, the authorization server issues an authorization code to the client. This code is transmitted back to the client via the redirect URI specified in the initial request. +4. **Exchanging the Code for an Access Token:** The client exchanges the authorization code for an access token through a secure back-channel communication with the authorization server. This exchange involves the client ID, client secret, and the authorization code. +5. **Accessing Protected Resources:** With the obtained access token, the client can now access the protected resources on the resource server. The access token is presented in the authorization header of the request. +### Illustration +![[OAuth 2.0 authorization code flow.png]] + +## Problems with OAuth 2.0 for authentication +- No standard way to get the user's information +- Every implementation is a little different +- No common set of scopes + +## OpenID Connect +### Explanation +- *OpenID Connect*: an authentication layer built on top of OAuth 2.0, standardizing the process of obtaining user information and enabling single sign-on. +- OpenID Connect adds: + - **ID Token:** A JSON Web Token (JWT) containing information about the authenticated user, including user ID, email address, and token expiration time. + - It allows applications to verify user identity and access basic profile information. + - **User Info Endpoint:** A dedicated endpoint that allows clients to retrieve additional user information using the access token. + - **Standard set of scopes**. + - **Standardized implementation**. +### Illustration +![[OpenID Connect authorization code flow.png]] + +# Sources +- [OktaDev - OAuth 2.0 and OpenID Connect (in plain English)](https://www.youtube.com/watch?v=996OiexHze0) diff --git a/Software Engineering/Backend Engineering/OpenID Connect authorization code flow.png b/Software Engineering/Backend Engineering/OpenID Connect authorization code flow.png new file mode 100644 index 0000000..53fae04 Binary files /dev/null and b/Software Engineering/Backend Engineering/OpenID Connect authorization code flow.png differ diff --git a/Software Engineering/Backend Engineering/Request - Response.md b/Software Engineering/Backend Engineering/Request - Response.md new file mode 100644 index 0000000..2391c8a --- /dev/null +++ b/Software Engineering/Backend Engineering/Request - Response.md @@ -0,0 +1,16 @@ +# Explanation + +## Usage +- Web, [[HTTP]], [[DNS (Domain Name System)]], [[SSH (Secure Shell)]] +- RPC (remote procedure call) +- [[Relational Model|SQL]] and Database Protocols +- APIs (REST/SOAP/GraphQL) + +## Not useful in +- Notification service +- Chatting application +- Very Long requests +- What if client disconnects? + +# Sources +- [Fundamentals of Backend Engineering - 7. Request Response](https://www.udemy.com/course/fundamentals-of-backend-communications-and-protocols/learn/lecture/34629344#overview) diff --git a/Software Engineering/Backend Engineering/Reverse Proxies.md b/Software Engineering/Backend Engineering/Reverse Proxies.md new file mode 100644 index 0000000..d501340 --- /dev/null +++ b/Software Engineering/Backend Engineering/Reverse Proxies.md @@ -0,0 +1,30 @@ +# Explanation +- *Reverse Proxy*: a server that sits in front of one or more web servers, intercepting requests from clients. + - This is different from a [[Forward Proxies|forward proxy]], where the proxy sits in front of the clients. +- With a reverse proxy, when clients send requests to the origin server of a website, those requests are intercepted at the [network edge](https://www.cloudflare.com/learning/serverless/glossary/what-is-edge-computing/) by the reverse proxy server. + - The reverse proxy server will then send requests to and receive responses from the origin server. + +## Illustration +![[Reverse Proxy Flow.png]] + +## Use Cases +- **[[Load balancing]]** +- **Protection from attacks** + - With a reverse proxy in place, a web site or service never needs to reveal the IP address of their origin server(s). + - This makes it much harder for attackers to leverage a targeted attack against them, such as a *DDoS attack*. Instead the attackers will only be able to target the reverse proxy which will have tighter security and more resources to fend off a cyber attack. +- **Global server load balancing (GSLB)**: A website can be distributed on several servers around the globe and the reverse proxy will *redirect* clients to the server that’s geographically closest to them. +- [[Cache|Caching]] content, resulting in faster performance. +- **SSL encryption** + - Encrypting and decrypting SSL (or TLS) communications for each client can be computationally expensive for an origin server. + - A reverse proxy can be configured to decrypt all incoming requests and encrypt all outgoing responses, freeing up valuable resources on the origin server. +- **Ingress**: A reverse proxy can act as a router to direct incoming requests to the appropriate microservice based on criteria like the requested API or content. +- **Canary Deployments**: + - This Allows a small percentage of users to be directed to a new version of an application while the majority of users remain on the old version. + - Used for testing new features before a full rollout. + +## Examples +- + +# Sources +- [Hussein Nasser - Proxy vs Reverse Proxy Server Explained](https://www.youtube.com/watch?v=SqqrOspasag) +- [Cloudflare - What is a reverse proxy? | Proxy servers explained](https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/) \ No newline at end of file diff --git a/Software Engineering/Backend Engineering/Reverse Proxy Flow.png b/Software Engineering/Backend Engineering/Reverse Proxy Flow.png new file mode 100644 index 0000000..cedbae2 Binary files /dev/null and b/Software Engineering/Backend Engineering/Reverse Proxy Flow.png differ diff --git a/Software Engineering/Backend Engineering/WebSockets.md b/Software Engineering/Backend Engineering/WebSockets.md new file mode 100644 index 0000000..8a7eb5e --- /dev/null +++ b/Software Engineering/Backend Engineering/WebSockets.md @@ -0,0 +1,4 @@ +# Resources + - [Writing WebSocket Servers - MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#pings_and_pongs_the_heartbeat_of_websockets) + - [WebSockets RFC](https://datatracker.ietf.org/doc/rfc6455/?include_text=1) + \ No newline at end of file diff --git a/Software Engineering/Cloud Computing/Cloud Computing.md b/Software Engineering/Cloud Computing/Cloud Computing.md new file mode 100644 index 0000000..ca95be4 --- /dev/null +++ b/Software Engineering/Cloud Computing/Cloud Computing.md @@ -0,0 +1,2 @@ +# Topics +- [[SSH (Secure Shell)]] diff --git a/Software Engineering/Cloud Computing/SSH (Secure Shell).md b/Software Engineering/Cloud Computing/SSH (Secure Shell).md new file mode 100644 index 0000000..4a784d7 --- /dev/null +++ b/Software Engineering/Cloud Computing/SSH (Secure Shell).md @@ -0,0 +1,30 @@ +# Explanation +- SSH stands for Secure Shell and provides a safe and secure way of executing commands, making changes, and configuring services remotely. +- When you connect through SSH, you log in using an account that exists on the remote server. + +## Authentication Mechanism +- Clients generally authenticate either using passwords (less secure and not recommended) or SSH keys, which are very secure. + +### Password Authentication +- Password logins are encrypted and are easy to understand for new users. +- However, automated bots and malicious users will often repeatedly try to authenticate to accounts that allow password-based logins, which can lead to security compromises. + - For this reason, it's recommended always setting up SSH key-based authentication for most configurations. + +### SSH Keys Authentication +- SSH keys are a matching set of cryptographic keys (public and private) which can be used for authentication. + - The public key can be shared freely without concern, + - while the private key must be vigilantly guarded and never exposed to anyone. +- To authenticate using SSH keys, a user must have an SSH key pair on their local computer. +- On the remote server, the public key must be copied to a file within the user’s home directory at `~/.ssh/authorized_keys`. + - This file contains a list of public keys, one-per-line, that are authorized to log into this account. + +#### Steps +1. When a client connects to the host, wishing to use SSH key authentication, it will inform the server of this intent and will tell the server which public key to use. +2. The server then checks its `authorized_keys` file for the public key, generates a random string, and encrypts it using the public key. + - This encrypted message can only be decrypted with the associated private key. +3. The server will send this encrypted message to the client to test whether they actually have the associated private key. +4. Upon receipt of this message, the client will decrypt it using the private key and combine the random string that is revealed with a previously negotiated session ID. It then generates an MD5 hash of this value and transmits it back to the server. +5. The server already had the original message and the session ID, so it can compare an MD5 hash generated by those values and determine that the client must have the private key. + +# Sources +- [SSH Essentials: Working with SSH Servers, Clients, and Keys](https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys) diff --git a/Software Engineering/Django/Django Channels.md b/Software Engineering/Django/Django Channels.md new file mode 100644 index 0000000..4c8b7b9 --- /dev/null +++ b/Software Engineering/Django/Django Channels.md @@ -0,0 +1,89 @@ +# Explanation +- Channels wraps Django’s native asynchronous view support, allowing Django projects to handle not only HTTP, but protocols that require long-running connections too - WebSockets, MQTT, chatbots, amateur radio, and more. +- It does this while preserving Django’s synchronous and easy-to-use nature, allowing you to choose how you write your code - synchronous in a style like Django views, fully asynchronous, or a mixture of both. On top of this, it provides integrations with Django’s auth system, session system, and more, making it easier than ever to extend your HTTP-only project to other protocols. +- Channels also bundles this event-driven architecture with _channel layers_, a system that allows you to easily communicate between processes, and separate your project into different processes. + +# Scopes and Events +- The _scope_ is a set of details about a single incoming connection - such as the path a web request was made from, or the originating IP address of a WebSocket, or the user messaging a chatbot. The scope persists throughout the connection. +- For HTTP, the scope just lasts a single request. For WebSockets, it lasts for the lifetime of the socket (but changes if the socket closes and reconnects). For other protocols, it varies based on how the protocol’s ASGI spec is written; for example, it’s likely that a chatbot protocol would keep one scope open for the entirety of a user’s conversation with the bot, even if the underlying chat protocol is stateless. +- During the lifetime of this _scope_, a series of _events_ occur. These represent user interactions - making a HTTP request, for example, or sending a WebSocket frame. Your Channels or ASGI applications will be **instantiated once per scope**, and then be fed the stream of _events_ happening within that scope to decide what action to take. + +# Consumers +- A consumer is the basic unit of Channels code. We call it a _consumer_ as it _consumes events_, but you can think of it as its own tiny little application. When a request or new socket comes in, Channels will follow its routing table - we’ll look at that in a bit - find the right consumer for that incoming connection, and start up a copy of it. +- This means that, unlike Django views, consumers are long-running. They can also be short-running - after all, HTTP requests can also be served by consumers - but they’re built around the idea of living for a little while (they live for the duration of a _scope_, as we described above). +- A basic consumer looks like this: + +```python +class ChatConsumer(WebsocketConsumer): + + def connect(self): + self.username = "Anonymous" + self.accept() + self.send(text_data="[Welcome %s!]" % self.username) + + def receive(self, *, text_data): + if text_data.startswith("/name"): + self.username = text_data[5:].strip() + self.send(text_data="[set your username to %s]" % self.username) + else: + self.send(text_data=self.username + ": " + text_data) + + def disconnect(self, message): + pass +``` + +# Channel Layers +- A channel layer is a kind of communication system. It allows multiple consumer instances to talk with each other, and with other parts of Django. +- A channel layer provides the following abstractions: + - A **channel** is a mailbox where messages can be sent to. Each channel has a name. Anyone who has the name of a channel can send a message to the channel. + - A **group** is a group of related channels. A group has a name. Anyone who has the name of a group can add/remove a channel to the group by name and send a message to all channels in the group. It is not possible to enumerate what channels are in a particular group. +- Every consumer instance has an automatically generated unique channel name, and so can be communicated with via a channel layer. +- Example Code: +```python +import json + +from asgiref.sync import async_to_sync +from channels.generic.websocket import WebsocketConsumer + +class ChatConsumer(WebsocketConsumer): + def connect(self): + self.room_name = self.scope["url_route"]["kwargs"]["room_name"] + self.room_group_name = f"chat_{self.room_name}" + + # Join room group + async_to_sync(self.channel_layer.group_add)( + self.room_group_name, self.channel_name + ) + + self.accept() + + def disconnect(self, close_code): + # Leave room group + async_to_sync(self.channel_layer.group_discard)( + self.room_group_name, self.channel_name + ) + + # Receive message from WebSocket + def receive(self, text_data): + text_data_json = json.loads(text_data) + message = text_data_json["message"] + + # Send message to room group + async_to_sync(self.channel_layer.group_send)( + self.room_group_name, {"type": "chat.message", "message": message} + ) + + # Receive message from room group + def chat_message(self, event): + message = event["message"] + + # Send message to WebSocket + self.send(text_data=json.dumps({"message": message})) +``` + +- Every consumer has a [scope](https://channels.readthedocs.io/en/latest/topics/consumers.html#scope) that contains information about its connection, including in particular any positional or keyword arguments from the URL route and the currently authenticated user if any. +- Group names are restricted to ASCII alphanumerics, hyphens, and periods only and are limited to a maximum length of 100 in the default backend. Since this code constructs a group name directly from the room name, it will fail if the room name contains any characters that aren’t valid in a group name or exceeds the length limit. +- An event has a special `'type'` key corresponding to the name of the method that should be invoked on consumers that receive the event. This translation is done by replacing `.` with `_`, thus in this example, `chat.message` calls the `chat_message` method. + +# Sources +- [Introduction - Channels](https://channels.readthedocs.io/en/latest/introduction.html) \ No newline at end of file diff --git a/Software Engineering/Software Engineering.md b/Software Engineering/Software Engineering.md deleted file mode 100644 index 2f0c974..0000000 --- a/Software Engineering/Software Engineering.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topics -- [[Design Patterns]]