From 7bb7885f6eb19547b906513d2664e3730ef5b593 Mon Sep 17 00:00:00 2001 From: jwijenbergh Date: Thu, 5 May 2022 17:47:36 +0200 Subject: Docs: Add API and building improvements --- docs/src/SUMMARY.md | 14 +++- docs/src/api/README.md | 1 + docs/src/api/go/README.md | 9 +++ docs/src/api/go/example.md | 63 +++++++++++++++ docs/src/api/go/functions.md | 61 ++++++++++++++ docs/src/api/overview/README.md | 8 ++ docs/src/api/overview/connecting.md | 14 ++++ docs/src/api/overview/deregistering.md | 11 +++ docs/src/api/overview/discovery.md | 63 +++++++++++++++ docs/src/api/overview/flow.md | 8 ++ docs/src/api/overview/getconfig.md | 73 +++++++++++++++++ docs/src/api/overview/registering.md | 35 ++++++++ docs/src/api/python/README.md | 11 ++- docs/src/api/python/example.md | 48 +++++++++++ docs/src/api/python/functions.md | 69 ++++++++++++++++ docs/src/gettingstarted/building.md | 119 ---------------------------- docs/src/gettingstarted/building/README.md | 2 + docs/src/gettingstarted/building/example.md | 28 +++++++ docs/src/gettingstarted/building/go.md | 72 +++++++++++++++++ docs/src/gettingstarted/building/python.md | 19 +++++ docs/src/gettingstarted/debugging/fsm.md | 6 +- docs/src/gettingstarted/testing.md | 4 +- 22 files changed, 612 insertions(+), 126 deletions(-) create mode 100644 docs/src/api/go/example.md create mode 100644 docs/src/api/overview/README.md create mode 100644 docs/src/api/overview/connecting.md create mode 100644 docs/src/api/overview/deregistering.md create mode 100644 docs/src/api/overview/discovery.md create mode 100644 docs/src/api/overview/flow.md create mode 100644 docs/src/api/overview/getconfig.md create mode 100644 docs/src/api/overview/registering.md create mode 100644 docs/src/api/python/example.md create mode 100644 docs/src/gettingstarted/building/README.md create mode 100644 docs/src/gettingstarted/building/example.md create mode 100644 docs/src/gettingstarted/building/go.md create mode 100644 docs/src/gettingstarted/building/python.md (limited to 'docs/src') diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 0fea28b..bbe4917 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -2,13 +2,25 @@ - [About](./about.md) - [Getting Started](./gettingstarted/README.md) - - [Building](./gettingstarted/building.md) + - [Building](./gettingstarted/building/README.md) + - [Go library](./gettingstarted/building/go.md) + - [Python wrapper](./gettingstarted/building/python.md) + - [Example from scratch](./gettingstarted/building/example.md) - [Testing](./gettingstarted/testing.md) - [Debugging](./gettingstarted/debugging/README.md) - [Logging](./gettingstarted/debugging/logging.md) - [Finite State Machine](./gettingstarted/debugging/fsm.md) - [API](./api/README.md) + - [Overview](./api/overview/README.md) + - [Registering](./api/overview/registering.md) + - [Discovery](./api/overview/discovery.md) + - [OpenVPN/Wireguard Config](./api/overview/getconfig.md) + - [Connecting/Disconnecting](./api/overview/connecting.md) + - [Deregistering](./api/overview/deregistering.md) + - [Typical flow](./api/overview/flow.md) - [Go](./api/go/README.md) - [Functions](./api/go/functions.md) + - [Example](./api/go/example.md) - [Python](./api/python/README.md) - [Functions](./api/python/functions.md) + - [Example](./api/python/example.md) diff --git a/docs/src/api/README.md b/docs/src/api/README.md index 5932792..0b7ec55 100644 --- a/docs/src/api/README.md +++ b/docs/src/api/README.md @@ -1 +1,2 @@ # API +This section gives the documentation for the API. We first give an overview of the API in a language-agnostic way. Afterwards, we continue with the language specific documentation. We recommend to read both to get a complete picture, regardless of the language you're using. diff --git a/docs/src/api/go/README.md b/docs/src/api/go/README.md index 452b575..6106f1e 100644 --- a/docs/src/api/go/README.md +++ b/docs/src/api/go/README.md @@ -1 +1,10 @@ # Go +The API that has no additional wrapper code is the Go API. To begin to use the Go library in a Go client you first need to import it: + +```go +import "github.com/jwijenbergh/eduvpn-common" +``` + +This brings the library into scope using the eduvpn-common prefix. + +The functions that we define all operate on a `VPNState` object, thus to call a function it needs to be first created and then the function needs to be called. An example of how to tie all of this together is done at the end. diff --git a/docs/src/api/go/example.md b/docs/src/api/go/example.md new file mode 100644 index 0000000..e7b0d36 --- /dev/null +++ b/docs/src/api/go/example.md @@ -0,0 +1,63 @@ +# Example with Comments + +```go + +// Bring the library into scope with the eduvpn prefix +import eduvpn "github.com/jwijenbergh/eduvpn-common" + +// Callbacks + +func stateCallback(state *eduvpn.VPNState, oldState string, newState string, data string) { + + // OAuth is started, open the browser with the authorization URL + if newState == "OAuth_Started" { + openBrowser(data) + } + + // Multiple profiles are found, we need to send a profile ID back using state.SetProfileID + if newState == "Ask_Profile" { + selectAndSendProfile(state, data) + } +} + +func main() { + // Create the VPNState + state := &eduvpn.VPNState{} + + // Register the state + // We use linux so the client ID will be org.eduvpn.app.linux + // We want to store the config files in configs + // We wrap the callback with the state argument + // And enable debugging + registerErr := state.Register("org.eduvpn.app.linux", "configs", func(old string, new string, data string) { + stateCallback(state, old, new, data) + }, true) + + if registErr != nil { + // handle the error of not being able to register + } + + // Cleanup the library at the end + defer state.Deregister() + + // Connect to an example server without forcing TCP + config, configType, configErr := state.GetConnectConfig("eduvpn.example.com", false) + + if configErr != nil { + // handle the error of not being able to get a config + } + + if configType == "wireguard" { + // Connect using wireguard with the config + } else { + // Connect using OpenVPN with the config + } + + // We are connected + setConnectErr := state.SetConnected() + + if setConnectErr != nil { + // handle the error of not being able to call set connected + } +} +``` diff --git a/docs/src/api/go/functions.md b/docs/src/api/go/functions.md index 0c5faf5..c647787 100644 --- a/docs/src/api/go/functions.md +++ b/docs/src/api/go/functions.md @@ -1 +1,62 @@ # Functions +## Registering +See [Overview](../overview/registering.html) +```go +func Register(name string, directory string, stateCallback func, debug bool) error +``` +- `name`: The name of the client +- `directory`: The directory where the configs and logging should be stored +- `stateCallback`: function with three arguments, full type: + ```go + func(oldState string, newState string, data string) + ``` +- `debug`: Whether or not we want to enable debugging + +Returns an `error` type, nil if no error + +## Discovery +See [Overview](../overview/discovery.html) +```go +func GetDiscoServers() (string, error) +func GetDiscoOrganizations() (string, error) +``` + +Returns a string of JSON data with the servers/organizations and an `error`, nil if no error + +## OpenVPN/Wireguard config +See [Overview](../overview/getconfig.html) +```go +func GetConnectConfig(url string, forceTCP bool) (string, string, error) +``` +- `url`: The url of the server to get a connect config for +- `forceTCP`: Whether or not we want to force enable TCP + +Returns: +- A `string` of the OpenVPN/Wireguard config +- A `string`, `openvpn` or `wireguard` indicating if it is an OpenVPN or Wireguard config +- An `error` (can be nil) + +### Setting a profile ID +```go +func SetProfileID(profileID string) error +``` +- `profileID`: The profile ID to connect to + +Returns an `error`, can be nil indicating no error + +## Connecting/Disconnecting +See [Overview](../overview/connecting.html) +```go +func SetConnected() error +func SetDisconnected() error +``` + +Returns an `error`, can be nil indicating no error + +## Deregister +See [Overview](../overview/deregistering.html) +```go +func Deregister() error +``` + +Returns an `error`, can be nil indicating no error diff --git a/docs/src/api/overview/README.md b/docs/src/api/overview/README.md new file mode 100644 index 0000000..d233b0c --- /dev/null +++ b/docs/src/api/overview/README.md @@ -0,0 +1,8 @@ +# API Overview + +This section defines the API in high-level, we explain what functions there are, what their use is and what a typical flow is for creating an eduVPN client with this library. The language specific documentation will be given in separate sections. + +## Note on types and names +This section acts as an introduction to the API, as such this section will e.g. only give general typing information for the arguments and return values. Please read the language specific API documentation as well. To give an example, we will often say that an `Error` is returned. For Go this is the `error` type, whereas for Python this is simply a string with the error message. + +Additionally, the name of the function described will not be stated exactly as this has language specific differences. For example in Go we use the camel case construct, whereas for python snake case is used. E.g. compare `GetConnectConfig` (Go) and `get_connect_config` (Python) diff --git a/docs/src/api/overview/connecting.md b/docs/src/api/overview/connecting.md new file mode 100644 index 0000000..c2a82a0 --- /dev/null +++ b/docs/src/api/overview/connecting.md @@ -0,0 +1,14 @@ +# Connecting/Disconnecting +## Summary +Name: `Set Connected` and `Set Disconnected` + +Arguments: None + +Returns: `Error` + +Used to signal to the FSM that we're connected/disconnected to the VPN + +## Detailed information +This function is used to set the internal FSM state to connected. As the library does not actually connect to a VPN server, as this is platform specific, this must be called by the client to signal to the library that the user is connected to the VPN. If the FSM does not have a transition to the Connected state it will signal this with a returned error. + +The same function is used to signal the FSM that the VPN is disconnected. diff --git a/docs/src/api/overview/deregistering.md b/docs/src/api/overview/deregistering.md new file mode 100644 index 0000000..0503dbe --- /dev/null +++ b/docs/src/api/overview/deregistering.md @@ -0,0 +1,11 @@ +# Deregistering +## Summary +name: `Deregister` + +Arguments: None + +Returns: Nothing + +Used to cleanup the library by deregistering the client and saving the config files +## Detailed information +The deregister method is used to cleanup the library. It should be called when the client closes. This also saves the state to the directory that was passed in the [Register](./registering.html) method. diff --git a/docs/src/api/overview/discovery.md b/docs/src/api/overview/discovery.md new file mode 100644 index 0000000..0999912 --- /dev/null +++ b/docs/src/api/overview/discovery.md @@ -0,0 +1,63 @@ +# Discovery +## Summary +Name: `Get Disco Servers` and `Get Disco Organizations` + +Arguments: None + +Returns: `JSON string for servers/organizations` and `Error for servers/organizations` + +Note: Depending on the wrapper they may be combined into one function, the return value of this function is then the following: +`organizations, error for organizations, servers, errors for servers` + +Used to obtain the servers and organizations list from the discovery server. +## Detailed information +Discovery is the aspect of eduVPN that allows a client to gather all the servers and organizations it can connect to. For this a discovery server is used, which is registered as `https://disco.eduvpn.org` in the library. We refer to the [official eduVPN documentation](https://github.com/eduvpn/documentation/blob/v3/SERVER_DISCOVERY.md) to learn more about the exact way that these organizations and servers are structured. + +The JSON data that this returns must be used by the client to build an UI. It is common for clients that the discovery functions get called on startup of the client. Note that there can be an error in retrieving the newest version of the servers/organizations. However, this library's goal is to ensure that a version is always available. Thus, a local copy is distributed with this library in the future. + +This library also internally looks at the version of the servers and organizations such that rollbacks attacks are prevented. The client does not have to do any additional checks for this. + +The structure of the JSON data is the structure in the [official eduVPN documentation](https://github.com/eduvpn/documentation/blob/v3/SERVER_DISCOVERY.md) without the `v` (version) field. So, for example, the servers list has a possible JSON structure of this: + +```json +[ + { + "server_type": "institute_access", + "base_url": "https://hku.eduvpn.nl/", + "display_name": { + "en-US": "Utrecht School of the Arts", + "nl-NL": "Hogeschool voor de Kunsten Utrecht" + }, + "keyword_list": "hku" + }, + { + "server_type": "secure_internet", + "base_url": "https://eduvpn.rash.al/", + "country_code": "AL", + "support_contact": [ + "mailto:helpdesk@rash.al" + ] + } +] +``` + +And the organizations list has a possible JSON structure of the following: + +```json +[ + { + "display_name": { + "nl": "SURFnet bv", + "en": "SURFnet bv" + }, + "org_id": "https://idp.surfnet.nl", + "secure_internet_home": "https://nl.eduvpn.org/", + "keyword_list": { + "en": "SURFnet bv SURF konijn surf surfnet powered by", + "nl": "SURFnet bv SURF konijn powered by" + } + } +] +``` + + diff --git a/docs/src/api/overview/flow.md b/docs/src/api/overview/flow.md new file mode 100644 index 0000000..14b5a72 --- /dev/null +++ b/docs/src/api/overview/flow.md @@ -0,0 +1,8 @@ +# Typical flow +A typical flow of creating a client is calling the methods that we talked about in order that we introduced them: + +- The client starts, it registers with the library +- A list of discovery servers/organizations is obtained using the library +- The client selects an URL to connect to and calls the function to get an OpenVPN/Wireguard config from the library +- The client uses the OS specific libraries and programs to use the OpenVPN/Wireguard config to establish a tunnel and calls the function to connect or disconnect +- When the client is done it calls the deregister method to save all configuration and clean up diff --git a/docs/src/api/overview/getconfig.md b/docs/src/api/overview/getconfig.md new file mode 100644 index 0000000..70bcb39 --- /dev/null +++ b/docs/src/api/overview/getconfig.md @@ -0,0 +1,73 @@ +# Getting an OpenVPN/Wireguard config +## Summary +name: `Get Connect Config` + +| Arguments | Description | type | +| --------- | -------------------------------------- | -------- | +| URL | The url of the VPN server to connect to | string | +| Force TCP | Whether or not to force the use of TCP | string | + +Returns: `OpenVPN/Wireguard config (string)` `wireguard/openvpn type (string)`, `Error` + +Used to obtain the OpenVPN/Wireguard config + +## Detailed information + +To get a configuration that is used to actually establish a tunnel with the VPN server, we have the Get Connect Config (the exact name depends on the language you're using) function in the library. This function has two parameters *URL* and *Force TCP*. + +*URL* is the base url of the server to connect to e.g. `nl.eduvpn.org`. Note that this function does not need any further input whether or not we want to connect for institute access or secure internet. This is handled in the library by checking the discovery list. If it does not find the server in the discovery list, it assumes it wants to connect as an institute server. + +The *Force TCP* flag is a boolean that indicates whether or not we want to use TCP to connect over the VPN. This flag is useful if the user has enabled e.g. a setting that forces the use of TCP, which is only supported by OpenVPN. If the Force TCP flag is set to true but the server only supports Wireguard then an error is returned and the config will be empty. + +This function takes care of OAuth which has certain callbacks with data. Additionally, there are also callbacks that need to be registered for selecting the right profile to connect to. These callbacks will be explained now. + +The data that this function returns is the OpenVPN/Wireguard config as a string, the type of config (a string: "wireguard" or "openvpn") and an error if present. + +### Callback: OAuth started + +OAuth has an important callback which is used to obtain the authorization URL by the client. This client needs to open this authorization URL in a web browser such that the user can authenticate with the VPN portal and then authorize the client to obtain OpenVPN/Wireguard configs. + +The callback for this is triggered whenever the OAuth Started state is triggered. The data which this callback has is the authorization url that needs to be opened in the web browser. + +The format of the authorization URL is e.g. this: + +`https://eduvpn.example.com/vpn-user-portal/oauth/authorize?client_id=org.eduvpn.app.linux&code_challenge=DsmGyWFBkvDXiIO33Fs40Z0fn4pxtzDCW2jKvAMptBg&code_challenge_method=S256&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fcallback&response_type=code&scope=config&state=vha2Krx-HpOyvFkWsWYmey0jrHQ6bnb06PQ6zBXX_bg` + +### Callback: Selecting a profile + +Another aspect that needs to be taken into account is the fact that there can be multiple profiles that a client can connect to. When the function gets called for obtaining an OpenVPN/Wireguard configuration, it asks the client which profile it wants to connect to using the callback that gets triggered on the Ask Profile state. The data is the list of profiles in JSON format, e.g. + +```json +{ + "info": { + "profile_list": [ + { + "profile_id": "internet", + "default_gateway": true, + "display_name": "IPv4 (NAT) IPv6 (GUA) Access", + "vpn_proto_list": [ + "openvpn" + ] + }, + { + "profile_id": "adblock", + "default_gateway": true, + "display_name": "Malware/Tracking-Blocker IPv4 (NAT) IPv6 (GUA)", + "vpn_proto_list": [ + "openvpn" + ] + }, + { + "profile_id": "dnsonly", + "default_gateway": false, + "display_name": "DNS-Only & Malware/Tracking-Blocker (experimental)", + "vpn_proto_list": [ + "openvpn" + ] + } + ] + } +} +``` + +For actually selecting the profile, there is a separate function which takes care of this. This function takes as only argument the profile ID as a string. diff --git a/docs/src/api/overview/registering.md b/docs/src/api/overview/registering.md new file mode 100644 index 0000000..5c40614 --- /dev/null +++ b/docs/src/api/overview/registering.md @@ -0,0 +1,35 @@ +# Registering a client +## Summary +Name: `Register` + +| Arguments | Description | type | +| --------- | -------------------------------------- | -------- | +| Name | Name of the client | string | +| Directory | Path to save logging and state | string | +| Callback | Function to be used as the FSM callback | function | +| Debug | Indicates whether or not to configure debugging capabilities. See [this section](../../../gettingstarted/debugging/index.html) for more information on debugging. | boolean | + +Returns: `Error` + +Used as initialization function of the library +## Detailed information +This library is made to build eduVPN clients. To create such a client, the register method is used. This method takes a *name*, *directory* and *callback*. This method needs to be called whenever a client wants to use this library. If this method is not called then the remaining methods will not be available to use. + +The *name* is the name of the client, also used as a client ID for OAuth. In general the name is the following for each official eduVPN client (documented [here](https://git.sr.ht/~fkooman/vpn-user-portal/tree/v3/item/src/OAuth/ClientDb.php)): + + +| Platform | Client ID | +| -------- | ------------------------ | +| Linux | `org.eduvpn.app.linux` | +| Windows | `org.eduvpn.app.windows` | +| MacOS | `org.eduvpn.app.macos` | +| Android | `org.eduvpn.app.android` | +| iOS | `org.eduvpn.app.ios` | + +The *directory* is the file path where logging and config files are stored. The library creates this directory if it doesn't exist. This can be an absolute or relative path. We recommend to use an absolute path to ensure that the right directory is chosen. + +The *callback* is the function that gets called when the internal Finite State Machine switches state. This callback function must consist of three arguments + +- Old state: The old state as a string, which is the current FSM state before the transition. See [FSM states](../../gettingstarted/debugging/fsm.html#state-explanation) for a list of states. +- New state: The current state for the FSM after the transition, also a string. See [FSM states](../../gettingstarted/debugging/fsm.html#state-explanation) for a list of states. +- Data: The data that gets sent by the library as a string. Most common this is JSON data to build the UI or in case of OAuth it is the authorization URL that needs to be opened by the browser. When there is no data this is an empty string. diff --git a/docs/src/api/python/README.md b/docs/src/api/python/README.md index 452b575..01a14a0 100644 --- a/docs/src/api/python/README.md +++ b/docs/src/api/python/README.md @@ -1 +1,10 @@ -# Go +# Python +As the Go library is build as a *shared* library, it can be loaded by other languages. We have created wrapper code for Python to use this library. We define the functions and then give a similar example to the Go example. + +The functions that we will discuss are all part of the `EduVPN` class defined in eduvpncommon.main. You can import it like so: + +```python +import eduvpncommon.main as eduvpn + +# Then use eduvpn.EduVPN +``` diff --git a/docs/src/api/python/example.md b/docs/src/api/python/example.md new file mode 100644 index 0000000..7c0997f --- /dev/null +++ b/docs/src/api/python/example.md @@ -0,0 +1,48 @@ +# Example with Comments + +```python +import eduvpncommon.main as eduvpn + +# Callbacks +@_eduvpn.event.on("OAuth_Started", eduvpn.StateType.Enter) +def oauth_initialized(url): + # Open the webbrowser with the url + webbrowser.open(url) + + +@_eduvpn.event.on("Ask_Profile", eduvpn.StateType.Enter) +def ask_profile(profiles): + # Set a profile + _eduvpn.set_profile("example") + +# Register the state +# We use linux so the client ID will be org.eduvpn.app.linux +# We want to store the config files in configs +# And enable debugging +_eduvpn = eduvpn.EduVPN("org.eduvpn.app.linux", "configs") +register_err = _eduvpn.register(debug=True) + +if register_err: + # Handle error + +# Connect to eduvpn.example.com +config, config_type, config_err = _eduvpn.get_connect_config("eduvpn.example.com", False) + +if config_err: + # Handle error + +if config_type == "wireguard": + # Connect using wireguard with the config +elif config_type == "openvpn": + # Connect using OpenVPN with the config +else: + # Handle error + +# Set connected +set_connect_err = _eduvpn.set_connected() +if set_connect_err: + # Handle error + +# Handle cleanup +_eduvpn.deregister() +``` diff --git a/docs/src/api/python/functions.md b/docs/src/api/python/functions.md index 0c5faf5..ebfb774 100644 --- a/docs/src/api/python/functions.md +++ b/docs/src/api/python/functions.md @@ -1 +1,70 @@ # Functions +## Creating the class +See [Overview](../overview/registering.html) + +This creates the class and basically forwards these arguments when `register` is called. +```python +def __init__(self, name: str, directory: str) +``` +- `name`: The name of the client +- `directory`: The directory where the configs and logging should be stored + +## Registering +See [Overview](../overview/registering.html) +```python +def register(self, debug=False: bool) -> Optional[str] +``` +- `debug`: Whether or not we want to enable debugging + +Returns an optional `string` for the error message + +## Discovery +See [Overview](../overview/discovery.html) +```python +def get_disco_servers(self) -> (Optional[str], Optional[str]) +``` +```python +def get_disco_organizations(self) -> (Optional[str], Optional[str]) +``` + +Returns an optional `string` of JSON data with the servers/organizations and an optional error message + +## OpenVPN/Wireguard config +See [Overview](../overview/getconfig.html) +```python +def get_connect_config(self, url: str, forceTCP: bool) -> (Optional[str], Optional[str], Optional[str]) +``` +- `url`: The url of the server to get a connect config for +- `forceTCP`: Whether or not we want to force enable TCP + +Returns: +- An optional `string` of the OpenVPN/Wireguard config +- An optional `string`, `openvpn` or `wireguard` indicating if it is an OpenVPN or Wireguard config +- An optional error message `string` + +### Setting a profile ID +```python +def set_profile(self, profile_id: str) -> Optional[str] +``` +- `profile_id`: The profile ID to connect to + +Returns an optional `string`, which is the error message + +## Connecting/Disconnecting +See [Overview](../overview/connecting.html) +```python +def set_connected(self) -> Optional[str] +``` +```python +def set_disconnected(self) -> Optional[str] +``` + +Returns an optional `string`, which is the error message + +## Deregister +See [Overview](../overview/deregistering.html) +```python +def deregister() -> Optional[str] +``` + +Returns an optional `string`, which is the error message diff --git a/docs/src/gettingstarted/building.md b/docs/src/gettingstarted/building.md index 962540e..e69de29 100644 --- a/docs/src/gettingstarted/building.md +++ b/docs/src/gettingstarted/building.md @@ -1,119 +0,0 @@ -# Building -To build the Go library, you need the dependencies for your system installed. We will go over the needed dependencies for Linux and Windows. Afterwards, we explain the basic commands to build the library. -## Linux -To build the GO shared library using Linux you need the following dependencies: - -- [Go](https://go.dev/doc/install) 1.15 or later -- [Gcc](https://gcc.gnu.org/) -- [GNU Make](https://www.gnu.org/software/make/) -- Dependencies for each wrapper you are interested in - -## Windows -On Windows, you can install gcc and make (or even Go) via MinGW or Cygwin or use WSL. For MinGW: - -1. [Install MinGW](https://www.msys2.org/#installation) (you don't need to install any extra packages yet) and open some - MSYS2 terminal (e.g. from the start menu or one of the installed binaries) -2. Install the [`make`](https://packages.msys2.org/package/make?repo=msys) package (`pacman -S make`) (or - e.g. [`mingw-w64-x86_64-make`](https://packages.msys2.org/package/mingw-w64-x86_64-make?repo=mingw64) and - use `mingw32-make` in the command line) -3. To compile for x86_64: - 1. Install the [`mingw-w64-x86_64-gcc`](https://packages.msys2.org/package/mingw-w64-x86_64-gcc?repo=mingw64) - package - 2. Open the MinGW 64-bit console, via the start menu, or in your current - terminal: `path/to/msys64/msys2_shell.cmd -mingw64 -defterm -no-start -use-full-path` - 3. Run the make commands in the project directory -4. To compile for x86 (32-bit): - 1. Install the [`mingw-w64-i686-gcc`](https://packages.msys2.org/package/mingw-w64-i686-gcc?repo=mingw32) package - 2. Open the MinGW 32-bit console, via the start menu, or in your current - terminal: `path/to/msys64/msys2_shell.cmd -mingw32 -defterm -no-start -use-full-path` - 3. Run the make commands in the project directory - -## Building Go shared library -Before we can begin building the wrapper code, we need to build the Go code as a shared library. This section will tell you how to do so. - -To build the shared library for the current platform issue the following command in the root directory: - -```bash -make -``` - -You can also build the shared library for a specified OS & architecture (example): - -```bash -make GOOS=windows GOARCH=386 -``` - -We use cgo to build a shared library, to list all platform supported by cgo issue `go tool dist list`. - -The shared library will be output in `exports/lib/`. - -For cross compiling, you usually need to specify the compiler, for example: - -```bash -make GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc -``` - -For example, you can cross compile for Windows from Linux using [MinGW-w64](https://www.mingw-w64.org/downloads/). - -This shared library gets loaded by the different wrappers. To build the actual wrapper code, you need other build commands. This will be explained now - -### Python - -To build the python wrapper issue the following command (in the root directory of the eduvpn-common project): - -```bash -make -C wrappers/python -``` - -This uses the makefile in `wrappers/python/Makefile` to build the python file into a wheel placed in `wrappers/python/dist/eduvpncommon-[version]-py3-none-[platform].whl`. Where version is the version of the library and platform is your current platform. Like Go you can also build for a specific platform: - -```bash -make PLAT_NAME=win32 -``` - -The wheel can be installed with `pip`: - -```bash -pip install ./wrappers/python/dist/eduvpncommon-[version]-py3-none-[platform].whl -``` - -### Cleaning -Clean built libraries and wrapper builds: - -```bash -make -j clean -``` - -Usually you won't need to do this, as changes in the library should automatically be incorporated in wrappers. -Specify `CLEAN_ALL=1` to also remove downloaded dependencies for some wrappers. You can clean individual wrappers by -executing clean in their directories, or specify `WRAPPERS=...`. - -### Example: commands to build for Python -This section gives an example on how to build and install the library from scratch (assuming you have all the dependencies) - -1. Clone the library -```bash -git clone https://github.com/jwijenbergh/eduvpn-common -``` - -2. Go to the library directory -```bash -cd eduvpn-common -``` - -3. Build the go library -```bash -make -``` - -4. Build the python wrapper -```bash -make -C wrappers/python -``` - -5. Install the wheel using pip -```bash -pip install wrappers/python/dist/eduvpncommon-0.1.0-py3-none-linux_x86_64.whl -``` -Note that the name of your wheel changes on the platform and version. - diff --git a/docs/src/gettingstarted/building/README.md b/docs/src/gettingstarted/building/README.md new file mode 100644 index 0000000..70df2b7 --- /dev/null +++ b/docs/src/gettingstarted/building/README.md @@ -0,0 +1,2 @@ +# Building +This section contains the instruction on how to build the library and associated wrappers. We first explain how to build the Go library and then further explain the wrapper specific building process. As the Python wrapper is the only stable wrapper at the moment, this only consists of this wrapper language for now. diff --git a/docs/src/gettingstarted/building/example.md b/docs/src/gettingstarted/building/example.md new file mode 100644 index 0000000..668d77a --- /dev/null +++ b/docs/src/gettingstarted/building/example.md @@ -0,0 +1,28 @@ +# Example: commands to build for Python +This section gives an example on how to build and install the library from scratch (assuming you have all the dependencies). It builds the Go library and then builds and installs the Python wrapper. + +1. Clone the library +```bash +git clone https://github.com/jwijenbergh/eduvpn-common +``` + +2. Go to the library directory +```bash +cd eduvpn-common +``` + +3. Build the go library +```bash +make +``` + +4. Build the python wrapper +```bash +make -C wrappers/python +``` + +5. Install the wheel using pip +```bash +pip install wrappers/python/dist/eduvpncommon-0.1.0-py3-none-linux_x86_64.whl +``` +Note that the name of your wheel changes on the platform and version. diff --git a/docs/src/gettingstarted/building/go.md b/docs/src/gettingstarted/building/go.md new file mode 100644 index 0000000..65f62a5 --- /dev/null +++ b/docs/src/gettingstarted/building/go.md @@ -0,0 +1,72 @@ +# Building the Go library +To build the Go library, you need the dependencies for your system installed. We will go over the needed dependencies for Linux and Windows. Afterwards, we explain the basic commands to build the library. + +## Dependencies +### Linux +To build the Go shared library using Linux you need the following dependencies: + +- [Go](https://go.dev/doc/install) 1.15 or later +- [Gcc](https://gcc.gnu.org/) +- [GNU Make](https://www.gnu.org/software/make/) +- Dependencies for each wrapper you are interested in + +### Windows +On Windows, you can install gcc and make (or even Go) via MinGW or Cygwin or use WSL. For MinGW: + +1. [Install MinGW](https://www.msys2.org/#installation) (you don't need to install any extra packages yet) and open some + MSYS2 terminal (e.g. from the start menu or one of the installed binaries) +2. Install the [`make`](https://packages.msys2.org/package/make?repo=msys) package (`pacman -S make`) (or + e.g. [`mingw-w64-x86_64-make`](https://packages.msys2.org/package/mingw-w64-x86_64-make?repo=mingw64) and + use `mingw32-make` in the command line) +3. To compile for x86_64: + 1. Install the [`mingw-w64-x86_64-gcc`](https://packages.msys2.org/package/mingw-w64-x86_64-gcc?repo=mingw64) + package + 2. Open the MinGW 64-bit console, via the start menu, or in your current + terminal: `path/to/msys64/msys2_shell.cmd -mingw64 -defterm -no-start -use-full-path` + 3. Run the make commands in the project directory +4. To compile for x86 (32-bit): + 1. Install the [`mingw-w64-i686-gcc`](https://packages.msys2.org/package/mingw-w64-i686-gcc?repo=mingw32) package + 2. Open the MinGW 32-bit console, via the start menu, or in your current + terminal: `path/to/msys64/msys2_shell.cmd -mingw32 -defterm -no-start -use-full-path` + 3. Run the make commands in the project directory + +## Commands +Before we can begin building the wrapper code, we need to build the Go code as a shared library. This section will tell you how to do so. + +To build the shared library for the current platform issue the following command in the root directory: + +```bash +make +``` + +You can also build the shared library for a specified OS & architecture (example): + +```bash +make GOOS=windows GOARCH=386 +``` + +We use cgo to build a shared library, to list all platform supported by cgo issue `go tool dist list`. + +The shared library will be output in `exports/lib/`. + +For cross compiling, you usually need to specify the compiler, for example: + +```bash +make GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc +``` + +For example, you can cross compile for Windows from Linux using [MinGW-w64](https://www.mingw-w64.org/downloads/). + +This shared library gets loaded by the different wrappers. To build the actual wrapper code, you need other build commands. This will be explained now + +### Cleaning +To clean build the library and wrapper, issue the following command in the root directory: + +```bash +make -j clean +``` + +Usually you won't need to do this, as changes in the library should automatically be incorporated in wrappers. +Specify `CLEAN_ALL=1` to also remove downloaded dependencies for some wrappers. You can clean individual wrappers by +executing clean in their directories, or specify `WRAPPERS=...`. + diff --git a/docs/src/gettingstarted/building/python.md b/docs/src/gettingstarted/building/python.md new file mode 100644 index 0000000..6995f9e --- /dev/null +++ b/docs/src/gettingstarted/building/python.md @@ -0,0 +1,19 @@ +# Python Wrapper + +To build the python wrapper issue the following command (in the root directory of the eduvpn-common project): + +```bash +make -C wrappers/python +``` + +This uses the makefile in `wrappers/python/Makefile` to build the python file into a wheel placed in `wrappers/python/dist/eduvpncommon-[version]-py3-none-[platform].whl`. Where version is the version of the library and platform is your current platform. Like Go you can also build for a specific platform: + +```bash +make PLAT_NAME=win32 +``` + +The wheel can be installed with `pip`: + +```bash +pip install ./wrappers/python/dist/eduvpncommon-[version]-py3-none-[platform].whl +``` diff --git a/docs/src/gettingstarted/debugging/fsm.md b/docs/src/gettingstarted/debugging/fsm.md index 08022cb..11d51de 100644 --- a/docs/src/gettingstarted/debugging/fsm.md +++ b/docs/src/gettingstarted/debugging/fsm.md @@ -19,9 +19,9 @@ The current state is highlighted in the cyan col ## State explanation The states mean the following: -- `DEREGISTERED`: The client has not registered with the library yet, the state variables are not initialized -- `NO_SERVER`: The client is registered, but has not chosen a server yet -- `CHOSEN_SERVER`: The client has chosen a server to connect to +- `Deregistered`: The client has not registered with the library yet, the state variables are not initialized +- `No_Server`: The client is registered, but has not chosen a server yet +- `Chosen_ServeR`: The client has chosen a server to connect to - `OAuth_Started`: The OAuth process has been started. This means that the client needs to redirect to the browser so that the user can login and approve the application - `Authorized`: The OAuth process has finished. The client now has tokens and is thus authorized - `Request_Config`: The client is in the process of requesting an OpenVPN/Wireguard configuration from the server diff --git a/docs/src/gettingstarted/testing.md b/docs/src/gettingstarted/testing.md index f89757e..7bf4bf2 100644 --- a/docs/src/gettingstarted/testing.md +++ b/docs/src/gettingstarted/testing.md @@ -1,7 +1,6 @@ # Testing To test the Go code, issue the following command in a shell -## Testing the Go code ```bash make test-go ``` @@ -13,12 +12,13 @@ SERVER_URI="eduvpn.example.com" PORTAL_USER="example" PORTAL_PASS="example" make ``` If you have [Docker](https://www.docker.com/get-started/) installed and [Docker-compose](https://docs.docker.com/compose/install/) you can use a convenient helper script which starts up two containers -- An eduvpnserver for testing +- An EduVPN Server for testing - A Go container that builds and runs the test-suite ```bash PORTAL_USER="example" PORTAL_PASS="example" ./ci/startcompose.sh ``` +Note that this helper script also assumes you have the `openssl` command line tool installed. This is used to install the self-signed certificates for testing. This script is also used in the continuous integration, so we recommend to run this before you submit any changes. ## Testing the wrappers -- cgit v1.2.3