diff options
| author | Jeroen Wijenbergh <jeroenwijenbergh@protonmail.com> | 2024-05-08 11:49:19 +0200 |
|---|---|---|
| committer | Jeroen Wijenbergh <46386452+jwijenbergh@users.noreply.github.com> | 2024-05-08 13:54:45 +0000 |
| commit | 9ce4e4458794290755c68a180125acc68ab84038 (patch) | |
| tree | d4211e55bd77d07938651619733c7b435597d53a | |
| parent | 580f94b4023fba35ab2f58d2e6d7b3b7c40ec139 (diff) | |
Server: Add a way to pass OAuth start time
| -rw-r--r-- | client/client.go | 10 | ||||
| -rw-r--r-- | client/client_test.go | 11 | ||||
| -rw-r--r-- | cmd/cli/main.go | 2 | ||||
| -rw-r--r-- | docs/src/api/functiondocs.md | 9 | ||||
| -rw-r--r-- | exports/exports.go | 14 | ||||
| -rw-r--r-- | internal/server/custom.go | 15 | ||||
| -rw-r--r-- | internal/server/institute.go | 16 | ||||
| -rw-r--r-- | internal/server/secureinternet.go | 17 | ||||
| -rw-r--r-- | wrappers/python/eduvpn_common/loader.py | 4 | ||||
| -rw-r--r-- | wrappers/python/eduvpn_common/main.py | 9 | ||||
| -rw-r--r-- | wrappers/python/eduvpn_common/types.py | 11 |
11 files changed, 82 insertions, 36 deletions
diff --git a/client/client.go b/client/client.go index 7a6747b..291b190 100644 --- a/client/client.go +++ b/client/client.go @@ -302,9 +302,11 @@ func (c *Client) TrySave() { } // AddServer adds a server with identifier and type -func (c *Client) AddServer(ck *cookie.Cookie, identifier string, _type srvtypes.Type, ni bool) (err error) { +func (c *Client) AddServer(ck *cookie.Cookie, identifier string, _type srvtypes.Type, ot *int64) (err error) { c.mu.Lock() defer c.mu.Unlock() + // we are non-interactive if oauth time is non-nil + ni := ot != nil // If we have failed to add the server, we remove it again // We add the server because we can then obtain it in other callback functions previousState := c.FSM.Current @@ -335,17 +337,17 @@ func (c *Client) AddServer(ck *cookie.Cookie, identifier string, _type srvtypes. switch _type { case srvtypes.TypeInstituteAccess: - err = c.Servers.AddInstitute(ck.Context(), c.cfg.Discovery(), identifier, ni) + err = c.Servers.AddInstitute(ck.Context(), c.cfg.Discovery(), identifier, ot) if err != nil { return i18nerr.Wrapf(err, "The institute access server with URL: '%s' could not be added", identifier) } case srvtypes.TypeSecureInternet: - err = c.Servers.AddSecure(ck.Context(), c.cfg.Discovery(), identifier, ni) + err = c.Servers.AddSecure(ck.Context(), c.cfg.Discovery(), identifier, ot) if err != nil { return i18nerr.Wrapf(err, "The secure internet server with organisation ID: '%s' could not be added", identifier) } case srvtypes.TypeCustom: - err = c.Servers.AddCustom(ck.Context(), identifier, ni) + err = c.Servers.AddCustom(ck.Context(), identifier, ot) if err != nil { return i18nerr.Wrapf(err, "The custom server with URL: '%s' could not be added", identifier) } diff --git a/client/client_test.go b/client/client_test.go index a221c93..4afcff5 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -95,7 +95,7 @@ func TestServer(t *testing.T) { t.Fatalf("Registering error: %v", err) } - addErr := state.AddServer(ck, serverURI, srvtypes.TypeCustom, false) + addErr := state.AddServer(ck, serverURI, srvtypes.TypeCustom, nil) if addErr != nil { t.Fatalf("Add error: %v", addErr) } @@ -143,7 +143,7 @@ func TestTokenExpired(t *testing.T) { t.Fatalf("Registering error: %v", err) } - addErr := state.AddServer(ck, serverURI, srvtypes.TypeCustom, false) + addErr := state.AddServer(ck, serverURI, srvtypes.TypeCustom, nil) if addErr != nil { t.Fatalf("Add error: %v", addErr) } @@ -202,7 +202,7 @@ func TestInvalidProfileCorrected(t *testing.T) { t.Fatalf("Registering error: %v", err) } - addErr := state.AddServer(ck, serverURI, srvtypes.TypeCustom, false) + addErr := state.AddServer(ck, serverURI, srvtypes.TypeCustom, nil) if addErr != nil { t.Fatalf("Add error: %v", addErr) } @@ -259,7 +259,8 @@ func TestConfigStartup(t *testing.T) { t.Fatalf("Failed to register with error: %v", err) } // we set true as last argument here such that no callbacks are ran - err = state.AddServer(ck, serverURI, srvtypes.TypeCustom, true) + var ot int64 = 5 + err = state.AddServer(ck, serverURI, srvtypes.TypeCustom, &ot) if err != nil { t.Fatalf("Failed to add server for trying config startup: %v", err) } @@ -319,7 +320,7 @@ func TestPreferTCP(t *testing.T) { t.Fatalf("Registering error: %v", err) } - addErr := state.AddServer(ck, serverURI, srvtypes.TypeCustom, false) + addErr := state.AddServer(ck, serverURI, srvtypes.TypeCustom, nil) if addErr != nil { t.Fatalf("Add error: %v", addErr) } diff --git a/cmd/cli/main.go b/cmd/cli/main.go index f769044..3f5913a 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -146,7 +146,7 @@ func getConfig(state *client.Client, url string, srvType srvtypes.Type) (*srvtyp } ck := cookie.NewWithContext(context.Background()) defer ck.Cancel() //nolint:errcheck - err := state.AddServer(ck, url, srvType, false) + err := state.AddServer(ck, url, srvType, nil) if err != nil { return nil, err } diff --git a/docs/src/api/functiondocs.md b/docs/src/api/functiondocs.md index 42013ce..58134f7 100644 --- a/docs/src/api/functiondocs.md +++ b/docs/src/api/functiondocs.md @@ -56,7 +56,7 @@ the whole UI around it. The SetState and InState functions are useful for this ## AddServer Signature: ```go -func AddServer(c C.uintptr_t, _type C.int, id *C.char, ni C.int) *C.char +func AddServer(c C.uintptr_t, _type C.int, id *C.char, ot *C.longlong) *C.char ``` AddServer adds a server to the eduvpn-common server list `c` is the cookie that is used for cancellation. Create a cookie first with CookieNew. @@ -76,8 +76,11 @@ in types/server/server.go Type `ni` stands for non-interactive. If non-zero, any state transitions will not be run. -This `ni` flag is useful for preprovisioned servers. For normal usage, -you want to set this to zero (meaning: False) +This `ot` flag is useful for preprovisioned servers; set this to non-null to +non-interactively add a server. This flag represents the Unix time OAuth was +last triggered, if the server needs to be added non-interactively but there +is no token structure, set this to zero (integer) or the current Unix time. +This value will be overwritten once OAuth is triggered. If the server cannot be added it returns the error as types/error/error.go Error. Note that the server is removed when an error has occured diff --git a/exports/exports.go b/exports/exports.go index 4b48d12..4c9e0dc 100644 --- a/exports/exports.go +++ b/exports/exports.go @@ -291,7 +291,9 @@ func Deregister() *C.char { // // `ni` stands for non-interactive. If non-zero, any state transitions will not be run. // -// This `ni` flag is useful for preprovisioned servers. For normal usage, you want to set this to zero (meaning: False) +// This `ot` flag is useful for preprovisioned servers; set this to non-null to non-interactively add a server. +// This flag represents the Unix time OAuth was last triggered, if the server needs to be added non-interactively but there is no +// token structure, set this to zero (integer) or the current Unix time. This value will be overwritten once OAuth is triggered. // // If the server cannot be added it returns the error as types/error/error.go Error. // Note that the server is removed when an error has occured @@ -316,7 +318,7 @@ func Deregister() *C.char { // } // //export AddServer -func AddServer(c C.uintptr_t, _type C.int, id *C.char, ni C.int) *C.char { +func AddServer(c C.uintptr_t, _type C.int, id *C.char, ot *C.longlong) *C.char { state, stateErr := getVPNState() if stateErr != nil { return getCError(stateErr) @@ -325,7 +327,13 @@ func AddServer(c C.uintptr_t, _type C.int, id *C.char, ni C.int) *C.char { if err != nil { return getCError(err) } - err = state.AddServer(v, C.GoString(id), srvtypes.Type(_type), ni != 0) + // get the go oauth time + var auth *int64 + if ot != nil { + got := int64(*ot) + auth = &got + } + err = state.AddServer(v, C.GoString(id), srvtypes.Type(_type), auth) return getCError(err) } diff --git a/internal/server/custom.go b/internal/server/custom.go index a35cbab..dabf9e5 100644 --- a/internal/server/custom.go +++ b/internal/server/custom.go @@ -2,6 +2,7 @@ package server import ( "context" + "time" "github.com/eduvpn/eduvpn-common/internal/api" "github.com/eduvpn/eduvpn-common/internal/config/v2" @@ -13,8 +14,8 @@ import ( // AddCustom adds a custom server to the internal server list // `ctx` is the context used for cancellation // `id` is the identifier of the server, the base URL -// `na` specifies whether or not we want to add the server without doing authorization now -func (s *Servers) AddCustom(ctx context.Context, id string, na bool) error { +// `ot` specifies specifies the start time OAuth was already triggered +func (s *Servers) AddCustom(ctx context.Context, id string, ot *int64) error { sd := api.ServerData{ ID: id, Type: server.TypeCustom, @@ -22,13 +23,19 @@ func (s *Servers) AddCustom(ctx context.Context, id string, na bool) error { BaseAuthWK: id, } - err := s.config.AddServer(id, server.TypeCustom, v2.Server{}) + auth := time.Time{} + if ot != nil { + auth = time.Unix(*ot, 0) + } + err := s.config.AddServer(id, server.TypeCustom, v2.Server{ + LastAuthorizeTime: auth, + }) if err != nil { return err } // no authorization should be triggered, return - if na { + if ot != nil { return nil } diff --git a/internal/server/institute.go b/internal/server/institute.go index 7cb399f..caae004 100644 --- a/internal/server/institute.go +++ b/internal/server/institute.go @@ -2,6 +2,7 @@ package server import ( "context" + "time" "github.com/eduvpn/eduvpn-common/internal/api" "github.com/eduvpn/eduvpn-common/internal/config/v2" @@ -15,8 +16,8 @@ import ( // `ctx` is the context used for cancellation // `disco` are the discovery servers // `id` is the identifier for the server, the base url -// `na` is true when authorization should not be triggered -func (s *Servers) AddInstitute(ctx context.Context, disco *discovery.Discovery, id string, na bool) error { +// `ot` specifies specifies the start time OAuth was already triggered +func (s *Servers) AddInstitute(ctx context.Context, disco *discovery.Discovery, id string, ot *int64) error { // This is basically done to double check if the server is part of the institute access section of disco dsrv, err := disco.ServerByURL(id, "institute_access") if err != nil { @@ -30,13 +31,20 @@ func (s *Servers) AddInstitute(ctx context.Context, disco *discovery.Discovery, BaseAuthWK: dsrv.BaseURL, } - err = s.config.AddServer(dsrv.BaseURL, server.TypeInstituteAccess, v2.Server{}) + auth := time.Time{} + if ot != nil { + auth = time.Unix(*ot, 0) + } + + err = s.config.AddServer(dsrv.BaseURL, server.TypeInstituteAccess, v2.Server{ + LastAuthorizeTime: auth, + }) if err != nil { return err } // no authorization should be triggered, return - if na { + if ot != nil { return nil } diff --git a/internal/server/secureinternet.go b/internal/server/secureinternet.go index 4b9c29e..746dd4f 100644 --- a/internal/server/secureinternet.go +++ b/internal/server/secureinternet.go @@ -3,6 +3,7 @@ package server import ( "context" "errors" + "time" "github.com/eduvpn/eduvpn-common/internal/api" "github.com/eduvpn/eduvpn-common/internal/config/v2" @@ -17,8 +18,8 @@ import ( // `ctx` is the context used for cancellation // `disco` are the discovery servers // `orgID` is the organiztaion ID -// `na` specifies whether or not authorization should be triggered when adding -func (s *Servers) AddSecure(ctx context.Context, disco *discovery.Discovery, orgID string, na bool) error { +// `ot` specifies specifies the start time OAuth was already triggered +func (s *Servers) AddSecure(ctx context.Context, disco *discovery.Discovery, orgID string, ot *int64) error { if s.config.HasSecureInternet() { return errors.New("a secure internet server already exists") } @@ -41,13 +42,21 @@ func (s *Servers) AddSecure(ctx context.Context, disco *discovery.Discovery, org }, } - err = s.config.AddServer(orgID, server.TypeSecureInternet, v2.Server{CountryCode: dsrv.CountryCode}) + auth := time.Time{} + if ot != nil { + auth = time.Unix(*ot, 0) + } + + err = s.config.AddServer(orgID, server.TypeSecureInternet, v2.Server{ + CountryCode: dsrv.CountryCode, + LastAuthorizeTime: auth, + }) if err != nil { return err } // no authorization should be triggered, return - if na { + if ot != nil { return nil } diff --git a/wrappers/python/eduvpn_common/loader.py b/wrappers/python/eduvpn_common/loader.py index 360ec04..d258dab 100644 --- a/wrappers/python/eduvpn_common/loader.py +++ b/wrappers/python/eduvpn_common/loader.py @@ -1,5 +1,5 @@ import pathlib -from ctypes import CDLL, c_char_p, c_int, c_void_p, cdll +from ctypes import CDLL, c_char_p, c_int, c_longlong, c_void_p, cdll, POINTER from eduvpn_common import __version__ from eduvpn_common.types import ( @@ -66,7 +66,7 @@ def initialize_functions(lib: CDLL) -> None: c_int, c_int, c_char_p, - c_int, + POINTER(c_longlong), ], c_char_p, ) diff --git a/wrappers/python/eduvpn_common/main.py b/wrappers/python/eduvpn_common/main.py index 84ae9ab..4582c8d 100644 --- a/wrappers/python/eduvpn_common/main.py +++ b/wrappers/python/eduvpn_common/main.py @@ -1,7 +1,7 @@ import ctypes import json from enum import IntEnum -from typing import Any, Callable, Iterator +from typing import Any, Callable, Iterator, Optional from eduvpn_common.event import EventHandler from eduvpn_common.loader import initialize_functions, load_lib @@ -151,16 +151,17 @@ class EduVPN(object): if register_err: forwardError(register_err) - def add_server(self, _type: ServerType, _id: str, ni: bool = False) -> None: + def add_server(self, _type: ServerType, _id: str, ot: Optional[int] = None) -> None: """Add a server :param _type: ServerType: The type of server e.g. SERVER.INSTITUTE_ACCESS :param _id: str: The identifier of the server, e.g. "https://vpn.example.com/" - :param ni: bool: Whether the server should be added non interactively, meaning no callbacks + :param ot: Optional[int]: The time when OAuth was last started. + if != None the server is added without any interactivity :raises WrappedError: An error by the Go library """ - add_err = self.go_cookie_function(self.lib.AddServer, int(_type), _id, ni) + add_err = self.go_cookie_function(self.lib.AddServer, int(_type), _id, ot) if add_err: forwardError(add_err) diff --git a/wrappers/python/eduvpn_common/types.py b/wrappers/python/eduvpn_common/types.py index 837ead6..e9a1e86 100644 --- a/wrappers/python/eduvpn_common/types.py +++ b/wrappers/python/eduvpn_common/types.py @@ -1,5 +1,5 @@ -from ctypes import CDLL, CFUNCTYPE, POINTER, Structure, c_char, c_char_p, c_int, c_size_t, c_ulonglong, c_void_p, cast -from typing import Any, Iterator, List, Tuple +from ctypes import CDLL, CFUNCTYPE, POINTER, Structure, byref, c_char, c_char_p, c_int, c_longlong, c_size_t, c_ulonglong, c_void_p, cast +from typing import Any, Iterator, List, Optional, Tuple class DataError(Structure): @@ -29,6 +29,12 @@ TokenGetter = CFUNCTYPE(c_void_p, c_char_p, c_int, POINTER(c_char), c_size_t) TokenSetter = CFUNCTYPE(c_void_p, c_char_p, c_int, c_char_p) +def conv_longlongp(val: Optional[int]) -> POINTER(c_longlong): + if val is None: + return None + return byref(c_longlong(val)) + + def encode_args(args: List[Any], types: List[Any]) -> Iterator[Any]: """Encode the arguments ready to be used by the Go library @@ -44,6 +50,7 @@ def encode_args(args: List[Any], types: List[Any]) -> Iterator[Any]: # c_char_p needs the str to be encoded to bytes encode_map = { c_char_p: lambda x: x.encode("utf-8"), + POINTER(c_longlong): conv_longlongp, } if t in encode_map: arg = encode_map[t](arg) |
