@@ -5,11 +5,8 @@ import (
55 "fmt"
66 "io"
77 "log"
8- "net"
98 "net/http"
109 "os"
11- "os/exec"
12- "strings"
1310 "time"
1411
1512 "github.com/doubleunion/accesscontrol/door"
@@ -21,20 +18,13 @@ import (
2118 "golang.org/x/crypto/acme/autocert"
2219)
2320
24- const serviceFilePath = "/etc/systemd/system/accesscontrol.service"
25- const ipQueryURL = "https://wtfismyip.com/text"
26-
27- var localInternetAddress = os .Getenv ("LOCAL_INTERNET_ADDRESS" )
28-
2921func RunRouter () {
3022 signingKey := os .Getenv ("ACCESS_CONTROL_SIGNING_KEY" )
3123 if signingKey == "" {
3224 log .Fatal ("signing key is missing" )
3325 }
3426
35- if localInternetAddress == "" {
36- log .Fatal ("local internet address is missing" )
37- }
27+ beginLocalIPMonitoring ()
3828
3929 door := door .New ()
4030
@@ -96,88 +86,3 @@ func RunRouter() {
9686func jsonResponse (c echo.Context , code int , message string ) error {
9787 return c .JSON (code , map [string ]string {"message" : message })
9888}
99-
100- func requireLocalNetworkMiddleware (next echo.HandlerFunc ) echo.HandlerFunc {
101- return func (c echo.Context ) error {
102- // Get the remote address from the request
103- remoteAddr := c .Request ().RemoteAddr
104-
105- // Parse the IP address
106- ip , _ , err := net .SplitHostPort (remoteAddr )
107- if err != nil {
108- return echo .NewHTTPError (http .StatusInternalServerError , "failed to parse IP address" )
109- }
110-
111- if ip != localInternetAddress {
112- return jsonResponse (c , http .StatusForbidden , "requests not allowed from remote hosts" )
113- }
114-
115- // Continue to the next middleware or route handler
116- return next (c )
117- }
118- }
119-
120- func UpdateIPAndRestart () error {
121- // Step 1: Query current IP address
122- resp , err := http .Get (ipQueryURL )
123- if err != nil {
124- return err
125- }
126- defer resp .Body .Close ()
127-
128- ipBytes , err := io .ReadAll (resp .Body )
129- if err != nil {
130- return err
131- }
132- currentIP := strings .TrimSpace (string (ipBytes ))
133-
134- // Step 2: Read the service file
135- content , err := os .ReadFile (serviceFilePath )
136- if err != nil {
137- return err
138- }
139-
140- // Step 3: Check if the IP matches
141- lines := strings .Split (string (content ), "\n " )
142- var updatedContent []string
143- ipUpdated := false
144- for _ , line := range lines {
145- if strings .HasPrefix (line , "Environment=LOCAL_INTERNET_ADDRESS=" ) {
146- fileIP := strings .TrimPrefix (line , "Environment=LOCAL_INTERNET_ADDRESS=" )
147- if fileIP != currentIP {
148- line = "Environment=LOCAL_INTERNET_ADDRESS=" + currentIP
149- ipUpdated = true
150- }
151- }
152- updatedContent = append (updatedContent , line )
153- }
154-
155- // Step 4: Update the file if necessary
156- if ipUpdated {
157- // first we have to output the new contents to a temporary file
158- // because we don't have access to the service file directly
159- tempFilePath := "/tmp/accesscontrol.service"
160- err = os .WriteFile (tempFilePath , []byte (strings .Join (updatedContent , "\n " )), 0644 )
161- if err != nil {
162- return err
163- }
164-
165- // then we copy the temporary file to the service file path
166- // the path is owned by the process user so this is allowed by the OS without sudo
167- cmd := exec .Command ("cp" , tempFilePath , serviceFilePath )
168- err = cmd .Run ()
169- if err != nil {
170- return err
171- }
172-
173- // Step 5: Restart the Raspberry Pi
174- cmd = exec .Command ("sudo" , "shutdown" , "-r" , "now" )
175- //log.Printf("Error in updateIPAndRestart: %v", err)
176- err = cmd .Run ()
177- if err != nil {
178- return err
179- }
180- }
181-
182- return nil
183- }
0 commit comments