-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
273 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package repo | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/cli/browser" | ||
"github.com/sirupsen/logrus" | ||
|
||
"github.com/go-vela/sdk-go/vela" | ||
api "github.com/go-vela/server/api/types" | ||
) | ||
|
||
// Install executes the repo app installation process, which should redirect to the SCM web flow. | ||
func (c *Config) Install(client *vela.Client, repo *api.Repo) error { | ||
logrus.Debug("executing app install for repo configuration") | ||
|
||
// start the local server | ||
err := c.StartServer() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// request the install URL from the server | ||
installHTMLURL, _, err := client.Repo.InstallHTMLURL(repo.GetOrg(), repo.GetName()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// attach contextual information like cli type and local server port | ||
*installHTMLURL = fmt.Sprintf( | ||
"%s&type=%s&port=%s", | ||
*installHTMLURL, | ||
"cli", strconv.Itoa(c.server.Port()), | ||
) | ||
|
||
// launch the login process in the browser | ||
err = browser.OpenURL(*installHTMLURL) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// capture result from local server | ||
err = c.WaitForResult(client) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// WaitForResult will wait for the callback and handle the response. | ||
func (c *Config) WaitForResult(client *vela.Client) error { | ||
logrus.Debug("waiting for app installation server callback") | ||
|
||
// waiting for local server to receive the redirect | ||
_, err := c.server.WaitForResult() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// StartServer starts a local server as part of the | ||
// auth flow. It will handle the callback. | ||
func (c *Config) StartServer() error { | ||
logrus.Debug("starting local server") | ||
|
||
// set up the local server to capture the redirect from auth | ||
server, err := bindLocalServer() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
logrus.Debug("local server is bound") | ||
|
||
// store on struct | ||
c.server = server | ||
|
||
// start the server up | ||
go func() { | ||
_ = c.server.Serve() | ||
}() | ||
|
||
logrus.Debug("local server started") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// mostly taken from https://github.com/cli/oauth/tree/v0.8.0/webapp | ||
|
||
package repo | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"net" | ||
"net/http" | ||
) | ||
|
||
type CodeResponse struct { | ||
Code string | ||
State string | ||
} | ||
|
||
type localServer struct { | ||
CallbackPath string | ||
WriteSuccessHTML func(w io.Writer) | ||
|
||
resultChan chan (CodeResponse) | ||
listener net.Listener | ||
} | ||
|
||
// bindLocalServer initializes a LocalServer that will listen on a randomly available TCP port. | ||
func bindLocalServer() (*localServer, error) { | ||
listener, err := net.Listen("tcp4", "127.0.0.1:0") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &localServer{ | ||
listener: listener, | ||
resultChan: make(chan CodeResponse, 1), | ||
}, nil | ||
} | ||
|
||
func (s *localServer) Port() int { | ||
return s.listener.Addr().(*net.TCPAddr).Port | ||
} | ||
|
||
func (s *localServer) Close() error { | ||
return s.listener.Close() | ||
} | ||
|
||
func (s *localServer) Serve() error { | ||
//nolint:gosec // TODO: add a way to timeout the local server | ||
return http.Serve(s.listener, s) | ||
} | ||
|
||
func (s *localServer) WaitForResult() (CodeResponse, error) { | ||
return <-s.resultChan, nil | ||
} | ||
|
||
// ServeHTTP implements http.Handler. | ||
func (s *localServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||
if s.CallbackPath != "" && r.URL.Path != s.CallbackPath { | ||
w.WriteHeader(http.StatusNotFound) | ||
return | ||
} | ||
|
||
defer func() { | ||
_ = s.Close() | ||
}() | ||
|
||
params := r.URL.Query() | ||
s.resultChan <- CodeResponse{ | ||
Code: params.Get("code"), | ||
State: params.Get("state"), | ||
} | ||
|
||
w.Header().Add("content-type", "text/html") | ||
|
||
if s.WriteSuccessHTML != nil { | ||
s.WriteSuccessHTML(w) | ||
} else { | ||
defaultSuccessHTML(w) | ||
} | ||
} | ||
|
||
func defaultSuccessHTML(w io.Writer) { | ||
fmt.Fprint(w, authSuccess) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,4 +27,6 @@ type Config struct { | |
PerPage int | ||
Output string | ||
Color output.ColorOptions | ||
|
||
server *localServer | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package repo | ||
|
||
// authSuccess provides the HTML for rendering | ||
// a message in the browser after successfully | ||
// completing the oauth workflow. | ||
const authSuccess = ` | ||
<!doctype html> | ||
<meta charset="utf-8"> | ||
<title>Success: Vela CLI</title> | ||
<style type="text/css"> | ||
body { | ||
color: hsl(0, 0%, 98%); | ||
background-color: hsl(0, 0%, 16%); | ||
font-size: 14px; | ||
font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif; | ||
line-height: 1.5; | ||
max-width: 620px; | ||
margin: 28px auto; | ||
text-align: center; | ||
} | ||
.vela-logo-star { | ||
fill: hsl(289, 54.8%, 57.5%); | ||
} | ||
.vela-logo-lines { | ||
fill: hsl(194, 89.7%, 58%); | ||
} | ||
.box { | ||
background-color: hsl(0, 0%, 16%); | ||
} | ||
h1 { | ||
font-size: 24px; | ||
margin-bottom: 0; | ||
} | ||
p { | ||
margin-top: 0; | ||
} | ||
.box { | ||
border: 1px solid hsl(286, 29%, 51%); | ||
padding: 24px; | ||
margin: 28px; | ||
} | ||
@media (prefers-color-scheme: light) { | ||
body { | ||
color: hsl(0, 0%, 16%); | ||
background-color: hsl(0, 0%, 98%); | ||
} | ||
.box { | ||
background-color: hsl(0, 0%, 98%); | ||
} | ||
</style> | ||
<body> | ||
<svg width="72" height="72" viewBox="0 0 1920 1920" class="vela-logo"> | ||
<path class="vela-logo-lines" | ||
d="M618.73 431.74h-162.1a56.87 56.87 0 0 0-50.86 82.3l501.05 1002.1a56.86 56.86 0 0 0 101.72 0l332.85-665.72 63.63 127.07-294.74 589.5a170.64 170.64 0 0 1-152.6 94.33 170.64 170.64 0 0 1-152.6-94.33L304.03 564.9A170.61 170.61 0 0 1 456.63 318h105.14l56.96 113.75Z" /> | ||
<path class="vela-logo-lines" | ||
d="M625.05 318h126.9l56.94 113.74h-126.9L625.05 318Zm253.65 0h63.45l56.94 113.74h-63.44L878.7 318ZM675.82 545.47l281.86 563.74 147.3-294.62 137.58-20.82-284.88 569.76-409.03-818.06h127.17Z" /> | ||
<path class="vela-logo-star" | ||
d="m1372.75 659.05-234.4 35.44 168.8-166.43L1201.96 318l209.51 107.16 168.8-166.45-38.7 233.88 210.46 109.1-234.4 35.43-38.7 233.89-106.17-211.97Z" /> | ||
</svg> | ||
<div class="box"> | ||
<h1>Successfully authenticated with Vela!</h1> | ||
<p>You may now close this tab and return to the terminal.</p> | ||
</div> | ||
</body> | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters