summaryrefslogtreecommitdiff
path: root/internal/server/institute/institute.go
blob: 46977ac8b6fbb65c0b9bd410b667e822c7bf9edf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package institute

import (
	"context"

	"github.com/eduvpn/eduvpn-common/internal/discovery"
	"github.com/eduvpn/eduvpn-common/internal/oauth"
	"github.com/eduvpn/eduvpn-common/internal/server/api"
	"github.com/eduvpn/eduvpn-common/internal/server/base"
	"github.com/eduvpn/eduvpn-common/types/server"
	"github.com/go-errors/errors"
)

type Server struct {
	// An instute access server has its own OAuth
	Auth oauth.OAuth `json:"oauth"`

	// Embed the server base
	Basic base.Base `json:"base"`
}

type Servers struct {
	Map        map[string]*Server `json:"map"`
	CurrentURL string             `json:"current_url"`
}

func New(
	ctx context.Context,
	clientID string,
	url string,
	name map[string]string,
	supportContact []string,
) (*Server, error) {
	b := base.Base{
		URL:            url,
		DisplayName:    name,
		SupportContact: supportContact,
		Type:           server.TypeInstituteAccess,
	}
	if err := api.Endpoints(ctx, &b); err != nil {
		return nil, err
	}
	API := b.Endpoints.API.V3

	s := &Server{Basic: b}
	s.Auth.Init(clientID, url, API.Authorization, API.Token)
	return s, nil
}

func (s *Servers) Current() (*Server, error) {
	if s.Map == nil {
		return nil, errors.Errorf("No map is found when getting the current server")
	}

	srv, ok := s.Map[s.CurrentURL]
	if !ok || srv == nil {
		return nil, errors.Errorf("server not found")
	}
	return srv, nil
}

func (s *Servers) Remove(url string) error {
	// check if it is in the map to begin with
	if _, ok := s.Map[url]; ok {
		delete(s.Map, url)
	} else {
		return errors.Errorf("cannot remove URL: %v, not found in list", url)
	}

	// Reset the current url
	if s.CurrentURL == url {
		s.CurrentURL = ""
	}
	return nil
}

func (s *Servers) Add(srv *Server) {
	if s.Map == nil {
		s.Map = make(map[string]*Server)
	}
	s.Map[srv.Basic.URL] = srv
}

func (s *Server) TemplateAuth() func(string) string {
	return func(authURL string) string {
		return authURL
	}
}

func (s *Server) Base() (*base.Base, error) {
	return &s.Basic, nil
}

func (s *Server) OAuth() *oauth.OAuth {
	return &s.Auth
}

func (s *Server) NeedsLocation() bool {
	return false
}

func (s *Server) RefreshEndpoints(ctx context.Context, _ *discovery.Discovery) error {
	// Re-initialize the endpoints
	b, err := s.Base()
	if err != nil {
		return err
	}

	err = api.Endpoints(ctx, b)
	if err != nil {
		return err
	}

	// update OAuth
	auth := s.OAuth()
	if auth != nil {
		auth.BaseAuthorizationURL = b.Endpoints.API.V3.Authorization
		auth.TokenURL = b.Endpoints.API.V3.Token
	}
	return nil
}

func (s *Server) Public() (interface{}, error) {
	return &server.Server{
		DisplayName: s.Basic.DisplayName,
		Identifier:  s.Basic.URL,
		Profiles:    s.Basic.Profiles.Public(),
	}, nil
}