-func (s oauth2State) computeHMAC(key []byte) []byte {
- mac := hmac.New(sha256.New, key)
- fmt.Fprintf(mac, "%x %s %s", s.Time, s.Remote, s.ReturnTo)
- return mac.Sum(nil)
+func createAPIClientAuthorization(ctx context.Context, conn *rpc.Conn, rootToken string, authinfo rpc.UserSessionAuthInfo) (resp arvados.APIClientAuthorization, err error) {
+ ctxRoot := auth.NewContext(ctx, &auth.Credentials{Tokens: []string{rootToken}})
+ newsession, err := conn.UserSessionCreate(ctxRoot, rpc.UserSessionCreateOptions{
+ // Send a fake ReturnTo value instead of the caller's
+ // opts.ReturnTo. We won't follow the resulting
+ // redirect target anyway.
+ ReturnTo: ",https://none.invalid",
+ AuthInfo: authinfo,
+ })
+ if err != nil {
+ return
+ }
+ target, err := url.Parse(newsession.RedirectLocation)
+ if err != nil {
+ return
+ }
+ token := target.Query().Get("api_token")
+ tx, err := ctrlctx.CurrentTx(ctx)
+ if err != nil {
+ return
+ }
+ tokensecret := token
+ if strings.Contains(token, "/") {
+ tokenparts := strings.Split(token, "/")
+ if len(tokenparts) >= 3 {
+ tokensecret = tokenparts[2]
+ }
+ }
+ var exp sql.NullString
+ var scopes []byte
+ err = tx.QueryRowxContext(ctx, "select uuid, api_token, expires_at, scopes from api_client_authorizations where api_token=$1", tokensecret).Scan(&resp.UUID, &resp.APIToken, &exp, &scopes)
+ if err != nil {
+ return
+ }
+ resp.ExpiresAt = exp.String
+ if len(scopes) > 0 {
+ err = json.Unmarshal(scopes, &resp.Scopes)
+ if err != nil {
+ return resp, fmt.Errorf("unmarshal scopes: %s", err)
+ }
+ }
+ return