func changeAccountPassword(ctx context.Context, w http.ResponseWriter, r *http.Request) { var acct account.Account var email string var newPassword string // read the account ID if emailBytes, err := base64.RawURLEncoding.DecodeString(rest.Param(ctx, "id")); err != nil { rest.WriteJSON(w, err) return } else { email = string(emailBytes) } if err := rest.ReadJSON(r, &newPassword); err != nil { rest.WriteJSON(w, err) } else if err := account.Get(ctx, email, &acct); err != nil { rest.WriteJSON(w, err) } else if err := acct.SetPassword(newPassword); err != nil { rest.WriteJSON(w, err) } else if err := account.Save(ctx, &acct); err != nil { rest.WriteJSON(w, err) } else { rest.WriteJSON(w, &rest.NoContent) } }
func changeAccount(ctx context.Context, w http.ResponseWriter, r *http.Request) { var acct account.Account var resp rest.Response resp.Body = &acct var email string var err error // read the account ID if emailBytes, err := base64.RawURLEncoding.DecodeString(rest.Param(ctx, "id")); err != nil { rest.WriteJSON(w, err) return } else { email = string(emailBytes) } // read the account and merge it with the request body if err = account.Get(ctx, email, &acct); err != nil { rest.WriteJSON(w, err) return } else if err = rest.ReadJSON(r, &acct); err != nil { rest.WriteJSON(w, err) return } // is the email address changing? if email != acct.Email { // run the change, then reread the account if err = account.ChangeEmail(ctx, email, acct.Email); err != nil { rest.WriteJSON(w, err) return } email = acct.Email if err = account.Get(ctx, email, &acct); err != nil { rest.WriteJSON(w, err) return } // point to the new URL on response newAccountURL, _ := r.URL.Parse("..") newAccountURL, _ = newAccountURL.Parse(base64.RawURLEncoding.EncodeToString([]byte(acct.Email))) w.Header().Set("Location", newAccountURL.String()) resp.Code = http.StatusMovedPermanently } // save the remaining changes to the account if err = account.Save(ctx, &acct); err != nil { rest.WriteJSON(w, err) return } rest.WriteJSON(w, &resp) }
func TestHasRole(t *testing.T) { ctx, done, _ := aetest.NewContext() defer done() ctx = test.WithConfig(ctx, map[string]interface{}{"AuthSecret": "foo"}) w := httptest.NewRecorder() r, _ := http.NewRequest("GET", "/", nil) r.Header.Set("Authorization", "wrong") // Make up a fake user acct, _ := account.New(ctx, "*****@*****.**", "foobar") acct.Roles = append(acct.Roles, "tyrant") account.Save(ctx, acct) // Unretrievable user, because middleware hasn't been run. if err := HasRole("foo")(ctx, w, r); err != ErrCannotGetAccount { t.Errorf("Unexpected error, wanted ErrCannotGetAccount, got %s", err) } // User's set, but claimset isn't for some reason. ctx2 := context.WithValue(ctx, internal.AuthContextKey, &account.Nobody) if err := HasRole("foo")(ctx2, w, r); err != ErrCannotGetClaimSet { t.Errorf("Unexpected error, wanted ErrCannotGetClaimSet, got %s", err) } // Account doesn't have the role. r.Header.Set("Authorization", test.JWT(&jws.ClaimSet{Sub: "*****@*****.**", Scope: AllScope}, "foo")) ctx2 = Middleware(ctx, w, r) if err := HasRole("foo")(ctx2, w, r); err != ErrRoleMissing { t.Errorf("Unexpected error, wanted ErrRoleMissing, got %s", err) } // Token doesn't have the role in scope. r.Header.Set("Authorization", test.JWT(&jws.ClaimSet{Sub: "*****@*****.**", Scope: "somethingelse"}, "foo")) ctx2 = Middleware(ctx, w, r) if err := HasRole("tyrant")(ctx2, w, r); err != ErrRoleNotInScope { t.Errorf("Unexpected error, wanted ErrRoleNotInScope, got %s", err) } // Token is consumable, but hasn't been used yet. consumableToken := test.ConsumableJWT(&jws.ClaimSet{Sub: "*****@*****.**", Scope: "tyrant"}, "foo", 1) r.Header.Set("Authorization", consumableToken) ctx2 = Middleware(ctx, w, r) if err := HasRole("tyrant")(ctx2, w, r); err != nil { t.Errorf("Unexpected error, wanted nil, got %s", err) } // We used this token once already. Should be used up. ctx2 = Middleware(ctx, w, r) if err := HasRole("tyrant")(ctx2, w, r); err != ErrClaimSetUsedUp { t.Errorf("Unexpected error, wanted ErrClaimSetUsedUp, got %s", err) } }