blob: 93769764055d536d2bb53e9abf50b63ce6b2214c [file] [log] [blame] [view]
# URL Shortener
URL shortener will be one of the first party applications developed and published by pcloud team.
## Background
PCloud customers, especially businesses, will want to share documents with easy to find and intuitive names. For example internal design document hosted at https://docs.google.com/document/d/X0N4-M0oI2P9l8NMRN6JZR9ETo1fpPIMUf_LUPB5Omgw/edit can be named and shared as **https://go/auth-service-dd**
## Goals
* Authenticated user must be able to assign name to any given URL address.
* User can choose name manually or generate it randomly.
* User must be able to view list of all named URLs owned by them.
* [Stretch] User must be able to transfer ownership of the name to the other user.
* [Stretch] Administrator of the system must be able to act as any other user.
## Non-goals
* Authentication will be implemented outside of this service. URL shortener can assume that if user can access the page that user has already been authorized.
* [Maybe] Changing address of alread created entry must not be possible.
## Technichal overview
URL Shortener service will serve only one page at the root path `/`. At the top of the page must be a form to create new named address entry. And below the form must be listed all the named addresses created by currently logged in user.
Form will have two input texts: one to input the address user wants to name and second one for the name itself. Name can be either entered manually or auto-generated by server (user will have to click **Randomize** button. Clicking **Create** button must store new named entry in the storage.
Storage component will have following interface:
```go
type NamedAddress struct {
// Name of the address. Must be unique across the service.
Name string
Address string
OwnerId string
Active bool
}
type Store interface {
// Creates new named address.
Create(name, address, ownerId string) error
// Activates given named address. Does nothing if named address is already active.
Activate(name string) error
// Deactivates given named address. Does nothing if named address is already inactive.
Deactivate(name string) error
// Transfers ownership of the given named address to new owner.
ChangeOwner(name, ownerId string) error
// Retreives all named addresses owned by given owner.
List(ownerId string) ([]NamedAddress, error)
}
```
We will have single implementation of the `Store` interface backed by [go-sqlite3](https://github.com/mattn/go-sqlite3). Path to the sqlite3 file will be passed as a flag, which can be parsed and accessed using standard [flag](https://pkg.go.dev/flag) package, for example `./url-shortener --db-path=/path/to/sqlite3.db`. At the startup server must check if file at given path exists and if not create and initialize (create table for named address entries) it with new sqlite db.
Standard [net/http](https://pkg.go.dev/net/http) is sufficient to implement the web server. Server will have just two handlers registered:
* `GET /` - if request path is `/` render form and list of addresses owner by current user, otherwise (for example `/foo`) server will find named address for `foo` and send HTTP redirect (StatusSeeOther) to address given name was assigned to.
* `POST /` - to create new named address entry
Single HTML template will be sufficient to render the home page via [html/template](https://pkg.go.dev/html/template) package. And [embed](https://pkg.go.dev/embed) package will be used to embed said HTML template into the final binary.
Implementation will go to `apps/url-shortener` directory.